Skip to content

Commit

Permalink
Merge pull request #84760 from KoBeWi/ultimate_get_property_list_relo…
Browse files Browse the repository at this point in the history
…aded

Fetch override list from ThemeDB
  • Loading branch information
akien-mga committed Jan 29, 2024
2 parents 64ddf1f + 7d6ded2 commit 6c2f412
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 75 deletions.
2 changes: 1 addition & 1 deletion editor/doc_tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
// Theme items.
{
List<ThemeDB::ThemeItemBind> theme_items;
ThemeDB::get_singleton()->get_class_own_items(cname, &theme_items);
ThemeDB::get_singleton()->get_class_items(cname, &theme_items);
Ref<Theme> default_theme = ThemeDB::get_singleton()->get_default_theme();

for (const ThemeDB::ThemeItemBind &theme_item : theme_items) {
Expand Down
110 changes: 45 additions & 65 deletions scene/gui/control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,80 +370,60 @@ bool Control::_get(const StringName &p_name, Variant &r_ret) const {

void Control::_get_property_list(List<PropertyInfo> *p_list) const {
ERR_MAIN_THREAD_GUARD;
Ref<Theme> default_theme = ThemeDB::get_singleton()->get_default_theme();
List<ThemeDB::ThemeItemBind> 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<StringName> 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<StringName> 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<StringName> 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<StringName> 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<StringName> 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<StringName> 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;

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;

p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_styles") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage));
default: {
// Silences warning.
} break;
}
}
}
Expand Down
30 changes: 22 additions & 8 deletions scene/theme/theme_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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<ThemeItemBind> *r_list) {
void ThemeDB::get_class_items(const StringName &p_class_name, List<ThemeItemBind> *r_list, bool p_include_inherited) {
List<StringName> class_hierarchy;
StringName class_name = p_class_name;
while (class_name != StringName()) {
Expand All @@ -381,23 +383,32 @@ void ThemeDB::get_class_own_items(const StringName &p_class_name, List<ThemeItem

HashSet<StringName> inherited_props;
for (const StringName &theme_type : class_hierarchy) {
HashMap<StringName, HashMap<StringName, ThemeItemBind>>::Iterator E = theme_item_binds.find(theme_type);
HashMap<StringName, List<ThemeItemBind>>::Iterator E = theme_item_binds_list.find(theme_type);
if (E) {
for (const KeyValue<StringName, ThemeItemBind> &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<StringName, List<ThemeDB::ThemeItemBind>> &E : theme_item_binds_list) {
E.value.sort_custom<ThemeItemBind::SortByType>();
}
}

// Object methods.

void ThemeDB::_bind_methods() {
Expand Down Expand Up @@ -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() {
Expand Down
11 changes: 10 additions & 1 deletion scene/theme/theme_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,19 @@ class ThemeDB : public Object {
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<StringName, HashMap<StringName, ThemeItemBind>> theme_item_binds;
HashMap<StringName, List<ThemeItemBind>> theme_item_binds_list; // Used for listing purposes.

void _sort_theme_items();

protected:
static void _bind_methods();
Expand Down Expand Up @@ -162,7 +171,7 @@ class ThemeDB : public Object {
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<ThemeItemBind> *r_list);
void get_class_items(const StringName &p_class_name, List<ThemeItemBind> *r_list, bool p_include_inherited = false);

// Memory management, reference, and initialization.

Expand Down

0 comments on commit 6c2f412

Please sign in to comment.