|
@@ -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<EditorProperty>(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<EditorInspectorPlugin::AddedEditor> editors;
|
|
|
+ Vector<EditorInspectorPlugin::AddedEditor> late_editors;
|
|
|
+
|
|
|
// Search for the inspector plugin that will handle the properties. Then add the correct property editor to it.
|
|
|
for (Ref<EditorInspectorPlugin> &ped : valid_plugins) {
|
|
|
bool exclusive = ped->parse_property(object, p.type, p.name, p.hint, p.hint_string, p.usage, wide_editors);
|
|
|
|
|
|
- List<EditorInspectorPlugin::AddedEditor> 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<EditorProperty>(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<EditorProperty>(editors[i].property_editor);
|
|
|
+ const Vector<String> &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<EditorProperty *>();
|
|
|
- }
|
|
|
- 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<EditorProperty *>();
|
|
|
+ }
|
|
|
+ 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);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|