Add ui for Tree search
This commit is contained in:
parent
134bb3214a
commit
7c4a462a69
|
@ -799,6 +799,9 @@ void LimboAIEditor::_misc_option_selected(int p_id) {
|
|||
EDITOR_FILE_SYSTEM()->scan();
|
||||
EDIT_SCRIPT(template_path);
|
||||
} break;
|
||||
case MISC_SEARCH_TREE: {
|
||||
UtilityFunctions::print("Search Tree");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1319,6 +1322,9 @@ void LimboAIEditor::_update_misc_menu() {
|
|||
misc_menu->add_item(
|
||||
FILE_EXISTS(_get_script_template_path()) ? TTR("Edit Script Template") : TTR("Create Script Template"),
|
||||
MISC_CREATE_SCRIPT_TEMPLATE);
|
||||
|
||||
misc_menu->add_separator();
|
||||
misc_menu->add_icon_item(theme_cache.search_icon, ("Search Tree"), MISC_SEARCH_TREE);
|
||||
}
|
||||
|
||||
void LimboAIEditor::_update_banners() {
|
||||
|
@ -1381,6 +1387,7 @@ void LimboAIEditor::_do_update_theme_item_cache() {
|
|||
theme_cache.cut_icon = get_theme_icon(LW_NAME(ActionCut), LW_NAME(EditorIcons));
|
||||
theme_cache.copy_icon = get_theme_icon(LW_NAME(ActionCopy), LW_NAME(EditorIcons));
|
||||
theme_cache.paste_icon = get_theme_icon(LW_NAME(ActionPaste), LW_NAME(EditorIcons));
|
||||
theme_cache.search_icon = get_theme_icon(LW_NAME(Search), LW_NAME(EditorIcons));
|
||||
|
||||
theme_cache.behavior_tree_icon = LimboUtility::get_singleton()->get_task_icon("BehaviorTree");
|
||||
theme_cache.percent_icon = LimboUtility::get_singleton()->get_task_icon("LimboPercent");
|
||||
|
@ -1512,6 +1519,7 @@ LimboAIEditor::LimboAIEditor() {
|
|||
LW_SHORTCUT("limbo_ai/open_debugger", TTR("Open Debugger"), (Key)(LW_KEY_MASK(CMD_OR_CTRL) | LW_KEY_MASK(ALT) | LW_KEY(D)));
|
||||
LW_SHORTCUT("limbo_ai/jump_to_owner", TTR("Jump to Owner"), (Key)(LW_KEY_MASK(CMD_OR_CTRL) | LW_KEY(J)));
|
||||
LW_SHORTCUT("limbo_ai/close_tab", TTR("Close Tab"), (Key)(LW_KEY_MASK(CMD_OR_CTRL) | LW_KEY(W)));
|
||||
LW_SHORTCUT("limbo_ai/find_task", TTR("Find Task"), (Key)(LW_KEY_MASK(CMD_OR_CTRL) | LW_KEY(F)));
|
||||
|
||||
set_process_shortcut_input(true);
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "owner_picker.h"
|
||||
#include "task_palette.h"
|
||||
#include "task_tree.h"
|
||||
#include "tree_search.h"
|
||||
|
||||
#ifdef LIMBOAI_MODULE
|
||||
#include "core/object/class_db.h"
|
||||
|
@ -100,6 +101,7 @@ private:
|
|||
MISC_LAYOUT_WIDESCREEN_OPTIMIZED,
|
||||
MISC_PROJECT_SETTINGS,
|
||||
MISC_CREATE_SCRIPT_TEMPLATE,
|
||||
MISC_SEARCH_TREE
|
||||
};
|
||||
|
||||
enum TabMenu {
|
||||
|
@ -134,6 +136,7 @@ private:
|
|||
Ref<Texture2D> cut_icon;
|
||||
Ref<Texture2D> copy_icon;
|
||||
Ref<Texture2D> paste_icon;
|
||||
Ref<Texture2D> search_icon;
|
||||
} theme_cache;
|
||||
|
||||
EditorPlugin *plugin;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "../bt/tasks/composites/bt_probability_selector.h"
|
||||
#include "../util/limbo_compat.h"
|
||||
#include "../util/limbo_utility.h"
|
||||
#include "tree_search.h"
|
||||
|
||||
#ifdef LIMBOAI_MODULE
|
||||
#include "core/object/script_language.h"
|
||||
|
@ -124,6 +125,7 @@ void TaskTree::_update_tree() {
|
|||
for (const Ref<BTTask> &task : selection) {
|
||||
add_selection(task);
|
||||
}
|
||||
tree_search.apply_search(tree);
|
||||
}
|
||||
|
||||
TreeItem *TaskTree::_find_item(const Ref<BTTask> &p_task) const {
|
||||
|
@ -566,8 +568,15 @@ TaskTree::TaskTree() {
|
|||
editable = true;
|
||||
updating_tree = false;
|
||||
|
||||
// for Tree + TreeSearch, we want a VBoxContainer. For now, rather than changing this classes type, let's do nesting:
|
||||
// TaskTree -> VBoxContainer -> [Tree, TreeSearchPanel]
|
||||
VBoxContainer * vbox_container = memnew(VBoxContainer);
|
||||
add_child(vbox_container);
|
||||
vbox_container->set_anchors_preset(PRESET_FULL_RECT);
|
||||
|
||||
tree = memnew(Tree);
|
||||
add_child(tree);
|
||||
tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
vbox_container->add_child(tree);
|
||||
tree->set_columns(2);
|
||||
tree->set_column_expand(0, true);
|
||||
tree->set_column_expand(1, false);
|
||||
|
@ -578,6 +587,7 @@ TaskTree::TaskTree() {
|
|||
tree->set_select_mode(Tree::SelectMode::SELECT_MULTI);
|
||||
|
||||
tree->set_drag_forwarding(callable_mp(this, &TaskTree::_get_drag_data_fw), callable_mp(this, &TaskTree::_can_drop_data_fw), callable_mp(this, &TaskTree::_drop_data_fw));
|
||||
vbox_container->add_child(tree_search.search_panel);
|
||||
}
|
||||
|
||||
TaskTree::~TaskTree() {
|
||||
|
|
|
@ -9,9 +9,13 @@
|
|||
* =============================================================================
|
||||
*/
|
||||
|
||||
#ifndef TASK_TREE_H
|
||||
#define TASK_TREE_H
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
#include "../bt/behavior_tree.h"
|
||||
#include "tree_search.h"
|
||||
|
||||
#ifdef LIMBOAI_MODULE
|
||||
#include "scene/gui/control.h"
|
||||
|
@ -42,6 +46,7 @@ private:
|
|||
bool editable;
|
||||
bool updating_tree;
|
||||
HashMap<RECT_CACHE_KEY, Rect2> probability_rect_cache;
|
||||
TreeSearch tree_search;
|
||||
|
||||
struct ThemeCache {
|
||||
Ref<Font> comment_font;
|
||||
|
@ -109,3 +114,4 @@ public:
|
|||
};
|
||||
|
||||
#endif // ! TOOLS_ENABLED
|
||||
#endif // ! TASK_TREE_H
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
/**
|
||||
* tree_search.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 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 "tree_search.h"
|
||||
|
||||
#include "../util/limbo_compat.h" // for edge scale
|
||||
#include "../util/limbo_string_names.h"
|
||||
#include "../util/limbo_utility.h"
|
||||
#include <godot_cpp/classes/h_separator.hpp>
|
||||
#include <godot_cpp/classes/editor_interface.hpp> // for edge scale
|
||||
#include <godot_cpp/templates/vector.hpp>
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
/* ------- TreeSearchPanel ------- */
|
||||
|
||||
void TreeSearchPanel::_initialize_controls() {
|
||||
line_edit_search = memnew(LineEdit);
|
||||
check_button_filter_highlight = memnew(CheckButton);
|
||||
close_button = memnew(Button);
|
||||
label_highlight = memnew(Label);
|
||||
label_filter = memnew(Label);
|
||||
|
||||
line_edit_search->set_placeholder(TTR("Search tree"));
|
||||
|
||||
label_highlight->set_text(TTR("Highlight"));
|
||||
label_filter->set_text(TTR("Filter"));
|
||||
|
||||
close_button->set_button_icon(get_theme_icon(LW_NAME(Close), LW_NAME(EditorIcons)));
|
||||
// positioning and sizing
|
||||
this->set_anchors_and_offsets_preset(LayoutPreset::PRESET_BOTTOM_WIDE);
|
||||
this->set_v_size_flags(SIZE_SHRINK_CENTER); // Do not expand vertically
|
||||
|
||||
// hack add separator to the left so line edit doesn't clip.
|
||||
line_edit_search->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
add_spacer(0.25); // otherwise the lineedits expand margin touches the left border.
|
||||
add_child(line_edit_search);
|
||||
add_spacer();
|
||||
add_child(label_highlight);
|
||||
add_child(check_button_filter_highlight);
|
||||
add_child(label_filter);
|
||||
add_child(close_button);
|
||||
add_spacer(0.25);
|
||||
}
|
||||
|
||||
void TreeSearchPanel::add_spacer(float width_multiplier) {
|
||||
Control *spacer = memnew(Control);
|
||||
spacer->set_custom_minimum_size(Vector2(8.0 * EDSCALE * width_multiplier, 0.0));
|
||||
add_child(spacer);
|
||||
}
|
||||
|
||||
/* !TreeSearchPanel */
|
||||
|
||||
TreeSearchPanel::TreeSearchPanel() {
|
||||
_initialize_controls();
|
||||
}
|
||||
|
||||
TreeSearchMode TreeSearchPanel::get_search_mode() {
|
||||
if (!check_button_filter_highlight || !check_button_filter_highlight->is_pressed()) {
|
||||
return TreeSearchMode::HIGHLIGHT;
|
||||
}
|
||||
return TreeSearchMode::FILTER;
|
||||
}
|
||||
|
||||
String TreeSearchPanel::get_text() {
|
||||
if (!line_edit_search)
|
||||
return String();
|
||||
return line_edit_search->get_text();
|
||||
}
|
||||
|
||||
/* ------- TreeSearch ------- */
|
||||
|
||||
void TreeSearch::filter_tree(TreeItem *tree_item, String search_mask) {
|
||||
PRINT_LINE("filter tree not yet implemented!", search_mask);
|
||||
}
|
||||
|
||||
void TreeSearch::highlight_tree(TreeItem *tree_item, String search_mask) {
|
||||
PRINT_LINE("highlight tree not yet implemented! ", search_mask);
|
||||
// queue/iterative instead of recursive approach. dsf
|
||||
Vector<TreeItem> queue;
|
||||
Vector<TreeItem> hits;
|
||||
}
|
||||
|
||||
// Call this as a post-processing step for the already constructed tree.
|
||||
void TreeSearch::apply_search(Tree *tree) {
|
||||
if (!search_panel || !search_panel->is_visible()){
|
||||
return;
|
||||
}
|
||||
|
||||
TreeItem * tree_root = tree->get_root();
|
||||
String search_mask = search_panel->get_text();
|
||||
TreeSearchMode search_mode = search_panel->get_search_mode();
|
||||
if (search_mode == TreeSearchMode::HIGHLIGHT){
|
||||
highlight_tree(tree_root, search_mask);
|
||||
}
|
||||
if (search_mode == TreeSearchMode::FILTER){
|
||||
filter_tree(tree_root, search_mask);
|
||||
}
|
||||
}
|
||||
|
||||
TreeSearch::TreeSearch() {
|
||||
search_panel = memnew(TreeSearchPanel);
|
||||
}
|
||||
|
||||
TreeSearch::~TreeSearch() {
|
||||
}
|
||||
|
||||
/* !TreeSearch */
|
||||
|
||||
#endif // ! TOOLS_ENABLED
|
|
@ -0,0 +1,84 @@
|
|||
/**
|
||||
* tree_search.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 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.
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
#ifndef TREE_SEARCH_H
|
||||
#define TREE_SEARCH_H
|
||||
|
||||
#include "../bt/tasks/bt_task.h" // for tree item parsing
|
||||
|
||||
#ifdef LIMBOAI_GDEXTENSION
|
||||
#include <godot_cpp/classes/check_button.hpp>
|
||||
#include <godot_cpp/classes/control.hpp>
|
||||
#include <godot_cpp/classes/h_box_container.hpp>
|
||||
#include <godot_cpp/classes/line_edit.hpp>
|
||||
#include <godot_cpp/classes/tree.hpp>
|
||||
#include <godot_cpp/variant/signal.hpp>
|
||||
#include <godot_cpp/classes/label.hpp>
|
||||
#endif // LIMBOAI_GDEXTENSION
|
||||
|
||||
#ifdef LIMBOAI_MODULE
|
||||
// TODO: Add includes for godot module variant.
|
||||
#endif // LIMBOAI_MODULE
|
||||
|
||||
using namespace godot;
|
||||
|
||||
enum TreeSearchMode {
|
||||
HIGHLIGHT = 0,
|
||||
FILTER = 1
|
||||
};
|
||||
|
||||
class TreeSearchPanel : public HBoxContainer {
|
||||
GDCLASS(TreeSearchPanel, HBoxContainer)
|
||||
private:
|
||||
Button *toggle_button_filter_highlight;
|
||||
Button *close_button;
|
||||
Label * label_highlight;
|
||||
Label * label_filter;
|
||||
LineEdit *line_edit_search;
|
||||
CheckButton *check_button_filter_highlight;
|
||||
|
||||
void _initialize_controls();
|
||||
void add_spacer(float width_multiplier = 1.f);
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
static void _bind_methods(){}; // we don't need anything exposed.
|
||||
|
||||
public:
|
||||
TreeSearchMode get_search_mode();
|
||||
String get_text();
|
||||
|
||||
TreeSearchPanel();
|
||||
};
|
||||
|
||||
class TreeSearch {
|
||||
private:
|
||||
void filter_tree(TreeItem *tree_item, String search_mask);
|
||||
void highlight_tree(TreeItem *tree_item, String search_mask);
|
||||
|
||||
void highlight_item(TreeItem * tree_item, String search_mask);
|
||||
Vector<TreeItem *> find_matching_entries(TreeItem * tree_item, Vector<TreeItem * > buffer = Vector<TreeItem *>());
|
||||
|
||||
public:
|
||||
// we will add everything from TaskTree.h
|
||||
void apply_search(Tree *tree);
|
||||
void set_search_evaluation_method(Callable method);
|
||||
TreeSearchPanel *search_panel;
|
||||
|
||||
TreeSearch();
|
||||
~TreeSearch();
|
||||
};
|
||||
|
||||
#endif // TREE_SEARCH_H
|
||||
#endif // ! TOOLS_ENABLED
|
|
@ -106,6 +106,7 @@
|
|||
#include "util/limbo_string_names.h"
|
||||
#include "util/limbo_task_db.h"
|
||||
#include "util/limbo_utility.h"
|
||||
#include "editor/tree_search.h"
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
#include "editor/debugger/behavior_tree_view.h"
|
||||
|
@ -267,6 +268,7 @@ void initialize_limboai_module(ModuleInitializationLevel p_level) {
|
|||
GDREGISTER_CLASS(OwnerPicker);
|
||||
GDREGISTER_CLASS(LimboAIEditor);
|
||||
GDREGISTER_CLASS(LimboAIEditorPlugin);
|
||||
GDREGISTER_INTERNAL_CLASS(TreeSearchPanel);
|
||||
#endif // LIMBOAI_GDEXTENSION
|
||||
|
||||
EditorPlugins::add_by_type<LimboAIEditorPlugin>();
|
||||
|
|
|
@ -46,6 +46,7 @@ LimboStringNames::LimboStringNames() {
|
|||
button_up = SN("button_up");
|
||||
call_deferred = SN("call_deferred");
|
||||
changed = SN("changed");
|
||||
Close = SN("Close");
|
||||
dark_color_2 = SN("dark_color_2");
|
||||
Debug = SN("Debug");
|
||||
disabled_font_color = SN("disabled_font_color");
|
||||
|
|
|
@ -62,6 +62,7 @@ public:
|
|||
StringName button_up;
|
||||
StringName call_deferred;
|
||||
StringName changed;
|
||||
StringName Close;
|
||||
StringName dark_color_2;
|
||||
StringName Debug;
|
||||
StringName disabled_font_color;
|
||||
|
|
Loading…
Reference in New Issue