Filter tasks in TaskPalette by category and type
This commit is contained in:
parent
0bd60bae88
commit
62f964474c
|
@ -20,6 +20,7 @@
|
||||||
#include "editor/editor_paths.h"
|
#include "editor/editor_paths.h"
|
||||||
#include "editor/editor_scale.h"
|
#include "editor/editor_scale.h"
|
||||||
#include "editor/plugins/script_editor_plugin.h"
|
#include "editor/plugins/script_editor_plugin.h"
|
||||||
|
#include "scene/gui/check_box.h"
|
||||||
|
|
||||||
//**** TaskButton
|
//**** TaskButton
|
||||||
|
|
||||||
|
@ -198,6 +199,112 @@ void TaskPalette::_apply_filter(const String &p_text) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TaskPalette::_show_filter_popup() {
|
||||||
|
_update_filter_popup();
|
||||||
|
|
||||||
|
category_list->reset_size();
|
||||||
|
category_scroll->set_custom_minimum_size(category_list->get_size() + Size2(8, 8));
|
||||||
|
|
||||||
|
Rect2i rect = tool_filters->get_screen_rect();
|
||||||
|
rect.position.y += rect.size.height;
|
||||||
|
rect.size.height = 0;
|
||||||
|
filter_popup->reset_size();
|
||||||
|
filter_popup->popup(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskPalette::_update_filter_popup() {
|
||||||
|
switch (filter_settings.type_filter) {
|
||||||
|
case FilterSettings::TypeFilter::TYPE_ALL: {
|
||||||
|
type_all->set_pressed(true);
|
||||||
|
} break;
|
||||||
|
case FilterSettings::TypeFilter::TYPE_CORE: {
|
||||||
|
type_core->set_pressed(true);
|
||||||
|
} break;
|
||||||
|
case FilterSettings::TypeFilter::TYPE_USER: {
|
||||||
|
type_user->set_pressed(true);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (filter_settings.category_filter) {
|
||||||
|
case FilterSettings::CategoryFilter::CATEGORY_ALL: {
|
||||||
|
category_all->set_pressed(true);
|
||||||
|
} break;
|
||||||
|
case FilterSettings::CategoryFilter::CATEGORY_INCLUDE: {
|
||||||
|
category_include->set_pressed(true);
|
||||||
|
} break;
|
||||||
|
case FilterSettings::CategoryFilter::CATEGORY_EXCLUDE: {
|
||||||
|
category_exclude->set_pressed(true);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < category_list->get_child_count(); i++) {
|
||||||
|
category_list->get_child(i)->queue_free();
|
||||||
|
}
|
||||||
|
for (String &cat : LimboTaskDB::get_categories()) {
|
||||||
|
CheckBox *category_item = memnew(CheckBox);
|
||||||
|
category_item->set_text(cat);
|
||||||
|
category_item->set_pressed_no_signal(LOGICAL_XOR(
|
||||||
|
filter_settings.excluded_categories.has(cat),
|
||||||
|
filter_settings.category_filter == FilterSettings::CategoryFilter::CATEGORY_INCLUDE));
|
||||||
|
category_item->connect(SNAME("toggled"), callable_mp(this, &TaskPalette::_category_item_toggled).bind(cat));
|
||||||
|
category_list->add_child(category_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
category_choice->set_visible(filter_settings.category_filter != FilterSettings::CATEGORY_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskPalette::_category_filter_changed() {
|
||||||
|
if (category_all->is_pressed()) {
|
||||||
|
filter_settings.category_filter = FilterSettings::CategoryFilter::CATEGORY_ALL;
|
||||||
|
} else if (category_include->is_pressed()) {
|
||||||
|
filter_settings.category_filter = FilterSettings::CategoryFilter::CATEGORY_INCLUDE;
|
||||||
|
} else if (category_exclude->is_pressed()) {
|
||||||
|
filter_settings.category_filter = FilterSettings::CategoryFilter::CATEGORY_EXCLUDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < category_list->get_child_count(); i++) {
|
||||||
|
CheckBox *item = Object::cast_to<CheckBox>(category_list->get_child(i));
|
||||||
|
item->set_pressed_no_signal(LOGICAL_XOR(
|
||||||
|
filter_settings.excluded_categories.has(item->get_text()),
|
||||||
|
filter_settings.category_filter == FilterSettings::CATEGORY_INCLUDE));
|
||||||
|
}
|
||||||
|
|
||||||
|
category_choice->set_visible(filter_settings.category_filter != FilterSettings::CATEGORY_ALL);
|
||||||
|
filter_popup->reset_size();
|
||||||
|
_filter_data_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskPalette::_set_all_filter_categories(bool p_selected) {
|
||||||
|
for (int i = 0; i < category_list->get_child_count(); i++) {
|
||||||
|
CheckBox *item = Object::cast_to<CheckBox>(category_list->get_child(i));
|
||||||
|
item->set_pressed_no_signal(p_selected);
|
||||||
|
bool excluded = LOGICAL_XOR(p_selected, filter_settings.category_filter == FilterSettings::CATEGORY_INCLUDE);
|
||||||
|
_set_category_excluded(item->get_text(), excluded);
|
||||||
|
}
|
||||||
|
_filter_data_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskPalette::_type_filter_changed() {
|
||||||
|
if (type_all->is_pressed()) {
|
||||||
|
filter_settings.type_filter = FilterSettings::TypeFilter::TYPE_ALL;
|
||||||
|
} else if (type_core->is_pressed()) {
|
||||||
|
filter_settings.type_filter = FilterSettings::TypeFilter::TYPE_CORE;
|
||||||
|
} else if (type_user->is_pressed()) {
|
||||||
|
filter_settings.type_filter = FilterSettings::TypeFilter::TYPE_USER;
|
||||||
|
}
|
||||||
|
_filter_data_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskPalette::_category_item_toggled(bool p_pressed, const String &p_category) {
|
||||||
|
bool excluded = LOGICAL_XOR(p_pressed, filter_settings.category_filter == FilterSettings::CATEGORY_INCLUDE);
|
||||||
|
_set_category_excluded(p_category, excluded);
|
||||||
|
_filter_data_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskPalette::_filter_data_changed() {
|
||||||
|
call_deferred(SNAME("refresh"));
|
||||||
|
}
|
||||||
|
|
||||||
void TaskPalette::refresh() {
|
void TaskPalette::refresh() {
|
||||||
filter_edit->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
|
filter_edit->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons")));
|
||||||
|
|
||||||
|
@ -232,8 +339,11 @@ void TaskPalette::refresh() {
|
||||||
categories.sort();
|
categories.sort();
|
||||||
|
|
||||||
for (String cat : categories) {
|
for (String cat : categories) {
|
||||||
List<String> tasks = LimboTaskDB::get_tasks_in_category(cat);
|
if (filter_settings.category_filter != FilterSettings::CATEGORY_ALL && filter_settings.excluded_categories.has(cat)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> tasks = LimboTaskDB::get_tasks_in_category(cat);
|
||||||
if (tasks.size() == 0) {
|
if (tasks.size() == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -246,12 +356,18 @@ void TaskPalette::refresh() {
|
||||||
DocTools *dd = EditorHelp::get_doc_data();
|
DocTools *dd = EditorHelp::get_doc_data();
|
||||||
HashMap<String, DocData::ClassDoc>::Iterator E;
|
HashMap<String, DocData::ClassDoc>::Iterator E;
|
||||||
if (task_meta.begins_with("res:")) {
|
if (task_meta.begins_with("res:")) {
|
||||||
|
if (filter_settings.type_filter == FilterSettings::TYPE_CORE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
tname = task_meta.get_file().get_basename().trim_prefix("BT").to_pascal_case();
|
tname = task_meta.get_file().get_basename().trim_prefix("BT").to_pascal_case();
|
||||||
E = dd->class_list.find(vformat("\"%s\"", task_meta.trim_prefix("res://")));
|
E = dd->class_list.find(vformat("\"%s\"", task_meta.trim_prefix("res://")));
|
||||||
if (!E) {
|
if (!E) {
|
||||||
E = dd->class_list.find(tname);
|
E = dd->class_list.find(tname);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (filter_settings.type_filter == FilterSettings::TYPE_USER) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
tname = task_meta.trim_prefix("BT");
|
tname = task_meta.trim_prefix("BT");
|
||||||
E = dd->class_list.find(task_meta);
|
E = dd->class_list.find(task_meta);
|
||||||
}
|
}
|
||||||
|
@ -299,7 +415,11 @@ void TaskPalette::_notification(int p_what) {
|
||||||
conf.save(conf_path);
|
conf.save(conf_path);
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_THEME_CHANGED: {
|
case NOTIFICATION_THEME_CHANGED: {
|
||||||
refresh_btn->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
|
tool_filters->set_icon(get_theme_icon(SNAME("AnimationFilter"), SNAME("EditorIcons")));
|
||||||
|
tool_refresh->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons")));
|
||||||
|
select_all->set_icon(get_theme_icon(SNAME("LimboSelectAll"), SNAME("EditorIcons")));
|
||||||
|
deselect_all->set_icon(get_theme_icon(SNAME("LimboDeselectAll"), SNAME("EditorIcons")));
|
||||||
|
|
||||||
if (is_visible_in_tree()) {
|
if (is_visible_in_tree()) {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
@ -321,6 +441,13 @@ TaskPalette::TaskPalette() {
|
||||||
HBoxContainer *hb = memnew(HBoxContainer);
|
HBoxContainer *hb = memnew(HBoxContainer);
|
||||||
vb->add_child(hb);
|
vb->add_child(hb);
|
||||||
|
|
||||||
|
tool_filters = memnew(Button);
|
||||||
|
tool_filters->set_tooltip_text(TTR("Show filters"));
|
||||||
|
tool_filters->set_flat(true);
|
||||||
|
tool_filters->set_focus_mode(FocusMode::FOCUS_NONE);
|
||||||
|
tool_filters->connect("pressed", callable_mp(this, &TaskPalette::_show_filter_popup));
|
||||||
|
hb->add_child(tool_filters);
|
||||||
|
|
||||||
filter_edit = memnew(LineEdit);
|
filter_edit = memnew(LineEdit);
|
||||||
filter_edit->set_clear_button_enabled(true);
|
filter_edit->set_clear_button_enabled(true);
|
||||||
filter_edit->set_placeholder(TTR("Filter tasks"));
|
filter_edit->set_placeholder(TTR("Filter tasks"));
|
||||||
|
@ -328,12 +455,12 @@ TaskPalette::TaskPalette() {
|
||||||
filter_edit->set_h_size_flags(SIZE_EXPAND_FILL);
|
filter_edit->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
hb->add_child(filter_edit);
|
hb->add_child(filter_edit);
|
||||||
|
|
||||||
refresh_btn = memnew(Button);
|
tool_refresh = memnew(Button);
|
||||||
refresh_btn->set_tooltip_text(TTR("Refresh tasks"));
|
tool_refresh->set_tooltip_text(TTR("Refresh tasks"));
|
||||||
refresh_btn->set_flat(true);
|
tool_refresh->set_flat(true);
|
||||||
refresh_btn->set_focus_mode(FocusMode::FOCUS_NONE);
|
tool_refresh->set_focus_mode(FocusMode::FOCUS_NONE);
|
||||||
refresh_btn->connect("pressed", callable_mp(this, &TaskPalette::refresh));
|
tool_refresh->connect("pressed", callable_mp(this, &TaskPalette::refresh));
|
||||||
hb->add_child(refresh_btn);
|
hb->add_child(tool_refresh);
|
||||||
|
|
||||||
ScrollContainer *sc = memnew(ScrollContainer);
|
ScrollContainer *sc = memnew(ScrollContainer);
|
||||||
sc->set_h_size_flags(SIZE_EXPAND_FILL);
|
sc->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
@ -348,6 +475,120 @@ TaskPalette::TaskPalette() {
|
||||||
menu = memnew(PopupMenu);
|
menu = memnew(PopupMenu);
|
||||||
add_child(menu);
|
add_child(menu);
|
||||||
menu->connect("id_pressed", callable_mp(this, &TaskPalette::_menu_action_selected));
|
menu->connect("id_pressed", callable_mp(this, &TaskPalette::_menu_action_selected));
|
||||||
|
|
||||||
|
filter_popup = memnew(PopupPanel);
|
||||||
|
{
|
||||||
|
VBoxContainer *vbox = memnew(VBoxContainer);
|
||||||
|
filter_popup->add_child(vbox);
|
||||||
|
|
||||||
|
Label *type_header = memnew(Label);
|
||||||
|
type_header->set_text(TTR("Type"));
|
||||||
|
type_header->set_theme_type_variation("HeaderSmall");
|
||||||
|
vbox->add_child(type_header);
|
||||||
|
|
||||||
|
HBoxContainer *type_filter = memnew(HBoxContainer);
|
||||||
|
vbox->add_child(type_filter);
|
||||||
|
|
||||||
|
Ref<ButtonGroup> type_filter_group;
|
||||||
|
type_filter_group.instantiate();
|
||||||
|
|
||||||
|
type_all = memnew(Button);
|
||||||
|
type_all->set_text(TTR("All"));
|
||||||
|
type_all->set_tooltip_text(TTR("Show tasks of all types"));
|
||||||
|
type_all->set_toggle_mode(true);
|
||||||
|
type_all->set_focus_mode(FocusMode::FOCUS_NONE);
|
||||||
|
type_all->set_button_group(type_filter_group);
|
||||||
|
type_all->set_pressed(true);
|
||||||
|
type_all->connect("pressed", callable_mp(this, &TaskPalette::_type_filter_changed));
|
||||||
|
type_filter->add_child(type_all);
|
||||||
|
|
||||||
|
type_core = memnew(Button);
|
||||||
|
type_core->set_text(TTR("Core"));
|
||||||
|
type_core->set_tooltip_text(TTR("Show only core tasks"));
|
||||||
|
type_core->set_toggle_mode(true);
|
||||||
|
type_core->set_focus_mode(FocusMode::FOCUS_NONE);
|
||||||
|
type_core->set_button_group(type_filter_group);
|
||||||
|
type_core->connect("pressed", callable_mp(this, &TaskPalette::_type_filter_changed));
|
||||||
|
type_filter->add_child(type_core);
|
||||||
|
|
||||||
|
type_user = memnew(Button);
|
||||||
|
type_user->set_text(TTR("User"));
|
||||||
|
type_user->set_tooltip_text(TTR("Show only user-implemented tasks (aka scripts)"));
|
||||||
|
type_user->set_toggle_mode(true);
|
||||||
|
type_user->set_focus_mode(FocusMode::FOCUS_NONE);
|
||||||
|
type_user->set_button_group(type_filter_group);
|
||||||
|
type_user->connect("pressed", callable_mp(this, &TaskPalette::_type_filter_changed));
|
||||||
|
type_filter->add_child(type_user);
|
||||||
|
|
||||||
|
Control *space1 = memnew(Control);
|
||||||
|
space1->set_custom_minimum_size(Size2(0, 4));
|
||||||
|
vbox->add_child(space1);
|
||||||
|
|
||||||
|
Label *category_header = memnew(Label);
|
||||||
|
category_header->set_text(TTR("Categories"));
|
||||||
|
category_header->set_theme_type_variation("HeaderSmall");
|
||||||
|
vbox->add_child(category_header);
|
||||||
|
|
||||||
|
HBoxContainer *category_filter = memnew(HBoxContainer);
|
||||||
|
vbox->add_child(category_filter);
|
||||||
|
|
||||||
|
Ref<ButtonGroup> category_filter_group;
|
||||||
|
category_filter_group.instantiate();
|
||||||
|
|
||||||
|
category_all = memnew(Button);
|
||||||
|
category_all->set_text(TTR("All"));
|
||||||
|
category_all->set_tooltip_text(TTR("Show tasks of all categories"));
|
||||||
|
category_all->set_toggle_mode(true);
|
||||||
|
category_all->set_focus_mode(FocusMode::FOCUS_NONE);
|
||||||
|
category_all->set_pressed(true);
|
||||||
|
category_all->set_button_group(category_filter_group);
|
||||||
|
category_all->connect("pressed", callable_mp(this, &TaskPalette::_category_filter_changed));
|
||||||
|
category_filter->add_child(category_all);
|
||||||
|
|
||||||
|
category_include = memnew(Button);
|
||||||
|
category_include->set_text(TTR("Include"));
|
||||||
|
category_include->set_tooltip_text(TTR("Show tasks from selected categories"));
|
||||||
|
category_include->set_toggle_mode(true);
|
||||||
|
category_include->set_focus_mode(FocusMode::FOCUS_NONE);
|
||||||
|
category_include->set_button_group(category_filter_group);
|
||||||
|
category_include->connect("pressed", callable_mp(this, &TaskPalette::_category_filter_changed));
|
||||||
|
category_filter->add_child(category_include);
|
||||||
|
|
||||||
|
category_exclude = memnew(Button);
|
||||||
|
category_exclude->set_text(TTR("Exclude"));
|
||||||
|
category_exclude->set_tooltip_text(TTR("Don't show tasks from selected categories"));
|
||||||
|
category_exclude->set_toggle_mode(true);
|
||||||
|
category_exclude->set_focus_mode(FocusMode::FOCUS_NONE);
|
||||||
|
category_exclude->set_button_group(category_filter_group);
|
||||||
|
category_exclude->connect("pressed", callable_mp(this, &TaskPalette::_category_filter_changed));
|
||||||
|
category_filter->add_child(category_exclude);
|
||||||
|
|
||||||
|
category_choice = memnew(VBoxContainer);
|
||||||
|
vbox->add_child(category_choice);
|
||||||
|
|
||||||
|
HBoxContainer *selection_controls = memnew(HBoxContainer);
|
||||||
|
selection_controls->set_alignment(BoxContainer::ALIGNMENT_CENTER);
|
||||||
|
category_choice->add_child(selection_controls);
|
||||||
|
|
||||||
|
select_all = memnew(Button);
|
||||||
|
select_all->set_tooltip_text(TTR("Select all categories"));
|
||||||
|
select_all->set_focus_mode(FocusMode::FOCUS_NONE);
|
||||||
|
select_all->connect("pressed", callable_mp(this, &TaskPalette::_set_all_filter_categories).bind(true));
|
||||||
|
selection_controls->add_child(select_all);
|
||||||
|
|
||||||
|
deselect_all = memnew(Button);
|
||||||
|
deselect_all->set_tooltip_text(TTR("Deselect all categories"));
|
||||||
|
deselect_all->set_focus_mode(FocusMode::FOCUS_NONE);
|
||||||
|
deselect_all->connect("pressed", callable_mp(this, &TaskPalette::_set_all_filter_categories).bind(false));
|
||||||
|
selection_controls->add_child(deselect_all);
|
||||||
|
|
||||||
|
category_scroll = memnew(ScrollContainer);
|
||||||
|
category_choice->add_child(category_scroll);
|
||||||
|
|
||||||
|
category_list = memnew(VBoxContainer);
|
||||||
|
category_scroll->add_child(category_list);
|
||||||
|
}
|
||||||
|
add_child(filter_popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskPalette::~TaskPalette() {
|
TaskPalette::~TaskPalette() {
|
||||||
|
|
|
@ -15,8 +15,10 @@
|
||||||
|
|
||||||
#include "scene/gui/box_container.h"
|
#include "scene/gui/box_container.h"
|
||||||
#include "scene/gui/button.h"
|
#include "scene/gui/button.h"
|
||||||
|
#include "scene/gui/check_box.h"
|
||||||
#include "scene/gui/flow_container.h"
|
#include "scene/gui/flow_container.h"
|
||||||
#include "scene/gui/line_edit.h"
|
#include "scene/gui/line_edit.h"
|
||||||
|
#include "scene/gui/popup.h"
|
||||||
|
|
||||||
class TaskButton : public Button {
|
class TaskButton : public Button {
|
||||||
GDCLASS(TaskButton, Button);
|
GDCLASS(TaskButton, Button);
|
||||||
|
@ -64,10 +66,41 @@ private:
|
||||||
MENU_FAVORITE,
|
MENU_FAVORITE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FilterSettings {
|
||||||
|
enum TypeFilter {
|
||||||
|
TYPE_ALL,
|
||||||
|
TYPE_CORE,
|
||||||
|
TYPE_USER,
|
||||||
|
} type_filter;
|
||||||
|
|
||||||
|
enum CategoryFilter {
|
||||||
|
CATEGORY_ALL,
|
||||||
|
CATEGORY_INCLUDE,
|
||||||
|
CATEGORY_EXCLUDE,
|
||||||
|
} category_filter;
|
||||||
|
|
||||||
|
HashSet<String> excluded_categories;
|
||||||
|
} filter_settings;
|
||||||
|
|
||||||
LineEdit *filter_edit;
|
LineEdit *filter_edit;
|
||||||
VBoxContainer *sections;
|
VBoxContainer *sections;
|
||||||
PopupMenu *menu;
|
PopupMenu *menu;
|
||||||
Button *refresh_btn;
|
Button *tool_filters;
|
||||||
|
Button *tool_refresh;
|
||||||
|
|
||||||
|
// Filter popup
|
||||||
|
PopupPanel *filter_popup;
|
||||||
|
Button *type_all;
|
||||||
|
Button *type_core;
|
||||||
|
Button *type_user;
|
||||||
|
Button *category_all;
|
||||||
|
Button *category_include;
|
||||||
|
Button *category_exclude;
|
||||||
|
VBoxContainer *category_choice;
|
||||||
|
Button *select_all;
|
||||||
|
Button *deselect_all;
|
||||||
|
ScrollContainer *category_scroll;
|
||||||
|
VBoxContainer *category_list;
|
||||||
|
|
||||||
String context_task;
|
String context_task;
|
||||||
|
|
||||||
|
@ -75,6 +108,21 @@ private:
|
||||||
void _on_task_button_pressed(const String &p_task);
|
void _on_task_button_pressed(const String &p_task);
|
||||||
void _on_task_button_rmb(const String &p_task);
|
void _on_task_button_rmb(const String &p_task);
|
||||||
void _apply_filter(const String &p_text);
|
void _apply_filter(const String &p_text);
|
||||||
|
void _show_filter_popup();
|
||||||
|
void _update_filter_popup();
|
||||||
|
void _type_filter_changed();
|
||||||
|
void _category_filter_changed();
|
||||||
|
void _set_all_filter_categories(bool p_selected);
|
||||||
|
void _category_item_toggled(bool p_pressed, const String &p_category);
|
||||||
|
void _filter_data_changed();
|
||||||
|
|
||||||
|
_FORCE_INLINE_ void _set_category_excluded(const String &p_category, bool p_excluded) {
|
||||||
|
if (p_excluded) {
|
||||||
|
filter_settings.excluded_categories.insert(p_category);
|
||||||
|
} else {
|
||||||
|
filter_settings.excluded_categories.erase(p_category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<svg enable-background="new 0 0 16 16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m14.67 0h-4.35c-.61 0-1.11.43-1.25 1h1.26 3.79.55c.18 0 .33.15.33.33v1.21 3.14 1.26c.57-.15 1-.64 1-1.26v-4.35c0-.74-.59-1.33-1.33-1.33z"/><path d="m1.48 15h-.15c-.18 0-.33-.15-.33-.33v-2.05-2.3-1.25c-.57.15-1 .64-1 1.26v4.35c0 .73.59 1.32 1.33 1.32h4.35c.62 0 1.11-.43 1.26-1h-1.27z"/><path d="m11.62 2.25h-1.62-1-4.62c-1.17 0-2.13.95-2.13 2.13v4.62 1 1.62c0 1.17.95 2.13 2.13 2.13h1.62 1 1.29 3.33c1.17 0 2.13-.95 2.13-2.13v-4.62-1-1.62c0-1.18-.95-2.13-2.13-2.13zm.63 9.37c0 .35-.28.63-.63.63h-7.24c-.35 0-.63-.28-.63-.63v-7.24c0-.35.28-.63.63-.63h7.25c.34 0 .63.28.63.63v7.24z"/></g></svg>
|
After Width: | Height: | Size: 713 B |
|
@ -0,0 +1 @@
|
||||||
|
<svg enable-background="new 0 0 16 16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m10.23 4.83-3.03 4.7-1.44-2.12-.93.65 1.92 2.82c.11.15.28.25.47.25h.01c.19 0 .36-.1.47-.26l3.42-5.32.07-.1z"/><path d="m14.67 0h-4.35c-.61 0-1.11.43-1.25 1h1.26 3.79.55c.18 0 .33.15.33.33v1.21 3.14 1.26c.57-.15 1-.64 1-1.26v-4.35c0-.74-.59-1.33-1.33-1.33z"/><path d="m1.48 15h-.15c-.18 0-.33-.15-.33-.33v-2.05-2.3-1.25c-.57.15-1 .64-1 1.26v4.35c0 .73.59 1.32 1.33 1.32h4.35c.62 0 1.11-.43 1.26-1h-1.27z"/><path d="m11.62 2.25h-1.62-1-4.62c-1.17 0-2.13.95-2.13 2.13v4.62 1 1.62c0 1.17.95 2.13 2.13 2.13h1.62 1 1.29 3.33c1.17 0 2.13-.95 2.13-2.13v-4.62-1-1.62c0-1.18-.95-2.13-2.13-2.13zm.63 9.37c0 .35-.28.63-.63.63h-7.24c-.35 0-.63-.28-.63-.63v-7.24c0-.35.28-.63.63-.63h7.25c.34 0 .63.28.63.63v7.24z"/></g></svg>
|
After Width: | Height: | Size: 832 B |
|
@ -94,6 +94,7 @@ List<String> LimboTaskDB::get_categories() {
|
||||||
for (const KeyValue<String, List<String>> &E : tasks_cache) {
|
for (const KeyValue<String, List<String>> &E : tasks_cache) {
|
||||||
r_cat.push_back(E.key);
|
r_cat.push_back(E.key);
|
||||||
}
|
}
|
||||||
|
r_cat.sort();
|
||||||
return r_cat;
|
return r_cat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include "core/variant/variant.h"
|
#include "core/variant/variant.h"
|
||||||
#include "scene/resources/texture.h"
|
#include "scene/resources/texture.h"
|
||||||
|
|
||||||
|
#define LOGICAL_XOR(a, b) (a) ? !(b) : (b)
|
||||||
|
|
||||||
class LimboUtility : public Object {
|
class LimboUtility : public Object {
|
||||||
GDCLASS(LimboUtility, Object);
|
GDCLASS(LimboUtility, Object);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue