diff options
author | Bojidar Marinov <bojidar.marinov.bg@gmail.com> | 2019-07-19 22:21:30 +0300 |
---|---|---|
committer | Bojidar Marinov <bojidar.marinov.bg@gmail.com> | 2019-07-19 22:33:58 +0300 |
commit | 4f721788681533d4c53736bb873fb4e468fcfea9 (patch) | |
tree | 761b1a172523e9c3910cc0b8121402d4d64dad7f /editor | |
parent | 22c843b0c451a0c3d79a3b3e6af900b841c51c12 (diff) |
Make custom types more subtle and more useful
Implements #6067 (aaronfranke's idea)
Fixes #26980
Diffstat (limited to 'editor')
-rw-r--r-- | editor/animation_track_editor.cpp | 11 | ||||
-rw-r--r-- | editor/editor_data.cpp | 3 | ||||
-rw-r--r-- | editor/editor_node.cpp | 92 | ||||
-rw-r--r-- | editor/editor_node.h | 2 | ||||
-rw-r--r-- | editor/scene_tree_dock.cpp | 11 | ||||
-rw-r--r-- | editor/scene_tree_editor.cpp | 18 |
6 files changed, 105 insertions, 32 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index f5b5cfa848..d1ac69c8d8 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1274,12 +1274,7 @@ void AnimationTrackEdit::_notification(int p_what) { } text_color.a *= 0.7; } else if (node) { - Ref<Texture> icon; - if (has_icon(node->get_class(), "EditorIcons")) { - icon = get_icon(node->get_class(), "EditorIcons"); - } else { - icon = get_icon("Node", "EditorIcons"); - } + Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(node, "Node"); draw_texture(icon, Point2(ofs, int(get_size().height - icon->get_height()) / 2)); icon_cache = icon; @@ -3500,9 +3495,7 @@ void AnimationTrackEditor::_update_tracks() { if (root && root->has_node(base_path)) { Node *n = root->get_node(base_path); if (n) { - if (has_icon(n->get_class(), "EditorIcons")) { - icon = get_icon(n->get_class(), "EditorIcons"); - } + icon = EditorNode::get_singleton()->get_object_icon(n, "Node"); name = n->get_name(); tooltip = root->get_path_to(n); } diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 38f30df169..f5846c10f6 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -499,7 +499,6 @@ Object *EditorData::instance_custom_type(const String &p_type, const String &p_i for (int i = 0; i < get_custom_types()[p_inherits].size(); i++) { if (get_custom_types()[p_inherits][i].name == p_type) { - Ref<Texture> icon = get_custom_types()[p_inherits][i].icon; Ref<Script> script = get_custom_types()[p_inherits][i].script; Object *ob = ClassDB::instance(p_inherits); @@ -508,8 +507,6 @@ Object *EditorData::instance_custom_type(const String &p_type, const String &p_i ob->call("set_name", p_type); } ob->set_script(script.get_ref_ptr()); - if (icon.is_valid()) - ob->set_meta("_editor_icon", icon); return ob; } } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 3183f1ae97..8bbfb38845 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -3488,6 +3488,69 @@ void EditorNode::stop_child_process() { _menu_option_confirm(RUN_STOP, false); } +Ref<Script> EditorNode::get_object_custom_type_base(const Object *p_object) const { + ERR_FAIL_COND_V(!p_object, NULL); + + Ref<Script> script = p_object->get_script(); + + if (script.is_valid()) { + // Uncommenting would break things! Consider adding a parameter if you need it. + // StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path()); + // if (name != StringName()) + // return name; + + // should probably be deprecated in 4.x + StringName base = script->get_instance_base_type(); + if (base != StringName() && EditorNode::get_editor_data().get_custom_types().has(base)) { + const Vector<EditorData::CustomType> &types = EditorNode::get_editor_data().get_custom_types()[base]; + + Ref<Script> base_script = script; + while (base_script.is_valid()) { + for (int i = 0; i < types.size(); ++i) { + if (types[i].script == base_script) { + return types[i].script; + } + } + base_script = base_script->get_base_script(); + } + } + } + + return NULL; +} + +StringName EditorNode::get_object_custom_type_name(const Object *p_object) const { + ERR_FAIL_COND_V(!p_object, StringName()); + + Ref<Script> script = p_object->get_script(); + if (script.is_null() && p_object->is_class("Script")) { + script = p_object; + } + + if (script.is_valid()) { + Ref<Script> base_script = script; + while (base_script.is_valid()) { + StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path()); + if (name != StringName()) + return name; + + // should probably be deprecated in 4.x + StringName base = base_script->get_instance_base_type(); + if (base != StringName() && EditorNode::get_editor_data().get_custom_types().has(base)) { + const Vector<EditorData::CustomType> &types = EditorNode::get_editor_data().get_custom_types()[base]; + for (int i = 0; i < types.size(); ++i) { + if (types[i].script == base_script) { + return types[i].name; + } + } + } + base_script = base_script->get_base_script(); + } + } + + return StringName(); +} + Ref<Texture> EditorNode::get_object_icon(const Object *p_object, const String &p_fallback) const { ERR_FAIL_COND_V(!p_object || !gui_base, NULL); @@ -3497,23 +3560,24 @@ Ref<Texture> EditorNode::get_object_icon(const Object *p_object, const String &p } if (script.is_valid()) { - StringName name = EditorNode::get_editor_data().script_class_get_name(script->get_path()); - String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(name); - if (icon_path.length()) - return ResourceLoader::load(icon_path); - - // should probably be deprecated in 4.x - StringName base = script->get_instance_base_type(); - if (base != StringName()) { - const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types(); - for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) { - const Vector<EditorData::CustomType> &ct = E->value(); - for (int i = 0; i < ct.size(); ++i) { - if (ct[i].name == base && ct[i].icon.is_valid()) { - return ct[i].icon; + Ref<Script> base_script = script; + while (base_script.is_valid()) { + StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path()); + String icon_path = EditorNode::get_editor_data().script_class_get_icon_path(name); + if (icon_path.length()) + return ResourceLoader::load(icon_path); + + // should probably be deprecated in 4.x + StringName base = base_script->get_instance_base_type(); + if (base != StringName() && EditorNode::get_editor_data().get_custom_types().has(base)) { + const Vector<EditorData::CustomType> &types = EditorNode::get_editor_data().get_custom_types()[base]; + for (int i = 0; i < types.size(); ++i) { + if (types[i].script == base_script && types[i].icon.is_valid()) { + return types[i].icon; } } } + base_script = base_script->get_base_script(); } } diff --git a/editor/editor_node.h b/editor/editor_node.h index 5dabe529f9..9aee19e6c1 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -776,6 +776,8 @@ public: void stop_child_process(); Ref<Theme> get_editor_theme() const { return theme; } + Ref<Script> get_object_custom_type_base(const Object *p_object) const; + StringName get_object_custom_type_name(const Object *p_object) const; Ref<Texture> get_object_icon(const Object *p_object, const String &p_fallback = "Object") const; Ref<Texture> get_class_icon(const String &p_class, const String &p_fallback = "Object") const; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index c43d164078..a717b08d82 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -466,8 +466,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { Node *n = Object::cast_to<Node>(selection[i]); Ref<Script> existing = n->get_script(); - if (existing.is_valid()) { - const RefPtr empty; + Ref<Script> empty = EditorNode::get_singleton()->get_object_custom_type_base(n); + if (existing != empty) { editor_data->get_undo_redo().add_do_method(n, "set_script", empty); editor_data->get_undo_redo().add_undo_method(n, "set_script", existing); } @@ -2329,6 +2329,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->clear(); Ref<Script> existing_script; + bool exisiting_script_removable = true; if (selection.size() == 1) { Node *selected = selection[0]; @@ -2348,6 +2349,10 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->add_separator(); existing_script = selected->get_script(); + + if (EditorNode::get_singleton()->get_object_custom_type_base(selected) == existing_script) { + exisiting_script_removable = false; + } } if (profile_allow_script_editing) { @@ -2359,7 +2364,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->add_icon_shortcut(get_icon("ScriptExtend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/extend_script"), TOOL_ATTACH_SCRIPT); } } - if (selection.size() > 1 || existing_script.is_valid()) { + if (selection.size() > 1 || (existing_script.is_valid() && exisiting_script_removable)) { menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT); } menu->add_separator(); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index c1a14685b0..2d9accc3d8 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -212,13 +212,19 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { Color accent = get_color("accent_color", "Editor"); Ref<Script> script = p_node->get_script(); - if (!script.is_null()) { + if (!script.is_null() && EditorNode::get_singleton()->get_object_custom_type_base(p_node) != script) { //has script item->add_button(0, get_icon("Script", "EditorIcons"), BUTTON_SCRIPT); } else { - //has no script + //has no script (or script is a custom type) item->set_custom_color(0, get_color("disabled_font_color", "Editor")); item->set_selectable(0, false); + + if (!script.is_null()) { // make sure to mark the script if a custom type + item->add_button(0, get_icon("Script", "EditorIcons"), BUTTON_SCRIPT); + item->set_button_disabled(0, item->get_button_count(0) - 1, true); + } + accent.a *= 0.7; } @@ -284,7 +290,10 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { item->add_button(0, get_icon("InstanceOptions", "EditorIcons"), BUTTON_SUBSCENE, false, TTR("Open in Editor")); item->set_tooltip(0, TTR("Instance:") + " " + p_node->get_filename() + "\n" + TTR("Type:") + " " + p_node->get_class()); } else { - item->set_tooltip(0, String(p_node->get_name()) + "\n" + TTR("Type:") + " " + p_node->get_class()); + StringName type = EditorNode::get_singleton()->get_object_custom_type_name(p_node); + if (type == StringName()) + type = p_node->get_class(); + item->set_tooltip(0, String(p_node->get_name()) + "\n" + TTR("Type:") + " " + type); } if (can_open_instance && undo_redo) { //Show buttons only when necessary(SceneTreeDock) to avoid crashes @@ -295,6 +304,9 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { Ref<Script> script = p_node->get_script(); if (!script.is_null()) { item->add_button(0, get_icon("Script", "EditorIcons"), BUTTON_SCRIPT, false, TTR("Open Script:") + " " + script->get_path()); + if (EditorNode::get_singleton()->get_object_custom_type_base(p_node) == script) { + item->set_button_color(0, item->get_button_count(0) - 1, Color(1, 1, 1, 0.5)); + } } if (p_node->is_class("CanvasItem")) { |