summaryrefslogtreecommitdiffstats
path: root/scene/theme
diff options
context:
space:
mode:
Diffstat (limited to 'scene/theme')
-rw-r--r--scene/theme/default_theme.cpp42
-rw-r--r--scene/theme/icons/default_theme_icons_builders.py20
-rw-r--r--scene/theme/icons/value_down.svg1
-rw-r--r--scene/theme/icons/value_up.svg1
-rw-r--r--scene/theme/theme_db.cpp24
-rw-r--r--scene/theme/theme_db.h47
-rw-r--r--scene/theme/theme_owner.cpp14
-rw-r--r--scene/theme/theme_owner.h6
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();