From 7d6ded2027d0c81fa0e0419d8afc57699fe1e468 Mon Sep 17 00:00:00 2001 From: kobewi Date: Sat, 11 Nov 2023 18:29:42 +0100 Subject: [PATCH] Fetch override list from ThemeDB --- editor/doc_tools.cpp | 2 +- scene/gui/control.cpp | 110 ++++++++++++++++----------------------- scene/theme/theme_db.cpp | 30 ++++++++--- scene/theme/theme_db.h | 11 +++- 4 files changed, 78 insertions(+), 75 deletions(-) diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index 9c1fc2a8bf5f..8af586008eca 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -632,7 +632,7 @@ void DocTools::generate(BitField p_flags) { // Theme items. { List theme_items; - ThemeDB::get_singleton()->get_class_own_items(cname, &theme_items); + ThemeDB::get_singleton()->get_class_items(cname, &theme_items); Ref default_theme = ThemeDB::get_singleton()->get_default_theme(); for (const ThemeDB::ThemeItemBind &theme_item : theme_items) { diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 349102fafbee..b85cbcf6ffab 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -370,80 +370,60 @@ bool Control::_get(const StringName &p_name, Variant &r_ret) const { void Control::_get_property_list(List *p_list) const { ERR_MAIN_THREAD_GUARD; - Ref default_theme = ThemeDB::get_singleton()->get_default_theme(); + List theme_items; + ThemeDB::get_singleton()->get_class_items(get_class_name(), &theme_items, true); p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Theme Overrides", "theme_override_"), PROPERTY_HINT_NONE, "theme_override_", PROPERTY_USAGE_GROUP)); - { - List names; - default_theme->get_color_list(get_class_name(), &names); - for (const StringName &E : names) { - uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.theme_color_override.has(E)) { - usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; - } + for (const ThemeDB::ThemeItemBind &E : theme_items) { + uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - p_list->push_back(PropertyInfo(Variant::COLOR, PNAME("theme_override_colors") + String("/") + E, PROPERTY_HINT_NONE, "", usage)); - } - } - { - List names; - default_theme->get_constant_list(get_class_name(), &names); - for (const StringName &E : names) { - uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.theme_constant_override.has(E)) { - usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; - } + switch (E.data_type) { + case Theme::DATA_TYPE_COLOR: { + if (data.theme_color_override.has(E.item_name)) { + usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; + } + p_list->push_back(PropertyInfo(Variant::COLOR, PNAME("theme_override_colors") + String("/") + E.item_name, PROPERTY_HINT_NONE, "", usage)); + } break; - p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_constants") + String("/") + E, PROPERTY_HINT_RANGE, "-16384,16384", usage)); - } - } - { - List names; - default_theme->get_font_list(get_class_name(), &names); - for (const StringName &E : names) { - uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.theme_font_override.has(E)) { - usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; - } + case Theme::DATA_TYPE_CONSTANT: { + if (data.theme_constant_override.has(E.item_name)) { + usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; + } + p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_constants") + String("/") + E.item_name, PROPERTY_HINT_RANGE, "-16384,16384", usage)); + } break; - p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_fonts") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "Font", usage)); - } - } - { - List names; - default_theme->get_font_size_list(get_class_name(), &names); - for (const StringName &E : names) { - uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.theme_font_size_override.has(E)) { - usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; - } + case Theme::DATA_TYPE_FONT: { + if (data.theme_font_override.has(E.item_name)) { + usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; + } + p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_fonts") + String("/") + E.item_name, PROPERTY_HINT_RESOURCE_TYPE, "Font", usage)); + } break; - p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_font_sizes") + String("/") + E, PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px", usage)); - } - } - { - List names; - default_theme->get_icon_list(get_class_name(), &names); - for (const StringName &E : names) { - uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.theme_icon_override.has(E)) { - usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; - } + case Theme::DATA_TYPE_FONT_SIZE: { + if (data.theme_font_size_override.has(E.item_name)) { + usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; + } + p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_font_sizes") + String("/") + E.item_name, PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px", usage)); + } break; - p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_icons") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage)); - } - } - { - List names; - default_theme->get_stylebox_list(get_class_name(), &names); - for (const StringName &E : names) { - uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.theme_style_override.has(E)) { - usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; - } + case Theme::DATA_TYPE_ICON: { + if (data.theme_icon_override.has(E.item_name)) { + usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; + } + p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_icons") + String("/") + E.item_name, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage)); + } break; - p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_styles") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage)); + case Theme::DATA_TYPE_STYLEBOX: { + if (data.theme_style_override.has(E.item_name)) { + usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; + } + p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_styles") + String("/") + E.item_name, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage)); + } break; + + default: { + // Silences warning. + } break; } } } diff --git a/scene/theme/theme_db.cpp b/scene/theme/theme_db.cpp index 8dc9d288e2c6..eaa9ce8f058b 100644 --- a/scene/theme/theme_db.cpp +++ b/scene/theme/theme_db.cpp @@ -337,6 +337,7 @@ void ThemeDB::bind_class_item(Theme::DataType p_data_type, const StringName &p_c bind.setter = p_setter; theme_item_binds[p_class_name][p_prop_name] = bind; + theme_item_binds_list[p_class_name].push_back(bind); } void ThemeDB::bind_class_external_item(Theme::DataType p_data_type, const StringName &p_class_name, const StringName &p_prop_name, const StringName &p_item_name, const StringName &p_type_name, ThemeItemSetter p_setter) { @@ -351,6 +352,7 @@ void ThemeDB::bind_class_external_item(Theme::DataType p_data_type, const String bind.setter = p_setter; theme_item_binds[p_class_name][p_prop_name] = bind; + theme_item_binds_list[p_class_name].push_back(bind); } void ThemeDB::update_class_instance_items(Node *p_instance) { @@ -371,7 +373,7 @@ void ThemeDB::update_class_instance_items(Node *p_instance) { } } -void ThemeDB::get_class_own_items(const StringName &p_class_name, List *r_list) { +void ThemeDB::get_class_items(const StringName &p_class_name, List *r_list, bool p_include_inherited) { List class_hierarchy; StringName class_name = p_class_name; while (class_name != StringName()) { @@ -381,23 +383,32 @@ void ThemeDB::get_class_own_items(const StringName &p_class_name, List inherited_props; for (const StringName &theme_type : class_hierarchy) { - HashMap>::Iterator E = theme_item_binds.find(theme_type); + HashMap>::Iterator E = theme_item_binds_list.find(theme_type); if (E) { - for (const KeyValue &F : E->value) { - if (inherited_props.has(F.value.item_name)) { + for (const ThemeItemBind &F : E->value) { + if (inherited_props.has(F.item_name)) { continue; // Skip inherited properties. } - if (F.value.external || F.value.class_name != p_class_name) { - inherited_props.insert(F.value.item_name); - continue; // Track properties defined in parent classes, and skip them. + if (F.external || F.class_name != p_class_name) { + inherited_props.insert(F.item_name); + + if (!p_include_inherited) { + continue; // Track properties defined in parent classes, and skip them. + } } - r_list->push_back(F.value); + r_list->push_back(F); } } } } +void ThemeDB::_sort_theme_items() { + for (KeyValue> &E : theme_item_binds_list) { + E.value.sort_custom(); + } +} + // Object methods. void ThemeDB::_bind_methods() { @@ -435,6 +446,9 @@ ThemeDB *ThemeDB::get_singleton() { ThemeDB::ThemeDB() { singleton = this; + if (MessageQueue::get_singleton()) { // May not exist in tests etc. + callable_mp(this, &ThemeDB::_sort_theme_items).call_deferred(); + } } ThemeDB::~ThemeDB() { diff --git a/scene/theme/theme_db.h b/scene/theme/theme_db.h index e472f4e93569..d9428ad213eb 100644 --- a/scene/theme/theme_db.h +++ b/scene/theme/theme_db.h @@ -107,10 +107,19 @@ public: bool external = false; ThemeItemSetter setter; + + struct SortByType { + _FORCE_INLINE_ bool operator()(const ThemeItemBind &l, const ThemeItemBind &r) const { + return l.data_type < r.data_type; + } + }; }; private: HashMap> theme_item_binds; + HashMap> theme_item_binds_list; // Used for listing purposes. + + void _sort_theme_items(); protected: static void _bind_methods(); @@ -162,7 +171,7 @@ public: void bind_class_external_item(Theme::DataType p_data_type, const StringName &p_class_name, const StringName &p_prop_name, const StringName &p_item_name, const StringName &p_type_name, ThemeItemSetter p_setter); void update_class_instance_items(Node *p_instance); - void get_class_own_items(const StringName &p_class_name, List *r_list); + void get_class_items(const StringName &p_class_name, List *r_list, bool p_include_inherited = false); // Memory management, reference, and initialization.