summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
authorwillnationsdev <willnationsdev@gmail.com>2022-04-26 00:55:51 -0500
committerwillnationsdev <willnationsdev@gmail.com>2022-09-17 18:34:57 -0500
commitd32f2700ffd8ca01af0077d9e8dcff10079bc776 (patch)
tree26176dbff3cdd66f481de837027409e9106093a6 /editor
parent4ab3fdcda07bf700b33eb7c85f53826b2464c02f (diff)
Script-class-aware Inspector & related controls.
Diffstat (limited to 'editor')
-rw-r--r--editor/editor_resource_picker.cpp146
-rw-r--r--editor/editor_resource_picker.h1
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;