Implement mode switch button for BB parameters
This commit is contained in:
parent
b4bef31df5
commit
91ed8bfe3d
|
@ -12,6 +12,7 @@
|
|||
#include "editor_property_bb_param.h"
|
||||
|
||||
#include "modules/limboai/blackboard/bb_param/bb_param.h"
|
||||
#include "modules/limboai/editor/mode_switch_button.h"
|
||||
|
||||
#include "core/error/error_macros.h"
|
||||
#include "core/object/class_db.h"
|
||||
|
@ -204,7 +205,7 @@ void EditorPropertyBBParam::_value_edited(const String &p_property, Variant p_va
|
|||
}
|
||||
|
||||
void EditorPropertyBBParam::_mode_changed() {
|
||||
_get_edited_param()->set_value_source(value_mode->is_pressed() ? BBParam::SAVED_VALUE : BBParam::BLACKBOARD_VAR);
|
||||
_get_edited_param()->set_value_source(mode_button->get_mode() == Mode::SPECIFY_VALUE ? BBParam::SAVED_VALUE : BBParam::BLACKBOARD_VAR);
|
||||
update_property();
|
||||
}
|
||||
|
||||
|
@ -219,15 +220,13 @@ void EditorPropertyBBParam::update_property() {
|
|||
variable_edit->set_text(param->get_variable());
|
||||
variable_edit->set_editable(true);
|
||||
variable_edit->show();
|
||||
variable_mode->set_pressed_no_signal(true);
|
||||
value_mode->set_pressed_no_signal(false);
|
||||
mode_button->set_mode(Mode::BIND_VAR, true);
|
||||
} else {
|
||||
variable_edit->hide();
|
||||
_create_value_editor(param->get_type());
|
||||
value_editor->show();
|
||||
value_editor->set_object_and_property(param.ptr(), SNAME("saved_value"));
|
||||
value_mode->set_pressed_no_signal(true);
|
||||
variable_mode->set_pressed_no_signal(false);
|
||||
mode_button->set_mode(Mode::SPECIFY_VALUE, true);
|
||||
value_editor->update_property();
|
||||
}
|
||||
}
|
||||
|
@ -241,8 +240,13 @@ void EditorPropertyBBParam::_notification(int p_what) {
|
|||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
value_mode->set_icon(get_editor_theme_icon(SNAME("LimboSpecifyValue")));
|
||||
variable_mode->set_icon(get_editor_theme_icon(SNAME("BTSetVar")));
|
||||
int id = mode_button->get_mode();
|
||||
mode_button->clear();
|
||||
mode_button->add_mode(Mode::SPECIFY_VALUE, get_editor_theme_icon(SNAME("LimboSpecifyValue")), TTR("Mode: Specify value.\nClick to switch mode."));
|
||||
mode_button->add_mode(Mode::BIND_VAR, get_editor_theme_icon(SNAME("BTSetVar")), TTR("Mode: Bind blackboard variable.\nClick to switch mode."));
|
||||
if (id >= 0) {
|
||||
mode_button->set_mode(id);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
@ -251,28 +255,10 @@ EditorPropertyBBParam::EditorPropertyBBParam() {
|
|||
hbox = memnew(HBoxContainer);
|
||||
add_child(hbox);
|
||||
|
||||
HBoxContainer *modes = memnew(HBoxContainer);
|
||||
hbox->add_child(modes);
|
||||
modes->add_theme_constant_override("separation", 0);
|
||||
|
||||
Ref<ButtonGroup> modes_group;
|
||||
modes_group.instantiate();
|
||||
|
||||
value_mode = memnew(Button);
|
||||
modes->add_child(value_mode);
|
||||
value_mode->set_focus_mode(FOCUS_NONE);
|
||||
value_mode->set_button_group(modes_group);
|
||||
value_mode->set_toggle_mode(true);
|
||||
value_mode->set_tooltip_text(TTR("Specify value"));
|
||||
value_mode->connect(SNAME("pressed"), callable_mp(this, &EditorPropertyBBParam::_mode_changed));
|
||||
|
||||
variable_mode = memnew(Button);
|
||||
modes->add_child(variable_mode);
|
||||
variable_mode->set_focus_mode(FOCUS_NONE);
|
||||
variable_mode->set_button_group(modes_group);
|
||||
variable_mode->set_toggle_mode(true);
|
||||
variable_mode->set_tooltip_text(TTR("Bind to a blackboard variable"));
|
||||
variable_mode->connect(SNAME("pressed"), callable_mp(this, &EditorPropertyBBParam::_mode_changed));
|
||||
mode_button = memnew(ModeSwitchButton);
|
||||
hbox->add_child(mode_button);
|
||||
mode_button->set_focus_mode(FOCUS_NONE);
|
||||
mode_button->connect(SNAME("mode_changed"), callable_mp(this, &EditorPropertyBBParam::_mode_changed));
|
||||
|
||||
variable_edit = memnew(LineEdit);
|
||||
hbox->add_child(variable_edit);
|
||||
|
|
|
@ -16,17 +16,23 @@
|
|||
#include "editor/editor_inspector.h"
|
||||
|
||||
#include "modules/limboai/blackboard/bb_param/bb_param.h"
|
||||
#include "modules/limboai/editor/mode_switch_button.h"
|
||||
|
||||
class EditorPropertyBBParam : public EditorProperty {
|
||||
GDCLASS(EditorPropertyBBParam, EditorProperty);
|
||||
|
||||
private:
|
||||
enum Mode {
|
||||
SPECIFY_VALUE,
|
||||
BIND_VAR,
|
||||
};
|
||||
|
||||
StringName param_type;
|
||||
PropertyHint property_hint = PROPERTY_HINT_NONE;
|
||||
Mode mode = Mode::SPECIFY_VALUE;
|
||||
|
||||
HBoxContainer *hbox = nullptr;
|
||||
Button *value_mode = nullptr;
|
||||
Button *variable_mode = nullptr;
|
||||
ModeSwitchButton *mode_button = nullptr;
|
||||
EditorProperty *value_editor = nullptr;
|
||||
LineEdit *variable_edit = nullptr;
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* mode_switch_button.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2023 Serhii Snitsaruk
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
#include "mode_switch_button.h"
|
||||
|
||||
#include "core/error/error_macros.h"
|
||||
#include "core/object/object.h"
|
||||
#include "core/variant/variant.h"
|
||||
|
||||
void ModeSwitchButton::add_mode(int p_id, const Ref<Texture2D> &p_icon, const String &p_tooltip) {
|
||||
bool unique_id = true;
|
||||
for (int i = 0; i < modes.size(); i++) {
|
||||
if (modes[i].id == p_id) {
|
||||
unique_id = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ERR_FAIL_COND_MSG(unique_id == false, "ID is already in use by another button state: " + itos(p_id));
|
||||
|
||||
Mode mode;
|
||||
mode.id = p_id;
|
||||
mode.icon = p_icon;
|
||||
mode.tooltip = p_tooltip;
|
||||
modes.append(mode);
|
||||
|
||||
if (current_mode_index == -1) {
|
||||
_set_mode(0);
|
||||
}
|
||||
}
|
||||
|
||||
void ModeSwitchButton::set_mode(int p_id, bool p_no_signal) {
|
||||
ERR_FAIL_COND_MSG(modes.is_empty(), "Cannot set button state with zero states.");
|
||||
|
||||
int idx = -1;
|
||||
for (int i = 0; i < modes.size(); i++) {
|
||||
if (modes[i].id == p_id) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ERR_FAIL_COND_MSG(idx == -1, "Button state not found with such id: " + itos(p_id));
|
||||
|
||||
_set_mode(p_id);
|
||||
if (!p_no_signal) {
|
||||
emit_signal(SNAME("mode_changed"));
|
||||
}
|
||||
}
|
||||
|
||||
void ModeSwitchButton::clear() {
|
||||
current_mode_index = -1;
|
||||
modes.clear();
|
||||
}
|
||||
|
||||
void ModeSwitchButton::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("add_mode", "p_id", "p_icon", "p_tooltip"), &ModeSwitchButton::add_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_mode"), &ModeSwitchButton::get_mode);
|
||||
ClassDB::bind_method(D_METHOD("set_mode", "p_id"), &ModeSwitchButton::set_mode);
|
||||
ClassDB::bind_method(D_METHOD("next_mode"), &ModeSwitchButton::next_mode);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("mode_changed"));
|
||||
}
|
||||
|
||||
ModeSwitchButton::ModeSwitchButton() {
|
||||
call_deferred(SNAME("connect"), SNAME("pressed"), callable_mp(this, &ModeSwitchButton::next_mode));
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* mode_switch_button.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2023 Serhii Snitsaruk
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
#ifndef MODE_SWITCH_BUTTON
|
||||
#define MODE_SWITCH_BUTTON
|
||||
|
||||
#include "scene/gui/button.h"
|
||||
|
||||
#include "core/typedefs.h"
|
||||
#include "scene/resources/texture.h"
|
||||
|
||||
class ModeSwitchButton : public Button {
|
||||
GDCLASS(ModeSwitchButton, Button);
|
||||
|
||||
private:
|
||||
struct Mode {
|
||||
int id = 0;
|
||||
Ref<Texture2D> icon = nullptr;
|
||||
String tooltip = "";
|
||||
};
|
||||
int current_mode_index = -1;
|
||||
|
||||
Vector<Mode> modes;
|
||||
|
||||
_FORCE_INLINE_ void _set_mode(int p_id) {
|
||||
current_mode_index = p_id;
|
||||
set_icon(modes[current_mode_index].icon);
|
||||
if (!modes[current_mode_index].tooltip.is_empty()) {
|
||||
set_tooltip_text(modes[current_mode_index].tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void add_mode(int p_id, const Ref<Texture2D> &p_icon, const String &p_tooltip = "");
|
||||
int get_mode() const { return modes.size() > 0 ? modes[current_mode_index].id : -1; }
|
||||
void set_mode(int p_id, bool p_no_signal = false);
|
||||
_FORCE_INLINE_ void next_mode() { set_mode((current_mode_index + 1) % modes.size()); };
|
||||
void clear();
|
||||
|
||||
ModeSwitchButton();
|
||||
};
|
||||
|
||||
#endif // MODE_SWITCH_BUTTON
|
Loading…
Reference in New Issue