Port BehaviorTreeView
This commit is contained in:
parent
f5b1b52f67
commit
3d86a76db9
|
@ -13,10 +13,11 @@
|
||||||
|
|
||||||
#include "behavior_tree_view.h"
|
#include "behavior_tree_view.h"
|
||||||
|
|
||||||
|
#include "../../bt/tasks/bt_task.h"
|
||||||
|
#include "../../util/limbo_utility.h"
|
||||||
#include "behavior_tree_data.h"
|
#include "behavior_tree_data.h"
|
||||||
#include "modules/limboai/bt/tasks/bt_task.h"
|
|
||||||
#include "modules/limboai/util/limbo_utility.h"
|
|
||||||
|
|
||||||
|
#ifdef LIMBOAI_MODULE
|
||||||
#include "core/math/color.h"
|
#include "core/math/color.h"
|
||||||
#include "core/math/math_defs.h"
|
#include "core/math/math_defs.h"
|
||||||
#include "core/object/callable_method_pointer.h"
|
#include "core/object/callable_method_pointer.h"
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
#include "editor/editor_scale.h"
|
#include "editor/editor_scale.h"
|
||||||
#include "editor/editor_settings.h"
|
#include "editor/editor_settings.h"
|
||||||
#include "scene/resources/style_box.h"
|
#include "scene/resources/style_box.h"
|
||||||
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
void BehaviorTreeView::_draw_running_status(Object *p_obj, Rect2 p_rect) {
|
void BehaviorTreeView::_draw_running_status(Object *p_obj, Rect2 p_rect) {
|
||||||
p_rect = p_rect.grow_side(SIDE_LEFT, p_rect.get_position().x);
|
p_rect = p_rect.grow_side(SIDE_LEFT, p_rect.get_position().x);
|
||||||
|
@ -95,18 +97,18 @@ void BehaviorTreeView::update_tree(const BehaviorTreeData &p_data) {
|
||||||
item->set_icon_max_width(0, 16 * EDSCALE); // Force user icon size.
|
item->set_icon_max_width(0, 16 * EDSCALE); // Force user icon size.
|
||||||
|
|
||||||
if (task_data.status == BTTask::SUCCESS) {
|
if (task_data.status == BTTask::SUCCESS) {
|
||||||
item->set_custom_draw(0, this, SNAME("_draw_success_status"));
|
item->set_custom_draw(0, this, LSNAME(_draw_success_status));
|
||||||
item->set_icon(1, theme_cache.icon_success);
|
item->set_icon(1, theme_cache.icon_success);
|
||||||
} else if (task_data.status == BTTask::FAILURE) {
|
} else if (task_data.status == BTTask::FAILURE) {
|
||||||
item->set_custom_draw(0, this, SNAME("_draw_failure_status"));
|
item->set_custom_draw(0, this, LSNAME(_draw_failure_status));
|
||||||
item->set_icon(1, theme_cache.icon_failure);
|
item->set_icon(1, theme_cache.icon_failure);
|
||||||
} else if (task_data.status == BTTask::RUNNING) {
|
} else if (task_data.status == BTTask::RUNNING) {
|
||||||
item->set_custom_draw(0, this, SNAME("_draw_running_status"));
|
item->set_custom_draw(0, this, LSNAME(_draw_running_status));
|
||||||
item->set_icon(1, theme_cache.icon_running);
|
item->set_icon(1, theme_cache.icon_running);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task_data.id == selected_id) {
|
if (task_data.id == selected_id) {
|
||||||
tree->set_selected(item);
|
tree->set_selected(item, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collapsed_ids.has(task_data.id)) {
|
if (collapsed_ids.has(task_data.id)) {
|
||||||
|
@ -125,14 +127,12 @@ void BehaviorTreeView::clear() {
|
||||||
collapsed_ids.clear();
|
collapsed_ids.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BehaviorTreeView::_update_theme_item_cache() {
|
void BehaviorTreeView::_do_update_theme_item_cache() {
|
||||||
Control::_update_theme_item_cache();
|
theme_cache.icon_running = get_theme_icon(LSNAME(LimboExtraClock), LSNAME(EditorIcons));
|
||||||
|
theme_cache.icon_success = get_theme_icon(LSNAME(BTAlwaysSucceed), LSNAME(EditorIcons));
|
||||||
|
theme_cache.icon_failure = get_theme_icon(LSNAME(BTAlwaysFail), LSNAME(EditorIcons));
|
||||||
|
|
||||||
theme_cache.icon_running = get_theme_icon(SNAME("LimboExtraClock"), SNAME("EditorIcons"));
|
theme_cache.font_custom_name = get_theme_font(LSNAME(bold), LSNAME(EditorFonts));
|
||||||
theme_cache.icon_success = get_theme_icon(SNAME("BTAlwaysSucceed"), SNAME("EditorIcons"));
|
|
||||||
theme_cache.icon_failure = get_theme_icon(SNAME("BTAlwaysFail"), SNAME("EditorIcons"));
|
|
||||||
|
|
||||||
theme_cache.font_custom_name = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
|
|
||||||
|
|
||||||
Color running_border = Color::html("#fea900");
|
Color running_border = Color::html("#fea900");
|
||||||
Color running_fill = Color(running_border, 0.1);
|
Color running_fill = Color(running_border, 0.1);
|
||||||
|
@ -165,6 +165,17 @@ void BehaviorTreeView::_update_theme_item_cache() {
|
||||||
tree->set_column_custom_minimum_width(2, (50.0 + extra_spacing) * EDSCALE);
|
tree->set_column_custom_minimum_width(2, (50.0 + extra_spacing) * EDSCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BehaviorTreeView::_notification(int p_what) {
|
||||||
|
switch (p_what) {
|
||||||
|
case NOTIFICATION_POSTINITIALIZE:
|
||||||
|
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
|
||||||
|
case NOTIFICATION_TRANSLATION_CHANGED:
|
||||||
|
case NOTIFICATION_THEME_CHANGED: {
|
||||||
|
_do_update_theme_item_cache();
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BehaviorTreeView::_bind_methods() {
|
void BehaviorTreeView::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("_draw_running_status"), &BehaviorTreeView::_draw_running_status);
|
ClassDB::bind_method(D_METHOD("_draw_running_status"), &BehaviorTreeView::_draw_running_status);
|
||||||
ClassDB::bind_method(D_METHOD("_draw_success_status"), &BehaviorTreeView::_draw_success_status);
|
ClassDB::bind_method(D_METHOD("_draw_success_status"), &BehaviorTreeView::_draw_success_status);
|
||||||
|
@ -181,7 +192,7 @@ BehaviorTreeView::BehaviorTreeView() {
|
||||||
tree->set_column_expand(2, false);
|
tree->set_column_expand(2, false);
|
||||||
tree->set_anchor(SIDE_RIGHT, ANCHOR_END);
|
tree->set_anchor(SIDE_RIGHT, ANCHOR_END);
|
||||||
tree->set_anchor(SIDE_BOTTOM, ANCHOR_END);
|
tree->set_anchor(SIDE_BOTTOM, ANCHOR_END);
|
||||||
tree->connect(SNAME("item_collapsed"), callable_mp(this, &BehaviorTreeView::_item_collapsed));
|
tree->connect(LSNAME(item_collapsed), callable_mp(this, &BehaviorTreeView::_item_collapsed));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TOOLS_ENABLED
|
#endif // TOOLS_ENABLED
|
||||||
|
|
|
@ -16,12 +16,19 @@
|
||||||
|
|
||||||
#include "behavior_tree_data.h"
|
#include "behavior_tree_data.h"
|
||||||
|
|
||||||
#include "core/object/class_db.h"
|
#ifdef LIMBOAI_MODULE
|
||||||
#include "core/object/object.h"
|
|
||||||
#include "scene/gui/control.h"
|
#include "scene/gui/control.h"
|
||||||
#include "scene/gui/tree.h"
|
#include "scene/gui/tree.h"
|
||||||
#include "scene/resources/style_box_flat.h"
|
#include "scene/resources/style_box_flat.h"
|
||||||
#include "scene/resources/texture.h"
|
#include "scene/resources/texture.h"
|
||||||
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
#include <godot_cpp/classes/control.hpp>
|
||||||
|
#include <godot_cpp/classes/font.hpp>
|
||||||
|
#include <godot_cpp/classes/style_box_flat.hpp>
|
||||||
|
#include <godot_cpp/classes/tree.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
class BehaviorTreeView : public Control {
|
class BehaviorTreeView : public Control {
|
||||||
GDCLASS(BehaviorTreeView, Control);
|
GDCLASS(BehaviorTreeView, Control);
|
||||||
|
@ -49,7 +56,9 @@ private:
|
||||||
void _item_collapsed(Object *p_obj);
|
void _item_collapsed(Object *p_obj);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void _update_theme_item_cache() override;
|
void _do_update_theme_item_cache();
|
||||||
|
|
||||||
|
void _notification(int p_what);
|
||||||
|
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* limbo_def.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 "limbo_def.h"
|
||||||
|
#include "godot_cpp/classes/editor_interface.hpp"
|
||||||
|
|
||||||
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
|
#include <godot_cpp/classes/editor_settings.hpp>
|
||||||
|
|
||||||
|
using namespace godot;
|
||||||
|
|
||||||
|
Variant _EDITOR_GET(const String &p_setting) {
|
||||||
|
Ref<EditorSettings> es = EditorInterface::get_singleton()->get_editor_settings();
|
||||||
|
ERR_FAIL_COND_V(es.is_null() || !es->has_setting(p_setting), Variant());
|
||||||
|
return es->get(p_setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -26,7 +26,11 @@
|
||||||
|
|
||||||
#ifdef LIMBOAI_GDEXTENSION
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
|
#include <godot_cpp/variant/string.hpp>
|
||||||
#include <godot_cpp/variant/utility_functions.hpp>
|
#include <godot_cpp/variant/utility_functions.hpp>
|
||||||
|
#include <godot_cpp/variant/variant.hpp>
|
||||||
|
|
||||||
|
using namespace godot;
|
||||||
|
|
||||||
#define IS_CLASS(m_obj, m_class) (m_obj->get_class_static() == m_class::get_class_static())
|
#define IS_CLASS(m_obj, m_class) (m_obj->get_class_static() == m_class::get_class_static())
|
||||||
#define RAND_RANGE(m_from, m_to) (UtilityFunctions::randf_range(m_from, m_to))
|
#define RAND_RANGE(m_from, m_to) (UtilityFunctions::randf_range(m_from, m_to))
|
||||||
|
@ -37,4 +41,9 @@
|
||||||
#define VCALL(m_name) (call(LSNAME(m_name)))
|
#define VCALL(m_name) (call(LSNAME(m_name)))
|
||||||
#define VCALL_ARGS(m_name, ...) (call(LSNAME(m_name), __VA_ARGS__))
|
#define VCALL_ARGS(m_name, ...) (call(LSNAME(m_name), __VA_ARGS__))
|
||||||
|
|
||||||
|
#define EDITOR_GET(m_var) _EDITOR_GET(m_var)
|
||||||
|
Variant _EDITOR_GET(const String &p_setting);
|
||||||
|
|
||||||
|
#define EDSCALE ((int)EDITOR_GET("interface/editor/display_scale"))
|
||||||
|
|
||||||
#endif // LIMBOAI_GDEXTENSION
|
#endif // LIMBOAI_GDEXTENSION
|
|
@ -41,6 +41,16 @@ LimboStringNames::LimboStringNames() {
|
||||||
_weight_ = SN("_weight_");
|
_weight_ = SN("_weight_");
|
||||||
error_value = SN("error_value");
|
error_value = SN("error_value");
|
||||||
behavior_tree = SN("behavior_tree");
|
behavior_tree = SN("behavior_tree");
|
||||||
|
_draw_success_status = SN("_draw_success_status");
|
||||||
|
_draw_failure_status = SN("_draw_failure_status");
|
||||||
|
_draw_running_status = SN("_draw_running_status");
|
||||||
|
LimboExtraClock = SN("LimboExtraClock");
|
||||||
|
EditorIcons = SN("EditorIcons");
|
||||||
|
BTAlwaysSucceed = SN("BTAlwaysSucceed");
|
||||||
|
BTAlwaysFail = SN("BTAlwaysFail");
|
||||||
|
bold = SN("bold");
|
||||||
|
EditorFonts = SN("EditorFonts");
|
||||||
|
item_collapsed = SN("item_collapsed");
|
||||||
|
|
||||||
EVENT_FINISHED = "finished";
|
EVENT_FINISHED = "finished";
|
||||||
repeat_forever.parse_utf8("Repeat ∞");
|
repeat_forever.parse_utf8("Repeat ∞");
|
||||||
|
|
|
@ -19,7 +19,9 @@
|
||||||
#endif // LIMBOAI_MODULE
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
#ifdef LIMBOAI_GDEXTENSION
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
#include "godot_cpp/variant/string.hpp"
|
||||||
#include <godot_cpp/variant/string_name.hpp>
|
#include <godot_cpp/variant/string_name.hpp>
|
||||||
|
|
||||||
using namespace godot;
|
using namespace godot;
|
||||||
#endif // LIMBOAI_GDEXTENSION
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
|
@ -58,6 +60,16 @@ public:
|
||||||
StringName _weight_;
|
StringName _weight_;
|
||||||
StringName error_value;
|
StringName error_value;
|
||||||
StringName behavior_tree;
|
StringName behavior_tree;
|
||||||
|
StringName _draw_success_status;
|
||||||
|
StringName _draw_failure_status;
|
||||||
|
StringName _draw_running_status;
|
||||||
|
StringName LimboExtraClock;
|
||||||
|
StringName EditorIcons;
|
||||||
|
StringName BTAlwaysSucceed;
|
||||||
|
StringName BTAlwaysFail;
|
||||||
|
StringName bold;
|
||||||
|
StringName EditorFonts;
|
||||||
|
StringName item_collapsed;
|
||||||
|
|
||||||
String EVENT_FINISHED;
|
String EVENT_FINISHED;
|
||||||
String repeat_forever;
|
String repeat_forever;
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#ifdef LIMBOAI_GDEXTENSION
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
#include "bt/tasks/bt_task.h"
|
#include "bt/tasks/bt_task.h"
|
||||||
|
|
||||||
|
#include <godot_cpp/classes/resource_loader.hpp>
|
||||||
|
#include <godot_cpp/classes/theme.hpp>
|
||||||
#include <godot_cpp/core/error_macros.hpp>
|
#include <godot_cpp/core/error_macros.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -63,7 +65,7 @@ String LimboUtility::get_status_name(int p_status) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Texture2D> LimboUtility::get_task_icon(String p_class_or_script_path) const {
|
Ref<Texture2D> LimboUtility::get_task_icon(String p_class_or_script_path) const {
|
||||||
#ifdef TOOLS_ENABLED
|
#if defined(TOOLS_ENABLED) && defined(LIMBOAI_MODULE)
|
||||||
ERR_FAIL_COND_V_MSG(p_class_or_script_path.is_empty(), Variant(), "BTTask: script path or class cannot be empty.");
|
ERR_FAIL_COND_V_MSG(p_class_or_script_path.is_empty(), Variant(), "BTTask: script path or class cannot be empty.");
|
||||||
|
|
||||||
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
|
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
|
||||||
|
|
Loading…
Reference in New Issue