diff options
author | willnationsdev <willnationsdev@gmail.com> | 2022-04-26 00:55:51 -0500 |
---|---|---|
committer | willnationsdev <willnationsdev@gmail.com> | 2022-09-17 18:34:57 -0500 |
commit | d32f2700ffd8ca01af0077d9e8dcff10079bc776 (patch) | |
tree | 26176dbff3cdd66f481de837027409e9106093a6 /editor | |
parent | 4ab3fdcda07bf700b33eb7c85f53826b2464c02f (diff) |
Script-class-aware Inspector & related controls.
Diffstat (limited to 'editor')
-rw-r--r-- | editor/editor_resource_picker.cpp | 146 | ||||
-rw-r--r-- | editor/editor_resource_picker.h | 1 |
2 files changed, 92 insertions, 55 deletions
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 84cb085551..de8259c25c 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -53,6 +53,7 @@ void EditorResourcePicker::_update_resource() { if (edited_resource.is_valid() && edited_resource->get_path().is_resource_file()) { resource_path = edited_resource->get_path() + "\n"; } + String class_name = _get_resource_type(edited_resource); if (preview_rect) { preview_rect->set_texture(Ref<Texture2D>()); @@ -64,16 +65,20 @@ void EditorResourcePicker::_update_resource() { assign_button->set_text(TTR("<empty>")); assign_button->set_tooltip_text(""); } else { - assign_button->set_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), "Object")); + assign_button->set_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), SNAME("Object"))); if (!edited_resource->get_name().is_empty()) { assign_button->set_text(edited_resource->get_name()); } else if (edited_resource->get_path().is_resource_file()) { assign_button->set_text(edited_resource->get_path().get_file()); } else { - assign_button->set_text(edited_resource->get_class()); + assign_button->set_text(class_name); } - assign_button->set_tooltip_text(resource_path + TTR("Type:") + " " + edited_resource->get_class()); + + if (edited_resource->get_path().is_resource_file()) { + resource_path = edited_resource->get_path() + "\n"; + } + assign_button->set_tooltip_text(resource_path + TTR("Type:") + " " + class_name); // Preview will override the above, so called at the end. EditorResourcePreview::get_singleton()->queue_edited_resource_preview(edited_resource, this, "_update_resource_preview", edited_resource->get_instance_id()); @@ -134,16 +139,29 @@ void EditorResourcePicker::_file_selected(const String &p_path) { if (!base_type.is_empty()) { bool any_type_matches = false; + String res_type = loaded_resource->get_class(); + Ref<Script> res_script = loaded_resource->get_script(); + bool is_global_class = false; + if (res_script.is_valid()) { + String script_type = EditorNode::get_editor_data().script_class_get_name(res_script->get_path()); + if (!script_type.is_empty()) { + is_global_class = true; + res_type = script_type; + } + } + for (int i = 0; i < base_type.get_slice_count(","); i++) { String base = base_type.get_slice(",", i); - if (loaded_resource->is_class(base)) { - any_type_matches = true; + + any_type_matches = is_global_class ? EditorNode::get_editor_data().script_class_is_parent(res_type, base) : loaded_resource->is_class(base); + + if (!any_type_matches) { break; } } if (!any_type_matches) { - EditorNode::get_singleton()->show_warning(vformat(TTR("The selected resource (%s) does not match any type expected for this property (%s)."), loaded_resource->get_class(), base_type)); + EditorNode::get_singleton()->show_warning(vformat(TTR("The selected resource (%s) does not match any type expected for this property (%s)."), res_type, base_type)); return; } } @@ -227,16 +245,19 @@ void EditorResourcePicker::_update_menu_items() { // Add options to copy/paste resource. Ref<Resource> cb = EditorSettings::get_singleton()->get_resource_clipboard(); bool paste_valid = false; - if (is_editable()) { - if (cb.is_valid()) { - if (base_type.is_empty()) { - paste_valid = true; - } else { - for (int i = 0; i < base_type.get_slice_count(","); i++) { - if (ClassDB::is_parent_class(cb->get_class(), base_type.get_slice(",", i))) { - paste_valid = true; - break; - } + if (is_editable() && cb.is_valid()) { + if (base_type.is_empty()) { + paste_valid = true; + } else { + String res_type = _get_resource_type(cb); + + for (int i = 0; i < base_type.get_slice_count(","); i++) { + String base = base_type.get_slice(",", i); + + paste_valid = ClassDB::is_parent_class(res_type, base) || EditorNode::get_editor_data().script_class_is_parent(res_type, base); + + if (!paste_valid) { + break; } } } @@ -281,6 +302,9 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { for (int i = 0; i < base_type.get_slice_count(","); i++) { String base = base_type.get_slice(",", i); ResourceLoader::get_recognized_extensions_for_type(base, &extensions); + if (ScriptServer::is_global_class(base)) { + ResourceLoader::get_recognized_extensions_for_type(ScriptServer::get_global_class_native_base(base), &extensions); + } } HashSet<String> valid_extensions; @@ -408,13 +432,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { Variant obj; if (ScriptServer::is_global_class(intype)) { - obj = ClassDB::instantiate(ScriptServer::get_global_class_native_base(intype)); - if (obj) { - Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(intype)); - if (script.is_valid()) { - ((Object *)obj)->set_script(script); - } - } + obj = EditorNode::get_editor_data().script_class_instance(intype); } else { obj = ClassDB::instantiate(intype); } @@ -512,23 +530,40 @@ void EditorResourcePicker::_button_draw() { void EditorResourcePicker::_button_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid()) { - if (mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { - // Only attempt to update and show the menu if we have - // a valid resource or the Picker is editable, as - // there will otherwise be nothing to display. - if (edited_resource.is_valid() || is_editable()) { - _update_menu_items(); - - Vector2 pos = get_screen_position() + mb->get_position(); - edit_menu->reset_size(); - edit_menu->set_position(pos); - edit_menu->popup(); - } + if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { + // Only attempt to update and show the menu if we have + // a valid resource or the Picker is editable, as + // there will otherwise be nothing to display. + if (edited_resource.is_valid() || is_editable()) { + _update_menu_items(); + + Vector2 pos = get_screen_position() + mb->get_position(); + edit_menu->reset_size(); + edit_menu->set_position(pos); + edit_menu->popup(); } } } +String EditorResourcePicker::_get_resource_type(const Ref<Resource> &p_resource) const { + if (p_resource.is_null()) { + return String(); + } + String res_type = p_resource->get_class(); + + Ref<Script> res_script = p_resource->get_script(); + if (res_script.is_null()) { + return res_type; + } + + // TODO: Replace with EditorFileSystem when PR #60606 is merged to use cached resource type. + String script_type = EditorNode::get_editor_data().script_class_get_name(res_script->get_path()); + if (!script_type.is_empty()) { + res_type = script_type; + } + return res_type; +} + void EditorResourcePicker::_get_allowed_types(bool p_with_convert, HashSet<String> *p_vector) const { Vector<String> allowed_types = base_type.split(","); int size = allowed_types.size(); @@ -550,7 +585,9 @@ void EditorResourcePicker::_get_allowed_types(bool p_with_convert, HashSet<Strin List<StringName> allowed_subtypes; List<StringName> inheriters; - ClassDB::get_inheriters_from_class(base, &inheriters); + if (!ScriptServer::is_global_class(base)) { + ClassDB::get_inheriters_from_class(base, &inheriters); + } for (const StringName &subtype_name : inheriters) { p_vector->insert(subtype_name); allowed_subtypes.push_back(subtype_name); @@ -602,32 +639,29 @@ bool EditorResourcePicker::_is_drop_valid(const Dictionary &p_drag_data) const { } } else if (drag_data.has("type") && String(drag_data["type"]) == "resource") { res = drag_data["resource"]; + } else if (drag_data.has("type") && String(drag_data["type"]) == "files") { + Vector<String> files = drag_data["files"]; + + // TODO: Extract the typename of the dropped filepath's resource in a more performant way, without fully loading it. + if (files.size() == 1) { + String file = files[0]; + res = ResourceLoader::load(file); + } } HashSet<String> allowed_types; _get_allowed_types(true, &allowed_types); - if (res.is_valid() && _is_type_valid(res->get_class(), allowed_types)) { - return true; - } + if (res.is_valid()) { + String res_type = _get_resource_type(res); - if (res.is_valid() && res->get_script()) { - StringName custom_class = EditorNode::get_singleton()->get_object_custom_type_name(res->get_script()); - if (_is_type_valid(custom_class, allowed_types)) { + if (_is_type_valid(res_type, allowed_types)) { return true; } - } - - if (drag_data.has("type") && String(drag_data["type"]) == "files") { - Vector<String> files = drag_data["files"]; - - if (files.size() == 1) { - String file = files[0]; - String file_type = EditorFileSystem::get_singleton()->get_file_type(file); - if (!file_type.is_empty() && _is_type_valid(file_type, allowed_types)) { - return true; - } + StringName custom_class = EditorNode::get_singleton()->get_object_custom_type_name(res.ptr()); + if (_is_type_valid(custom_class, allowed_types)) { + return true; } } @@ -685,8 +719,10 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_ HashSet<String> allowed_types; _get_allowed_types(false, &allowed_types); + String res_type = _get_resource_type(dropped_resource); + // If the accepted dropped resource is from the extended list, it requires conversion. - if (!_is_type_valid(dropped_resource->get_class(), allowed_types)) { + if (!_is_type_valid(res_type, allowed_types)) { for (const String &E : allowed_types) { String at = E.strip_edges(); diff --git a/editor/editor_resource_picker.h b/editor/editor_resource_picker.h index 3d6127e656..d1a20f04b7 100644 --- a/editor/editor_resource_picker.h +++ b/editor/editor_resource_picker.h @@ -91,6 +91,7 @@ class EditorResourcePicker : public HBoxContainer { void _button_draw(); void _button_input(const Ref<InputEvent> &p_event); + String _get_resource_type(const Ref<Resource> &p_resource) const; void _get_allowed_types(bool p_with_convert, HashSet<String> *p_vector) const; bool _is_drop_valid(const Dictionary &p_drag_data) const; bool _is_type_valid(const String p_type_name, HashSet<String> p_allowed_types) const; |