Introduce the concept of global theme contexts
This commit adds the default theme context, which replaces the need to manually check the project and the default theme all the time; simplifies related code. It also adds framework for custom theme contexts, to be used by the editor. Custom contexts can be attached to any node, and not necessarily a GUI/Window node. Contexts do no break theme inheritance and only define which global themes a node uses as a fallback. Contexts propagate NOTIFICATION_THEME_CHANGED when one of their global themes changes. This ensures that global themes act just like themes assigned to individual nodes and can be previewed live in the editor.
This commit is contained in:
@@ -2779,48 +2779,25 @@ Ref<Font> FontVariation::_get_base_font_or_default() const {
|
||||
return base_font;
|
||||
}
|
||||
|
||||
// Check the project-defined Theme resource.
|
||||
if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
|
||||
List<StringName> theme_types;
|
||||
ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
|
||||
StringName theme_name = "font";
|
||||
List<StringName> theme_types;
|
||||
ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), &theme_types);
|
||||
|
||||
for (const StringName &E : theme_types) {
|
||||
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 == this) {
|
||||
continue;
|
||||
}
|
||||
if (f.is_valid()) {
|
||||
theme_font = f;
|
||||
theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lastly, fall back on the items defined in the default Theme, if they exist.
|
||||
if (ThemeDB::get_singleton()->get_default_theme().is_valid()) {
|
||||
List<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 (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 == this) {
|
||||
continue;
|
||||
}
|
||||
if (f.is_valid()) {
|
||||
theme_font = f;
|
||||
theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
ThemeContext *global_context = ThemeDB::get_singleton()->get_default_theme_context();
|
||||
for (const Ref<Theme> &theme : global_context->get_themes()) {
|
||||
if (theme.is_null()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If they don't exist, use any type to return the default/empty value.
|
||||
Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
|
||||
if (f != this) {
|
||||
for (const StringName &E : theme_types) {
|
||||
if (!theme->has_font(theme_name, E)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Ref<Font> f = theme->get_font(theme_name, E);
|
||||
if (f == this) {
|
||||
continue;
|
||||
}
|
||||
if (f.is_valid()) {
|
||||
theme_font = f;
|
||||
theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
|
||||
@@ -2829,6 +2806,15 @@ Ref<Font> FontVariation::_get_base_font_or_default() const {
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Font> f = global_context->get_fallback_theme()->get_font(theme_name, StringName());
|
||||
if (f != this) {
|
||||
if (f.is_valid()) {
|
||||
theme_font = f;
|
||||
theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
return Ref<Font>();
|
||||
}
|
||||
|
||||
@@ -3131,48 +3117,25 @@ Ref<Font> SystemFont::_get_base_font_or_default() const {
|
||||
return base_font;
|
||||
}
|
||||
|
||||
// Check the project-defined Theme resource.
|
||||
if (ThemeDB::get_singleton()->get_project_theme().is_valid()) {
|
||||
List<StringName> theme_types;
|
||||
ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types);
|
||||
StringName theme_name = "font";
|
||||
List<StringName> theme_types;
|
||||
ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), &theme_types);
|
||||
|
||||
for (const StringName &E : theme_types) {
|
||||
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 == this) {
|
||||
continue;
|
||||
}
|
||||
if (f.is_valid()) {
|
||||
theme_font = f;
|
||||
theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lastly, fall back on the items defined in the default Theme, if they exist.
|
||||
if (ThemeDB::get_singleton()->get_default_theme().is_valid()) {
|
||||
List<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 (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 == this) {
|
||||
continue;
|
||||
}
|
||||
if (f.is_valid()) {
|
||||
theme_font = f;
|
||||
theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
ThemeContext *global_context = ThemeDB::get_singleton()->get_default_theme_context();
|
||||
for (const Ref<Theme> &theme : global_context->get_themes()) {
|
||||
if (theme.is_null()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If they don't exist, use any type to return the default/empty value.
|
||||
Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
|
||||
if (f != this) {
|
||||
for (const StringName &E : theme_types) {
|
||||
if (!theme->has_font(theme_name, E)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Ref<Font> f = theme->get_font(theme_name, E);
|
||||
if (f == this) {
|
||||
continue;
|
||||
}
|
||||
if (f.is_valid()) {
|
||||
theme_font = f;
|
||||
theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
|
||||
@@ -3181,6 +3144,15 @@ Ref<Font> SystemFont::_get_base_font_or_default() const {
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Font> f = global_context->get_fallback_theme()->get_font(theme_name, StringName());
|
||||
if (f != this) {
|
||||
if (f.is_valid()) {
|
||||
theme_font = f;
|
||||
theme_font->connect_changed(callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
return Ref<Font>();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user