diff options
Diffstat (limited to 'scene/theme')
-rw-r--r-- | scene/theme/default_theme.cpp | 42 | ||||
-rw-r--r-- | scene/theme/icons/default_theme_icons_builders.py | 20 | ||||
-rw-r--r-- | scene/theme/icons/value_down.svg | 1 | ||||
-rw-r--r-- | scene/theme/icons/value_up.svg | 1 | ||||
-rw-r--r-- | scene/theme/theme_db.cpp | 24 | ||||
-rw-r--r-- | scene/theme/theme_db.h | 47 | ||||
-rw-r--r-- | scene/theme/theme_owner.cpp | 14 | ||||
-rw-r--r-- | scene/theme/theme_owner.h | 6 |
8 files changed, 95 insertions, 60 deletions
diff --git a/scene/theme/default_theme.cpp b/scene/theme/default_theme.cpp index b2a3843b02..0c211be9f9 100644 --- a/scene/theme/default_theme.cpp +++ b/scene/theme/default_theme.cpp @@ -504,6 +504,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_icon("can_fold_code_region", "CodeEdit", icons["region_unfolded"]); theme->set_icon("folded_code_region", "CodeEdit", icons["region_folded"]); theme->set_icon("folded_eol_icon", "CodeEdit", icons["text_edit_ellipsis"]); + theme->set_icon("completion_color_bg", "CodeEdit", icons["mini_checkerboard"]); theme->set_font(SceneStringName(font), "CodeEdit", Ref<Font>()); theme->set_font_size(SceneStringName(font_size), "CodeEdit", -1); @@ -613,7 +614,43 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // SpinBox - theme->set_icon("updown", "SpinBox", icons["updown"]); + theme->set_icon("updown", "SpinBox", empty_icon); + theme->set_icon("up", "SpinBox", icons["value_up"]); + theme->set_icon("up_hover", "SpinBox", icons["value_up"]); + theme->set_icon("up_pressed", "SpinBox", icons["value_up"]); + theme->set_icon("up_disabled", "SpinBox", icons["value_up"]); + theme->set_icon("down", "SpinBox", icons["value_down"]); + theme->set_icon("down_hover", "SpinBox", icons["value_down"]); + theme->set_icon("down_pressed", "SpinBox", icons["value_down"]); + theme->set_icon("down_disabled", "SpinBox", icons["value_down"]); + + theme->set_stylebox("up_background", "SpinBox", make_empty_stylebox()); + theme->set_stylebox("up_background_hovered", "SpinBox", button_hover); + theme->set_stylebox("up_background_pressed", "SpinBox", button_pressed); + theme->set_stylebox("up_background_disabled", "SpinBox", make_empty_stylebox()); + theme->set_stylebox("down_background", "SpinBox", make_empty_stylebox()); + theme->set_stylebox("down_background_hovered", "SpinBox", button_hover); + theme->set_stylebox("down_background_pressed", "SpinBox", button_pressed); + theme->set_stylebox("down_background_disabled", "SpinBox", make_empty_stylebox()); + + theme->set_color("up_icon_modulate", "SpinBox", control_font_color); + theme->set_color("up_hover_icon_modulate", "SpinBox", control_font_hover_color); + theme->set_color("up_pressed_icon_modulate", "SpinBox", control_font_hover_color); + theme->set_color("up_disabled_icon_modulate", "SpinBox", control_font_disabled_color); + theme->set_color("down_icon_modulate", "SpinBox", control_font_color); + theme->set_color("down_hover_icon_modulate", "SpinBox", control_font_hover_color); + theme->set_color("down_pressed_icon_modulate", "SpinBox", control_font_hover_color); + theme->set_color("down_disabled_icon_modulate", "SpinBox", control_font_disabled_color); + + theme->set_stylebox("field_and_buttons_separator", "SpinBox", make_empty_stylebox()); + theme->set_stylebox("up_down_buttons_separator", "SpinBox", make_empty_stylebox()); + + theme->set_constant("buttons_vertical_separation", "SpinBox", 0); + theme->set_constant("field_and_buttons_separation", "SpinBox", 2); + theme->set_constant("buttons_width", "SpinBox", 16); +#ifndef DISABLE_DEPRECATED + theme->set_constant("set_min_buttons_width_from_icons", "SpinBox", 1); +#endif // ScrollContainer @@ -1174,6 +1211,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("v_separation", "VFlowContainer", Math::round(4 * scale)); theme->set_stylebox(SceneStringName(panel), "PanelContainer", make_flat_stylebox(style_normal_color, 0, 0, 0, 0)); + theme->set_stylebox("split_bar_background", "SplitContainer", make_empty_stylebox(0, 0, 0, 0)); + theme->set_stylebox("split_bar_background", "VSplitContainer", make_empty_stylebox(0, 0, 0, 0)); + theme->set_stylebox("split_bar_background", "HSplitContainer", make_empty_stylebox(0, 0, 0, 0)); theme->set_icon("zoom_out", "GraphEdit", icons["zoom_less"]); theme->set_icon("zoom_in", "GraphEdit", icons["zoom_more"]); diff --git a/scene/theme/icons/default_theme_icons_builders.py b/scene/theme/icons/default_theme_icons_builders.py index 49c0a93191..3a673af92e 100644 --- a/scene/theme/icons/default_theme_icons_builders.py +++ b/scene/theme/icons/default_theme_icons_builders.py @@ -3,6 +3,8 @@ import os from io import StringIO +from methods import to_raw_cstring + # See also `editor/icons/editor_icons_builders.py`. def make_default_theme_icons_action(target, source, env): @@ -10,21 +12,9 @@ def make_default_theme_icons_action(target, source, env): svg_icons = [str(x) for x in source] with StringIO() as icons_string, StringIO() as s: - for f in svg_icons: - fname = str(f) - - icons_string.write('\t"') - - with open(fname, "rb") as svgf: - b = svgf.read(1) - while len(b) == 1: - icons_string.write("\\" + str(hex(ord(b)))[1:]) - b = svgf.read(1) - - icons_string.write('"') - if fname != svg_icons[-1]: - icons_string.write(",") - icons_string.write("\n") + for svg in svg_icons: + with open(svg, "r") as svgf: + icons_string.write("\t%s,\n" % to_raw_cstring(svgf.read())) s.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n\n") s.write('#include "modules/modules_enabled.gen.h"\n\n') diff --git a/scene/theme/icons/value_down.svg b/scene/theme/icons/value_down.svg new file mode 100644 index 0000000000..57837d03fd --- /dev/null +++ b/scene/theme/icons/value_down.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="8"><path fill="none" stroke="#fff" stroke-width="2" d="m12 2-4 3.5L4 2"/></svg>
\ No newline at end of file diff --git a/scene/theme/icons/value_up.svg b/scene/theme/icons/value_up.svg new file mode 100644 index 0000000000..53fb102fe2 --- /dev/null +++ b/scene/theme/icons/value_up.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="8"><path fill="none" stroke="#fff" stroke-width="2" d="m4 6 4-3.5L12 6"/></svg>
\ No newline at end of file diff --git a/scene/theme/theme_db.cpp b/scene/theme/theme_db.cpp index 7249fd7ba8..c33c31558f 100644 --- a/scene/theme/theme_db.cpp +++ b/scene/theme/theme_db.cpp @@ -198,21 +198,21 @@ Ref<StyleBox> ThemeDB::get_fallback_stylebox() { return fallback_stylebox; } -void ThemeDB::get_native_type_dependencies(const StringName &p_base_type, List<StringName> *p_list) { - ERR_FAIL_NULL(p_list); +void ThemeDB::get_native_type_dependencies(const StringName &p_base_type, Vector<StringName> &r_result) { + if (p_base_type == StringName()) { + return; + } // TODO: It may make sense to stop at Control/Window, because their parent classes cannot be used in // a meaningful way. - StringName class_name = p_base_type; - while (class_name != StringName()) { - p_list->push_back(class_name); - class_name = ClassDB::get_parent_class_nocheck(class_name); + if (!ClassDB::get_inheritance_chain_nocheck(p_base_type, r_result)) { + r_result.push_back(p_base_type); } } // Global theme contexts. -ThemeContext *ThemeDB::create_theme_context(Node *p_node, List<Ref<Theme>> &p_themes) { +ThemeContext *ThemeDB::create_theme_context(Node *p_node, Vector<Ref<Theme>> &p_themes) { ERR_FAIL_COND_V(!p_node->is_inside_tree(), nullptr); ERR_FAIL_COND_V(theme_contexts.has(p_node), nullptr); ERR_FAIL_COND_V(p_themes.is_empty(), nullptr); @@ -270,7 +270,7 @@ void ThemeDB::_propagate_theme_context(Node *p_from_node, ThemeContext *p_contex void ThemeDB::_init_default_theme_context() { default_theme_context = memnew(ThemeContext); - List<Ref<Theme>> themes; + Vector<Ref<Theme>> themes; // Only add the project theme to the default context when running projects. @@ -365,7 +365,7 @@ void ThemeDB::update_class_instance_items(Node *p_instance) { HashMap<StringName, HashMap<StringName, ThemeItemBind>>::Iterator E = theme_item_binds.find(class_name); if (E) { for (const KeyValue<StringName, ThemeItemBind> &F : E->value) { - F.value.setter(p_instance); + F.value.setter(p_instance, F.value.item_name, F.value.type_name); } } @@ -475,7 +475,7 @@ void ThemeContext::_emit_changed() { emit_signal(CoreStringName(changed)); } -void ThemeContext::set_themes(List<Ref<Theme>> &p_themes) { +void ThemeContext::set_themes(Vector<Ref<Theme>> &p_themes) { for (const Ref<Theme> &theme : themes) { theme->disconnect_changed(callable_mp(this, &ThemeContext::_emit_changed)); } @@ -494,7 +494,7 @@ void ThemeContext::set_themes(List<Ref<Theme>> &p_themes) { _emit_changed(); } -List<Ref<Theme>> ThemeContext::get_themes() const { +const Vector<Ref<Theme>> ThemeContext::get_themes() const { return themes; } @@ -504,7 +504,7 @@ Ref<Theme> ThemeContext::get_fallback_theme() const { return ThemeDB::get_singleton()->get_default_theme(); } - return themes.back()->get(); + return themes[themes.size() - 1]; } void ThemeContext::_bind_methods() { diff --git a/scene/theme/theme_db.h b/scene/theme/theme_db.h index f403c1ef20..353894f41e 100644 --- a/scene/theme/theme_db.h +++ b/scene/theme/theme_db.h @@ -46,26 +46,29 @@ class ThemeContext; // Macros for binding theme items of this class. This information is used for the documentation, theme // overrides, etc. This is also the basis for theme cache. -#define BIND_THEME_ITEM(m_data_type, m_class, m_prop) \ - ThemeDB::get_singleton()->bind_class_item(m_data_type, get_class_static(), #m_prop, #m_prop, [](Node *p_instance) { \ - m_class *p_cast = Object::cast_to<m_class>(p_instance); \ - p_cast->theme_cache.m_prop = p_cast->get_theme_item(m_data_type, _scs_create(#m_prop)); \ - }) - -#define BIND_THEME_ITEM_CUSTOM(m_data_type, m_class, m_prop, m_item_name) \ - ThemeDB::get_singleton()->bind_class_item(m_data_type, get_class_static(), #m_prop, m_item_name, [](Node *p_instance) { \ - m_class *p_cast = Object::cast_to<m_class>(p_instance); \ - p_cast->theme_cache.m_prop = p_cast->get_theme_item(m_data_type, _scs_create(m_item_name)); \ - }) +#define BIND_THEME_ITEM(m_data_type, m_class, m_prop) \ + ThemeDB::get_singleton()->bind_class_item(m_data_type, get_class_static(), #m_prop, #m_prop, \ + [](Node *p_instance, const StringName &p_item_name, const StringName &p_type_name) { \ + m_class *p_cast = Object::cast_to<m_class>(p_instance); \ + p_cast->theme_cache.m_prop = p_cast->get_theme_item(m_data_type, p_item_name, p_type_name); \ + }) + +#define BIND_THEME_ITEM_CUSTOM(m_data_type, m_class, m_prop, m_item_name) \ + ThemeDB::get_singleton()->bind_class_item(m_data_type, get_class_static(), #m_prop, m_item_name, \ + [](Node *p_instance, const StringName &p_item_name, const StringName &p_type_name) { \ + m_class *p_cast = Object::cast_to<m_class>(p_instance); \ + p_cast->theme_cache.m_prop = p_cast->get_theme_item(m_data_type, p_item_name, p_type_name); \ + }) // Macro for binding theme items used by this class, but defined/binded by other classes. This is primarily used for // the theme cache. Can also be used to list such items in documentation. -#define BIND_THEME_ITEM_EXT(m_data_type, m_class, m_prop, m_item_name, m_type_name) \ - ThemeDB::get_singleton()->bind_class_external_item(m_data_type, get_class_static(), #m_prop, m_item_name, m_type_name, [](Node *p_instance) { \ - m_class *p_cast = Object::cast_to<m_class>(p_instance); \ - p_cast->theme_cache.m_prop = p_cast->get_theme_item(m_data_type, _scs_create(m_item_name), _scs_create(m_type_name)); \ - }) +#define BIND_THEME_ITEM_EXT(m_data_type, m_class, m_prop, m_item_name, m_type_name) \ + ThemeDB::get_singleton()->bind_class_external_item(m_data_type, get_class_static(), #m_prop, m_item_name, m_type_name, \ + [](Node *p_instance, const StringName &p_item_name, const StringName &p_type_name) { \ + m_class *p_cast = Object::cast_to<m_class>(p_instance); \ + p_cast->theme_cache.m_prop = p_cast->get_theme_item(m_data_type, p_item_name, p_type_name); \ + }) class ThemeDB : public Object { GDCLASS(ThemeDB, Object); @@ -97,7 +100,7 @@ class ThemeDB : public Object { // Binding of theme items to Node classes. public: - typedef std::function<void(Node *)> ThemeItemSetter; + typedef std::function<void(Node *, const StringName &, const StringName &)> ThemeItemSetter; struct ThemeItemBind { Theme::DataType data_type; @@ -154,11 +157,11 @@ public: void set_fallback_stylebox(const Ref<StyleBox> &p_stylebox); Ref<StyleBox> get_fallback_stylebox(); - void get_native_type_dependencies(const StringName &p_base_type, List<StringName> *p_list); + void get_native_type_dependencies(const StringName &p_base_type, Vector<StringName> &r_result); // Global theme contexts. - ThemeContext *create_theme_context(Node *p_node, List<Ref<Theme>> &p_themes); + ThemeContext *create_theme_context(Node *p_node, Vector<Ref<Theme>> &p_themes); void destroy_theme_context(Node *p_node); ThemeContext *get_theme_context(Node *p_node) const; @@ -191,7 +194,7 @@ class ThemeContext : public Object { // Themes are stacked in the order of relevance, for easy iteration. // This means that the first theme is the one you should check first, // and the last theme is the fallback theme where every lookup ends. - List<Ref<Theme>> themes; + Vector<Ref<Theme>> themes; void _emit_changed(); @@ -199,8 +202,8 @@ protected: static void _bind_methods(); public: - void set_themes(List<Ref<Theme>> &p_themes); - List<Ref<Theme>> get_themes() const; + void set_themes(Vector<Ref<Theme>> &p_themes); + const Vector<Ref<Theme>> get_themes() const; Ref<Theme> get_fallback_theme() const; }; diff --git a/scene/theme/theme_owner.cpp b/scene/theme/theme_owner.cpp index a25adddc09..b3d51e71c0 100644 --- a/scene/theme/theme_owner.cpp +++ b/scene/theme/theme_owner.cpp @@ -199,7 +199,7 @@ void ThemeOwner::propagate_theme_changed(Node *p_to_node, Node *p_owner_node, bo // Theme lookup. -void ThemeOwner::get_theme_type_dependencies(const Node *p_for_node, const StringName &p_theme_type, List<StringName> *r_list) const { +void ThemeOwner::get_theme_type_dependencies(const Node *p_for_node, const StringName &p_theme_type, Vector<StringName> &r_result) const { const Control *for_c = Object::cast_to<Control>(p_for_node); const Window *for_w = Object::cast_to<Window>(p_for_node); ERR_FAIL_COND_MSG(!for_c && !for_w, "Only Control and Window nodes and derivatives can be polled for theming."); @@ -224,7 +224,7 @@ void ThemeOwner::get_theme_type_dependencies(const Node *p_for_node, const Strin while (owner_node) { Ref<Theme> owner_theme = _get_owner_node_theme(owner_node); if (owner_theme.is_valid() && owner_theme->get_type_variation_base(type_variation) != StringName()) { - owner_theme->get_type_dependencies(type_name, type_variation, r_list); + owner_theme->get_type_dependencies(type_name, type_variation, r_result); return; } @@ -235,21 +235,21 @@ void ThemeOwner::get_theme_type_dependencies(const Node *p_for_node, const Strin ThemeContext *global_context = _get_active_owner_context(); for (const Ref<Theme> &theme : global_context->get_themes()) { if (theme.is_valid() && theme->get_type_variation_base(type_variation) != StringName()) { - theme->get_type_dependencies(type_name, type_variation, r_list); + theme->get_type_dependencies(type_name, type_variation, r_result); return; } } // If nothing was found, get the native dependencies for the current class. - ThemeDB::get_singleton()->get_native_type_dependencies(type_name, r_list); + ThemeDB::get_singleton()->get_native_type_dependencies(type_name, r_result); return; } // Otherwise, get the native dependencies for the provided theme type. - ThemeDB::get_singleton()->get_native_type_dependencies(p_theme_type, r_list); + ThemeDB::get_singleton()->get_native_type_dependencies(p_theme_type, r_result); } -Variant ThemeOwner::get_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const List<StringName> &p_theme_types) { +Variant ThemeOwner::get_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const Vector<StringName> &p_theme_types) { ERR_FAIL_COND_V_MSG(p_theme_types.is_empty(), Variant(), "At least one theme type must be specified."); // First, look through each control or window node in the branch, until no valid parent can be found. @@ -285,7 +285,7 @@ Variant ThemeOwner::get_theme_item_in_types(Theme::DataType p_data_type, const S return global_context->get_fallback_theme()->get_theme_item(p_data_type, p_name, StringName()); } -bool ThemeOwner::has_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const List<StringName> &p_theme_types) { +bool ThemeOwner::has_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const Vector<StringName> &p_theme_types) { ERR_FAIL_COND_V_MSG(p_theme_types.is_empty(), false, "At least one theme type must be specified."); // First, look through each control or window node in the branch, until no valid parent can be found. diff --git a/scene/theme/theme_owner.h b/scene/theme/theme_owner.h index 7e19279c2a..14bfa35587 100644 --- a/scene/theme/theme_owner.h +++ b/scene/theme/theme_owner.h @@ -69,10 +69,10 @@ public: // Theme lookup. - void get_theme_type_dependencies(const Node *p_for_node, const StringName &p_theme_type, List<StringName> *r_list) const; + void get_theme_type_dependencies(const Node *p_for_node, const StringName &p_theme_type, Vector<StringName> &r_result) const; - Variant get_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const List<StringName> &p_theme_types); - bool has_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const List<StringName> &p_theme_types); + Variant get_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const Vector<StringName> &p_theme_types); + bool has_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const Vector<StringName> &p_theme_types); float get_theme_default_base_scale(); Ref<Font> get_theme_default_font(); |