Merge branch 'bbparam-editor'
This commit is contained in:
commit
a3594e173c
|
@ -41,8 +41,6 @@ private:
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
virtual Variant::Type get_type() const { return Variant::NIL; }
|
|
||||||
|
|
||||||
_FORCE_INLINE_ void _assign_default_value() {
|
_FORCE_INLINE_ void _assign_default_value() {
|
||||||
Callable::CallError err;
|
Callable::CallError err;
|
||||||
Variant::construct(get_type(), saved_value, nullptr, 0, err);
|
Variant::construct(get_type(), saved_value, nullptr, 0, err);
|
||||||
|
@ -51,6 +49,8 @@ protected:
|
||||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual Variant::Type get_type() const { return Variant::NIL; }
|
||||||
|
|
||||||
void set_value_source(ValueSource p_value);
|
void set_value_source(ValueSource p_value);
|
||||||
ValueSource get_value_source() const { return value_source; }
|
ValueSource get_value_source() const { return value_source; }
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,10 @@ private:
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
public:
|
||||||
virtual Variant::Type get_type() const override;
|
virtual Variant::Type get_type() const override;
|
||||||
void set_type(Variant::Type p_type);
|
void set_type(Variant::Type p_type);
|
||||||
|
|
||||||
public:
|
|
||||||
BBVariant();
|
BBVariant();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
@tool
|
@tool
|
||||||
@icon("res://icon.png")
|
@icon("res://icon.png")
|
||||||
class_name ArrivePos
|
|
||||||
extends BTAction
|
extends BTAction
|
||||||
|
|
||||||
@export var target_position_var := "target_position"
|
@export var target_position_var := "target_position"
|
||||||
|
|
|
@ -11,6 +11,7 @@ config_version=5
|
||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="LimboAI Test"
|
config/name="LimboAI Test"
|
||||||
|
config/tags=PackedStringArray("demo")
|
||||||
run/main_scene="res://examples/waypoints/example_waypoints.tscn"
|
run/main_scene="res://examples/waypoints/example_waypoints.tscn"
|
||||||
config/features=PackedStringArray("4.2")
|
config/features=PackedStringArray("4.2")
|
||||||
config/icon="res://icon.png"
|
config/icon="res://icon.png"
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
@tool
|
||||||
|
class_name TestBBParams
|
||||||
|
extends Resource
|
||||||
|
|
||||||
|
@export var bool_param: BBBool
|
||||||
|
@export var int_param: BBInt
|
||||||
|
@export var float_param: BBFloat
|
||||||
|
@export var string_param: BBString
|
||||||
|
@export var vec2_param: BBVector2
|
||||||
|
@export var vec2i_param: BBVector2i
|
||||||
|
@export var rect2_param: BBRect2
|
||||||
|
@export var rect2i_param: BBRect2i
|
||||||
|
@export var vector3_param: BBVector3
|
||||||
|
@export var vector3i_param: BBVector3i
|
||||||
|
@export var vector4_param: BBVector4
|
||||||
|
@export var vector4i_param: BBVector4i
|
||||||
|
@export var transform2d_param: BBTransform2D
|
||||||
|
@export var plane_param: BBPlane
|
||||||
|
@export var quaternion_param: BBQuaternion
|
||||||
|
@export var aabb_param: BBAabb
|
||||||
|
@export var basis_param: BBBasis
|
||||||
|
@export var transform3d_param: BBTransform3D
|
||||||
|
#@export var projection_param: BBProjection
|
||||||
|
@export var color_param: BBColor
|
||||||
|
@export var stringname_param: BBStringName
|
||||||
|
@export var node_param: BBNode
|
||||||
|
@export var dictionary_param: BBDictionary
|
||||||
|
@export var array_param: BBArray
|
||||||
|
@export var byte_array_param: BBByteArray
|
||||||
|
@export var int_array_param: BBIntArray
|
||||||
|
@export var float_array_param: BBFloatArray
|
||||||
|
@export var string_array_param: BBStringArray
|
||||||
|
@export var vector2_array_param: BBVector2Array
|
||||||
|
@export var vector3_array_param: BBVector2Array
|
||||||
|
@export var color_array_param: BBColorArray
|
||||||
|
@export var variant_param: BBVariant
|
||||||
|
|
|
@ -0,0 +1,347 @@
|
||||||
|
/**
|
||||||
|
* editor_property_bb_param.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 "editor_property_bb_param.h"
|
||||||
|
|
||||||
|
#include "core/variant/variant.h"
|
||||||
|
#include "modules/limboai/blackboard/bb_param/bb_param.h"
|
||||||
|
#include "modules/limboai/blackboard/bb_param/bb_variant.h"
|
||||||
|
#include "modules/limboai/editor/mode_switch_button.h"
|
||||||
|
|
||||||
|
#include "core/error/error_macros.h"
|
||||||
|
#include "core/io/marshalls.h"
|
||||||
|
#include "core/object/class_db.h"
|
||||||
|
#include "core/object/ref_counted.h"
|
||||||
|
#include "core/os/memory.h"
|
||||||
|
#include "core/string/print_string.h"
|
||||||
|
#include "editor/editor_inspector.h"
|
||||||
|
#include "editor/editor_properties.h"
|
||||||
|
#include "editor/editor_properties_array_dict.h"
|
||||||
|
#include "editor/editor_properties_vector.h"
|
||||||
|
#include "editor/editor_settings.h"
|
||||||
|
#include "scene/gui/base_button.h"
|
||||||
|
#include "scene/gui/box_container.h"
|
||||||
|
#include "scene/gui/button.h"
|
||||||
|
#include "scene/gui/line_edit.h"
|
||||||
|
#include "scene/gui/menu_button.h"
|
||||||
|
|
||||||
|
Ref<BBParam> EditorPropertyBBParam::_get_edited_param() {
|
||||||
|
Ref<BBParam> param = get_edited_property_value();
|
||||||
|
if (param.is_null()) {
|
||||||
|
// Create parameter resource if null.
|
||||||
|
param = ClassDB::instantiate(param_type);
|
||||||
|
get_edited_object()->set(get_edited_property(), param);
|
||||||
|
}
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyBBParam::_create_value_editor(Variant::Type p_type) {
|
||||||
|
if (value_editor) {
|
||||||
|
if (value_editor->get_meta(SNAME("_param_type")) == Variant(p_type)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_remove_value_editor();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (p_type) {
|
||||||
|
case Variant::NIL: {
|
||||||
|
value_editor = memnew(EditorPropertyNil);
|
||||||
|
} break;
|
||||||
|
case Variant::BOOL: {
|
||||||
|
value_editor = memnew(EditorPropertyCheck);
|
||||||
|
} break;
|
||||||
|
case Variant::INT: {
|
||||||
|
EditorPropertyInteger *editor = memnew(EditorPropertyInteger);
|
||||||
|
editor->setup(-100000, 100000, 1, false, true, true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::FLOAT: {
|
||||||
|
EditorPropertyFloat *editor = memnew(EditorPropertyFloat);
|
||||||
|
editor->setup(-100000, 100000, EDITOR_GET("interface/inspector/default_float_step"), true, false, true, true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::STRING: {
|
||||||
|
if (property_hint == PROPERTY_HINT_MULTILINE_TEXT) {
|
||||||
|
value_editor = memnew(EditorPropertyMultilineText);
|
||||||
|
} else {
|
||||||
|
value_editor = memnew(EditorPropertyText);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case Variant::VECTOR2: {
|
||||||
|
EditorPropertyVector2 *editor = memnew(EditorPropertyVector2);
|
||||||
|
editor->setup(-100000, 100000, EDITOR_GET("interface/inspector/default_float_step"), true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::VECTOR2I: {
|
||||||
|
EditorPropertyVector2i *editor = memnew(EditorPropertyVector2i);
|
||||||
|
editor->setup(-100000, 100000);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::RECT2: {
|
||||||
|
EditorPropertyRect2 *editor = memnew(EditorPropertyRect2);
|
||||||
|
editor->setup(-100000, 100000, EDITOR_GET("interface/inspector/default_float_step"), true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::RECT2I: {
|
||||||
|
EditorPropertyRect2i *editor = memnew(EditorPropertyRect2i);
|
||||||
|
editor->setup(-100000, 100000);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::VECTOR3: {
|
||||||
|
EditorPropertyVector3 *editor = memnew(EditorPropertyVector3);
|
||||||
|
editor->setup(-100000, 100000, EDITOR_GET("interface/inspector/default_float_step"), true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::VECTOR3I: {
|
||||||
|
EditorPropertyVector3i *editor = memnew(EditorPropertyVector3i);
|
||||||
|
editor->setup(-100000, 100000);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::VECTOR4: {
|
||||||
|
EditorPropertyVector4 *editor = memnew(EditorPropertyVector4);
|
||||||
|
editor->setup(-100000, 100000, EDITOR_GET("interface/inspector/default_float_step"), true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::VECTOR4I: {
|
||||||
|
EditorPropertyVector4i *editor = memnew(EditorPropertyVector4i);
|
||||||
|
editor->setup(-100000, 100000);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::TRANSFORM2D: {
|
||||||
|
EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D);
|
||||||
|
editor->setup(-100000, 100000, EDITOR_GET("interface/inspector/default_float_step"), true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::PLANE: {
|
||||||
|
EditorPropertyPlane *editor = memnew(EditorPropertyPlane);
|
||||||
|
editor->setup(-100000, 100000, EDITOR_GET("interface/inspector/default_float_step"), true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::QUATERNION: {
|
||||||
|
EditorPropertyQuaternion *editor = memnew(EditorPropertyQuaternion);
|
||||||
|
editor->setup(-100000, 100000, EDITOR_GET("interface/inspector/default_float_step"), true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::AABB: {
|
||||||
|
EditorPropertyAABB *editor = memnew(EditorPropertyAABB);
|
||||||
|
editor->setup(-100000, 100000, EDITOR_GET("interface/inspector/default_float_step"), true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::BASIS: {
|
||||||
|
EditorPropertyBasis *editor = memnew(EditorPropertyBasis);
|
||||||
|
editor->setup(-100000, 100000, EDITOR_GET("interface/inspector/default_float_step"), true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::TRANSFORM3D: {
|
||||||
|
EditorPropertyTransform3D *editor = memnew(EditorPropertyTransform3D);
|
||||||
|
editor->setup(-100000, 100000, EDITOR_GET("interface/inspector/default_float_step"), true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::PROJECTION: {
|
||||||
|
EditorPropertyProjection *editor = memnew(EditorPropertyProjection);
|
||||||
|
editor->setup(-100000, 100000, EDITOR_GET("interface/inspector/default_float_step"), true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::COLOR: {
|
||||||
|
value_editor = memnew(EditorPropertyColor);
|
||||||
|
} break;
|
||||||
|
case Variant::STRING_NAME: {
|
||||||
|
EditorPropertyText *editor = memnew(EditorPropertyText);
|
||||||
|
editor->set_string_name(true);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::NODE_PATH: {
|
||||||
|
value_editor = memnew(EditorPropertyNodePath);
|
||||||
|
} break;
|
||||||
|
// case Variant::RID: {
|
||||||
|
// } break;
|
||||||
|
// case Variant::SIGNAL: {
|
||||||
|
// } break;
|
||||||
|
// case Variant::CALLABLE: {
|
||||||
|
// } break;
|
||||||
|
case Variant::OBJECT: {
|
||||||
|
// Only resources are supported.
|
||||||
|
EditorPropertyResource *editor = memnew(EditorPropertyResource);
|
||||||
|
editor->setup(_get_edited_param().ptr(), SNAME("saved_value"), "Resource");
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
case Variant::DICTIONARY: {
|
||||||
|
value_editor = memnew(EditorPropertyDictionary);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Variant::ARRAY:
|
||||||
|
case Variant::PACKED_BYTE_ARRAY:
|
||||||
|
case Variant::PACKED_INT32_ARRAY:
|
||||||
|
case Variant::PACKED_FLOAT32_ARRAY:
|
||||||
|
case Variant::PACKED_INT64_ARRAY:
|
||||||
|
case Variant::PACKED_FLOAT64_ARRAY:
|
||||||
|
case Variant::PACKED_STRING_ARRAY:
|
||||||
|
case Variant::PACKED_VECTOR2_ARRAY:
|
||||||
|
case Variant::PACKED_VECTOR3_ARRAY:
|
||||||
|
case Variant::PACKED_COLOR_ARRAY: {
|
||||||
|
EditorPropertyArray *editor = memnew(EditorPropertyArray);
|
||||||
|
editor->setup(p_type);
|
||||||
|
value_editor = editor;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
ERR_PRINT("Unexpected variant type!");
|
||||||
|
value_editor = memnew(EditorPropertyNil);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value_editor->set_name_split_ratio(0.0);
|
||||||
|
editor_hbox->add_child(value_editor);
|
||||||
|
value_editor->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
value_editor->set_meta(SNAME("_param_type"), p_type);
|
||||||
|
value_editor->connect(SNAME("property_changed"), callable_mp(this, &EditorPropertyBBParam::_value_edited));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyBBParam::_remove_value_editor() {
|
||||||
|
if (value_editor) {
|
||||||
|
editor_hbox->remove_child(value_editor);
|
||||||
|
value_editor->queue_free();
|
||||||
|
value_editor = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyBBParam::_value_edited(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
|
||||||
|
_get_edited_param()->set_saved_value(p_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyBBParam::_mode_changed() {
|
||||||
|
_get_edited_param()->set_value_source(mode_button->get_mode() == Mode::SPECIFY_VALUE ? BBParam::SAVED_VALUE : BBParam::BLACKBOARD_VAR);
|
||||||
|
update_property();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyBBParam::_type_selected(int p_index) {
|
||||||
|
Ref<BBVariant> param = _get_edited_param();
|
||||||
|
ERR_FAIL_COND(param.is_null());
|
||||||
|
param->set_type(Variant::Type(p_index));
|
||||||
|
update_property();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyBBParam::_variable_edited(const String &p_text) {
|
||||||
|
_get_edited_param()->set_variable(p_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyBBParam::update_property() {
|
||||||
|
Ref<BBParam> param = _get_edited_param();
|
||||||
|
bool is_variant_param = param->is_class_ptr(BBVariant::get_class_ptr_static());
|
||||||
|
|
||||||
|
if (param->get_value_source() == BBParam::BLACKBOARD_VAR) {
|
||||||
|
_remove_value_editor();
|
||||||
|
variable_edit->set_text(param->get_variable());
|
||||||
|
variable_edit->set_editable(true);
|
||||||
|
variable_edit->show();
|
||||||
|
mode_button->set_mode(Mode::BIND_VAR, true);
|
||||||
|
type_choice->hide();
|
||||||
|
} else {
|
||||||
|
variable_edit->hide();
|
||||||
|
_create_value_editor(param->get_type());
|
||||||
|
value_editor->show();
|
||||||
|
value_editor->set_object_and_property(param.ptr(), SNAME("saved_value"));
|
||||||
|
mode_button->set_mode(Mode::SPECIFY_VALUE, true);
|
||||||
|
value_editor->update_property();
|
||||||
|
type_choice->set_visible(is_variant_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_variant_param) {
|
||||||
|
Variant::Type t = Variant::Type(param->get_type());
|
||||||
|
String type_name = Variant::get_type_name(t);
|
||||||
|
type_choice->set_icon(get_editor_theme_icon(type_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyBBParam::setup(PropertyHint p_hint, const String &p_hint_text) {
|
||||||
|
param_type = p_hint_text;
|
||||||
|
property_hint = p_hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyBBParam::_notification(int p_what) {
|
||||||
|
switch (p_what) {
|
||||||
|
case NOTIFICATION_ENTER_TREE:
|
||||||
|
case NOTIFICATION_THEME_CHANGED: {
|
||||||
|
{
|
||||||
|
String type = Variant::get_type_name(_get_edited_param()->get_type());
|
||||||
|
type_choice->set_icon(get_editor_theme_icon(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize mode button.
|
||||||
|
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."));
|
||||||
|
mode_button->set_mode(_get_edited_param()->get_value_source() == BBParam::BLACKBOARD_VAR ? Mode::BIND_VAR : Mode::SPECIFY_VALUE);
|
||||||
|
|
||||||
|
bool is_variant_param = _get_edited_param()->is_class_ptr(BBVariant::get_class_ptr_static());
|
||||||
|
if (is_variant_param) {
|
||||||
|
// Initialize type choice.
|
||||||
|
PopupMenu *type_menu = type_choice->get_popup();
|
||||||
|
type_menu->clear();
|
||||||
|
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
|
||||||
|
if (i == Variant::RID || i == Variant::CALLABLE || i == Variant::SIGNAL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String type = Variant::get_type_name(Variant::Type(i));
|
||||||
|
type_menu->add_icon_item(get_editor_theme_icon(type), type, i);
|
||||||
|
}
|
||||||
|
} else { // Not a variant param.
|
||||||
|
type_choice->hide();
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorPropertyBBParam::EditorPropertyBBParam() {
|
||||||
|
hbox = memnew(HBoxContainer);
|
||||||
|
add_child(hbox);
|
||||||
|
hbox->add_theme_constant_override(SNAME("separation"), 0);
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
type_choice = memnew(MenuButton);
|
||||||
|
hbox->add_child(type_choice);
|
||||||
|
type_choice->get_popup()->connect(SNAME("id_pressed"), callable_mp(this, &EditorPropertyBBParam::_type_selected));
|
||||||
|
type_choice->set_tooltip_text(TTR("Click to choose type"));
|
||||||
|
type_choice->set_flat(false);
|
||||||
|
|
||||||
|
editor_hbox = memnew(HBoxContainer);
|
||||||
|
hbox->add_child(editor_hbox);
|
||||||
|
editor_hbox->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
editor_hbox->add_theme_constant_override(SNAME("separation"), 0);
|
||||||
|
|
||||||
|
variable_edit = memnew(LineEdit);
|
||||||
|
editor_hbox->add_child(variable_edit);
|
||||||
|
variable_edit->set_placeholder(TTR("Variable"));
|
||||||
|
variable_edit->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
variable_edit->connect(SNAME("text_changed"), callable_mp(this, &EditorPropertyBBParam::_variable_edited));
|
||||||
|
|
||||||
|
param_type = SNAME("BBString");
|
||||||
|
}
|
||||||
|
|
||||||
|
//***** EditorInspectorPluginBBParam
|
||||||
|
|
||||||
|
bool EditorInspectorPluginBBParam::can_handle(Object *p_object) {
|
||||||
|
return true; // Handles everything.
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorInspectorPluginBBParam::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField<PropertyUsageFlags> p_usage, const bool p_wide) {
|
||||||
|
if (p_hint == PROPERTY_HINT_RESOURCE_TYPE && p_hint_text.begins_with("BB")) {
|
||||||
|
// TODO: Add more rigid hint check.
|
||||||
|
EditorPropertyBBParam *editor = memnew(EditorPropertyBBParam());
|
||||||
|
editor->setup(p_hint, p_hint_text);
|
||||||
|
add_property_editor(p_path, editor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
* editor_property_bb_param.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 EDITOR_PROPERTY_BB_PARAM_H
|
||||||
|
#define EDITOR_PROPERTY_BB_PARAM_H
|
||||||
|
|
||||||
|
#include "editor/editor_inspector.h"
|
||||||
|
|
||||||
|
#include "modules/limboai/blackboard/bb_param/bb_param.h"
|
||||||
|
#include "modules/limboai/editor/mode_switch_button.h"
|
||||||
|
|
||||||
|
#include "scene/gui/box_container.h"
|
||||||
|
#include "scene/gui/menu_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;
|
||||||
|
HBoxContainer *editor_hbox = nullptr;
|
||||||
|
ModeSwitchButton *mode_button = nullptr;
|
||||||
|
EditorProperty *value_editor = nullptr;
|
||||||
|
LineEdit *variable_edit = nullptr;
|
||||||
|
MenuButton *type_choice = nullptr;
|
||||||
|
|
||||||
|
Ref<BBParam> _get_edited_param();
|
||||||
|
|
||||||
|
void _create_value_editor(Variant::Type p_type);
|
||||||
|
void _remove_value_editor();
|
||||||
|
|
||||||
|
void _value_edited(const String &p_property, Variant p_value, const String &p_name = "", bool p_changing = false);
|
||||||
|
void _variable_edited(const String &p_text);
|
||||||
|
void _mode_changed();
|
||||||
|
void _type_selected(int p_index);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void _notification(int p_what);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void update_property() override;
|
||||||
|
void setup(PropertyHint p_hint, const String &p_hint_text);
|
||||||
|
|
||||||
|
EditorPropertyBBParam();
|
||||||
|
};
|
||||||
|
|
||||||
|
class EditorInspectorPluginBBParam : public EditorInspectorPlugin {
|
||||||
|
GDCLASS(EditorInspectorPluginBBParam, EditorInspectorPlugin);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool can_handle(Object *p_object) override;
|
||||||
|
virtual bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const BitField<PropertyUsageFlags> p_usage, const bool p_wide = false) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDITOR_PROPERTY_BB_PARAM_H
|
|
@ -18,6 +18,7 @@
|
||||||
#include "modules/limboai/bt/tasks/composites/bt_probability_selector.h"
|
#include "modules/limboai/bt/tasks/composites/bt_probability_selector.h"
|
||||||
#include "modules/limboai/bt/tasks/composites/bt_selector.h"
|
#include "modules/limboai/bt/tasks/composites/bt_selector.h"
|
||||||
#include "modules/limboai/editor/debugger/limbo_debugger_plugin.h"
|
#include "modules/limboai/editor/debugger/limbo_debugger_plugin.h"
|
||||||
|
#include "modules/limboai/editor/editor_property_bb_param.h"
|
||||||
#include "modules/limboai/util/limbo_utility.h"
|
#include "modules/limboai/util/limbo_utility.h"
|
||||||
|
|
||||||
#include "core/config/project_settings.h"
|
#include "core/config/project_settings.h"
|
||||||
|
@ -1157,6 +1158,7 @@ LimboAIEditorPlugin::LimboAIEditorPlugin() {
|
||||||
EditorNode::get_singleton()->get_main_screen_control()->add_child(limbo_ai_editor);
|
EditorNode::get_singleton()->get_main_screen_control()->add_child(limbo_ai_editor);
|
||||||
limbo_ai_editor->hide();
|
limbo_ai_editor->hide();
|
||||||
add_debugger_plugin(memnew(LimboDebuggerPlugin));
|
add_debugger_plugin(memnew(LimboDebuggerPlugin));
|
||||||
|
add_inspector_plugin(memnew(EditorInspectorPluginBBParam));
|
||||||
}
|
}
|
||||||
|
|
||||||
LimboAIEditorPlugin::~LimboAIEditorPlugin() {
|
LimboAIEditorPlugin::~LimboAIEditorPlugin() {
|
||||||
|
|
|
@ -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_by_index(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_by_index(idx);
|
||||||
|
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_by_index(int p_index) {
|
||||||
|
current_mode_index = p_index;
|
||||||
|
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
|
|
@ -0,0 +1 @@
|
||||||
|
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h16v16h-16z" fill="none"/><g fill="#e0e0e0"><path d="m1397.93 4.142v6.609c0 .94-.763 1.703-1.703 1.703h-6.609c-.94 0-1.703-.763-1.703-1.703v-6.609c0-.94.763-1.703 1.703-1.703h6.609c.94 0 1.703.763 1.703 1.703zm-.668 0c0-.572-.464-1.035-1.035-1.035h-6.609c-.572 0-1.035.463-1.035 1.035v6.609c0 .571.463 1.035 1.035 1.035h6.609c.571 0 1.035-.464 1.035-1.035z" transform="matrix(1.4978 0 0 1.4978 -2078.316 -3.15325)"/><path d="m1360.05 1.642c-1.019 0-1.932-.298-2.738-.892-.806-.595-1.44-1.459-1.903-2.592-.462-1.133-.693-2.504-.693-4.113 0-1.608.231-2.979.693-4.113.463-1.133 1.097-1.997 1.903-2.591.806-.595 1.719-.892 2.738-.892 1.032 0 1.947.297 2.748.892.8.594 1.431 1.458 1.893 2.591.463 1.134.694 2.505.694 4.113 0 1.609-.231 2.98-.694 4.113-.462 1.133-1.093 1.997-1.893 2.592-.801.594-1.716.892-2.748.892zm0-2.875c.486 0 .91-.161 1.272-.483.361-.322.646-.832.853-1.532.208-.699.311-1.601.311-2.707 0-1.105-.103-2.007-.311-2.707-.207-.699-.492-1.21-.853-1.531-.362-.322-.786-.483-1.272-.483-.474 0-.892.161-1.253.483-.362.321-.646.832-.854 1.531-.207.7-.311 1.602-.311 2.707 0 1.106.104 2.008.311 2.707.208.7.492 1.21.854 1.532.361.322.779.483 1.253.483z" fill-rule="nonzero" transform="matrix(.337428 0 0 .285928 -453.917 6.80259)"/><path d="m1373.24-10.571h-2.489v-2.728h5.37v14.689h-2.881z" transform="matrix(.337428 0 0 .285928 -452.885 6.80259)"/><path d="m1356.6 9.714h-2.49v-2.728h5.37v14.689h-2.88z" transform="matrix(.337428 0 0 .285928 -452.819 6.80259)"/><path d="m1371.59 21.927c-1.02 0-1.933-.298-2.739-.892-.806-.595-1.44-1.459-1.902-2.592-.463-1.133-.694-2.504-.694-4.113s.231-2.98.694-4.113c.462-1.133 1.096-1.997 1.902-2.591.806-.595 1.719-.892 2.739-.892 1.031 0 1.947.297 2.747.892.8.594 1.431 1.458 1.894 2.591.462 1.133.693 2.504.693 4.113s-.231 2.98-.693 4.113c-.463 1.133-1.094 1.997-1.894 2.592-.8.594-1.716.892-2.747.892zm0-2.875c.486 0 .909-.161 1.271-.483.361-.322.646-.832.853-1.532.208-.699.312-1.602.312-2.707s-.104-2.007-.312-2.707c-.207-.699-.492-1.21-.853-1.532-.362-.321-.785-.482-1.271-.482-.475 0-.892.161-1.254.482-.362.322-.646.833-.854 1.532-.207.7-.311 1.602-.311 2.707s.104 2.008.311 2.707c.208.7.492 1.21.854 1.532s.779.483 1.254.483z" fill-rule="nonzero" transform="matrix(.337428 0 0 .285928 -451.815 6.80259)"/></g></svg>
|
After Width: | Height: | Size: 2.4 KiB |
Loading…
Reference in New Issue