summaryrefslogtreecommitdiff
path: root/scene/resources/theme.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/theme.cpp')
-rw-r--r--scene/resources/theme.cpp148
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);