Port TaskTree
This commit is contained in:
parent
97daa29eda
commit
bb346ef5f2
|
@ -11,12 +11,18 @@
|
||||||
|
|
||||||
#include "task_tree.h"
|
#include "task_tree.h"
|
||||||
|
|
||||||
#include "modules/limboai/bt/tasks/bt_comment.h"
|
#include "../bt/tasks/bt_comment.h"
|
||||||
#include "modules/limboai/bt/tasks/composites/bt_probability_selector.h"
|
#include "../bt/tasks/composites/bt_probability_selector.h"
|
||||||
#include "modules/limboai/util/limbo_utility.h"
|
#include "../util/limbo_utility.h"
|
||||||
|
|
||||||
|
#ifdef LIMBOAI_MODULE
|
||||||
#include "core/object/script_language.h"
|
#include "core/object/script_language.h"
|
||||||
#include "editor/editor_scale.h"
|
#include "editor/editor_scale.h"
|
||||||
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
using namespace godot;
|
||||||
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
//**** TaskTree
|
//**** TaskTree
|
||||||
|
|
||||||
|
@ -40,7 +46,7 @@ void TaskTree::_update_item(TreeItem *p_item) {
|
||||||
if (p_item->get_parent()) {
|
if (p_item->get_parent()) {
|
||||||
Ref<BTProbabilitySelector> sel = p_item->get_parent()->get_metadata(0);
|
Ref<BTProbabilitySelector> sel = p_item->get_parent()->get_metadata(0);
|
||||||
if (sel.is_valid() && sel->has_probability(p_item->get_index())) {
|
if (sel.is_valid() && sel->has_probability(p_item->get_index())) {
|
||||||
p_item->set_custom_draw(0, this, SNAME("_draw_probability"));
|
p_item->set_custom_draw(0, this, LSNAME(_draw_probability));
|
||||||
p_item->set_cell_mode(0, TreeItem::CELL_MODE_CUSTOM);
|
p_item->set_cell_mode(0, TreeItem::CELL_MODE_CUSTOM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +54,7 @@ void TaskTree::_update_item(TreeItem *p_item) {
|
||||||
Ref<BTTask> task = p_item->get_metadata(0);
|
Ref<BTTask> task = p_item->get_metadata(0);
|
||||||
ERR_FAIL_COND_MSG(!task.is_valid(), "Invalid task reference in metadata.");
|
ERR_FAIL_COND_MSG(!task.is_valid(), "Invalid task reference in metadata.");
|
||||||
p_item->set_text(0, task->get_task_name());
|
p_item->set_text(0, task->get_task_name());
|
||||||
if (task->is_class_ptr(BTComment::get_class_ptr_static())) {
|
if (IS_CLASS(task, BTComment)) {
|
||||||
p_item->set_custom_font(0, theme_cache.comment_font);
|
p_item->set_custom_font(0, theme_cache.comment_font);
|
||||||
p_item->set_custom_color(0, theme_cache.comment_color);
|
p_item->set_custom_color(0, theme_cache.comment_color);
|
||||||
} else if (task->get_custom_name().is_empty()) {
|
} else if (task->get_custom_name().is_empty()) {
|
||||||
|
@ -59,9 +65,10 @@ void TaskTree::_update_item(TreeItem *p_item) {
|
||||||
// p_item->set_custom_color(0, get_theme_color(SNAME("warning_color"), SNAME("Editor")));
|
// p_item->set_custom_color(0, get_theme_color(SNAME("warning_color"), SNAME("Editor")));
|
||||||
}
|
}
|
||||||
String type_arg;
|
String type_arg;
|
||||||
if (task->get_script_instance() && !task->get_script_instance()->get_script()->get_path().is_empty()) {
|
if (task->get_script() != Variant()) {
|
||||||
type_arg = task->get_script_instance()->get_script()->get_path();
|
type_arg = task->get_path();
|
||||||
} else {
|
}
|
||||||
|
if (type_arg.is_empty()) {
|
||||||
type_arg = task->get_class();
|
type_arg = task->get_class();
|
||||||
}
|
}
|
||||||
p_item->set_icon(0, LimboUtility::get_singleton()->get_task_icon(type_arg));
|
p_item->set_icon(0, LimboUtility::get_singleton()->get_task_icon(type_arg));
|
||||||
|
@ -126,13 +133,13 @@ TreeItem *TaskTree::_find_item(const Ref<BTTask> &p_task) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskTree::_on_item_mouse_selected(const Vector2 &p_pos, MouseButton p_button_index) {
|
void TaskTree::_on_item_mouse_selected(const Vector2 &p_pos, MouseButton p_button_index) {
|
||||||
if (p_button_index == MouseButton::LEFT) {
|
if (p_button_index == MBTN_LEFT) {
|
||||||
Rect2 rect = get_selected_probability_rect();
|
Rect2 rect = get_selected_probability_rect();
|
||||||
if (rect != Rect2() && rect.has_point(p_pos)) {
|
if (rect != Rect2() && rect.has_point(p_pos)) {
|
||||||
emit_signal(SNAME("probability_clicked"));
|
emit_signal(LSNAME(probability_clicked));
|
||||||
}
|
}
|
||||||
} else if (p_button_index == MouseButton::RIGHT) {
|
} else if (p_button_index == MBTN_RIGHT) {
|
||||||
emit_signal(SNAME("rmb_pressed"), get_screen_position() + p_pos);
|
emit_signal(LSNAME(rmb_pressed), get_screen_position() + p_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,17 +147,17 @@ void TaskTree::_on_item_selected() {
|
||||||
Callable on_task_changed = callable_mp(this, &TaskTree::_on_task_changed);
|
Callable on_task_changed = callable_mp(this, &TaskTree::_on_task_changed);
|
||||||
if (last_selected.is_valid()) {
|
if (last_selected.is_valid()) {
|
||||||
update_task(last_selected);
|
update_task(last_selected);
|
||||||
if (last_selected->is_connected(SNAME("changed"), on_task_changed)) {
|
if (last_selected->is_connected(LSNAME(changed), on_task_changed)) {
|
||||||
last_selected->disconnect(SNAME("changed"), on_task_changed);
|
last_selected->disconnect(LSNAME(changed), on_task_changed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
last_selected = get_selected();
|
last_selected = get_selected();
|
||||||
last_selected->connect(SNAME("changed"), on_task_changed);
|
last_selected->connect(LSNAME(changed), on_task_changed);
|
||||||
emit_signal(SNAME("task_selected"), last_selected);
|
emit_signal(LSNAME(task_selected), last_selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskTree::_on_item_activated() {
|
void TaskTree::_on_item_activated() {
|
||||||
emit_signal(SNAME("task_activated"));
|
emit_signal(LSNAME(task_activated));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskTree::_on_task_changed() {
|
void TaskTree::_on_task_changed() {
|
||||||
|
@ -161,8 +168,8 @@ void TaskTree::load_bt(const Ref<BehaviorTree> &p_behavior_tree) {
|
||||||
ERR_FAIL_COND_MSG(p_behavior_tree.is_null(), "Tried to load a null tree.");
|
ERR_FAIL_COND_MSG(p_behavior_tree.is_null(), "Tried to load a null tree.");
|
||||||
|
|
||||||
Callable on_task_changed = callable_mp(this, &TaskTree::_on_task_changed);
|
Callable on_task_changed = callable_mp(this, &TaskTree::_on_task_changed);
|
||||||
if (last_selected.is_valid() && last_selected->is_connected("changed", on_task_changed)) {
|
if (last_selected.is_valid() && last_selected->is_connected(LSNAME(changed), on_task_changed)) {
|
||||||
last_selected->disconnect("changed", on_task_changed);
|
last_selected->disconnect(LSNAME(changed), on_task_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
bt = p_behavior_tree;
|
bt = p_behavior_tree;
|
||||||
|
@ -175,8 +182,8 @@ void TaskTree::load_bt(const Ref<BehaviorTree> &p_behavior_tree) {
|
||||||
|
|
||||||
void TaskTree::unload() {
|
void TaskTree::unload() {
|
||||||
Callable on_task_changed = callable_mp(this, &TaskTree::_on_task_changed);
|
Callable on_task_changed = callable_mp(this, &TaskTree::_on_task_changed);
|
||||||
if (last_selected.is_valid() && last_selected->is_connected("changed", on_task_changed)) {
|
if (last_selected.is_valid() && last_selected->is_connected(LSNAME(changed), on_task_changed)) {
|
||||||
last_selected->disconnect("changed", on_task_changed);
|
last_selected->disconnect(LSNAME(changed), on_task_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
bt->unreference();
|
bt->unreference();
|
||||||
|
@ -210,7 +217,7 @@ Rect2 TaskTree::get_selected_probability_rect() const {
|
||||||
return Rect2();
|
return Rect2();
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectID key = tree->get_selected()->get_instance_id();
|
RECT_CACHE_KEY key = tree->get_selected()->get_instance_id();
|
||||||
if (unlikely(!probability_rect_cache.has(key))) {
|
if (unlikely(!probability_rect_cache.has(key))) {
|
||||||
return Rect2();
|
return Rect2();
|
||||||
} else {
|
} else {
|
||||||
|
@ -237,7 +244,7 @@ double TaskTree::get_selected_probability_percent() const {
|
||||||
bool TaskTree::selected_has_probability() const {
|
bool TaskTree::selected_has_probability() const {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
Ref<BTTask> selected = get_selected();
|
Ref<BTTask> selected = get_selected();
|
||||||
if (selected.is_valid() && !selected->is_class_ptr(BTComment::get_class_ptr_static())) {
|
if (selected.is_valid() && !IS_CLASS(selected, BTComment)) {
|
||||||
Ref<BTProbabilitySelector> probability_selector = selected->get_parent();
|
Ref<BTProbabilitySelector> probability_selector = selected->get_parent();
|
||||||
result = probability_selector.is_valid();
|
result = probability_selector.is_valid();
|
||||||
}
|
}
|
||||||
|
@ -291,7 +298,7 @@ void TaskTree::_drop_data_fw(const Point2 &p_point, const Variant &p_data) {
|
||||||
TreeItem *item = tree->get_item_at_position(p_point);
|
TreeItem *item = tree->get_item_at_position(p_point);
|
||||||
if (item && d.has("task")) {
|
if (item && d.has("task")) {
|
||||||
Ref<BTTask> task = d["task"];
|
Ref<BTTask> task = d["task"];
|
||||||
emit_signal(SNAME("task_dragged"), task, item->get_metadata(0), tree->get_drop_section_at_position(p_point));
|
emit_signal(LSNAME(task_dragged), task, item->get_metadata(0), tree->get_drop_section_at_position(p_point));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,30 +334,29 @@ void TaskTree::_draw_probability(Object *item_obj, Rect2 rect) {
|
||||||
prob_rect.size.x, theme_cache.probability_font_size, theme_cache.probability_font_color);
|
prob_rect.size.x, theme_cache.probability_font_size, theme_cache.probability_font_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskTree::_update_theme_item_cache() {
|
void TaskTree::_do_update_theme_item_cache() {
|
||||||
Control::_update_theme_item_cache();
|
theme_cache.name_font = get_theme_font(LSNAME(font));
|
||||||
|
theme_cache.custom_name_font = get_theme_font(LSNAME(bold), LSNAME(EditorFonts));
|
||||||
|
theme_cache.comment_font = get_theme_font(LSNAME(doc_italic), LSNAME(EditorFonts));
|
||||||
|
theme_cache.probability_font = get_theme_font(LSNAME(font));
|
||||||
|
|
||||||
theme_cache.name_font = get_theme_font(SNAME("font"));
|
theme_cache.name_font_size = get_theme_font_size(LSNAME(font_size));
|
||||||
theme_cache.custom_name_font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
|
theme_cache.probability_font_size = Math::floor(get_theme_font_size(LSNAME(font_size)) * 0.9);
|
||||||
theme_cache.comment_font = get_theme_font(SNAME("doc_italic"), SNAME("EditorFonts"));
|
|
||||||
theme_cache.probability_font = get_theme_font(SNAME("font"));
|
|
||||||
|
|
||||||
theme_cache.name_font_size = get_theme_font_size("font_size");
|
theme_cache.task_warning_icon = get_theme_icon(LSNAME(NodeWarning), LSNAME(EditorIcons));
|
||||||
theme_cache.probability_font_size = Math::floor(get_theme_font_size("font_size") * 0.9);
|
|
||||||
|
|
||||||
theme_cache.task_warning_icon = get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons"));
|
theme_cache.comment_color = get_theme_color(LSNAME(disabled_font_color), LSNAME(Editor));
|
||||||
|
theme_cache.probability_font_color = get_theme_color(LSNAME(font_color), LSNAME(Editor));
|
||||||
theme_cache.comment_color = get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"));
|
|
||||||
theme_cache.probability_font_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
|
|
||||||
|
|
||||||
theme_cache.probability_bg.instantiate();
|
theme_cache.probability_bg.instantiate();
|
||||||
theme_cache.probability_bg->set_bg_color(get_theme_color(SNAME("accent_color"), SNAME("Editor")) * Color(1, 1, 1, 0.25));
|
theme_cache.probability_bg->set_bg_color(get_theme_color(LSNAME(accent_color), LSNAME(Editor)) * Color(1, 1, 1, 0.25));
|
||||||
theme_cache.probability_bg->set_corner_radius_all(12.0 * EDSCALE);
|
theme_cache.probability_bg->set_corner_radius_all(12.0 * EDSCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskTree::_notification(int p_what) {
|
void TaskTree::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_THEME_CHANGED: {
|
case NOTIFICATION_THEME_CHANGED: {
|
||||||
|
_do_update_theme_item_cache();
|
||||||
_update_tree();
|
_update_tree();
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,27 @@
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "modules/limboai/bt/behavior_tree.h"
|
#include "../bt/behavior_tree.h"
|
||||||
|
|
||||||
|
#ifdef LIMBOAI_MODULE
|
||||||
#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"
|
||||||
|
|
||||||
|
#define RECT_CACHE_KEY ObjectID
|
||||||
|
#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/texture2d.hpp>
|
||||||
|
#include <godot_cpp/classes/tree.hpp>
|
||||||
|
#include <godot_cpp/templates/hash_map.hpp>
|
||||||
|
|
||||||
|
#define RECT_CACHE_KEY uint64_t
|
||||||
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
class TaskTree : public Control {
|
class TaskTree : public Control {
|
||||||
GDCLASS(TaskTree, Control);
|
GDCLASS(TaskTree, Control);
|
||||||
|
|
||||||
|
@ -23,7 +38,7 @@ private:
|
||||||
Ref<BehaviorTree> bt;
|
Ref<BehaviorTree> bt;
|
||||||
Ref<BTTask> last_selected;
|
Ref<BTTask> last_selected;
|
||||||
bool editable;
|
bool editable;
|
||||||
HashMap<ObjectID, Rect2> probability_rect_cache;
|
HashMap<RECT_CACHE_KEY, Rect2> probability_rect_cache;
|
||||||
|
|
||||||
struct ThemeCache {
|
struct ThemeCache {
|
||||||
Ref<Font> comment_font;
|
Ref<Font> comment_font;
|
||||||
|
@ -60,7 +75,7 @@ private:
|
||||||
void _draw_probability(Object *item_obj, Rect2 rect);
|
void _draw_probability(Object *item_obj, Rect2 rect);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void _update_theme_item_cache() override;
|
virtual void _do_update_theme_item_cache();
|
||||||
|
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);)
|
EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);)
|
||||||
|
|
||||||
#define MBTN_RIGHT MouseButton::RIGHT
|
#define MBTN_RIGHT MouseButton::RIGHT
|
||||||
|
#define MBTN_LEFT MouseButton::LEFT
|
||||||
|
|
||||||
#endif // LIMBOAI_MODULE
|
#endif // LIMBOAI_MODULE
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ using namespace godot;
|
||||||
#define SHOW_DOC(m_doc) EditorInterface::get_singleton()->get_script_editor()->get_current_editor()->emit_signal("go_to_help", m_doc)
|
#define SHOW_DOC(m_doc) EditorInterface::get_singleton()->get_script_editor()->get_current_editor()->emit_signal("go_to_help", m_doc)
|
||||||
|
|
||||||
#define MBTN_RIGHT MouseButton::MOUSE_BUTTON_RIGHT
|
#define MBTN_RIGHT MouseButton::MOUSE_BUTTON_RIGHT
|
||||||
|
#define MBTN_LEFT MouseButton::MOUSE_BUTTON_LEFT
|
||||||
|
|
||||||
// Missing definitions
|
// Missing definitions
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,18 @@ LimboStringNames::LimboStringNames() {
|
||||||
LimboDeselectAll = SN("LimboDeselectAll");
|
LimboDeselectAll = SN("LimboDeselectAll");
|
||||||
Search = SN("Search");
|
Search = SN("Search");
|
||||||
refresh = SN("refresh");
|
refresh = SN("refresh");
|
||||||
|
_draw_probability = SN("_draw_probability");
|
||||||
|
probability_clicked = SN("probability_clicked");
|
||||||
|
rmb_pressed = SN("rmb_pressed");
|
||||||
|
task_activated = SN("task_activated");
|
||||||
|
task_dragged = SN("task_dragged");
|
||||||
|
doc_italic = SN("doc_italic");
|
||||||
|
NodeWarning = SN("NodeWarning");
|
||||||
|
Editor = SN("Editor");
|
||||||
|
disabled_font_color = SN("disabled_font_color");
|
||||||
|
font_color = SN("font_color");
|
||||||
|
accent_color = SN("accent_color");
|
||||||
|
font_size = SN("font_size");
|
||||||
|
|
||||||
EVENT_FINISHED = "finished";
|
EVENT_FINISHED = "finished";
|
||||||
repeat_forever.parse_utf8("Repeat ∞");
|
repeat_forever.parse_utf8("Repeat ∞");
|
||||||
|
|
|
@ -96,6 +96,18 @@ public:
|
||||||
StringName LimboDeselectAll;
|
StringName LimboDeselectAll;
|
||||||
StringName Search;
|
StringName Search;
|
||||||
StringName refresh;
|
StringName refresh;
|
||||||
|
StringName _draw_probability;
|
||||||
|
StringName probability_clicked;
|
||||||
|
StringName rmb_pressed;
|
||||||
|
StringName task_activated;
|
||||||
|
StringName task_dragged;
|
||||||
|
StringName doc_italic;
|
||||||
|
StringName NodeWarning;
|
||||||
|
StringName Editor;
|
||||||
|
StringName disabled_font_color;
|
||||||
|
StringName font_color;
|
||||||
|
StringName accent_color;
|
||||||
|
StringName font_size;
|
||||||
|
|
||||||
String EVENT_FINISHED;
|
String EVENT_FINISHED;
|
||||||
String repeat_forever;
|
String repeat_forever;
|
||||||
|
|
Loading…
Reference in New Issue