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 "editor_property_bb_param.h"
|
||||||
|
|
||||||
#include "modules/limboai/blackboard/bb_param/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/error/error_macros.h"
|
||||||
#include "core/object/class_db.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() {
|
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();
|
update_property();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,15 +220,13 @@ void EditorPropertyBBParam::update_property() {
|
||||||
variable_edit->set_text(param->get_variable());
|
variable_edit->set_text(param->get_variable());
|
||||||
variable_edit->set_editable(true);
|
variable_edit->set_editable(true);
|
||||||
variable_edit->show();
|
variable_edit->show();
|
||||||
variable_mode->set_pressed_no_signal(true);
|
mode_button->set_mode(Mode::BIND_VAR, true);
|
||||||
value_mode->set_pressed_no_signal(false);
|
|
||||||
} else {
|
} else {
|
||||||
variable_edit->hide();
|
variable_edit->hide();
|
||||||
_create_value_editor(param->get_type());
|
_create_value_editor(param->get_type());
|
||||||
value_editor->show();
|
value_editor->show();
|
||||||
value_editor->set_object_and_property(param.ptr(), SNAME("saved_value"));
|
value_editor->set_object_and_property(param.ptr(), SNAME("saved_value"));
|
||||||
value_mode->set_pressed_no_signal(true);
|
mode_button->set_mode(Mode::SPECIFY_VALUE, true);
|
||||||
variable_mode->set_pressed_no_signal(false);
|
|
||||||
value_editor->update_property();
|
value_editor->update_property();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,8 +240,13 @@ void EditorPropertyBBParam::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_ENTER_TREE:
|
case NOTIFICATION_ENTER_TREE:
|
||||||
case NOTIFICATION_THEME_CHANGED: {
|
case NOTIFICATION_THEME_CHANGED: {
|
||||||
value_mode->set_icon(get_editor_theme_icon(SNAME("LimboSpecifyValue")));
|
int id = mode_button->get_mode();
|
||||||
variable_mode->set_icon(get_editor_theme_icon(SNAME("BTSetVar")));
|
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;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,28 +255,10 @@ EditorPropertyBBParam::EditorPropertyBBParam() {
|
||||||
hbox = memnew(HBoxContainer);
|
hbox = memnew(HBoxContainer);
|
||||||
add_child(hbox);
|
add_child(hbox);
|
||||||
|
|
||||||
HBoxContainer *modes = memnew(HBoxContainer);
|
mode_button = memnew(ModeSwitchButton);
|
||||||
hbox->add_child(modes);
|
hbox->add_child(mode_button);
|
||||||
modes->add_theme_constant_override("separation", 0);
|
mode_button->set_focus_mode(FOCUS_NONE);
|
||||||
|
mode_button->connect(SNAME("mode_changed"), callable_mp(this, &EditorPropertyBBParam::_mode_changed));
|
||||||
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));
|
|
||||||
|
|
||||||
variable_edit = memnew(LineEdit);
|
variable_edit = memnew(LineEdit);
|
||||||
hbox->add_child(variable_edit);
|
hbox->add_child(variable_edit);
|
||||||
|
|
|
@ -16,17 +16,23 @@
|
||||||
#include "editor/editor_inspector.h"
|
#include "editor/editor_inspector.h"
|
||||||
|
|
||||||
#include "modules/limboai/blackboard/bb_param/bb_param.h"
|
#include "modules/limboai/blackboard/bb_param/bb_param.h"
|
||||||
|
#include "modules/limboai/editor/mode_switch_button.h"
|
||||||
|
|
||||||
class EditorPropertyBBParam : public EditorProperty {
|
class EditorPropertyBBParam : public EditorProperty {
|
||||||
GDCLASS(EditorPropertyBBParam, EditorProperty);
|
GDCLASS(EditorPropertyBBParam, EditorProperty);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum Mode {
|
||||||
|
SPECIFY_VALUE,
|
||||||
|
BIND_VAR,
|
||||||
|
};
|
||||||
|
|
||||||
StringName param_type;
|
StringName param_type;
|
||||||
PropertyHint property_hint = PROPERTY_HINT_NONE;
|
PropertyHint property_hint = PROPERTY_HINT_NONE;
|
||||||
|
Mode mode = Mode::SPECIFY_VALUE;
|
||||||
|
|
||||||
HBoxContainer *hbox = nullptr;
|
HBoxContainer *hbox = nullptr;
|
||||||
Button *value_mode = nullptr;
|
ModeSwitchButton *mode_button = nullptr;
|
||||||
Button *variable_mode = nullptr;
|
|
||||||
EditorProperty *value_editor = nullptr;
|
EditorProperty *value_editor = nullptr;
|
||||||
LineEdit *variable_edit = 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