From 4044cc7d5753e44b586b63271f2a80f7a5fa05f9 Mon Sep 17 00:00:00 2001 From: reduz Date: Tue, 24 May 2022 00:35:01 +0200 Subject: Reorganize Region Rect Editor Problem: * Region rect was pretty much a hidden editor. Because it was annoying for it to pop up automatically, it did not. * Because it did not, most users have no idea it even exists. * But because it is a transient editor, it would steal focus of other editor and annoy users. Solution: * Editor has been moved to a window. * Regions that can be edited add a button below the region which can be pressed to open the editor. This required a slight change in EditorInspectorPlugin to allow custom editors to be below others. --- editor/editor_inspector.cpp | 147 ++++++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 68 deletions(-) (limited to 'editor/editor_inspector.cpp') diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 4bc37456d5..9a400eb2bc 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1008,12 +1008,11 @@ void EditorInspectorPlugin::add_custom_control(Control *control) { added_editors.push_back(ae); } -void EditorInspectorPlugin::add_property_editor(const String &p_for_property, Control *p_prop) { - ERR_FAIL_COND(Object::cast_to(p_prop) == nullptr); - +void EditorInspectorPlugin::add_property_editor(const String &p_for_property, Control *p_prop, bool p_add_to_end) { AddedEditor ae; ae.properties.push_back(p_for_property); ae.property_editor = p_prop; + ae.add_to_end = p_add_to_end; added_editors.push_back(ae); } @@ -1059,7 +1058,7 @@ void EditorInspectorPlugin::parse_end(Object *p_object) { void EditorInspectorPlugin::_bind_methods() { ClassDB::bind_method(D_METHOD("add_custom_control", "control"), &EditorInspectorPlugin::add_custom_control); - ClassDB::bind_method(D_METHOD("add_property_editor", "property", "editor"), &EditorInspectorPlugin::add_property_editor); + ClassDB::bind_method(D_METHOD("add_property_editor", "property", "editor", "add_to_end"), &EditorInspectorPlugin::add_property_editor, DEFVAL(false)); ClassDB::bind_method(D_METHOD("add_property_editor_for_multiple_properties", "label", "properties", "editor"), &EditorInspectorPlugin::add_property_editor_for_multiple_properties); GDVIRTUAL_BIND(_can_handle, "object") @@ -2894,87 +2893,99 @@ void EditorInspector::update_tree() { doc_hint = descr; } + Vector editors; + Vector late_editors; + // Search for the inspector plugin that will handle the properties. Then add the correct property editor to it. for (Ref &ped : valid_plugins) { bool exclusive = ped->parse_property(object, p.type, p.name, p.hint, p.hint_string, p.usage, wide_editors); - List editors = ped->added_editors; // Make a copy, since plugins may be used again in a sub-inspector. + for (const EditorInspectorPlugin::AddedEditor &F : ped->added_editors) { + if (F.add_to_end) { + late_editors.push_back(F); + } else { + editors.push_back(F); + } + } + ped->added_editors.clear(); - for (const EditorInspectorPlugin::AddedEditor &F : editors) { - EditorProperty *ep = Object::cast_to(F.property_editor); + if (exclusive) { + break; + } + } - if (ep) { - // Set all this before the control gets the ENTER_TREE notification. - ep->object = object; + editors.append_array(late_editors); - if (F.properties.size()) { - if (F.properties.size() == 1) { - //since it's one, associate: - ep->property = F.properties[0]; - ep->property_path = property_prefix + F.properties[0]; - ep->property_usage = p.usage; - //and set label? - } + for (int i = 0; i < editors.size(); i++) { + EditorProperty *ep = Object::cast_to(editors[i].property_editor); + const Vector &properties = editors[i].properties; - if (!F.label.is_empty()) { - ep->set_label(F.label); - } else { - // Use the existing one. - ep->set_label(property_label_string); - } - for (int i = 0; i < F.properties.size(); i++) { - String prop = F.properties[i]; + if (ep) { + // Set all this before the control gets the ENTER_TREE notification. + ep->object = object; - if (!editor_property_map.has(prop)) { - editor_property_map[prop] = List(); - } - editor_property_map[prop].push_back(ep); - } + if (properties.size()) { + if (properties.size() == 1) { + //since it's one, associate: + ep->property = properties[0]; + ep->property_path = property_prefix + properties[0]; + ep->property_usage = p.usage; + //and set label? } - ep->set_draw_warning(draw_warning); - ep->set_use_folding(use_folding); - ep->set_checkable(checkable); - ep->set_checked(checked); - ep->set_keying(keying); - ep->set_read_only(property_read_only); - ep->set_deletable(deletable_properties || p.name.begins_with("metadata/")); - } - - current_vbox->add_child(F.property_editor); - - if (ep) { - // Eventually, set other properties/signals after the property editor got added to the tree. - bool update_all = (p.usage & PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED); - ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed), varray(update_all)); - ep->connect("property_keyed", callable_mp(this, &EditorInspector::_property_keyed)); - ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED); - ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value)); - ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked)); - ep->connect("property_pinned", callable_mp(this, &EditorInspector::_property_pinned)); - ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected)); - ep->connect("multiple_properties_changed", callable_mp(this, &EditorInspector::_multiple_properties_changed)); - ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), varray(), CONNECT_DEFERRED); - ep->connect("object_id_selected", callable_mp(this, &EditorInspector::_object_id_selected), varray(), CONNECT_DEFERRED); - if (!doc_hint.is_empty()) { - ep->set_tooltip(property_prefix + p.name + "::" + doc_hint); + + if (!editors[i].label.is_empty()) { + ep->set_label(editors[i].label); } else { - ep->set_tooltip(property_prefix + p.name); + // Use the existing one. + ep->set_label(property_label_string); } - ep->update_property(); - ep->_update_pin_flags(); - ep->update_revert_and_pin_status(); - ep->update_cache(); + for (int j = 0; j < properties.size(); j++) { + String prop = properties[j]; - if (current_selected && ep->property == current_selected) { - ep->select(current_focusable); + if (!editor_property_map.has(prop)) { + editor_property_map[prop] = List(); + } + editor_property_map[prop].push_back(ep); } } - } + ep->set_draw_warning(draw_warning); + ep->set_use_folding(use_folding); + ep->set_checkable(checkable); + ep->set_checked(checked); + ep->set_keying(keying); + ep->set_read_only(property_read_only); + ep->set_deletable(deletable_properties || p.name.begins_with("metadata/")); + } + + current_vbox->add_child(editors[i].property_editor); + + if (ep) { + // Eventually, set other properties/signals after the property editor got added to the tree. + bool update_all = (p.usage & PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED); + ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed), varray(update_all)); + ep->connect("property_keyed", callable_mp(this, &EditorInspector::_property_keyed)); + ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED); + ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value)); + ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked)); + ep->connect("property_pinned", callable_mp(this, &EditorInspector::_property_pinned)); + ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected)); + ep->connect("multiple_properties_changed", callable_mp(this, &EditorInspector::_multiple_properties_changed)); + ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), varray(), CONNECT_DEFERRED); + ep->connect("object_id_selected", callable_mp(this, &EditorInspector::_object_id_selected), varray(), CONNECT_DEFERRED); + if (!doc_hint.is_empty()) { + ep->set_tooltip(property_prefix + p.name + "::" + doc_hint); + } else { + ep->set_tooltip(property_prefix + p.name); + } + ep->update_property(); + ep->_update_pin_flags(); + ep->update_revert_and_pin_status(); + ep->update_cache(); - if (exclusive) { - // If we know the plugin is exclusive, we don't need to go through other plugins. - break; + if (current_selected && ep->property == current_selected) { + ep->select(current_focusable); + } } } } -- cgit v1.2.3