summaryrefslogtreecommitdiffstats
path: root/scene/gui/control.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/control.cpp')
-rw-r--r--scene/gui/control.cpp75
1 files changed, 60 insertions, 15 deletions
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 0ca04faf9b..c7ff5980cb 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -1734,6 +1734,10 @@ void Control::_size_changed() {
if (pos_changed && !size_changed) {
_update_canvas_item_transform(); //move because it won't be updated
}
+ } else {
+ if (pos_changed) {
+ _notify_transform();
+ }
}
}
@@ -2303,6 +2307,10 @@ Control *Control::_get_focus_neighbor(Side p_side, int p_count) {
return result;
}
+Control *Control::find_valid_focus_neighbor(Side p_side) const {
+ return const_cast<Control *>(this)->_get_focus_neighbor(p_side);
+}
+
void Control::_window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, const Point2 *p_points, real_t p_min, real_t &r_closest_dist, Control **r_closest) {
if (Object::cast_to<Viewport>(p_at)) {
return; //bye
@@ -2444,6 +2452,7 @@ void Control::_invalidate_theme_cache() {
}
void Control::_update_theme_item_cache() {
+ ThemeDB::get_singleton()->update_class_instance_items(this);
}
void Control::set_theme_owner_node(Node *p_node) {
@@ -2461,6 +2470,11 @@ bool Control::has_theme_owner_node() const {
return data.theme_owner->has_owner_node();
}
+void Control::set_theme_context(ThemeContext *p_context, bool p_propagate) {
+ ERR_MAIN_THREAD_GUARD;
+ data.theme_owner->set_owner_context(p_context, p_propagate);
+}
+
void Control::set_theme(const Ref<Theme> &p_theme) {
ERR_MAIN_THREAD_GUARD;
if (data.theme == p_theme) {
@@ -2519,7 +2533,7 @@ StringName Control::get_theme_type_variation() const {
Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(Ref<Texture2D>());
if (!data.initialized) {
- WARN_PRINT_ONCE("Attempting to access theme items too early; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED");
+ WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", this->get_description()));
}
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
@@ -2543,7 +2557,7 @@ Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringNam
Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(Ref<StyleBox>());
if (!data.initialized) {
- WARN_PRINT_ONCE("Attempting to access theme items too early; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED");
+ WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", this->get_description()));
}
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
@@ -2567,7 +2581,7 @@ Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const String
Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(Ref<Font>());
if (!data.initialized) {
- WARN_PRINT_ONCE("Attempting to access theme items too early; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED");
+ WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", this->get_description()));
}
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
@@ -2591,7 +2605,7 @@ Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_
int Control::get_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(0);
if (!data.initialized) {
- WARN_PRINT_ONCE("Attempting to access theme items too early; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED");
+ WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", this->get_description()));
}
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
@@ -2615,7 +2629,7 @@ int Control::get_theme_font_size(const StringName &p_name, const StringName &p_t
Color Control::get_theme_color(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(Color());
if (!data.initialized) {
- WARN_PRINT_ONCE("Attempting to access theme items too early; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED");
+ WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", this->get_description()));
}
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
@@ -2639,7 +2653,7 @@ Color Control::get_theme_color(const StringName &p_name, const StringName &p_the
int Control::get_theme_constant(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(0);
if (!data.initialized) {
- WARN_PRINT_ONCE("Attempting to access theme items too early; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED");
+ WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", this->get_description()));
}
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
@@ -2660,10 +2674,37 @@ int Control::get_theme_constant(const StringName &p_name, const StringName &p_th
return constant;
}
+Variant Control::get_theme_item(Theme::DataType p_data_type, const StringName &p_name, const StringName &p_theme_type) const {
+ switch (p_data_type) {
+ case Theme::DATA_TYPE_COLOR:
+ return get_theme_color(p_name, p_theme_type);
+ case Theme::DATA_TYPE_CONSTANT:
+ return get_theme_constant(p_name, p_theme_type);
+ case Theme::DATA_TYPE_FONT:
+ return get_theme_font(p_name, p_theme_type);
+ case Theme::DATA_TYPE_FONT_SIZE:
+ return get_theme_font_size(p_name, p_theme_type);
+ case Theme::DATA_TYPE_ICON:
+ return get_theme_icon(p_name, p_theme_type);
+ case Theme::DATA_TYPE_STYLEBOX:
+ return get_theme_stylebox(p_name, p_theme_type);
+ case Theme::DATA_TYPE_MAX:
+ break; // Can't happen, but silences warning.
+ }
+
+ return Variant();
+}
+
+#ifdef TOOLS_ENABLED
+Ref<Texture2D> Control::get_editor_theme_icon(const StringName &p_name) const {
+ return get_theme_icon(p_name, SNAME("EditorIcons"));
+}
+#endif
+
bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(false);
if (!data.initialized) {
- WARN_PRINT_ONCE("Attempting to access theme items too early; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED");
+ WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", this->get_description()));
}
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
@@ -2680,7 +2721,7 @@ bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme
bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(false);
if (!data.initialized) {
- WARN_PRINT_ONCE("Attempting to access theme items too early; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED");
+ WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", this->get_description()));
}
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
@@ -2697,7 +2738,7 @@ bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_t
bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(false);
if (!data.initialized) {
- WARN_PRINT_ONCE("Attempting to access theme items too early; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED");
+ WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", this->get_description()));
}
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
@@ -2714,7 +2755,7 @@ bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme
bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(false);
if (!data.initialized) {
- WARN_PRINT_ONCE("Attempting to access theme items too early; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED");
+ WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", this->get_description()));
}
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
@@ -2731,7 +2772,7 @@ bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_
bool Control::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(false);
if (!data.initialized) {
- WARN_PRINT_ONCE("Attempting to access theme items too early; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED");
+ WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", this->get_description()));
}
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
@@ -2748,7 +2789,7 @@ bool Control::has_theme_color(const StringName &p_name, const StringName &p_them
bool Control::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const {
ERR_READ_THREAD_GUARD_V(false);
if (!data.initialized) {
- WARN_PRINT_ONCE("Attempting to access theme items too early; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED");
+ WARN_PRINT_ONCE(vformat("Attempting to access theme items too early in %s; prefer NOTIFICATION_POSTINITIALIZE and NOTIFICATION_THEME_CHANGED", this->get_description()));
}
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
@@ -3114,7 +3155,9 @@ void Control::_notification(int p_notification) {
notification(NOTIFICATION_TRANSLATION_CHANGED);
}
#endif
- notification(NOTIFICATION_THEME_CHANGED);
+
+ // Emits NOTIFICATION_THEME_CHANGED internally.
+ set_theme_context(ThemeDB::get_singleton()->get_nearest_theme_context(this));
} break;
case NOTIFICATION_POST_ENTER_TREE: {
@@ -3124,6 +3167,7 @@ void Control::_notification(int p_notification) {
} break;
case NOTIFICATION_EXIT_TREE: {
+ set_theme_context(nullptr, false);
release_focus();
get_viewport()->_gui_remove_control(this);
} break;
@@ -3326,6 +3370,7 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("release_focus"), &Control::release_focus);
ClassDB::bind_method(D_METHOD("find_prev_valid_focus"), &Control::find_prev_valid_focus);
ClassDB::bind_method(D_METHOD("find_next_valid_focus"), &Control::find_next_valid_focus);
+ ClassDB::bind_method(D_METHOD("find_valid_focus_neighbor", "side"), &Control::find_valid_focus_neighbor);
ClassDB::bind_method(D_METHOD("set_h_size_flags", "flags"), &Control::set_h_size_flags);
ClassDB::bind_method(D_METHOD("get_h_size_flags"), &Control::get_h_size_flags);
@@ -3478,7 +3523,7 @@ void Control::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_EDITOR), "_set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_EDITOR), "_set_position", "get_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_NONE), "_set_global_position", "get_global_position");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians"), "set_rotation", "get_rotation");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_less,or_greater,radians_as_degrees"), "set_rotation", "get_rotation");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_rotation_degrees", "get_rotation_degrees");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "pivot_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_pivot_offset", "get_pivot_offset");
@@ -3622,7 +3667,7 @@ void Control::_bind_methods() {
}
Control::Control() {
- data.theme_owner = memnew(ThemeOwner);
+ data.theme_owner = memnew(ThemeOwner(this));
}
Control::~Control() {