summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorYuri Sizov <yuris@humnom.net>2022-08-08 19:29:36 +0300
committerYuri Sizov <yuris@humnom.net>2022-08-26 19:23:05 +0300
commit6320a0fc18fa84363494df9013b65011a3018a62 (patch)
tree1e93dc743f3f5454918229ba0b6ec2d73ca86feb /scene
parentc8ef12a03a81c931480be41739ba5789415c4675 (diff)
Add ThemeDB, expose previously static Theme methods
Diffstat (limited to 'scene')
-rw-r--r--scene/3d/label_3d.cpp17
-rw-r--r--scene/SCsub1
-rw-r--r--scene/gui/control.cpp81
-rw-r--r--scene/main/window.cpp15
-rw-r--r--scene/register_scene_types.cpp63
-rw-r--r--scene/register_scene_types.h3
-rw-r--r--scene/resources/default_theme/default_theme.cpp20
-rw-r--r--scene/resources/default_theme/default_theme.h1
-rw-r--r--scene/resources/font.cpp37
-rw-r--r--scene/resources/primitive_meshes.cpp17
-rw-r--r--scene/resources/theme.cpp79
-rw-r--r--scene/resources/theme.h29
-rw-r--r--scene/theme/SCsub5
-rw-r--r--scene/theme/theme_db.cpp237
-rw-r--r--scene/theme/theme_db.h95
15 files changed, 447 insertions, 253 deletions
diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp
index 40b8af7d63..e4a7cf6ee5 100644
--- a/scene/3d/label_3d.cpp
+++ b/scene/3d/label_3d.cpp
@@ -34,6 +34,7 @@
#include "scene/main/viewport.h"
#include "scene/resources/theme.h"
#include "scene/scene_string_names.h"
+#include "scene/theme/theme_db.h"
void Label3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &Label3D::set_horizontal_alignment);
@@ -734,13 +735,13 @@ Ref<Font> Label3D::_get_font_or_default() const {
}
// Check the project-defined Theme resource.
- if (Theme::get_project_default().is_valid()) {
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
List<StringName> theme_types;
- Theme::get_project_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
+ ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
for (const StringName &E : theme_types) {
- if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- Ref<Font> f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
+ Ref<Font> f = ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
if (f.is_valid()) {
theme_font = f;
theme_font->connect(CoreStringNames::get_singleton()->changed, Callable(const_cast<Label3D *>(this), "_font_changed"));
@@ -753,11 +754,11 @@ Ref<Font> Label3D::_get_font_or_default() const {
// Lastly, fall back on the items defined in the default Theme, if they exist.
{
List<StringName> theme_types;
- Theme::get_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
+ ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
for (const StringName &E : theme_types) {
- if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
+ Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
if (f.is_valid()) {
theme_font = f;
theme_font->connect(CoreStringNames::get_singleton()->changed, Callable(const_cast<Label3D *>(this), "_font_changed"));
@@ -768,7 +769,7 @@ Ref<Font> Label3D::_get_font_or_default() const {
}
// If they don't exist, use any type to return the default/empty value.
- Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
+ Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
if (f.is_valid()) {
theme_font = f;
theme_font->connect(CoreStringNames::get_singleton()->changed, Callable(const_cast<Label3D *>(this), "_font_changed"));
diff --git a/scene/SCsub b/scene/SCsub
index 92288211bb..b4b2d6dd0a 100644
--- a/scene/SCsub
+++ b/scene/SCsub
@@ -17,6 +17,7 @@ SConscript("animation/SCsub")
SConscript("audio/SCsub")
SConscript("resources/SCsub")
SConscript("debugger/SCsub")
+SConscript("theme/SCsub")
# Build it all as a library
lib = env.add_library("scene", env.scene_sources)
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 9b6a19c50a..6dd3d46b27 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -43,6 +43,7 @@
#include "scene/main/canvas_layer.h"
#include "scene/main/window.h"
#include "scene/scene_string_names.h"
+#include "scene/theme/theme_db.h"
#include "servers/rendering_server.h"
#include "servers/text_server.h"
@@ -193,15 +194,15 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List
List<StringName> sn;
String pf = p_function;
if (pf == "add_theme_color_override" || pf == "has_theme_color" || pf == "has_theme_color_override" || pf == "get_theme_color") {
- Theme::get_default()->get_color_list(get_class(), &sn);
+ ThemeDB::get_singleton()->get_default_theme()->get_color_list(get_class(), &sn);
} else if (pf == "add_theme_style_override" || pf == "has_theme_style" || pf == "has_theme_style_override" || pf == "get_theme_style") {
- Theme::get_default()->get_stylebox_list(get_class(), &sn);
+ ThemeDB::get_singleton()->get_default_theme()->get_stylebox_list(get_class(), &sn);
} else if (pf == "add_theme_font_override" || pf == "has_theme_font" || pf == "has_theme_font_override" || pf == "get_theme_font") {
- Theme::get_default()->get_font_list(get_class(), &sn);
+ ThemeDB::get_singleton()->get_default_theme()->get_font_list(get_class(), &sn);
} else if (pf == "add_theme_font_size_override" || pf == "has_theme_font_size" || pf == "has_theme_font_size_override" || pf == "get_theme_font_size") {
- Theme::get_default()->get_font_size_list(get_class(), &sn);
+ ThemeDB::get_singleton()->get_default_theme()->get_font_size_list(get_class(), &sn);
} else if (pf == "add_theme_constant_override" || pf == "has_theme_constant" || pf == "has_theme_constant_override" || pf == "get_theme_constant") {
- Theme::get_default()->get_constant_list(get_class(), &sn);
+ ThemeDB::get_singleton()->get_default_theme()->get_constant_list(get_class(), &sn);
}
sn.sort_custom<StringName::AlphCompare>();
@@ -344,7 +345,7 @@ bool Control::_get(const StringName &p_name, Variant &r_ret) const {
}
void Control::_get_property_list(List<PropertyInfo> *p_list) const {
- Ref<Theme> theme = Theme::get_default();
+ Ref<Theme> theme = ThemeDB::get_singleton()->get_default_theme();
p_list->push_back(PropertyInfo(Variant::NIL, TTRC("Theme Overrides"), PROPERTY_HINT_NONE, "theme_override_", PROPERTY_USAGE_GROUP));
@@ -429,9 +430,9 @@ void Control::_validate_property(PropertyInfo &p_property) const {
// Only the default theme and the project theme are used for the list of options.
// This is an imposed limitation to simplify the logic needed to leverage those options.
- Theme::get_default()->get_type_variation_list(get_class_name(), &names);
- if (Theme::get_project_default().is_valid()) {
- Theme::get_project_default()->get_type_variation_list(get_class_name(), &names);
+ ThemeDB::get_singleton()->get_default_theme()->get_type_variation_list(get_class_name(), &names);
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
+ ThemeDB::get_singleton()->get_project_theme()->get_type_variation_list(get_class_name(), &names);
}
names.sort_custom<StringName::AlphCompare>();
@@ -2419,22 +2420,22 @@ T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner
}
// Secondly, check the project-defined Theme resource.
- if (Theme::get_project_default().is_valid()) {
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
for (const StringName &E : p_theme_types) {
- if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) {
- return Theme::get_project_default()->get_theme_item(p_data_type, p_name, E);
+ if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) {
+ return ThemeDB::get_singleton()->get_project_theme()->get_theme_item(p_data_type, p_name, E);
}
}
}
// Lastly, fall back on the items defined in the default Theme, if they exist.
for (const StringName &E : p_theme_types) {
- if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) {
- return Theme::get_default()->get_theme_item(p_data_type, p_name, E);
+ if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) {
+ return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, E);
}
}
// If they don't exist, use any type to return the default/empty value.
- return Theme::get_default()->get_theme_item(p_data_type, p_name, p_theme_types[0]);
+ return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, p_theme_types[0]);
}
bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) {
@@ -2475,9 +2476,9 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow
}
// Secondly, check the project-defined Theme resource.
- if (Theme::get_project_default().is_valid()) {
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
for (const StringName &E : p_theme_types) {
- if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) {
+ if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) {
return true;
}
}
@@ -2485,7 +2486,7 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow
// Lastly, fall back on the items defined in the default Theme, if they exist.
for (const StringName &E : p_theme_types) {
- if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) {
+ if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) {
return true;
}
}
@@ -2494,13 +2495,13 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow
void Control::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const {
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
- if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(data.theme_type_variation) != StringName()) {
- Theme::get_project_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list);
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid() && ThemeDB::get_singleton()->get_project_theme()->get_type_variation_base(data.theme_type_variation) != StringName()) {
+ ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list);
} else {
- Theme::get_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list);
+ ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list);
}
} else {
- Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list);
+ ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(p_theme_type, StringName(), p_list);
}
}
@@ -2851,17 +2852,17 @@ float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_
}
// Secondly, check the project-defined Theme resource.
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_default_base_scale()) {
- return Theme::get_project_default()->get_default_base_scale();
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
+ if (ThemeDB::get_singleton()->get_project_theme()->has_default_base_scale()) {
+ return ThemeDB::get_singleton()->get_project_theme()->get_default_base_scale();
}
}
// Lastly, fall back on the default Theme.
- if (Theme::get_default()->has_default_base_scale()) {
- return Theme::get_default()->get_default_base_scale();
+ if (ThemeDB::get_singleton()->get_default_theme()->has_default_base_scale()) {
+ return ThemeDB::get_singleton()->get_default_theme()->get_default_base_scale();
}
- return Theme::get_fallback_base_scale();
+ return ThemeDB::get_singleton()->get_fallback_base_scale();
}
float Control::get_theme_default_base_scale() const {
@@ -2902,17 +2903,17 @@ Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_th
}
// Secondly, check the project-defined Theme resource.
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_default_font()) {
- return Theme::get_project_default()->get_default_font();
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
+ if (ThemeDB::get_singleton()->get_project_theme()->has_default_font()) {
+ return ThemeDB::get_singleton()->get_project_theme()->get_default_font();
}
}
// Lastly, fall back on the default Theme.
- if (Theme::get_default()->has_default_font()) {
- return Theme::get_default()->get_default_font();
+ if (ThemeDB::get_singleton()->get_default_theme()->has_default_font()) {
+ return ThemeDB::get_singleton()->get_default_theme()->get_default_font();
}
- return Theme::get_fallback_font();
+ return ThemeDB::get_singleton()->get_fallback_font();
}
Ref<Font> Control::get_theme_default_font() const {
@@ -2953,17 +2954,17 @@ int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_the
}
// Secondly, check the project-defined Theme resource.
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_default_font_size()) {
- return Theme::get_project_default()->get_default_font_size();
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
+ if (ThemeDB::get_singleton()->get_project_theme()->has_default_font_size()) {
+ return ThemeDB::get_singleton()->get_project_theme()->get_default_font_size();
}
}
// Lastly, fall back on the default Theme.
- if (Theme::get_default()->has_default_font_size()) {
- return Theme::get_default()->get_default_font_size();
+ if (ThemeDB::get_singleton()->get_default_theme()->has_default_font_size()) {
+ return ThemeDB::get_singleton()->get_default_theme()->get_default_font_size();
}
- return Theme::get_fallback_font_size();
+ return ThemeDB::get_singleton()->get_fallback_font_size();
}
int Control::get_theme_default_font_size() const {
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 35414da9ed..fa71040159 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -35,6 +35,7 @@
#include "core/string/translation.h"
#include "scene/gui/control.h"
#include "scene/scene_string_names.h"
+#include "scene/theme/theme_db.h"
void Window::set_title(const String &p_title) {
title = p_title;
@@ -1330,13 +1331,13 @@ StringName Window::get_theme_type_variation() const {
void Window::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const {
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
- if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(theme_type_variation) != StringName()) {
- Theme::get_project_default()->get_type_dependencies(get_class_name(), theme_type_variation, p_list);
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid() && ThemeDB::get_singleton()->get_project_theme()->get_type_variation_base(theme_type_variation) != StringName()) {
+ ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), theme_type_variation, p_list);
} else {
- Theme::get_default()->get_type_dependencies(get_class_name(), theme_type_variation, p_list);
+ ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), theme_type_variation, p_list);
}
} else {
- Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list);
+ ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(p_theme_type, StringName(), p_list);
}
}
@@ -1522,9 +1523,9 @@ void Window::_validate_property(PropertyInfo &p_property) const {
// Only the default theme and the project theme are used for the list of options.
// This is an imposed limitation to simplify the logic needed to leverage those options.
- Theme::get_default()->get_type_variation_list(get_class_name(), &names);
- if (Theme::get_project_default().is_valid()) {
- Theme::get_project_default()->get_type_variation_list(get_class_name(), &names);
+ ThemeDB::get_singleton()->get_default_theme()->get_type_variation_list(get_class_name(), &names);
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
+ ThemeDB::get_singleton()->get_project_theme()->get_type_variation_list(get_class_name(), &names);
}
names.sort_custom<StringName::AlphCompare>();
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 9665873dce..6bfb1907a2 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -193,12 +193,14 @@
#include "scene/resources/sky.h"
#include "scene/resources/sky_material.h"
#include "scene/resources/sphere_shape_3d.h"
+#include "scene/resources/style_box.h"
#include "scene/resources/surface_tool.h"
#include "scene/resources/syntax_highlighter.h"
#include "scene/resources/text_file.h"
#include "scene/resources/text_line.h"
#include "scene/resources/text_paragraph.h"
#include "scene/resources/texture.h"
+#include "scene/resources/theme.h"
#include "scene/resources/tile_set.h"
#include "scene/resources/video_stream.h"
#include "scene/resources/visual_shader.h"
@@ -210,6 +212,7 @@
#include "scene/resources/world_boundary_shape_2d.h"
#include "scene/resources/world_boundary_shape_3d.h"
#include "scene/scene_string_names.h"
+#include "scene/theme/theme_db.h"
#include "scene/main/shader_globals_override.h"
@@ -1122,62 +1125,8 @@ void register_scene_types() {
SceneDebugger::initialize();
}
-void initialize_theme() {
- // Allow creating the default theme at a different scale to suit higher/lower base resolutions.
- float default_theme_scale = GLOBAL_DEF("gui/theme/default_theme_scale", 1.0);
- ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_theme_scale", PropertyInfo(Variant::FLOAT, "gui/theme/default_theme_scale", PROPERTY_HINT_RANGE, "0.5,8,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
-
- String theme_path = GLOBAL_DEF_RST("gui/theme/custom", "");
- ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom", PropertyInfo(Variant::STRING, "gui/theme/custom", PROPERTY_HINT_FILE, "*.tres,*.res,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
-
- String font_path = GLOBAL_DEF_RST("gui/theme/custom_font", "");
- ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
-
- TextServer::FontAntialiasing font_antialiasing = (TextServer::FontAntialiasing)(int)GLOBAL_DEF_RST("gui/theme/default_font_antialiasing", 1);
- ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_antialiasing", PropertyInfo(Variant::INT, "gui/theme/default_font_antialiasing", PROPERTY_HINT_ENUM, "None,Grayscale,LCD sub-pixel", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
-
- TextServer::Hinting font_hinting = (TextServer::Hinting)(int)GLOBAL_DEF_RST("gui/theme/default_font_hinting", TextServer::HINTING_LIGHT);
- ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_hinting", PropertyInfo(Variant::INT, "gui/theme/default_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
-
- TextServer::SubpixelPositioning font_subpixel_positioning = (TextServer::SubpixelPositioning)(int)GLOBAL_DEF_RST("gui/theme/default_font_subpixel_positioning", TextServer::SUBPIXEL_POSITIONING_AUTO);
- ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_subpixel_positioning", PropertyInfo(Variant::INT, "gui/theme/default_font_subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
-
- const bool font_msdf = GLOBAL_DEF_RST("gui/theme/default_font_multichannel_signed_distance_field", false);
- const bool font_generate_mipmaps = GLOBAL_DEF_RST("gui/theme/default_font_generate_mipmaps", false);
-
- GLOBAL_DEF_RST("gui/theme/lcd_subpixel_layout", 1);
- ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/lcd_subpixel_layout", PropertyInfo(Variant::INT, "gui/theme/lcd_subpixel_layout", PROPERTY_HINT_ENUM, "Disabled,Horizontal RGB,Horizontal BGR,Vertical RGB,Vertical BGR"));
- ProjectSettings::get_singleton()->set_restart_if_changed("gui/theme/lcd_subpixel_layout", false);
-
- Ref<Font> font;
- if (!font_path.is_empty()) {
- font = ResourceLoader::load(font_path);
- if (!font.is_valid()) {
- ERR_PRINT("Error loading custom font '" + font_path + "'");
- }
- }
-
- // Always make the default theme to avoid invalid default font/icon/style in the given theme.
- if (RenderingServer::get_singleton()) {
- make_default_theme(default_theme_scale, font, font_subpixel_positioning, font_hinting, font_antialiasing, font_msdf, font_generate_mipmaps);
- }
-
- if (!theme_path.is_empty()) {
- Ref<Theme> theme = ResourceLoader::load(theme_path);
- if (theme.is_valid()) {
- Theme::set_project_default(theme);
- if (font.is_valid()) {
- Theme::set_fallback_font(font);
- }
- } else {
- ERR_PRINT("Error loading custom theme '" + theme_path + "'");
- }
- }
-}
-
void unregister_scene_types() {
SceneDebugger::deinitialize();
- clear_default_theme();
ResourceLoader::remove_resource_format_loader(resource_loader_texture_layered);
resource_loader_texture_layered.unref();
@@ -1219,3 +1168,9 @@ void unregister_scene_types() {
ColorPicker::finish_shaders();
SceneStringNames::free();
}
+
+void register_scene_singletons() {
+ GDREGISTER_CLASS(ThemeDB);
+
+ Engine::get_singleton()->add_singleton(Engine::Singleton("ThemeDB", ThemeDB::get_singleton()));
+}
diff --git a/scene/register_scene_types.h b/scene/register_scene_types.h
index dce8713976..cb3249c5d7 100644
--- a/scene/register_scene_types.h
+++ b/scene/register_scene_types.h
@@ -33,7 +33,6 @@
void register_scene_types();
void unregister_scene_types();
-
-void initialize_theme();
+void register_scene_singletons();
#endif // REGISTER_SCENE_TYPES_H
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 5bfa1adfe5..410f35e597 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -35,6 +35,7 @@
#include "default_theme_icons.gen.h"
#include "scene/resources/font.h"
#include "scene/resources/theme.h"
+#include "scene/theme/theme_db.h"
#include "servers/text_server.h"
#include "modules/modules_enabled.gen.h" // For svg.
@@ -1101,18 +1102,11 @@ void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPos
fill_default_theme(t, default_font, bold_font, bold_italics_font, italics_font, default_icon, default_style, default_scale);
- Theme::set_default(t);
- Theme::set_fallback_base_scale(default_scale);
- Theme::set_fallback_icon(default_icon);
- Theme::set_fallback_style(default_style);
- Theme::set_fallback_font(default_font);
- Theme::set_fallback_font_size(default_font_size * default_scale);
-}
+ ThemeDB::get_singleton()->set_default_theme(t);
-void clear_default_theme() {
- Theme::set_project_default(nullptr);
- Theme::set_default(nullptr);
- Theme::set_fallback_icon(nullptr);
- Theme::set_fallback_style(nullptr);
- Theme::set_fallback_font(nullptr);
+ ThemeDB::get_singleton()->set_fallback_base_scale(default_scale);
+ ThemeDB::get_singleton()->set_fallback_icon(default_icon);
+ ThemeDB::get_singleton()->set_fallback_stylebox(default_style);
+ ThemeDB::get_singleton()->set_fallback_font(default_font);
+ ThemeDB::get_singleton()->set_fallback_font_size(default_font_size * default_scale);
}
diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h
index 15be5e676f..003934ce90 100644
--- a/scene/resources/default_theme/default_theme.h
+++ b/scene/resources/default_theme/default_theme.h
@@ -37,6 +37,5 @@ const int default_font_size = 16;
void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &bold_font, const Ref<Font> &bold_italics_font, const Ref<Font> &italics_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale);
void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_font_subpixel = TextServer::SUBPIXEL_POSITIONING_AUTO, TextServer::Hinting p_font_hinting = TextServer::HINTING_LIGHT, TextServer::FontAntialiasing p_font_antialiased = TextServer::FONT_ANTIALIASING_GRAY, bool p_font_msdf = false, bool p_font_generate_mipmaps = false);
-void clear_default_theme();
#endif // DEFAULT_THEME_H
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index be57d9c965..8ec5678f0a 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -39,6 +39,7 @@
#include "scene/resources/text_line.h"
#include "scene/resources/text_paragraph.h"
#include "scene/resources/theme.h"
+#include "scene/theme/theme_db.h"
/*************************************************************************/
/* Font */
@@ -2552,13 +2553,13 @@ Ref<Font> FontVariation::_get_base_font_or_default() const {
}
// Check the project-defined Theme resource.
- if (Theme::get_project_default().is_valid()) {
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
List<StringName> theme_types;
- Theme::get_project_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
+ ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
for (const StringName &E : theme_types) {
- if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- Ref<Font> f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
+ Ref<Font> f = ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
if (f.is_valid()) {
theme_font = f;
theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
@@ -2569,13 +2570,13 @@ Ref<Font> FontVariation::_get_base_font_or_default() const {
}
// Lastly, fall back on the items defined in the default Theme, if they exist.
- if (Theme::get_default().is_valid()) {
+ if (ThemeDB::get_singleton()->get_default_theme().is_valid()) {
List<StringName> theme_types;
- Theme::get_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
+ ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
for (const StringName &E : theme_types) {
- if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
+ Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
if (f.is_valid()) {
theme_font = f;
theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
@@ -2585,7 +2586,7 @@ Ref<Font> FontVariation::_get_base_font_or_default() const {
}
// If they don't exist, use any type to return the default/empty value.
- Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
+ Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
if (f.is_valid()) {
theme_font = f;
theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
@@ -2859,13 +2860,13 @@ Ref<Font> SystemFont::_get_base_font_or_default() const {
}
// Check the project-defined Theme resource.
- if (Theme::get_project_default().is_valid()) {
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
List<StringName> theme_types;
- Theme::get_project_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
+ ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
for (const StringName &E : theme_types) {
- if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- Ref<Font> f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
+ Ref<Font> f = ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
if (f.is_valid()) {
theme_font = f;
theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
@@ -2876,13 +2877,13 @@ Ref<Font> SystemFont::_get_base_font_or_default() const {
}
// Lastly, fall back on the items defined in the default Theme, if they exist.
- if (Theme::get_default().is_valid()) {
+ if (ThemeDB::get_singleton()->get_default_theme().is_valid()) {
List<StringName> theme_types;
- Theme::get_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
+ ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
for (const StringName &E : theme_types) {
- if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
+ Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
if (f.is_valid()) {
theme_font = f;
theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
@@ -2892,7 +2893,7 @@ Ref<Font> SystemFont::_get_base_font_or_default() const {
}
// If they don't exist, use any type to return the default/empty value.
- Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
+ Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
if (f.is_valid()) {
theme_font = f;
theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index e993936350..fc5cf2a028 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -32,6 +32,7 @@
#include "core/core_string_names.h"
#include "scene/resources/theme.h"
+#include "scene/theme/theme_db.h"
#include "servers/rendering_server.h"
#include "thirdparty/misc/clipper.hpp"
#include "thirdparty/misc/polypartition.h"
@@ -2984,13 +2985,13 @@ Ref<Font> TextMesh::_get_font_or_default() const {
}
// Check the project-defined Theme resource.
- if (Theme::get_project_default().is_valid()) {
+ if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
List<StringName> theme_types;
- Theme::get_project_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
+ ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
for (const StringName &E : theme_types) {
- if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- return Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
+ return ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
}
}
}
@@ -2998,17 +2999,17 @@ Ref<Font> TextMesh::_get_font_or_default() const {
// Lastly, fall back on the items defined in the default Theme, if they exist.
{
List<StringName> theme_types;
- Theme::get_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
+ ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
for (const StringName &E : theme_types) {
- if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- return Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
+ return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
}
}
}
// If they don't exist, use any type to return the default/empty value.
- return Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
+ return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
}
void TextMesh::set_font_size(int p_size) {
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 3f6eec8497..3321392821 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -31,17 +31,7 @@
#include "theme.h"
#include "core/string/print_string.h"
-
-// Universal Theme resources used when no other theme has the item.
-Ref<Theme> Theme::default_theme;
-Ref<Theme> Theme::project_default_theme;
-
-// Universal default values, final fallback for every theme.
-float Theme::fallback_base_scale = 1.0;
-Ref<Texture2D> Theme::fallback_icon;
-Ref<StyleBox> Theme::fallback_style;
-Ref<Font> Theme::fallback_font;
-int Theme::fallback_font_size = 16;
+#include "scene/theme/theme_db.h"
// Dynamic properties.
bool Theme::_set(const StringName &p_name, const Variant &p_value) {
@@ -185,64 +175,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
-// Universal fallback Theme resources.
-Ref<Theme> Theme::get_default() {
- return default_theme;
-}
-
-void Theme::set_default(const Ref<Theme> &p_default) {
- default_theme = p_default;
-}
-
-Ref<Theme> Theme::get_project_default() {
- return project_default_theme;
-}
-
-void Theme::set_project_default(const Ref<Theme> &p_project_default) {
- project_default_theme = p_project_default;
-}
-
-// Universal fallback values for theme item types.
-void Theme::set_fallback_base_scale(float p_base_scale) {
- fallback_base_scale = p_base_scale;
-}
-
-void Theme::set_fallback_icon(const Ref<Texture2D> &p_icon) {
- fallback_icon = p_icon;
-}
-
-void Theme::set_fallback_style(const Ref<StyleBox> &p_style) {
- fallback_style = p_style;
-}
-
-void Theme::set_fallback_font(const Ref<Font> &p_font) {
- fallback_font = p_font;
-}
-
-void Theme::set_fallback_font_size(int p_font_size) {
- fallback_font_size = p_font_size;
-}
-
-float Theme::get_fallback_base_scale() {
- return fallback_base_scale;
-}
-
-Ref<Texture2D> Theme::get_fallback_icon() {
- return fallback_icon;
-}
-
-Ref<StyleBox> Theme::get_fallback_style() {
- return fallback_style;
-}
-
-Ref<Font> Theme::get_fallback_font() {
- return fallback_font;
-}
-
-int Theme::get_fallback_font_size() {
- return fallback_font_size;
-}
-
+// Static helpers.
bool Theme::is_valid_type_name(const String &p_name) {
for (int i = 0; i < p_name.length(); i++) {
if (!is_ascii_identifier_char(p_name[i])) {
@@ -351,7 +284,7 @@ Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_the
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 {
- return fallback_icon;
+ return ThemeDB::get_singleton()->get_fallback_icon();
}
}
@@ -461,7 +394,7 @@ Ref<StyleBox> Theme::get_stylebox(const StringName &p_name, const StringName &p_
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 {
- return fallback_style;
+ return ThemeDB::get_singleton()->get_fallback_stylebox();
}
}
@@ -573,7 +506,7 @@ Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_theme_ty
} else if (has_default_font()) {
return default_font;
} else {
- return fallback_font;
+ return ThemeDB::get_singleton()->get_fallback_font();
}
}
@@ -676,7 +609,7 @@ int Theme::get_font_size(const StringName &p_name, const StringName &p_theme_typ
} else if (has_default_font_size()) {
return default_font_size;
} else {
- return fallback_font_size;
+ return ThemeDB::get_singleton()->get_fallback_font_size();
}
}
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index a2aca5e61f..ed1dc7c938 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -102,17 +102,6 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
- // Universal Theme resources used when no other theme has the item.
- static Ref<Theme> default_theme;
- static Ref<Theme> project_default_theme;
-
- // Universal default values, final fallback for every theme.
- static float fallback_base_scale;
- static Ref<Texture2D> fallback_icon;
- static Ref<StyleBox> fallback_style;
- static Ref<Font> fallback_font;
- static int fallback_font_size;
-
// Default values configurable for each individual theme.
float default_base_scale = 0.0;
Ref<Font> default_font;
@@ -126,24 +115,6 @@ protected:
virtual void reset_state() override;
public:
- static Ref<Theme> get_default();
- static void set_default(const Ref<Theme> &p_default);
-
- static Ref<Theme> get_project_default();
- static void set_project_default(const Ref<Theme> &p_project_default);
-
- static void set_fallback_base_scale(float p_base_scale);
- static void set_fallback_icon(const Ref<Texture2D> &p_icon);
- static void set_fallback_style(const Ref<StyleBox> &p_style);
- static void set_fallback_font(const Ref<Font> &p_font);
- static void set_fallback_font_size(int p_font_size);
-
- static float get_fallback_base_scale();
- static Ref<Texture2D> get_fallback_icon();
- static Ref<StyleBox> get_fallback_style();
- static Ref<Font> get_fallback_font();
- static int get_fallback_font_size();
-
static bool is_valid_type_name(const String &p_name);
static bool is_valid_item_name(const String &p_name);
diff --git a/scene/theme/SCsub b/scene/theme/SCsub
new file mode 100644
index 0000000000..fc61250247
--- /dev/null
+++ b/scene/theme/SCsub
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+Import("env")
+
+env.add_source_files(env.scene_sources, "*.cpp")
diff --git a/scene/theme/theme_db.cpp b/scene/theme/theme_db.cpp
new file mode 100644
index 0000000000..d6e892cd93
--- /dev/null
+++ b/scene/theme/theme_db.cpp
@@ -0,0 +1,237 @@
+/*************************************************************************/
+/* theme_db.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "theme_db.h"
+
+#include "core/config/project_settings.h"
+#include "core/io/resource_loader.h"
+#include "scene/resources/default_theme/default_theme.h"
+#include "scene/resources/font.h"
+#include "scene/resources/style_box.h"
+#include "scene/resources/texture.h"
+#include "scene/resources/theme.h"
+#include "servers/text_server.h"
+
+// Default engine theme creation and configuration.
+void ThemeDB::initialize_theme() {
+ // Allow creating the default theme at a different scale to suit higher/lower base resolutions.
+ float default_theme_scale = GLOBAL_DEF("gui/theme/default_theme_scale", 1.0);
+ ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_theme_scale", PropertyInfo(Variant::FLOAT, "gui/theme/default_theme_scale", PROPERTY_HINT_RANGE, "0.5,8,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
+
+ String theme_path = GLOBAL_DEF_RST("gui/theme/custom", "");
+ ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom", PropertyInfo(Variant::STRING, "gui/theme/custom", PROPERTY_HINT_FILE, "*.tres,*.res,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
+
+ String font_path = GLOBAL_DEF_RST("gui/theme/custom_font", "");
+ ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
+
+ TextServer::FontAntialiasing font_antialiasing = (TextServer::FontAntialiasing)(int)GLOBAL_DEF_RST("gui/theme/default_font_antialiasing", 1);
+ ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_antialiasing", PropertyInfo(Variant::INT, "gui/theme/default_font_antialiasing", PROPERTY_HINT_ENUM, "None,Grayscale,LCD sub-pixel", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
+
+ TextServer::Hinting font_hinting = (TextServer::Hinting)(int)GLOBAL_DEF_RST("gui/theme/default_font_hinting", TextServer::HINTING_LIGHT);
+ ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_hinting", PropertyInfo(Variant::INT, "gui/theme/default_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
+
+ TextServer::SubpixelPositioning font_subpixel_positioning = (TextServer::SubpixelPositioning)(int)GLOBAL_DEF_RST("gui/theme/default_font_subpixel_positioning", TextServer::SUBPIXEL_POSITIONING_AUTO);
+ ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_subpixel_positioning", PropertyInfo(Variant::INT, "gui/theme/default_font_subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
+
+ const bool font_msdf = GLOBAL_DEF_RST("gui/theme/default_font_multichannel_signed_distance_field", false);
+ const bool font_generate_mipmaps = GLOBAL_DEF_RST("gui/theme/default_font_generate_mipmaps", false);
+
+ GLOBAL_DEF_RST("gui/theme/lcd_subpixel_layout", 1);
+ ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/lcd_subpixel_layout", PropertyInfo(Variant::INT, "gui/theme/lcd_subpixel_layout", PROPERTY_HINT_ENUM, "Disabled,Horizontal RGB,Horizontal BGR,Vertical RGB,Vertical BGR"));
+ ProjectSettings::get_singleton()->set_restart_if_changed("gui/theme/lcd_subpixel_layout", false);
+
+ Ref<Font> font;
+ if (!font_path.is_empty()) {
+ font = ResourceLoader::load(font_path);
+ if (!font.is_valid()) {
+ ERR_PRINT("Error loading custom font '" + font_path + "'");
+ }
+ }
+
+ // Always make the default theme to avoid invalid default font/icon/style in the given theme.
+ if (RenderingServer::get_singleton()) {
+ make_default_theme(default_theme_scale, font, font_subpixel_positioning, font_hinting, font_antialiasing, font_msdf, font_generate_mipmaps);
+ }
+
+ if (!theme_path.is_empty()) {
+ Ref<Theme> theme = ResourceLoader::load(theme_path);
+ if (theme.is_valid()) {
+ set_project_theme(theme);
+ if (font.is_valid()) {
+ set_fallback_font(font);
+ }
+ } else {
+ ERR_PRINT("Error loading custom theme '" + theme_path + "'");
+ }
+ }
+}
+
+void ThemeDB::initialize_theme_noproject() {
+ if (RenderingServer::get_singleton()) {
+ make_default_theme(1.0, Ref<Font>());
+ }
+}
+
+// Universal fallback Theme resources.
+
+void ThemeDB::set_default_theme(const Ref<Theme> &p_default) {
+ default_theme = p_default;
+}
+
+Ref<Theme> ThemeDB::get_default_theme() {
+ return default_theme;
+}
+
+void ThemeDB::set_project_theme(const Ref<Theme> &p_project_default) {
+ project_theme = p_project_default;
+}
+
+Ref<Theme> ThemeDB::get_project_theme() {
+ return project_theme;
+}
+
+// Universal fallback values for theme item types.
+
+void ThemeDB::set_fallback_base_scale(float p_base_scale) {
+ if (fallback_base_scale == p_base_scale) {
+ return;
+ }
+
+ fallback_base_scale = p_base_scale;
+ emit_signal(SNAME("fallback_changed"));
+}
+
+float ThemeDB::get_fallback_base_scale() {
+ return fallback_base_scale;
+}
+
+void ThemeDB::set_fallback_font(const Ref<Font> &p_font) {
+ if (fallback_font == p_font) {
+ return;
+ }
+
+ fallback_font = p_font;
+ emit_signal(SNAME("fallback_changed"));
+}
+
+Ref<Font> ThemeDB::get_fallback_font() {
+ return fallback_font;
+}
+
+void ThemeDB::set_fallback_font_size(int p_font_size) {
+ if (fallback_font_size == p_font_size) {
+ return;
+ }
+
+ fallback_font_size = p_font_size;
+ emit_signal(SNAME("fallback_changed"));
+}
+
+int ThemeDB::get_fallback_font_size() {
+ return fallback_font_size;
+}
+
+void ThemeDB::set_fallback_icon(const Ref<Texture2D> &p_icon) {
+ if (fallback_icon == p_icon) {
+ return;
+ }
+
+ fallback_icon = p_icon;
+ emit_signal(SNAME("fallback_changed"));
+}
+
+Ref<Texture2D> ThemeDB::get_fallback_icon() {
+ return fallback_icon;
+}
+
+void ThemeDB::set_fallback_stylebox(const Ref<StyleBox> &p_stylebox) {
+ if (fallback_stylebox == p_stylebox) {
+ return;
+ }
+
+ fallback_stylebox = p_stylebox;
+ emit_signal(SNAME("fallback_changed"));
+}
+
+Ref<StyleBox> ThemeDB::get_fallback_stylebox() {
+ return fallback_stylebox;
+}
+
+// Object methods.
+void ThemeDB::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_default_theme"), &ThemeDB::get_default_theme);
+ ClassDB::bind_method(D_METHOD("get_project_theme"), &ThemeDB::get_project_theme);
+
+ ClassDB::bind_method(D_METHOD("set_fallback_base_scale", "base_scale"), &ThemeDB::set_fallback_base_scale);
+ ClassDB::bind_method(D_METHOD("get_fallback_base_scale"), &ThemeDB::get_fallback_base_scale);
+ ClassDB::bind_method(D_METHOD("set_fallback_font", "font"), &ThemeDB::set_fallback_font);
+ ClassDB::bind_method(D_METHOD("get_fallback_font"), &ThemeDB::get_fallback_font);
+ ClassDB::bind_method(D_METHOD("set_fallback_font_size", "font_size"), &ThemeDB::set_fallback_font_size);
+ ClassDB::bind_method(D_METHOD("get_fallback_font_size"), &ThemeDB::get_fallback_font_size);
+ ClassDB::bind_method(D_METHOD("set_fallback_icon", "icon"), &ThemeDB::set_fallback_icon);
+ ClassDB::bind_method(D_METHOD("get_fallback_icon"), &ThemeDB::get_fallback_icon);
+ ClassDB::bind_method(D_METHOD("set_fallback_stylebox", "stylebox"), &ThemeDB::set_fallback_stylebox);
+ ClassDB::bind_method(D_METHOD("get_fallback_stylebox"), &ThemeDB::get_fallback_stylebox);
+
+ ADD_GROUP("Fallback values", "fallback_");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fallback_base_scale", PROPERTY_HINT_RANGE, "0.0,2.0,0.01,or_greater"), "set_fallback_base_scale", "get_fallback_base_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_font", PROPERTY_HINT_RESOURCE_TYPE, "Font", PROPERTY_USAGE_NONE), "set_fallback_font", "get_fallback_font");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "fallback_font_size", PROPERTY_HINT_RANGE, "0,256,1,or_greater,suffix:px"), "set_fallback_font_size", "get_fallback_font_size");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_NONE), "set_fallback_icon", "get_fallback_icon");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_stylebox", PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", PROPERTY_USAGE_NONE), "set_fallback_stylebox", "get_fallback_stylebox");
+
+ ADD_SIGNAL(MethodInfo("fallback_changed"));
+}
+
+// Memory management, reference, and initialization
+ThemeDB *ThemeDB::singleton = nullptr;
+
+ThemeDB *ThemeDB::get_singleton() {
+ return singleton;
+}
+
+ThemeDB::ThemeDB() {
+ singleton = this;
+
+ // Universal default values, final fallback for every theme.
+ fallback_base_scale = 1.0;
+ fallback_font_size = 16;
+}
+
+ThemeDB::~ThemeDB() {
+ default_theme.unref();
+ project_theme.unref();
+
+ fallback_font.unref();
+ fallback_icon.unref();
+ fallback_stylebox.unref();
+
+ singleton = nullptr;
+}
diff --git a/scene/theme/theme_db.h b/scene/theme/theme_db.h
new file mode 100644
index 0000000000..aace33d82c
--- /dev/null
+++ b/scene/theme/theme_db.h
@@ -0,0 +1,95 @@
+/*************************************************************************/
+/* theme_db.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef THEME_DB_H
+#define THEME_DB_H
+
+#include "core/object/class_db.h"
+#include "core/object/ref_counted.h"
+
+class Font;
+class StyleBox;
+class Texture2D;
+class Theme;
+
+class ThemeDB : public Object {
+ GDCLASS(ThemeDB, Object);
+
+ static ThemeDB *singleton;
+
+ // Universal Theme resources used when no other theme has the item.
+ Ref<Theme> default_theme;
+ Ref<Theme> project_theme;
+
+ // Universal default values, final fallback for every theme.
+ float fallback_base_scale;
+ Ref<Font> fallback_font;
+ int fallback_font_size;
+ Ref<Texture2D> fallback_icon;
+ Ref<StyleBox> fallback_stylebox;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void initialize_theme();
+ void initialize_theme_noproject();
+
+ // Universal Theme resources
+
+ void set_default_theme(const Ref<Theme> &p_default);
+ Ref<Theme> get_default_theme();
+
+ void set_project_theme(const Ref<Theme> &p_project_default);
+ Ref<Theme> get_project_theme();
+
+ // Universal default values.
+
+ void set_fallback_base_scale(float p_base_scale);
+ float get_fallback_base_scale();
+
+ void set_fallback_font(const Ref<Font> &p_font);
+ Ref<Font> get_fallback_font();
+
+ void set_fallback_font_size(int p_font_size);
+ int get_fallback_font_size();
+
+ void set_fallback_icon(const Ref<Texture2D> &p_icon);
+ Ref<Texture2D> get_fallback_icon();
+
+ void set_fallback_stylebox(const Ref<StyleBox> &p_stylebox);
+ Ref<StyleBox> get_fallback_stylebox();
+
+ static ThemeDB *get_singleton();
+ ThemeDB();
+ ~ThemeDB();
+};
+
+#endif // THEME_DB_H