diff options
Diffstat (limited to 'scene/resources/theme.cpp')
-rw-r--r-- | scene/resources/theme.cpp | 347 |
1 files changed, 153 insertions, 194 deletions
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 373fbb94ea..10806aef45 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -123,76 +123,50 @@ bool Theme::_get(const StringName &p_name, Variant &r_ret) const { void Theme::_get_property_list(List<PropertyInfo> *p_list) const { List<PropertyInfo> list; - const StringName *key = nullptr; - // Type variations. - while ((key = variation_map.next(key))) { - list.push_back(PropertyInfo(Variant::STRING_NAME, String() + *key + "/base_type")); + for (const KeyValue<StringName, StringName> &E : variation_map) { + list.push_back(PropertyInfo(Variant::STRING_NAME, String() + E.key + "/base_type")); } - key = nullptr; - // Icons. - while ((key = icon_map.next(key))) { - const StringName *key2 = nullptr; - - while ((key2 = icon_map[*key].next(key2))) { - list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/icons/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL)); + for (const KeyValue<StringName, HashMap<StringName, Ref<Texture2D>>> &E : icon_map) { + for (const KeyValue<StringName, Ref<Texture2D>> &F : E.value) { + list.push_back(PropertyInfo(Variant::OBJECT, String() + E.key + "/icons/" + F.key, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL)); } } - key = nullptr; - // Styles. - while ((key = style_map.next(key))) { - const StringName *key2 = nullptr; - - while ((key2 = style_map[*key].next(key2))) { - list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/styles/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL)); + for (const KeyValue<StringName, HashMap<StringName, Ref<StyleBox>>> &E : style_map) { + for (const KeyValue<StringName, Ref<StyleBox>> &F : E.value) { + list.push_back(PropertyInfo(Variant::OBJECT, String() + E.key + "/styles/" + F.key, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL)); } } - key = nullptr; - // Fonts. - while ((key = font_map.next(key))) { - const StringName *key2 = nullptr; - - while ((key2 = font_map[*key].next(key2))) { - list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/fonts/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "Font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL)); + for (const KeyValue<StringName, HashMap<StringName, Ref<Font>>> &E : font_map) { + for (const KeyValue<StringName, Ref<Font>> &F : E.value) { + list.push_back(PropertyInfo(Variant::OBJECT, String() + E.key + "/fonts/" + F.key, PROPERTY_HINT_RESOURCE_TYPE, "Font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL)); } } - key = nullptr; - // Font sizes. - while ((key = font_size_map.next(key))) { - const StringName *key2 = nullptr; - - while ((key2 = font_size_map[*key].next(key2))) { - list.push_back(PropertyInfo(Variant::INT, String() + *key + "/font_sizes/" + *key2, PROPERTY_HINT_RANGE, "0,256,1,or_greater")); + for (const KeyValue<StringName, HashMap<StringName, int>> &E : font_size_map) { + for (const KeyValue<StringName, int> &F : E.value) { + list.push_back(PropertyInfo(Variant::INT, String() + E.key + "/font_sizes/" + F.key, PROPERTY_HINT_RANGE, "0,256,1,or_greater")); } } - key = nullptr; - // Colors. - while ((key = color_map.next(key))) { - const StringName *key2 = nullptr; - - while ((key2 = color_map[*key].next(key2))) { - list.push_back(PropertyInfo(Variant::COLOR, String() + *key + "/colors/" + *key2)); + for (const KeyValue<StringName, HashMap<StringName, Color>> &E : color_map) { + for (const KeyValue<StringName, Color> &F : E.value) { + list.push_back(PropertyInfo(Variant::INT, String() + E.key + "/colors/" + F.key)); } } - key = nullptr; - // Constants. - while ((key = constant_map.next(key))) { - const StringName *key2 = nullptr; - - while ((key2 = constant_map[*key].next(key2))) { - list.push_back(PropertyInfo(Variant::INT, String() + *key + "/constants/" + *key2)); + for (const KeyValue<StringName, HashMap<StringName, int>> &E : constant_map) { + for (const KeyValue<StringName, int> &F : E.value) { + list.push_back(PropertyInfo(Variant::INT, String() + E.key + "/constants/" + F.key)); } } @@ -261,6 +235,27 @@ int Theme::get_fallback_font_size() { return fallback_font_size; } +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])) { + return false; + } + } + return true; +} + +bool Theme::is_valid_item_name(const String &p_name) { + if (p_name.is_empty()) { + return false; + } + for (int i = 0; i < p_name.length(); i++) { + if (!is_ascii_identifier_char(p_name[i])) { + return false; + } + } + return true; +} + // Fallback values for theme item types, configurable per theme. void Theme::set_default_base_scale(float p_base_scale) { if (default_base_scale == p_base_scale) { @@ -326,6 +321,9 @@ bool Theme::has_default_font_size() const { // Icons. void Theme::set_icon(const StringName &p_name, const StringName &p_theme_type, const Ref<Texture2D> &p_icon) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + bool existing = false; if (icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()) { existing = true; @@ -358,6 +356,8 @@ bool Theme::has_icon_nocheck(const StringName &p_name, const StringName &p_theme } void Theme::rename_icon(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); ERR_FAIL_COND_MSG(!icon_map.has(p_theme_type), "Cannot rename the icon '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); ERR_FAIL_COND_MSG(icon_map[p_theme_type].has(p_name), "Cannot rename the icon '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); ERR_FAIL_COND_MSG(!icon_map[p_theme_type].has(p_old_name), "Cannot rename the icon '" + String(p_old_name) + "' because it does not exist."); @@ -388,14 +388,14 @@ void Theme::get_icon_list(StringName p_theme_type, List<StringName> *p_list) con return; } - const StringName *key = nullptr; - - while ((key = icon_map[p_theme_type].next(key))) { - p_list->push_back(*key); + for (const KeyValue<StringName, Ref<Texture2D>> &E : icon_map[p_theme_type]) { + p_list->push_back(E.key); } } void Theme::add_icon_type(const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + if (icon_map.has(p_theme_type)) { return; } @@ -409,9 +409,8 @@ void Theme::remove_icon_type(const StringName &p_theme_type) { _freeze_change_propagation(); - const StringName *L = nullptr; - while ((L = icon_map[p_theme_type].next(L))) { - Ref<Texture2D> icon = icon_map[p_theme_type][*L]; + for (const KeyValue<StringName, Ref<Texture2D>> &E : icon_map[p_theme_type]) { + Ref<Texture2D> icon = E.value; if (icon.is_valid()) { icon->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } @@ -425,14 +424,16 @@ void Theme::remove_icon_type(const StringName &p_theme_type) { void Theme::get_icon_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - const StringName *key = nullptr; - while ((key = icon_map.next(key))) { - p_list->push_back(*key); + for (const KeyValue<StringName, HashMap<StringName, Ref<Texture2D>>> &E : icon_map) { + p_list->push_back(E.key); } } // Styleboxes. void Theme::set_stylebox(const StringName &p_name, const StringName &p_theme_type, const Ref<StyleBox> &p_style) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + bool existing = false; if (style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()) { existing = true; @@ -465,6 +466,8 @@ bool Theme::has_stylebox_nocheck(const StringName &p_name, const StringName &p_t } void Theme::rename_stylebox(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); ERR_FAIL_COND_MSG(!style_map.has(p_theme_type), "Cannot rename the stylebox '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); ERR_FAIL_COND_MSG(style_map[p_theme_type].has(p_name), "Cannot rename the stylebox '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); ERR_FAIL_COND_MSG(!style_map[p_theme_type].has(p_old_name), "Cannot rename the stylebox '" + String(p_old_name) + "' because it does not exist."); @@ -495,14 +498,14 @@ void Theme::get_stylebox_list(StringName p_theme_type, List<StringName> *p_list) return; } - const StringName *key = nullptr; - - while ((key = style_map[p_theme_type].next(key))) { - p_list->push_back(*key); + for (const KeyValue<StringName, Ref<StyleBox>> &E : style_map[p_theme_type]) { + p_list->push_back(E.key); } } void Theme::add_stylebox_type(const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + if (style_map.has(p_theme_type)) { return; } @@ -516,9 +519,8 @@ void Theme::remove_stylebox_type(const StringName &p_theme_type) { _freeze_change_propagation(); - const StringName *L = nullptr; - while ((L = style_map[p_theme_type].next(L))) { - Ref<StyleBox> style = style_map[p_theme_type][*L]; + for (const KeyValue<StringName, Ref<StyleBox>> &E : style_map[p_theme_type]) { + Ref<StyleBox> style = E.value; if (style.is_valid()) { style->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } @@ -532,14 +534,16 @@ void Theme::remove_stylebox_type(const StringName &p_theme_type) { void Theme::get_stylebox_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - const StringName *key = nullptr; - while ((key = style_map.next(key))) { - p_list->push_back(*key); + for (const KeyValue<StringName, HashMap<StringName, Ref<StyleBox>>> &E : style_map) { + p_list->push_back(E.key); } } // Fonts. void Theme::set_font(const StringName &p_name, const StringName &p_theme_type, const Ref<Font> &p_font) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + bool existing = false; if (font_map[p_theme_type][p_name].is_valid()) { existing = true; @@ -574,6 +578,8 @@ bool Theme::has_font_nocheck(const StringName &p_name, const StringName &p_theme } void Theme::rename_font(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); ERR_FAIL_COND_MSG(!font_map.has(p_theme_type), "Cannot rename the font '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); ERR_FAIL_COND_MSG(font_map[p_theme_type].has(p_name), "Cannot rename the font '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); ERR_FAIL_COND_MSG(!font_map[p_theme_type].has(p_old_name), "Cannot rename the font '" + String(p_old_name) + "' because it does not exist."); @@ -604,14 +610,14 @@ void Theme::get_font_list(StringName p_theme_type, List<StringName> *p_list) con return; } - const StringName *key = nullptr; - - while ((key = font_map[p_theme_type].next(key))) { - p_list->push_back(*key); + for (const KeyValue<StringName, Ref<Font>> &E : font_map[p_theme_type]) { + p_list->push_back(E.key); } } void Theme::add_font_type(const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + if (font_map.has(p_theme_type)) { return; } @@ -625,9 +631,8 @@ void Theme::remove_font_type(const StringName &p_theme_type) { _freeze_change_propagation(); - const StringName *L = nullptr; - while ((L = font_map[p_theme_type].next(L))) { - Ref<Font> font = font_map[p_theme_type][*L]; + for (const KeyValue<StringName, Ref<Font>> &E : font_map[p_theme_type]) { + Ref<Font> font = E.value; if (font.is_valid()) { font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } @@ -641,14 +646,16 @@ void Theme::remove_font_type(const StringName &p_theme_type) { void Theme::get_font_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - const StringName *key = nullptr; - while ((key = font_map.next(key))) { - p_list->push_back(*key); + for (const KeyValue<StringName, HashMap<StringName, Ref<Font>>> &E : font_map) { + p_list->push_back(E.key); } } // Font sizes. void Theme::set_font_size(const StringName &p_name, const StringName &p_theme_type, int p_font_size) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + bool existing = has_font_size_nocheck(p_name, p_theme_type); font_size_map[p_theme_type][p_name] = p_font_size; @@ -674,6 +681,8 @@ bool Theme::has_font_size_nocheck(const StringName &p_name, const StringName &p_ } void Theme::rename_font_size(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); ERR_FAIL_COND_MSG(!font_size_map.has(p_theme_type), "Cannot rename the font size '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); ERR_FAIL_COND_MSG(font_size_map[p_theme_type].has(p_name), "Cannot rename the font size '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); ERR_FAIL_COND_MSG(!font_size_map[p_theme_type].has(p_old_name), "Cannot rename the font size '" + String(p_old_name) + "' because it does not exist."); @@ -700,14 +709,14 @@ void Theme::get_font_size_list(StringName p_theme_type, List<StringName> *p_list return; } - const StringName *key = nullptr; - - while ((key = font_size_map[p_theme_type].next(key))) { - p_list->push_back(*key); + for (const KeyValue<StringName, int> &E : font_size_map[p_theme_type]) { + p_list->push_back(E.key); } } void Theme::add_font_size_type(const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + if (font_size_map.has(p_theme_type)) { return; } @@ -725,14 +734,16 @@ void Theme::remove_font_size_type(const StringName &p_theme_type) { void Theme::get_font_size_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - const StringName *key = nullptr; - while ((key = font_size_map.next(key))) { - p_list->push_back(*key); + for (const KeyValue<StringName, HashMap<StringName, int>> &E : font_size_map) { + p_list->push_back(E.key); } } // Colors. void Theme::set_color(const StringName &p_name, const StringName &p_theme_type, const Color &p_color) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + bool existing = has_color_nocheck(p_name, p_theme_type); color_map[p_theme_type][p_name] = p_color; @@ -756,6 +767,8 @@ bool Theme::has_color_nocheck(const StringName &p_name, const StringName &p_them } void Theme::rename_color(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); ERR_FAIL_COND_MSG(!color_map.has(p_theme_type), "Cannot rename the color '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); ERR_FAIL_COND_MSG(color_map[p_theme_type].has(p_name), "Cannot rename the color '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); ERR_FAIL_COND_MSG(!color_map[p_theme_type].has(p_old_name), "Cannot rename the color '" + String(p_old_name) + "' because it does not exist."); @@ -782,14 +795,14 @@ void Theme::get_color_list(StringName p_theme_type, List<StringName> *p_list) co return; } - const StringName *key = nullptr; - - while ((key = color_map[p_theme_type].next(key))) { - p_list->push_back(*key); + for (const KeyValue<StringName, Color> &E : color_map[p_theme_type]) { + p_list->push_back(E.key); } } void Theme::add_color_type(const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + if (color_map.has(p_theme_type)) { return; } @@ -807,14 +820,16 @@ void Theme::remove_color_type(const StringName &p_theme_type) { void Theme::get_color_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - const StringName *key = nullptr; - while ((key = color_map.next(key))) { - p_list->push_back(*key); + for (const KeyValue<StringName, HashMap<StringName, Color>> &E : color_map) { + p_list->push_back(E.key); } } // Theme constants. void Theme::set_constant(const StringName &p_name, const StringName &p_theme_type, int p_constant) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + bool existing = has_constant_nocheck(p_name, p_theme_type); constant_map[p_theme_type][p_name] = p_constant; @@ -838,6 +853,8 @@ bool Theme::has_constant_nocheck(const StringName &p_name, const StringName &p_t } void Theme::rename_constant(const StringName &p_old_name, const StringName &p_name, const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_item_name(p_name), vformat("Invalid item name: '%s'", p_name)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); ERR_FAIL_COND_MSG(!constant_map.has(p_theme_type), "Cannot rename the constant '" + String(p_old_name) + "' because the node type '" + String(p_theme_type) + "' does not exist."); ERR_FAIL_COND_MSG(constant_map[p_theme_type].has(p_name), "Cannot rename the constant '" + String(p_old_name) + "' because the new name '" + String(p_name) + "' already exists."); ERR_FAIL_COND_MSG(!constant_map[p_theme_type].has(p_old_name), "Cannot rename the constant '" + String(p_old_name) + "' because it does not exist."); @@ -864,14 +881,14 @@ void Theme::get_constant_list(StringName p_theme_type, List<StringName> *p_list) return; } - const StringName *key = nullptr; - - while ((key = constant_map[p_theme_type].next(key))) { - p_list->push_back(*key); + for (const KeyValue<StringName, int> &E : constant_map[p_theme_type]) { + p_list->push_back(E.key); } } void Theme::add_constant_type(const StringName &p_theme_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + if (constant_map.has(p_theme_type)) { return; } @@ -889,9 +906,8 @@ void Theme::remove_constant_type(const StringName &p_theme_type) { void Theme::get_constant_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - const StringName *key = nullptr; - while ((key = constant_map.next(key))) { - p_list->push_back(*key); + for (const KeyValue<StringName, HashMap<StringName, int>> &E : constant_map) { + p_list->push_back(E.key); } } @@ -1154,6 +1170,8 @@ void Theme::get_theme_item_type_list(DataType p_data_type, List<StringName> *p_l // Theme type variations. void Theme::set_type_variation(const StringName &p_theme_type, const StringName &p_base_type) { + ERR_FAIL_COND_MSG(!is_valid_type_name(p_theme_type), vformat("Invalid type name: '%s'", p_theme_type)); + ERR_FAIL_COND_MSG(!is_valid_type_name(p_base_type), vformat("Invalid type name: '%s'", p_base_type)); ERR_FAIL_COND_MSG(p_theme_type == StringName(), "An empty theme type cannot be marked as a variation of another type."); ERR_FAIL_COND_MSG(ClassDB::class_exists(p_theme_type), "A type associated with a built-in class cannot be marked as a variation of another type."); ERR_FAIL_COND_MSG(p_base_type == StringName(), "An empty theme type cannot be the base type of a variation. Use clear_type_variation() instead if you want to unmark '" + String(p_theme_type) + "' as a variation."); @@ -1246,52 +1264,12 @@ void Theme::remove_type(const StringName &p_theme_type) { void Theme::get_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - Set<StringName> types; - const StringName *key = nullptr; - - // Icons. - while ((key = icon_map.next(key))) { - types.insert(*key); - } - - key = nullptr; - - // StyleBoxes. - while ((key = style_map.next(key))) { - types.insert(*key); - } - - key = nullptr; - - // Fonts. - while ((key = font_map.next(key))) { - types.insert(*key); - } - - key = nullptr; - - // Font sizes. - while ((key = font_size_map.next(key))) { - types.insert(*key); - } - - key = nullptr; - - // Colors. - while ((key = color_map.next(key))) { - types.insert(*key); - } - - key = nullptr; - - // Constants. - while ((key = constant_map.next(key))) { - types.insert(*key); - } - - for (Set<StringName>::Element *E = types.front(); E; E = E->next()) { - p_list->push_back(E->get()); - } + get_icon_type_list(p_list); + get_stylebox_type_list(p_list); + get_font_type_list(p_list); + get_font_size_type_list(p_list); + get_color_type_list(p_list); + get_constant_type_list(p_list); } void Theme::get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variation, List<StringName> *p_list) { @@ -1602,75 +1580,62 @@ void Theme::merge_with(const Ref<Theme> &p_other) { // Colors. { - const StringName *K = nullptr; - while ((K = p_other->color_map.next(K))) { - const StringName *L = nullptr; - while ((L = p_other->color_map[*K].next(L))) { - set_color(*L, *K, p_other->color_map[*K][*L]); + for (const KeyValue<StringName, HashMap<StringName, Color>> &E : p_other->color_map) { + for (const KeyValue<StringName, Color> &F : E.value) { + set_color(F.key, E.key, F.value); } } } // Constants. { - const StringName *K = nullptr; - while ((K = p_other->constant_map.next(K))) { - const StringName *L = nullptr; - while ((L = p_other->constant_map[*K].next(L))) { - set_constant(*L, *K, p_other->constant_map[*K][*L]); + for (const KeyValue<StringName, HashMap<StringName, int>> &E : p_other->constant_map) { + for (const KeyValue<StringName, int> &F : E.value) { + set_constant(F.key, E.key, F.value); } } } // Fonts. { - const StringName *K = nullptr; - while ((K = p_other->font_map.next(K))) { - const StringName *L = nullptr; - while ((L = p_other->font_map[*K].next(L))) { - set_font(*L, *K, p_other->font_map[*K][*L]); + for (const KeyValue<StringName, HashMap<StringName, Ref<Font>>> &E : p_other->font_map) { + for (const KeyValue<StringName, Ref<Font>> &F : E.value) { + set_font(F.key, E.key, F.value); } } } // Font sizes. { - const StringName *K = nullptr; - while ((K = p_other->font_size_map.next(K))) { - const StringName *L = nullptr; - while ((L = p_other->font_size_map[*K].next(L))) { - set_font_size(*L, *K, p_other->font_size_map[*K][*L]); + for (const KeyValue<StringName, HashMap<StringName, int>> &E : p_other->font_size_map) { + for (const KeyValue<StringName, int> &F : E.value) { + set_font_size(F.key, E.key, F.value); } } } // Icons. { - const StringName *K = nullptr; - while ((K = p_other->icon_map.next(K))) { - const StringName *L = nullptr; - while ((L = p_other->icon_map[*K].next(L))) { - set_icon(*L, *K, p_other->icon_map[*K][*L]); + for (const KeyValue<StringName, HashMap<StringName, Ref<Texture2D>>> &E : p_other->icon_map) { + for (const KeyValue<StringName, Ref<Texture2D>> &F : E.value) { + set_icon(F.key, E.key, F.value); } } } // Styleboxes. { - const StringName *K = nullptr; - while ((K = p_other->style_map.next(K))) { - const StringName *L = nullptr; - while ((L = p_other->style_map[*K].next(L))) { - set_stylebox(*L, *K, p_other->style_map[*K][*L]); + for (const KeyValue<StringName, HashMap<StringName, Ref<StyleBox>>> &E : p_other->style_map) { + for (const KeyValue<StringName, Ref<StyleBox>> &F : E.value) { + set_stylebox(F.key, E.key, F.value); } } } // Type variations. { - const StringName *K = nullptr; - while ((K = p_other->variation_map.next(K))) { - set_type_variation(*K, p_other->variation_map[*K]); + for (const KeyValue<StringName, StringName> &E : p_other->variation_map) { + set_type_variation(E.key, E.value); } } @@ -1680,12 +1645,10 @@ void Theme::merge_with(const Ref<Theme> &p_other) { void Theme::clear() { // These items need disconnecting. { - const StringName *K = nullptr; - while ((K = icon_map.next(K))) { - const StringName *L = nullptr; - while ((L = icon_map[*K].next(L))) { - Ref<Texture2D> icon = icon_map[*K][*L]; - if (icon.is_valid()) { + for (const KeyValue<StringName, HashMap<StringName, Ref<Texture2D>>> &E : icon_map) { + for (const KeyValue<StringName, Ref<Texture2D>> &F : E.value) { + if (F.value.is_valid()) { + Ref<Texture2D> icon = F.value; icon->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } } @@ -1693,12 +1656,10 @@ void Theme::clear() { } { - const StringName *K = nullptr; - while ((K = style_map.next(K))) { - const StringName *L = nullptr; - while ((L = style_map[*K].next(L))) { - Ref<StyleBox> style = style_map[*K][*L]; - if (style.is_valid()) { + for (const KeyValue<StringName, HashMap<StringName, Ref<StyleBox>>> &E : style_map) { + for (const KeyValue<StringName, Ref<StyleBox>> &F : E.value) { + if (F.value.is_valid()) { + Ref<StyleBox> style = F.value; style->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } } @@ -1706,12 +1667,10 @@ void Theme::clear() { } { - const StringName *K = nullptr; - while ((K = font_map.next(K))) { - const StringName *L = nullptr; - while ((L = font_map[*K].next(L))) { - Ref<Font> font = font_map[*K][*L]; - if (font.is_valid()) { + for (const KeyValue<StringName, HashMap<StringName, Ref<Font>>> &E : font_map) { + for (const KeyValue<StringName, Ref<Font>> &F : E.value) { + if (F.value.is_valid()) { + Ref<Font> font = F.value; font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } } |