Browse Source

Warn about accessing non-existing editor theme items

Yuri Sizov 1 year ago
parent
commit
6e11fcb92c
3 changed files with 130 additions and 16 deletions
  1. 99 1
      editor/editor_themes.cpp
  2. 16 0
      editor/editor_themes.h
  3. 15 15
      scene/resources/theme.h

+ 99 - 1
editor/editor_themes.cpp

@@ -41,6 +41,7 @@
 #include "scene/resources/style_box_flat.h"
 #include "scene/resources/style_box_flat.h"
 #include "scene/resources/style_box_line.h"
 #include "scene/resources/style_box_line.h"
 #include "scene/resources/style_box_texture.h"
 #include "scene/resources/style_box_texture.h"
+#include "scene/theme/theme_db.h"
 
 
 #include "modules/modules_enabled.gen.h" // For svg.
 #include "modules/modules_enabled.gen.h" // For svg.
 #ifdef MODULE_SVG_ENABLED
 #ifdef MODULE_SVG_ENABLED
@@ -214,6 +215,103 @@ void EditorColorMap::create() {
 	add_conversion_exception("Breakpoint");
 	add_conversion_exception("Breakpoint");
 }
 }
 
 
+Vector<StringName> EditorTheme::editor_theme_types;
+
+// TODO: Refactor these and corresponding Theme methods to use the bool get_xxx(r_value) pattern internally.
+
+// Keep in sync with Theme::get_color.
+Color EditorTheme::get_color(const StringName &p_name, const StringName &p_theme_type) const {
+	if (color_map.has(p_theme_type) && color_map[p_theme_type].has(p_name)) {
+		return color_map[p_theme_type][p_name];
+	} else {
+		if (editor_theme_types.has(p_theme_type)) {
+			WARN_PRINT(vformat("Trying to access a non-existing editor theme color '%s' in '%s'.", p_name, p_theme_type));
+		}
+		return Color();
+	}
+}
+
+// Keep in sync with Theme::get_constant.
+int EditorTheme::get_constant(const StringName &p_name, const StringName &p_theme_type) const {
+	if (constant_map.has(p_theme_type) && constant_map[p_theme_type].has(p_name)) {
+		return constant_map[p_theme_type][p_name];
+	} else {
+		if (editor_theme_types.has(p_theme_type)) {
+			WARN_PRINT(vformat("Trying to access a non-existing editor theme constant '%s' in '%s'.", p_name, p_theme_type));
+		}
+		return 0;
+	}
+}
+
+// Keep in sync with Theme::get_font.
+Ref<Font> EditorTheme::get_font(const StringName &p_name, const StringName &p_theme_type) const {
+	if (font_map.has(p_theme_type) && font_map[p_theme_type].has(p_name) && font_map[p_theme_type][p_name].is_valid()) {
+		return font_map[p_theme_type][p_name];
+	} else if (has_default_font()) {
+		if (editor_theme_types.has(p_theme_type)) {
+			WARN_PRINT(vformat("Trying to access a non-existing editor theme font '%s' in '%s'.", p_name, p_theme_type));
+		}
+		return default_font;
+	} else {
+		if (editor_theme_types.has(p_theme_type)) {
+			WARN_PRINT(vformat("Trying to access a non-existing editor theme font '%s' in '%s'.", p_name, p_theme_type));
+		}
+		return ThemeDB::get_singleton()->get_fallback_font();
+	}
+}
+
+// Keep in sync with Theme::get_font_size.
+int EditorTheme::get_font_size(const StringName &p_name, const StringName &p_theme_type) const {
+	if (font_size_map.has(p_theme_type) && font_size_map[p_theme_type].has(p_name) && (font_size_map[p_theme_type][p_name] > 0)) {
+		return font_size_map[p_theme_type][p_name];
+	} else if (has_default_font_size()) {
+		if (editor_theme_types.has(p_theme_type)) {
+			WARN_PRINT(vformat("Trying to access a non-existing editor theme font size '%s' in '%s'.", p_name, p_theme_type));
+		}
+		return default_font_size;
+	} else {
+		if (editor_theme_types.has(p_theme_type)) {
+			WARN_PRINT(vformat("Trying to access a non-existing editor theme font size '%s' in '%s'.", p_name, p_theme_type));
+		}
+		return ThemeDB::get_singleton()->get_fallback_font_size();
+	}
+}
+
+// Keep in sync with Theme::get_icon.
+Ref<Texture2D> EditorTheme::get_icon(const StringName &p_name, const StringName &p_theme_type) const {
+	if (icon_map.has(p_theme_type) && icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()) {
+		return icon_map[p_theme_type][p_name];
+	} else {
+		if (editor_theme_types.has(p_theme_type)) {
+			WARN_PRINT(vformat("Trying to access a non-existing editor theme icon '%s' in '%s'.", p_name, p_theme_type));
+		}
+		return ThemeDB::get_singleton()->get_fallback_icon();
+	}
+}
+
+// Keep in sync with Theme::get_stylebox.
+Ref<StyleBox> EditorTheme::get_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
+	if (style_map.has(p_theme_type) && style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()) {
+		return style_map[p_theme_type][p_name];
+	} else {
+		if (editor_theme_types.has(p_theme_type)) {
+			WARN_PRINT(vformat("Trying to access a non-existing editor theme stylebox '%s' in '%s'.", p_name, p_theme_type));
+		}
+		return ThemeDB::get_singleton()->get_fallback_stylebox();
+	}
+}
+
+EditorTheme::EditorTheme() {
+	if (editor_theme_types.is_empty()) {
+		editor_theme_types.append(EditorStringName(Editor));
+		editor_theme_types.append(EditorStringName(EditorFonts));
+		editor_theme_types.append(EditorStringName(EditorIcons));
+		editor_theme_types.append(EditorStringName(EditorStyles));
+	}
+}
+
+// Editor theme generatior.
+
 static Ref<StyleBoxTexture> make_stylebox(Ref<Texture2D> p_texture, float p_left, float p_top, float p_right, float p_bottom, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1, bool p_draw_center = true) {
 static Ref<StyleBoxTexture> make_stylebox(Ref<Texture2D> p_texture, float p_left, float p_top, float p_right, float p_bottom, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1, bool p_draw_center = true) {
 	Ref<StyleBoxTexture> style(memnew(StyleBoxTexture));
 	Ref<StyleBoxTexture> style(memnew(StyleBoxTexture));
 	style->set_texture(p_texture);
 	style->set_texture(p_texture);
@@ -430,7 +528,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme, f
 
 
 Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
 Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
 	OS::get_singleton()->benchmark_begin_measure("create_editor_theme");
 	OS::get_singleton()->benchmark_begin_measure("create_editor_theme");
-	Ref<Theme> theme = Ref<Theme>(memnew(Theme));
+	Ref<EditorTheme> theme = memnew(EditorTheme);
 
 
 	// Controls may rely on the scale for their internal drawing logic.
 	// Controls may rely on the scale for their internal drawing logic.
 	theme->set_default_base_scale(EDSCALE);
 	theme->set_default_base_scale(EDSCALE);

+ 16 - 0
editor/editor_themes.h

@@ -53,6 +53,22 @@ public:
 	static HashSet<StringName> &get_color_conversion_exceptions() { return color_conversion_exceptions; };
 	static HashSet<StringName> &get_color_conversion_exceptions() { return color_conversion_exceptions; };
 };
 };
 
 
+class EditorTheme : public Theme {
+	GDCLASS(EditorTheme, Theme);
+
+	static Vector<StringName> editor_theme_types;
+
+public:
+	virtual Color get_color(const StringName &p_name, const StringName &p_theme_type) const override;
+	virtual int get_constant(const StringName &p_name, const StringName &p_theme_type) const override;
+	virtual Ref<Font> get_font(const StringName &p_name, const StringName &p_theme_type) const override;
+	virtual int get_font_size(const StringName &p_name, const StringName &p_theme_type) const override;
+	virtual Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_theme_type) const override;
+	virtual Ref<StyleBox> get_stylebox(const StringName &p_name, const StringName &p_theme_type) const override;
+
+	EditorTheme();
+};
+
 Ref<Theme> create_editor_theme(Ref<Theme> p_theme = nullptr);
 Ref<Theme> create_editor_theme(Ref<Theme> p_theme = nullptr);
 
 
 Ref<Theme> create_custom_theme(Ref<Theme> p_theme = nullptr);
 Ref<Theme> create_custom_theme(Ref<Theme> p_theme = nullptr);

+ 15 - 15
scene/resources/theme.h

@@ -69,15 +69,6 @@ private:
 
 
 	void _emit_theme_changed(bool p_notify_list_changed = false);
 	void _emit_theme_changed(bool p_notify_list_changed = false);
 
 
-	HashMap<StringName, ThemeIconMap> icon_map;
-	HashMap<StringName, ThemeStyleMap> style_map;
-	HashMap<StringName, ThemeFontMap> font_map;
-	HashMap<StringName, ThemeFontSizeMap> font_size_map;
-	HashMap<StringName, ThemeColorMap> color_map;
-	HashMap<StringName, ThemeConstantMap> constant_map;
-	HashMap<StringName, StringName> variation_map;
-	HashMap<StringName, List<StringName>> variation_base_map;
-
 	Vector<String> _get_icon_list(const String &p_theme_type) const;
 	Vector<String> _get_icon_list(const String &p_theme_type) const;
 	Vector<String> _get_icon_type_list() const;
 	Vector<String> _get_icon_type_list() const;
 	Vector<String> _get_stylebox_list(const String &p_theme_type) const;
 	Vector<String> _get_stylebox_list(const String &p_theme_type) const;
@@ -107,6 +98,15 @@ protected:
 	Ref<Font> default_font;
 	Ref<Font> default_font;
 	int default_font_size = -1;
 	int default_font_size = -1;
 
 
+	HashMap<StringName, ThemeIconMap> icon_map;
+	HashMap<StringName, ThemeStyleMap> style_map;
+	HashMap<StringName, ThemeFontMap> font_map;
+	HashMap<StringName, ThemeFontSizeMap> font_size_map;
+	HashMap<StringName, ThemeColorMap> color_map;
+	HashMap<StringName, ThemeConstantMap> constant_map;
+	HashMap<StringName, StringName> variation_map;
+	HashMap<StringName, List<StringName>> variation_base_map;
+
 	static void _bind_methods();
 	static void _bind_methods();
 
 
 	void _freeze_change_propagation();
 	void _freeze_change_propagation();
@@ -131,7 +131,7 @@ public:
 	bool has_default_font_size() const;
 	bool has_default_font_size() const;
 
 
 	void set_icon(const StringName &p_name, const StringName &p_theme_type, const Ref<Texture2D> &p_icon);
 	void set_icon(const StringName &p_name, const StringName &p_theme_type, const Ref<Texture2D> &p_icon);
-	Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_theme_type) const;
+	virtual Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_icon(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_icon(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_icon_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_icon_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
 	void rename_icon(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
 	void rename_icon(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
@@ -142,7 +142,7 @@ public:
 	void get_icon_type_list(List<StringName> *p_list) const;
 	void get_icon_type_list(List<StringName> *p_list) const;
 
 
 	void set_stylebox(const StringName &p_name, const StringName &p_theme_type, const Ref<StyleBox> &p_style);
 	void set_stylebox(const StringName &p_name, const StringName &p_theme_type, const Ref<StyleBox> &p_style);
-	Ref<StyleBox> get_stylebox(const StringName &p_name, const StringName &p_theme_type) const;
+	virtual Ref<StyleBox> get_stylebox(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_stylebox(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_stylebox(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_stylebox_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_stylebox_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
 	void rename_stylebox(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
 	void rename_stylebox(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
@@ -153,7 +153,7 @@ public:
 	void get_stylebox_type_list(List<StringName> *p_list) const;
 	void get_stylebox_type_list(List<StringName> *p_list) const;
 
 
 	void set_font(const StringName &p_name, const StringName &p_theme_type, const Ref<Font> &p_font);
 	void set_font(const StringName &p_name, const StringName &p_theme_type, const Ref<Font> &p_font);
-	Ref<Font> get_font(const StringName &p_name, const StringName &p_theme_type) const;
+	virtual Ref<Font> get_font(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_font(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_font(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_font_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_font_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
 	void rename_font(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
 	void rename_font(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
@@ -164,7 +164,7 @@ public:
 	void get_font_type_list(List<StringName> *p_list) const;
 	void get_font_type_list(List<StringName> *p_list) const;
 
 
 	void set_font_size(const StringName &p_name, const StringName &p_theme_type, int p_font_size);
 	void set_font_size(const StringName &p_name, const StringName &p_theme_type, int p_font_size);
-	int get_font_size(const StringName &p_name, const StringName &p_theme_type) const;
+	virtual int get_font_size(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_font_size(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_font_size(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_font_size_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_font_size_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
 	void rename_font_size(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
 	void rename_font_size(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
@@ -175,7 +175,7 @@ public:
 	void get_font_size_type_list(List<StringName> *p_list) const;
 	void get_font_size_type_list(List<StringName> *p_list) const;
 
 
 	void set_color(const StringName &p_name, const StringName &p_theme_type, const Color &p_color);
 	void set_color(const StringName &p_name, const StringName &p_theme_type, const Color &p_color);
-	Color get_color(const StringName &p_name, const StringName &p_theme_type) const;
+	virtual Color get_color(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_color(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_color(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_color_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_color_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
 	void rename_color(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
 	void rename_color(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
@@ -186,7 +186,7 @@ public:
 	void get_color_type_list(List<StringName> *p_list) const;
 	void get_color_type_list(List<StringName> *p_list) const;
 
 
 	void set_constant(const StringName &p_name, const StringName &p_theme_type, int p_constant);
 	void set_constant(const StringName &p_name, const StringName &p_theme_type, int p_constant);
-	int get_constant(const StringName &p_name, const StringName &p_theme_type) const;
+	virtual int get_constant(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_constant(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_constant(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_constant_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
 	bool has_constant_nocheck(const StringName &p_name, const StringName &p_theme_type) const;
 	void rename_constant(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);
 	void rename_constant(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type);