summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
authorBojidar Marinov <bojidar.marinov.bg@gmail.com>2019-07-19 22:21:30 +0300
committerBojidar Marinov <bojidar.marinov.bg@gmail.com>2019-07-19 22:33:58 +0300
commit4f721788681533d4c53736bb873fb4e468fcfea9 (patch)
tree761b1a172523e9c3910cc0b8121402d4d64dad7f /editor
parent22c843b0c451a0c3d79a3b3e6af900b841c51c12 (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.cpp11
-rw-r--r--editor/editor_data.cpp3
-rw-r--r--editor/editor_node.cpp92
-rw-r--r--editor/editor_node.h2
-rw-r--r--editor/scene_tree_dock.cpp11
-rw-r--r--editor/scene_tree_editor.cpp18
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")) {