diff options
Diffstat (limited to 'scene/resources/theme.cpp')
-rw-r--r-- | scene/resources/theme.cpp | 148 |
1 files changed, 146 insertions, 2 deletions
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 8da287042e..373fbb94ea 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "theme.h" + #include "core/string/print_string.h" // Universal Theme resources used when no other theme has the item. @@ -46,7 +47,7 @@ int Theme::fallback_font_size = 16; bool Theme::_set(const StringName &p_name, const Variant &p_value) { String sname = p_name; - if (sname.find("/") != -1) { + if (sname.contains("/")) { String type = sname.get_slicec('/', 1); String theme_type = sname.get_slicec('/', 0); String name = sname.get_slicec('/', 2); @@ -78,7 +79,7 @@ bool Theme::_set(const StringName &p_name, const Variant &p_value) { bool Theme::_get(const StringName &p_name, Variant &r_ret) const { String sname = p_name; - if (sname.find("/") != -1) { + if (sname.contains("/")) { String type = sname.get_slicec('/', 1); String theme_type = sname.get_slicec('/', 0); String name = sname.get_slicec('/', 2); @@ -401,6 +402,26 @@ void Theme::add_icon_type(const StringName &p_theme_type) { icon_map[p_theme_type] = HashMap<StringName, Ref<Texture2D>>(); } +void Theme::remove_icon_type(const StringName &p_theme_type) { + if (!icon_map.has(p_theme_type)) { + return; + } + + _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]; + if (icon.is_valid()) { + icon->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + } + } + + icon_map.erase(p_theme_type); + + _unfreeze_and_propagate_changes(); +} + void Theme::get_icon_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -488,6 +509,26 @@ void Theme::add_stylebox_type(const StringName &p_theme_type) { style_map[p_theme_type] = HashMap<StringName, Ref<StyleBox>>(); } +void Theme::remove_stylebox_type(const StringName &p_theme_type) { + if (!style_map.has(p_theme_type)) { + return; + } + + _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]; + if (style.is_valid()) { + style->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + } + } + + style_map.erase(p_theme_type); + + _unfreeze_and_propagate_changes(); +} + void Theme::get_stylebox_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -577,6 +618,26 @@ void Theme::add_font_type(const StringName &p_theme_type) { font_map[p_theme_type] = HashMap<StringName, Ref<Font>>(); } +void Theme::remove_font_type(const StringName &p_theme_type) { + if (!font_map.has(p_theme_type)) { + return; + } + + _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]; + if (font.is_valid()) { + font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); + } + } + + font_map.erase(p_theme_type); + + _unfreeze_and_propagate_changes(); +} + void Theme::get_font_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -653,6 +714,14 @@ void Theme::add_font_size_type(const StringName &p_theme_type) { font_size_map[p_theme_type] = HashMap<StringName, int>(); } +void Theme::remove_font_size_type(const StringName &p_theme_type) { + if (!font_size_map.has(p_theme_type)) { + return; + } + + font_size_map.erase(p_theme_type); +} + void Theme::get_font_size_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -727,6 +796,14 @@ void Theme::add_color_type(const StringName &p_theme_type) { color_map[p_theme_type] = HashMap<StringName, Color>(); } +void Theme::remove_color_type(const StringName &p_theme_type) { + if (!color_map.has(p_theme_type)) { + return; + } + + color_map.erase(p_theme_type); +} + void Theme::get_color_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -801,6 +878,14 @@ void Theme::add_constant_type(const StringName &p_theme_type) { constant_map[p_theme_type] = HashMap<StringName, int>(); } +void Theme::remove_constant_type(const StringName &p_theme_type) { + if (!constant_map.has(p_theme_type)) { + return; + } + + constant_map.erase(p_theme_type); +} + void Theme::get_constant_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -1017,6 +1102,31 @@ void Theme::add_theme_item_type(DataType p_data_type, const StringName &p_theme_ } } +void Theme::remove_theme_item_type(DataType p_data_type, const StringName &p_theme_type) { + switch (p_data_type) { + case DATA_TYPE_COLOR: + remove_color_type(p_theme_type); + break; + case DATA_TYPE_CONSTANT: + remove_constant_type(p_theme_type); + break; + case DATA_TYPE_FONT: + remove_font_type(p_theme_type); + break; + case DATA_TYPE_FONT_SIZE: + remove_font_size_type(p_theme_type); + break; + case DATA_TYPE_ICON: + remove_icon_type(p_theme_type); + break; + case DATA_TYPE_STYLEBOX: + remove_stylebox_type(p_theme_type); + break; + case DATA_TYPE_MAX: + break; // Can't happen, but silences warning. + } +} + void Theme::get_theme_item_type_list(DataType p_data_type, List<StringName> *p_list) const { switch (p_data_type) { case DATA_TYPE_COLOR: @@ -1101,6 +1211,38 @@ void Theme::get_type_variation_list(const StringName &p_base_type, List<StringNa } // Theme types. +void Theme::add_type(const StringName &p_theme_type) { + // Add a record to every data type map. + for (int i = 0; i < Theme::DATA_TYPE_MAX; i++) { + Theme::DataType dt = (Theme::DataType)i; + add_theme_item_type(dt, p_theme_type); + } + + _emit_theme_changed(true); +} + +void Theme::remove_type(const StringName &p_theme_type) { + // Gracefully remove the record from every data type map. + for (int i = 0; i < Theme::DATA_TYPE_MAX; i++) { + Theme::DataType dt = (Theme::DataType)i; + remove_theme_item_type(dt, p_theme_type); + } + + // If type is a variation, remove that connection. + if (get_type_variation_base(p_theme_type) != StringName()) { + clear_type_variation(p_theme_type); + } + + // If type is a variation base, remove all those connections. + List<StringName> names; + get_type_variation_list(p_theme_type, &names); + for (const StringName &E : names) { + clear_type_variation(E); + } + + _emit_theme_changed(true); +} + void Theme::get_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); @@ -1668,6 +1810,8 @@ void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("get_type_variation_base", "theme_type"), &Theme::get_type_variation_base); ClassDB::bind_method(D_METHOD("get_type_variation_list", "base_type"), &Theme::_get_type_variation_list); + ClassDB::bind_method(D_METHOD("add_type", "theme_type"), &Theme::add_type); + ClassDB::bind_method(D_METHOD("remove_type", "theme_type"), &Theme::remove_type); ClassDB::bind_method(D_METHOD("get_type_list"), &Theme::_get_type_list); ClassDB::bind_method(D_METHOD("merge_with", "other"), &Theme::merge_with); |