From b9b68b755c32dc296eddd5b95116c21d63ac62c8 Mon Sep 17 00:00:00 2001
From: reduz <reduzio@gmail.com>
Date: Thu, 11 Feb 2021 18:01:56 -0300
Subject: [PATCH] Improved Inspector Sub-Resource Editing

-Better margins
-Colors to delimit subresources better.
---
 editor/editor_inspector.cpp  | 53 +++++++++++++++++++-------------
 editor/editor_inspector.h    |  3 ++
 editor/editor_node.cpp       |  2 +-
 editor/editor_properties.cpp | 42 ++++++++++++++++++++++++++
 editor/editor_properties.h   |  3 ++
 editor/editor_settings.cpp   |  2 ++
 editor/editor_themes.cpp     | 58 +++++++++++++++++++++++++++++++-----
 7 files changed, 134 insertions(+), 29 deletions(-)

diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 5fd03e44b9f..a7f808f63a7 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -81,7 +81,7 @@ Size2 EditorProperty::get_minimum_size() const {
 	}
 
 	if (bottom_editor != nullptr && bottom_editor->is_visible()) {
-		ms.height += get_theme_constant("vseparation", "Tree");
+		ms.height += get_theme_constant("vseparation");
 		Size2 bems = bottom_editor->get_combined_minimum_size();
 		//bems.width += get_constant("item_margin", "Tree");
 		ms.height += bems.height;
@@ -149,7 +149,7 @@ void EditorProperty::_notification(int p_what) {
 			if (bottom_editor) {
 				int m = 0; //get_constant("item_margin", "Tree");
 
-				bottom_rect = Rect2(m, rect.size.height + get_theme_constant("vseparation", "Tree"), size.width - m, bottom_editor->get_combined_minimum_size().height);
+				bottom_rect = Rect2(m, rect.size.height + get_theme_constant("vseparation"), size.width - m, bottom_editor->get_combined_minimum_size().height);
 			}
 
 			if (keying) {
@@ -226,11 +226,15 @@ void EditorProperty::_notification(int p_what) {
 			size.height = label_reference->get_size().height;
 		}
 
+		Ref<StyleBox> sb;
 		if (selected) {
-			Ref<StyleBox> sb = get_theme_stylebox("selected", "Tree");
-			draw_style_box(sb, Rect2(Vector2(), size));
+			sb = get_theme_stylebox("bg_selected");
+		} else {
+			sb = get_theme_stylebox("bg");
 		}
 
+		draw_style_box(sb, Rect2(Vector2(), size));
+
 		if (draw_top_bg && right_child_rect != Rect2()) {
 			draw_rect(right_child_rect, dark_color);
 		}
@@ -240,15 +244,15 @@ void EditorProperty::_notification(int p_what) {
 
 		Color color;
 		if (draw_red) {
-			color = get_theme_color("error_color", "Editor");
+			color = get_theme_color("error_color");
 		} else {
-			color = get_theme_color("property_color", "Editor");
+			color = get_theme_color("property_color");
 		}
 		if (label.find(".") != -1) {
 			color.a = 0.5; //this should be un-hacked honestly, as it's used for editor overrides
 		}
 
-		int ofs = 0;
+		int ofs = get_theme_constant("font_offset");
 		int text_limit = text_size;
 
 		if (checkable) {
@@ -2180,17 +2184,30 @@ void EditorInspector::set_use_wide_editors(bool p_enable) {
 	wide_editors = p_enable;
 }
 
+void EditorInspector::_update_inspector_bg() {
+	if (sub_inspector) {
+		int count_subinspectors = 0;
+		Node *n = get_parent();
+		while (n) {
+			EditorInspector *ei = Object::cast_to<EditorInspector>(n);
+			if (ei && ei->sub_inspector) {
+				count_subinspectors++;
+			}
+			n = n->get_parent();
+		}
+		count_subinspectors = MIN(15, count_subinspectors);
+		add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg" + itos(count_subinspectors), "Editor"));
+	} else {
+		add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
+	}
+}
 void EditorInspector::set_sub_inspector(bool p_enable) {
 	sub_inspector = p_enable;
 	if (!is_inside_tree()) {
 		return;
 	}
 
-	if (sub_inspector) {
-		add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor"));
-	} else {
-		add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
-	}
+	_update_inspector_bg();
 }
 
 void EditorInspector::set_use_deletable_properties(bool p_enabled) {
@@ -2418,10 +2435,8 @@ void EditorInspector::_notification(int p_what) {
 	}
 
 	if (p_what == NOTIFICATION_ENTER_TREE) {
-		if (sub_inspector) {
-			add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor"));
-		} else {
-			add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
+		_update_inspector_bg();
+		if (!sub_inspector) {
 			get_tree()->connect("node_removed", callable_mp(this, &EditorInspector::_node_removed));
 		}
 	}
@@ -2485,11 +2500,7 @@ void EditorInspector::_notification(int p_what) {
 	}
 
 	if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
-		if (sub_inspector) {
-			add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor"));
-		} else if (is_inside_tree()) {
-			add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
-		}
+		_update_inspector_bg();
 
 		update_tree();
 	}
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index ad8c1611b0a..b98801975fa 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -343,6 +343,8 @@ class EditorInspector : public ScrollContainer {
 
 	bool _is_property_disabled_by_feature_profile(const StringName &p_property);
 
+	void _update_inspector_bg();
+
 protected:
 	static void _bind_methods();
 	void _notification(int p_what);
@@ -394,6 +396,7 @@ public:
 
 	void set_use_wide_editors(bool p_enable);
 	void set_sub_inspector(bool p_enable);
+	bool is_sub_inspector() const { return sub_inspector; }
 
 	void set_use_deletable_properties(bool p_enabled);
 
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index dd39a08d1fa..045480868dd 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -5858,7 +5858,7 @@ EditorNode::EditorNode() {
 	EDITOR_DEF("interface/inspector/horizontal_vector2_editing", false);
 	EDITOR_DEF("interface/inspector/horizontal_vector_types_editing", true);
 	EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true);
-	EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "StandardMaterial3D,ORMMaterial3D,Script,MeshLibrary,TileSet");
+	EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "Script,MeshLibrary,TileSet");
 	EDITOR_DEF("interface/inspector/default_color_picker_mode", 0);
 	EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW", PROPERTY_USAGE_DEFAULT));
 	EDITOR_DEF("run/auto_save/save_before_running", true);
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 669f3819794..6bfc16ccd7e 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -2859,6 +2859,41 @@ void EditorPropertyResource::_fold_other_editors(Object *p_self) {
 	}
 }
 
+void EditorPropertyResource::_update_property_bg() {
+	if (!is_inside_tree()) {
+		return;
+	}
+
+	updating_theme = true;
+	if (sub_inspector != nullptr) {
+		int count_subinspectors = 0;
+		Node *n = get_parent();
+		while (n) {
+			EditorInspector *ei = Object::cast_to<EditorInspector>(n);
+			if (ei && ei->is_sub_inspector()) {
+				count_subinspectors++;
+			}
+			n = n->get_parent();
+		}
+		count_subinspectors = MIN(15, count_subinspectors);
+
+		add_theme_color_override("property_color", get_theme_color("sub_inspector_property_color", "Editor"));
+		add_theme_style_override("bg_selected", get_theme_stylebox("sub_inspector_property_bg_selected" + itos(count_subinspectors), "Editor"));
+		add_theme_style_override("bg", get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), "Editor"));
+
+		add_theme_constant_override("font_offset", get_theme_constant("sub_inspector_font_offset", "Editor"));
+		add_theme_constant_override("vseparation", 0);
+	} else {
+		add_theme_color_override("property_color", get_theme_color("property_color", "EditorProperty"));
+		add_theme_style_override("bg_selected", get_theme_stylebox("bg_selected", "EditorProperty"));
+		add_theme_style_override("bg", get_theme_stylebox("bg", "EditorProperty"));
+		add_theme_constant_override("vseparation", get_theme_constant("vseparation", "EditorProperty"));
+		add_theme_constant_override("font_offset", get_theme_constant("font_offset", "EditorProperty"));
+	}
+
+	updating_theme = false;
+	update();
+}
 void EditorPropertyResource::update_property() {
 	RES res = get_edited_object()->get(get_edited_property());
 
@@ -2907,6 +2942,8 @@ void EditorPropertyResource::update_property() {
 					}
 					opened_editor = true;
 				}
+
+				_update_property_bg();
 			}
 
 			if (res.ptr() != sub_inspector->get_edited_object()) {
@@ -2923,6 +2960,7 @@ void EditorPropertyResource::update_property() {
 					EditorNode::get_singleton()->hide_top_editors();
 					opened_editor = false;
 				}
+				_update_property_bg();
 			}
 		}
 	}
@@ -2976,8 +3014,12 @@ void EditorPropertyResource::setup(const String &p_base_type) {
 
 void EditorPropertyResource::_notification(int p_what) {
 	if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+		if (updating_theme) {
+			return;
+		}
 		Ref<Texture2D> t = get_theme_icon("select_arrow", "Tree");
 		edit->set_icon(t);
+		_update_property_bg();
 	}
 
 	if (p_what == NOTIFICATION_DRAG_BEGIN) {
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 4775259111e..6f097fb5df4 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -654,6 +654,9 @@ class EditorPropertyResource : public EditorProperty {
 
 	bool opened_editor;
 
+	bool updating_theme = false;
+	void _update_property_bg();
+
 protected:
 	static void _bind_methods();
 	void _notification(int p_what);
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index d813ae9353d..e37173bf683 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -442,6 +442,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
 
 	// Property editor
 	_initial_set("docks/property_editor/auto_refresh_interval", 0.2); //update 5 times per second by default
+	_initial_set("docks/property_editor/subresource_hue_tint", 0.75);
+	hints["docks/property_editor/subresource_hue_tint"] = PropertyInfo(Variant::FLOAT, "docks/property_editor/subresource_hue_tint", PROPERTY_HINT_RANGE, "0,1,0.01", PROPERTY_USAGE_DEFAULT);
 
 	/* Text editor */
 
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 8f877a47625..f81087ded90 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -724,14 +724,58 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
 	theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon("GuiVisibilityXray", "EditorIcons"));
 	theme->set_constant("vseparation", "PopupMenu", (extra_spacing + default_margin_size + 1) * EDSCALE);
 
-	Ref<StyleBoxFlat> sub_inspector_bg = make_flat_stylebox(dark_color_1.lerp(accent_color, 0.08), 2, 0, 2, 2);
-	sub_inspector_bg->set_border_width(SIDE_LEFT, 2);
-	sub_inspector_bg->set_border_width(SIDE_RIGHT, 2);
-	sub_inspector_bg->set_border_width(SIDE_BOTTOM, 2);
-	sub_inspector_bg->set_border_color(accent_color * Color(1, 1, 1, 0.3));
-	sub_inspector_bg->set_draw_center(true);
+	for (int i = 0; i < 16; i++) {
+		Color si_base_color = accent_color;
+
+		float hue_rotate = (i * 2 % 16) / 16.0;
+		si_base_color.set_hsv(Math::fmod(float(si_base_color.get_h() + hue_rotate), float(1.0)), si_base_color.get_s(), si_base_color.get_v());
+		si_base_color = accent_color.lerp(si_base_color, float(EDITOR_GET("docks/property_editor/subresource_hue_tint")));
+
+		Ref<StyleBoxFlat> sub_inspector_bg;
+
+		sub_inspector_bg = make_flat_stylebox(dark_color_1.lerp(si_base_color, 0.08), 2, 0, 2, 2);
+
+		sub_inspector_bg->set_border_width(SIDE_LEFT, 2);
+		sub_inspector_bg->set_border_width(SIDE_RIGHT, 2);
+		sub_inspector_bg->set_border_width(SIDE_BOTTOM, 2);
+		sub_inspector_bg->set_border_width(SIDE_TOP, 2);
+		sub_inspector_bg->set_default_margin(SIDE_LEFT, 3);
+		sub_inspector_bg->set_default_margin(SIDE_RIGHT, 3);
+		sub_inspector_bg->set_default_margin(SIDE_BOTTOM, 10);
+		sub_inspector_bg->set_default_margin(SIDE_TOP, 5);
+		sub_inspector_bg->set_border_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8));
+		sub_inspector_bg->set_draw_center(true);
+
+		theme->set_stylebox("sub_inspector_bg" + itos(i), "Editor", sub_inspector_bg);
+
+		Ref<StyleBoxFlat> bg_color;
+		bg_color.instance();
+		bg_color->set_bg_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8));
+		bg_color->set_border_width_all(0);
+
+		Ref<StyleBoxFlat> bg_color_selected;
+		bg_color_selected.instance();
+		bg_color_selected->set_border_width_all(0);
+		bg_color_selected->set_bg_color(si_base_color * Color(0.8, 0.8, 0.8, 0.8));
+
+		theme->set_stylebox("sub_inspector_property_bg" + itos(i), "Editor", bg_color);
+		theme->set_stylebox("sub_inspector_property_bg_selected" + itos(i), "Editor", bg_color_selected);
+	}
+
+	theme->set_color("sub_inspector_property_color", "Editor", dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1));
+	theme->set_constant("sub_inspector_font_offset", "Editor", 4 * EDSCALE);
+
+	Ref<StyleBoxFlat> style_property_bg = style_default->duplicate();
+	style_property_bg->set_bg_color(highlight_color);
+	style_property_bg->set_border_width_all(0);
+
+	theme->set_constant("font_offset", "EditorProperty", 1 * EDSCALE);
+	theme->set_stylebox("bg_selected", "EditorProperty", style_property_bg);
+	theme->set_stylebox("bg", "EditorProperty", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+	theme->set_constant("vseparation", "EditorProperty", (extra_spacing + default_margin_size) * EDSCALE);
+	theme->set_color("error_color", "EditorProperty", error_color);
+	theme->set_color("property_color", "EditorProperty", property_color);
 
-	theme->set_stylebox("sub_inspector_bg", "Editor", sub_inspector_bg);
 	theme->set_constant("inspector_margin", "Editor", 8 * EDSCALE);
 
 	// Tree & ItemList background