mirror of
https://github.com/godotengine/godot.git
synced 2025-01-22 10:32:54 -05:00
Make Inspector search inside sub-resources
This commit is contained in:
parent
1aaf20b1f1
commit
753900188a
4 changed files with 168 additions and 17 deletions
|
@ -37,6 +37,7 @@
|
|||
#include "editor/editor_feature_profile.h"
|
||||
#include "editor/editor_main_screen.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_properties.h"
|
||||
#include "editor/editor_property_name_processor.h"
|
||||
#include "editor/editor_settings.h"
|
||||
#include "editor/editor_string_names.h"
|
||||
|
@ -70,6 +71,126 @@ bool EditorInspector::_property_path_matches(const String &p_property_path, cons
|
|||
return false;
|
||||
}
|
||||
|
||||
bool EditorInspector::_resource_properties_matches(const Ref<Resource> &p_resource, const String &p_filter) {
|
||||
String group;
|
||||
String group_base;
|
||||
String subgroup;
|
||||
String subgroup_base;
|
||||
|
||||
List<PropertyInfo> plist;
|
||||
p_resource->get_property_list(&plist, true);
|
||||
|
||||
// Employ a lighter version of the update_tree() property listing to find a match.
|
||||
for (PropertyInfo &p : plist) {
|
||||
if (p.usage & PROPERTY_USAGE_SUBGROUP) {
|
||||
subgroup = p.name;
|
||||
subgroup_base = p.hint_string.get_slicec(',', 0);
|
||||
|
||||
continue;
|
||||
|
||||
} else if (p.usage & PROPERTY_USAGE_GROUP) {
|
||||
group = p.name;
|
||||
group_base = p.hint_string.get_slicec(',', 0);
|
||||
subgroup = "";
|
||||
subgroup_base = "";
|
||||
|
||||
continue;
|
||||
|
||||
} else if (p.usage & PROPERTY_USAGE_CATEGORY) {
|
||||
group = "";
|
||||
group_base = "";
|
||||
subgroup = "";
|
||||
subgroup_base = "";
|
||||
|
||||
continue;
|
||||
|
||||
} else if (p.name.begins_with("metadata/_") || !(p.usage & PROPERTY_USAGE_EDITOR) || _is_property_disabled_by_feature_profile(p.name) ||
|
||||
(p_filter.is_empty() && restrict_to_basic && !(p.usage & PROPERTY_USAGE_EDITOR_BASIC_SETTING))) {
|
||||
// Ignore properties that are not supposed to be in the inspector.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p.usage & PROPERTY_USAGE_HIGH_END_GFX && RS::get_singleton()->is_low_end()) {
|
||||
// Do not show this property in low end gfx.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p.name == "script") {
|
||||
// The script is always hidden in sub inspectors.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p.name.begins_with("metadata/") && bool(object->call(SNAME("_hide_metadata_from_inspector")))) {
|
||||
// Hide metadata from inspector if required.
|
||||
continue;
|
||||
}
|
||||
|
||||
String path = p.name;
|
||||
|
||||
// Check if we exit or not a subgroup. If there is a prefix, remove it from the property label string.
|
||||
if (!subgroup.is_empty() && !subgroup_base.is_empty()) {
|
||||
if (path.begins_with(subgroup_base)) {
|
||||
path = path.trim_prefix(subgroup_base);
|
||||
} else if (subgroup_base.begins_with(path)) {
|
||||
// Keep it, this is used pretty often.
|
||||
} else {
|
||||
subgroup = ""; // The prefix changed, we are no longer in the subgroup.
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we exit or not a group. If there is a prefix, remove it from the property label string.
|
||||
if (!group.is_empty() && !group_base.is_empty() && subgroup.is_empty()) {
|
||||
if (path.begins_with(group_base)) {
|
||||
path = path.trim_prefix(group_base);
|
||||
} else if (group_base.begins_with(path)) {
|
||||
// Keep it, this is used pretty often.
|
||||
} else {
|
||||
group = ""; // The prefix changed, we are no longer in the group.
|
||||
subgroup = "";
|
||||
}
|
||||
}
|
||||
|
||||
// Add the group and subgroup to the path.
|
||||
if (!subgroup.is_empty()) {
|
||||
path = subgroup + "/" + path;
|
||||
}
|
||||
if (!group.is_empty()) {
|
||||
path = group + "/" + path;
|
||||
}
|
||||
|
||||
// Get the property label's string.
|
||||
String name_override = (path.contains_char('/')) ? path.substr(path.rfind_char('/') + 1) : path;
|
||||
const int dot = name_override.find_char('.');
|
||||
if (dot != -1) {
|
||||
name_override = name_override.substr(0, dot);
|
||||
}
|
||||
|
||||
// Remove the property from the path.
|
||||
int idx = path.rfind_char('/');
|
||||
if (idx > -1) {
|
||||
path = path.left(idx);
|
||||
} else {
|
||||
path = "";
|
||||
}
|
||||
|
||||
// Check if the property matches the filter.
|
||||
const String property_path = (path.is_empty() ? "" : path + "/") + name_override;
|
||||
if (_property_path_matches(property_path, p_filter, property_name_style)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if the sub-resource has any properties that match the filter.
|
||||
if (p.hint && p.hint == PROPERTY_HINT_RESOURCE_TYPE) {
|
||||
Ref<Resource> res = p_resource->get(p.name);
|
||||
if (res.is_valid() && _resource_properties_matches(res, p_filter)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
String EditorProperty::get_tooltip_string(const String &p_string) const {
|
||||
// Trim to 100 characters to prevent the tooltip from being too long.
|
||||
constexpr int TOOLTIP_MAX_LENGTH = 100;
|
||||
|
@ -2923,6 +3044,7 @@ void EditorInspector::update_tree() {
|
|||
HashMap<String, HashMap<String, LocalVector<EditorProperty *>>> favorites_to_add;
|
||||
|
||||
Color sscolor = get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor));
|
||||
bool sub_inspectors_enabled = EDITOR_GET("interface/inspector/open_resources_in_current_inspector");
|
||||
|
||||
// Get the lists of editors to add the beginning.
|
||||
for (Ref<EditorInspectorPlugin> &ped : valid_plugins) {
|
||||
|
@ -3100,7 +3222,7 @@ void EditorInspector::update_tree() {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (p.name.begins_with("metadata/") && bool(object->call("_hide_metadata_from_inspector"))) {
|
||||
if (p.name.begins_with("metadata/") && bool(object->call(SNAME("_hide_metadata_from_inspector")))) {
|
||||
// Hide metadata from inspector if required.
|
||||
continue;
|
||||
}
|
||||
|
@ -3207,10 +3329,25 @@ void EditorInspector::update_tree() {
|
|||
}
|
||||
|
||||
// Ignore properties that do not fit the filter.
|
||||
bool sub_inspector_use_filter = false;
|
||||
if (use_filter && !filter.is_empty()) {
|
||||
const String property_path = property_prefix + (path.is_empty() ? "" : path + "/") + name_override;
|
||||
if (!_property_path_matches(property_path, filter, property_name_style)) {
|
||||
continue;
|
||||
if (!sub_inspectors_enabled || p.hint != PROPERTY_HINT_RESOURCE_TYPE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Ref<Resource> res = object->get(p.name);
|
||||
if (res.is_null()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if the sub-resource has any properties that match the filter.
|
||||
if (!_resource_properties_matches(res, filter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sub_inspector_use_filter = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3523,6 +3660,13 @@ void EditorInspector::update_tree() {
|
|||
}
|
||||
}
|
||||
|
||||
if (sub_inspector_use_filter) {
|
||||
EditorPropertyResource *epr = Object::cast_to<EditorPropertyResource>(ep);
|
||||
if (epr) {
|
||||
epr->set_use_filter(true);
|
||||
}
|
||||
}
|
||||
|
||||
Node *section_search = current_vbox->get_parent();
|
||||
while (section_search) {
|
||||
EditorInspectorSection *section = Object::cast_to<EditorInspectorSection>(section_search);
|
||||
|
@ -3877,14 +4021,10 @@ void EditorInspector::set_use_filter(bool p_use) {
|
|||
void EditorInspector::register_text_enter(Node *p_line_edit) {
|
||||
search_box = Object::cast_to<LineEdit>(p_line_edit);
|
||||
if (search_box) {
|
||||
search_box->connect(SceneStringName(text_changed), callable_mp(this, &EditorInspector::_filter_changed));
|
||||
search_box->connect(SceneStringName(text_changed), callable_mp(this, &EditorInspector::update_tree).unbind(1));
|
||||
}
|
||||
}
|
||||
|
||||
void EditorInspector::_filter_changed(const String &p_text) {
|
||||
update_tree();
|
||||
}
|
||||
|
||||
void EditorInspector::set_use_folding(bool p_use_folding, bool p_update_tree) {
|
||||
use_folding = p_use_folding;
|
||||
|
||||
|
|
|
@ -496,6 +496,7 @@ class EditorInspector : public ScrollContainer {
|
|||
GDCLASS(EditorInspector, ScrollContainer);
|
||||
|
||||
friend class EditorInspectorCategory;
|
||||
friend class EditorPropertyResource;
|
||||
|
||||
enum {
|
||||
MAX_PLUGINS = 1024
|
||||
|
@ -585,6 +586,7 @@ class EditorInspector : public ScrollContainer {
|
|||
void _property_checked(const String &p_path, bool p_checked);
|
||||
void _property_pinned(const String &p_path, bool p_pinned);
|
||||
bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style);
|
||||
bool _resource_properties_matches(const Ref<Resource> &p_resource, const String &p_filter);
|
||||
|
||||
void _resource_selected(const String &p_path, Ref<Resource> p_resource);
|
||||
void _property_selected(const String &p_path, int p_focusable);
|
||||
|
@ -604,7 +606,6 @@ class EditorInspector : public ScrollContainer {
|
|||
|
||||
void _keying_changed();
|
||||
|
||||
void _filter_changed(const String &p_text);
|
||||
void _parse_added_editors(VBoxContainer *current_vbox, EditorInspectorSection *p_section, Ref<EditorInspectorPlugin> ped);
|
||||
|
||||
void _vscroll_changed(double);
|
||||
|
|
|
@ -3292,6 +3292,9 @@ void EditorPropertyResource::update_property() {
|
|||
|
||||
sub_inspector->set_draw_focus_border(false);
|
||||
|
||||
sub_inspector->set_use_filter(use_filter);
|
||||
sub_inspector->register_text_enter(parent_inspector->search_box);
|
||||
|
||||
sub_inspector->set_mouse_filter(MOUSE_FILTER_STOP);
|
||||
add_child(sub_inspector);
|
||||
set_bottom_editor(sub_inspector);
|
||||
|
@ -3318,16 +3321,14 @@ void EditorPropertyResource::update_property() {
|
|||
_update_property_bg();
|
||||
}
|
||||
|
||||
} else {
|
||||
if (sub_inspector) {
|
||||
set_bottom_editor(nullptr);
|
||||
memdelete(sub_inspector);
|
||||
sub_inspector = nullptr;
|
||||
} else if (sub_inspector) {
|
||||
set_bottom_editor(nullptr);
|
||||
memdelete(sub_inspector);
|
||||
sub_inspector = nullptr;
|
||||
|
||||
if (opened_editor) {
|
||||
EditorNode::get_singleton()->hide_unused_editors();
|
||||
opened_editor = false;
|
||||
}
|
||||
if (opened_editor) {
|
||||
EditorNode::get_singleton()->hide_unused_editors();
|
||||
opened_editor = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3357,6 +3358,13 @@ void EditorPropertyResource::set_use_sub_inspector(bool p_enable) {
|
|||
use_sub_inspector = p_enable;
|
||||
}
|
||||
|
||||
void EditorPropertyResource::set_use_filter(bool p_use) {
|
||||
use_filter = p_use;
|
||||
if (sub_inspector) {
|
||||
update_property();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorPropertyResource::fold_resource() {
|
||||
bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property());
|
||||
if (unfolded) {
|
||||
|
|
|
@ -673,6 +673,7 @@ class EditorPropertyResource : public EditorProperty {
|
|||
bool use_sub_inspector = false;
|
||||
EditorInspector *sub_inspector = nullptr;
|
||||
bool opened_editor = false;
|
||||
bool use_filter = false;
|
||||
|
||||
void _resource_selected(const Ref<Resource> &p_resource, bool p_inspect);
|
||||
void _resource_changed(const Ref<Resource> &p_resource);
|
||||
|
@ -701,6 +702,7 @@ public:
|
|||
void expand_revertable() override;
|
||||
|
||||
void set_use_sub_inspector(bool p_enable);
|
||||
void set_use_filter(bool p_use);
|
||||
void fold_resource();
|
||||
|
||||
virtual bool is_colored(ColorationMode p_mode) override;
|
||||
|
|
Loading…
Reference in a new issue