feat(dependency_editor): add sort button and text filter to the dependency editor dialog
This commit is contained in:
parent
77579f93e6
commit
b3f9f8264c
2 changed files with 169 additions and 15 deletions
|
|
@ -42,7 +42,9 @@
|
|||
#include "editor/themes/editor_scale.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/item_list.h"
|
||||
#include "scene/gui/line_edit.h"
|
||||
#include "scene/gui/margin_container.h"
|
||||
#include "scene/gui/menu_button.h"
|
||||
#include "scene/gui/popup_menu.h"
|
||||
#include "scene/gui/tree.h"
|
||||
|
||||
|
|
@ -60,6 +62,34 @@ static void _setup_search_file_dialog(EditorFileDialog *p_dialog, const String &
|
|||
}
|
||||
}
|
||||
|
||||
struct DependencyEditorSortByType {
|
||||
bool operator()(const String &p_a, const String &p_b) const {
|
||||
const String a_type = p_a.contains("::") ? p_a.get_slice("::", 1) : "Resource";
|
||||
const String b_type = p_b.contains("::") ? p_b.get_slice("::", 1) : "Resource";
|
||||
const String a_path = p_a.contains("::") ? p_a.get_slice("::", 2) : p_a;
|
||||
const String b_path = p_b.contains("::") ? p_b.get_slice("::", 2) : p_b;
|
||||
return a_type == b_type ? a_path < b_path : a_type < b_type;
|
||||
}
|
||||
};
|
||||
|
||||
struct DependencyEditorSortByPath {
|
||||
bool operator()(const String &p_a, const String &p_b) const {
|
||||
const String a_path = p_a.contains("::") ? p_a.get_slice("::", 2) : p_a;
|
||||
const String b_path = p_b.contains("::") ? p_b.get_slice("::", 2) : p_b;
|
||||
return a_path < b_path;
|
||||
}
|
||||
};
|
||||
|
||||
struct DependencyEditorSortByFile {
|
||||
bool operator()(const String &p_a, const String &p_b) const {
|
||||
const String a_path = p_a.contains("::") ? p_a.get_slice("::", 2) : p_a;
|
||||
const String b_path = p_b.contains("::") ? p_b.get_slice("::", 2) : p_b;
|
||||
const String a_file = a_path.get_file();
|
||||
const String b_file = b_path.get_file();
|
||||
return a_file == b_file ? a_path < b_path : a_file < b_file;
|
||||
}
|
||||
};
|
||||
|
||||
void DependencyEditor::_searched(const String &p_path) {
|
||||
HashMap<String, String> dep_rename;
|
||||
dep_rename[replacing] = p_path;
|
||||
|
|
@ -75,7 +105,7 @@ void DependencyEditor::_load_pressed(Object *p_item, int p_cell, int p_button, M
|
|||
return;
|
||||
}
|
||||
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
|
||||
replacing = ti->get_text(1);
|
||||
replacing = ti->get_text((int)Column::PATH);
|
||||
|
||||
_setup_search_file_dialog(search, replacing, ti->get_metadata(0));
|
||||
search->popup_file_dialog();
|
||||
|
|
@ -176,6 +206,8 @@ void DependencyEditor::_update_file() {
|
|||
void DependencyEditor::_notification(int p_what) {
|
||||
if (p_what == NOTIFICATION_THEME_CHANGED) {
|
||||
warning_label->add_theme_color_override(SceneStringName(font_color), get_theme_color("warning_color", EditorStringName(Editor)));
|
||||
filter->set_right_icon(get_editor_theme_icon(SNAME("Search")));
|
||||
menu_sort->set_button_icon(get_editor_theme_icon(SNAME("Sort")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -203,9 +235,56 @@ static String _get_stored_dep_path(const String &p_dep) {
|
|||
return p_dep.get_slice("::", 0);
|
||||
}
|
||||
|
||||
List<String> DependencyEditor::_filter_deps(const List<String> &p_deps) {
|
||||
const String filter_text = filter->get_text();
|
||||
|
||||
if (filter_text.is_empty()) {
|
||||
return p_deps;
|
||||
}
|
||||
|
||||
List<String> filtered;
|
||||
|
||||
for (const String &item : p_deps) {
|
||||
const String path = item.contains("::") ? item.get_slice("::", 2) : item;
|
||||
|
||||
if (path.containsn(filter_text)) {
|
||||
filtered.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
void DependencyEditor::_update_list() {
|
||||
List<String> deps;
|
||||
ResourceLoader::get_dependencies(editing, &deps, true);
|
||||
deps = _filter_deps(deps);
|
||||
|
||||
switch (sort_by) {
|
||||
case DependencyEditorSortBy::TYPE:
|
||||
deps.sort_custom<DependencyEditorSortByType>();
|
||||
break;
|
||||
case DependencyEditorSortBy::TYPE_REVERSE:
|
||||
deps.sort_custom<DependencyEditorSortByType>();
|
||||
deps.reverse();
|
||||
break;
|
||||
case DependencyEditorSortBy::PATH:
|
||||
deps.sort_custom<DependencyEditorSortByPath>();
|
||||
break;
|
||||
case DependencyEditorSortBy::PATH_REVERSE:
|
||||
deps.sort_custom<DependencyEditorSortByPath>();
|
||||
deps.reverse();
|
||||
break;
|
||||
case DependencyEditorSortBy::NAME:
|
||||
deps.sort_custom<DependencyEditorSortByFile>();
|
||||
break;
|
||||
case DependencyEditorSortBy::NAME_REVERSE:
|
||||
deps.sort_custom<DependencyEditorSortByFile>();
|
||||
deps.reverse();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tree->clear();
|
||||
missing.clear();
|
||||
|
|
@ -221,23 +300,26 @@ void DependencyEditor::_update_list() {
|
|||
|
||||
const String path = _get_resolved_dep_path(dep);
|
||||
if (FileAccess::exists(path)) {
|
||||
item->set_text(0, path.get_file());
|
||||
item->set_text(1, path);
|
||||
item->set_text((int)Column::NAME, path.get_file());
|
||||
item->set_text((int)Column::PATH, path);
|
||||
} else {
|
||||
const String &stored_path = _get_stored_dep_path(dep);
|
||||
item->set_text(0, stored_path.get_file());
|
||||
item->set_text(1, stored_path);
|
||||
item->set_custom_color(1, Color(1, 0.4, 0.3));
|
||||
item->set_text((int)Column::NAME, stored_path.get_file());
|
||||
item->set_text((int)Column::PATH, stored_path);
|
||||
item->set_custom_color((int)Column::PATH, Color(1, 0.4, 0.3));
|
||||
missing.push_back(stored_path);
|
||||
broken = true;
|
||||
}
|
||||
|
||||
const String type = dep.contains("::") ? dep.get_slice("::", 1) : "Resource";
|
||||
String name = path.get_file();
|
||||
Ref<Texture2D> icon = EditorNode::get_singleton()->get_class_icon(type);
|
||||
item->set_icon(0, icon);
|
||||
item->set_icon((int)Column::TYPE, icon);
|
||||
item->set_metadata(0, type);
|
||||
|
||||
item->add_button(1, folder, 0);
|
||||
item->set_text((int)Column::TYPE, type);
|
||||
item->set_text((int)Column::NAME, name);
|
||||
item->set_text((int)Column::PATH, path);
|
||||
item->add_button((int)Column::PATH, folder, 0);
|
||||
}
|
||||
|
||||
fixdeps->set_disabled(!broken);
|
||||
|
|
@ -247,6 +329,9 @@ void DependencyEditor::edit(const String &p_path) {
|
|||
editing = p_path;
|
||||
set_title(TTR("Dependencies For:") + " " + p_path.get_file());
|
||||
|
||||
filter->set_text("");
|
||||
|
||||
_update_menu_sort();
|
||||
_update_list();
|
||||
|
||||
if (EditorNode::get_singleton()->is_scene_open(p_path)) {
|
||||
|
|
@ -261,21 +346,37 @@ void DependencyEditor::edit(const String &p_path) {
|
|||
popup_centered_ratio(0.4);
|
||||
}
|
||||
|
||||
void DependencyEditor::_sort_option_selected(int p_id) {
|
||||
sort_by = (DependencyEditorSortBy)p_id;
|
||||
_update_menu_sort();
|
||||
_update_list();
|
||||
}
|
||||
|
||||
void DependencyEditor::_update_menu_sort() {
|
||||
for (int i = 0; i != (int)DependencyEditorSortBy::MAX; i++) {
|
||||
menu_sort->get_popup()->set_item_checked(i, (i == (int)sort_by));
|
||||
}
|
||||
}
|
||||
|
||||
DependencyEditor::DependencyEditor() {
|
||||
VBoxContainer *vb = memnew(VBoxContainer);
|
||||
vb->set_name(TTR("Dependencies"));
|
||||
add_child(vb);
|
||||
|
||||
tree = memnew(Tree);
|
||||
tree->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
|
||||
tree->set_theme_type_variation("TreeTable");
|
||||
tree->set_hide_folding(true);
|
||||
tree->set_columns(2);
|
||||
tree->set_columns((int)Column::MAX);
|
||||
tree->set_column_titles_visible(true);
|
||||
tree->set_column_title(0, TTR("Resource"));
|
||||
tree->set_column_clip_content(0, true);
|
||||
tree->set_column_title(1, TTR("Path"));
|
||||
tree->set_column_clip_content(1, true);
|
||||
tree->set_column_title((int)Column::TYPE, TTRC("Type"));
|
||||
tree->set_column_clip_content((int)Column::TYPE, true);
|
||||
tree->set_column_expand_ratio((int)Column::TYPE, 2);
|
||||
tree->set_column_title((int)Column::NAME, TTRC("Name"));
|
||||
tree->set_column_clip_content((int)Column::NAME, true);
|
||||
tree->set_column_expand_ratio((int)Column::NAME, 3);
|
||||
tree->set_column_title((int)Column::PATH, TTRC("Path"));
|
||||
tree->set_column_clip_content((int)Column::PATH, true);
|
||||
tree->set_column_expand_ratio((int)Column::PATH, 5);
|
||||
tree->set_hide_root(true);
|
||||
tree->connect("button_clicked", callable_mp(this, &DependencyEditor::_load_pressed));
|
||||
|
||||
|
|
@ -291,6 +392,34 @@ DependencyEditor::DependencyEditor() {
|
|||
|
||||
vb->add_child(hbc);
|
||||
|
||||
HBoxContainer *hbc_filter = memnew(HBoxContainer);
|
||||
vb->add_child(hbc_filter);
|
||||
filter = memnew(LineEdit);
|
||||
filter->set_accessibility_name(TTRC("Filter Dependencies"));
|
||||
filter->set_placeholder(TTRC("Filter Dependencies"));
|
||||
filter->set_clear_button_enabled(true);
|
||||
filter->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
filter->connect(SceneStringName(text_changed), callable_mp(this, &DependencyEditor::_update_list).unbind(1));
|
||||
hbc_filter->add_child(filter);
|
||||
|
||||
menu_sort = memnew(MenuButton);
|
||||
menu_sort->set_flat(false);
|
||||
menu_sort->set_theme_type_variation("FlatMenuButton");
|
||||
menu_sort->set_tooltip_text(TTRC("Sort Dependencies"));
|
||||
menu_sort->set_accessibility_name(TTRC("Sort Dependencies"));
|
||||
|
||||
PopupMenu *popup_sort = menu_sort->get_popup();
|
||||
popup_sort->connect(SceneStringName(id_pressed), callable_mp(this, &DependencyEditor::_sort_option_selected));
|
||||
popup_sort->add_radio_check_item(TTRC("Sort by Type (Ascending)"), (int)DependencyEditorSortBy::TYPE);
|
||||
popup_sort->add_radio_check_item(TTRC("Sort by Type (Descending)"), (int)DependencyEditorSortBy::TYPE_REVERSE);
|
||||
popup_sort->add_radio_check_item(TTRC("Sort by Name (Ascending)"), (int)DependencyEditorSortBy::NAME);
|
||||
popup_sort->add_radio_check_item(TTRC("Sort by Name (Descending)"), (int)DependencyEditorSortBy::NAME_REVERSE);
|
||||
popup_sort->add_radio_check_item(TTRC("Sort by Path (Ascending)"), (int)DependencyEditorSortBy::PATH);
|
||||
popup_sort->add_radio_check_item(TTRC("Sort by Path (Descending)"), (int)DependencyEditorSortBy::PATH_REVERSE);
|
||||
popup_sort->set_item_checked((int)sort_by, true);
|
||||
|
||||
hbc_filter->add_child(menu_sort);
|
||||
|
||||
MarginContainer *mc = memnew(MarginContainer);
|
||||
mc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,25 @@ class PopupMenu;
|
|||
class Tree;
|
||||
class TreeItem;
|
||||
class VBoxContainer;
|
||||
class LineEdit;
|
||||
class MenuButton;
|
||||
|
||||
enum class DependencyEditorSortBy {
|
||||
TYPE,
|
||||
TYPE_REVERSE,
|
||||
NAME,
|
||||
NAME_REVERSE,
|
||||
PATH,
|
||||
PATH_REVERSE,
|
||||
MAX,
|
||||
};
|
||||
|
||||
enum class Column {
|
||||
TYPE,
|
||||
NAME,
|
||||
PATH,
|
||||
MAX,
|
||||
};
|
||||
|
||||
class DependencyEditor : public AcceptDialog {
|
||||
GDCLASS(DependencyEditor, AcceptDialog);
|
||||
|
|
@ -46,9 +65,12 @@ class DependencyEditor : public AcceptDialog {
|
|||
Tree *tree = nullptr;
|
||||
Button *fixdeps = nullptr;
|
||||
Label *warning_label = nullptr;
|
||||
LineEdit *filter = nullptr;
|
||||
MenuButton *menu_sort = nullptr;
|
||||
|
||||
EditorFileDialog *search = nullptr;
|
||||
|
||||
DependencyEditorSortBy sort_by = DependencyEditorSortBy::PATH;
|
||||
String replacing;
|
||||
String editing;
|
||||
List<String> missing;
|
||||
|
|
@ -57,9 +79,12 @@ class DependencyEditor : public AcceptDialog {
|
|||
|
||||
void _searched(const String &p_path);
|
||||
void _load_pressed(Object *p_item, int p_cell, int p_button, MouseButton p_mouse_button);
|
||||
List<String> _filter_deps(const List<String> &p_deps);
|
||||
void _fix_all();
|
||||
void _update_list();
|
||||
|
||||
void _update_menu_sort();
|
||||
void _sort_option_selected(int p_id);
|
||||
void _update_file();
|
||||
|
||||
protected:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue