diff options
Diffstat (limited to 'scene/gui/control.cpp')
-rw-r--r-- | scene/gui/control.cpp | 522 |
1 files changed, 295 insertions, 227 deletions
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 0ae1dec46d..81411d5844 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -30,6 +30,7 @@ #include "control.h" +#include "container.h" #include "core/config/project_settings.h" #include "core/math/geometry_2d.h" #include "core/object/message_queue.h" @@ -168,6 +169,20 @@ Size2 Control::_edit_get_minimum_size() const { } #endif +String Control::properties_managed_by_container[] = { + "offset_left", + "offset_top", + "offset_right", + "offset_bottom", + "anchor_left", + "anchor_top", + "anchor_right", + "anchor_bottom", + "rect_position", + "rect_scale", + "rect_size" +}; + void Control::accept_event() { if (is_inside_tree()) { get_viewport()->_gui_accept_event(); @@ -222,41 +237,42 @@ Transform2D Control::_get_internal_transform() const { bool Control::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; - if (!name.begins_with("custom")) { + // Prefixes "custom_*" are supported for compatibility with 3.x. + if (!name.begins_with("theme_override") && !name.begins_with("custom")) { return false; } if (p_value.get_type() == Variant::NIL) { - if (name.begins_with("custom_icons/")) { + if (name.begins_with("theme_override_icons/") || name.begins_with("custom_icons/")) { String dname = name.get_slicec('/', 1); if (data.icon_override.has(dname)) { data.icon_override[dname]->disconnect("changed", callable_mp(this, &Control::_override_changed)); } data.icon_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - } else if (name.begins_with("custom_styles/")) { + } else if (name.begins_with("theme_override_styles/") || name.begins_with("custom_styles/")) { String dname = name.get_slicec('/', 1); if (data.style_override.has(dname)) { data.style_override[dname]->disconnect("changed", callable_mp(this, &Control::_override_changed)); } data.style_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - } else if (name.begins_with("custom_fonts/")) { + } else if (name.begins_with("theme_override_fonts/") || name.begins_with("custom_fonts/")) { String dname = name.get_slicec('/', 1); if (data.font_override.has(dname)) { data.font_override[dname]->disconnect("changed", callable_mp(this, &Control::_override_changed)); } data.font_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - } else if (name.begins_with("custom_font_sizes/")) { + } else if (name.begins_with("theme_override_font_sizes/") || name.begins_with("custom_font_sizes/")) { String dname = name.get_slicec('/', 1); data.font_size_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - } else if (name.begins_with("custom_colors/")) { + } else if (name.begins_with("theme_override_colors/") || name.begins_with("custom_colors/")) { String dname = name.get_slicec('/', 1); data.color_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); - } else if (name.begins_with("custom_constants/")) { + } else if (name.begins_with("theme_override_constants/") || name.begins_with("custom_constants/")) { String dname = name.get_slicec('/', 1); data.constant_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); @@ -265,22 +281,22 @@ bool Control::_set(const StringName &p_name, const Variant &p_value) { } } else { - if (name.begins_with("custom_icons/")) { + if (name.begins_with("theme_override_icons/") || name.begins_with("custom_icons/")) { String dname = name.get_slicec('/', 1); add_theme_icon_override(dname, p_value); - } else if (name.begins_with("custom_styles/")) { + } else if (name.begins_with("theme_override_styles/") || name.begins_with("custom_styles/")) { String dname = name.get_slicec('/', 1); add_theme_style_override(dname, p_value); - } else if (name.begins_with("custom_fonts/")) { + } else if (name.begins_with("theme_override_fonts/") || name.begins_with("custom_fonts/")) { String dname = name.get_slicec('/', 1); add_theme_font_override(dname, p_value); - } else if (name.begins_with("custom_font_sizes/")) { + } else if (name.begins_with("theme_override_font_sizes/") || name.begins_with("custom_font_sizes/")) { String dname = name.get_slicec('/', 1); add_theme_font_size_override(dname, p_value); - } else if (name.begins_with("custom_colors/")) { + } else if (name.begins_with("theme_override_colors/") || name.begins_with("custom_colors/")) { String dname = name.get_slicec('/', 1); add_theme_color_override(dname, p_value); - } else if (name.begins_with("custom_constants/")) { + } else if (name.begins_with("theme_override_constants/") || name.begins_with("custom_constants/")) { String dname = name.get_slicec('/', 1); add_theme_constant_override(dname, p_value); } else { @@ -307,27 +323,26 @@ void Control::_update_minimum_size() { bool Control::_get(const StringName &p_name, Variant &r_ret) const { String sname = p_name; - - if (!sname.begins_with("custom")) { + if (!sname.begins_with("theme_override")) { return false; } - if (sname.begins_with("custom_icons/")) { + if (sname.begins_with("theme_override_icons/")) { String name = sname.get_slicec('/', 1); r_ret = data.icon_override.has(name) ? Variant(data.icon_override[name]) : Variant(); - } else if (sname.begins_with("custom_styles/")) { + } else if (sname.begins_with("theme_override_styles/")) { String name = sname.get_slicec('/', 1); r_ret = data.style_override.has(name) ? Variant(data.style_override[name]) : Variant(); - } else if (sname.begins_with("custom_fonts/")) { + } else if (sname.begins_with("theme_override_fonts/")) { String name = sname.get_slicec('/', 1); r_ret = data.font_override.has(name) ? Variant(data.font_override[name]) : Variant(); - } else if (sname.begins_with("custom_font_sizes/")) { + } else if (sname.begins_with("theme_override_font_sizes/")) { String name = sname.get_slicec('/', 1); r_ret = data.font_size_override.has(name) ? Variant(data.font_size_override[name]) : Variant(); - } else if (sname.begins_with("custom_colors/")) { + } else if (sname.begins_with("theme_override_colors/")) { String name = sname.get_slicec('/', 1); r_ret = data.color_override.has(name) ? Variant(data.color_override[name]) : Variant(); - } else if (sname.begins_with("custom_constants/")) { + } else if (sname.begins_with("theme_override_constants/")) { String name = sname.get_slicec('/', 1); r_ret = data.constant_override.has(name) ? Variant(data.constant_override[name]) : Variant(); } else { @@ -339,96 +354,139 @@ bool Control::_get(const StringName &p_name, Variant &r_ret) const { void Control::_get_property_list(List<PropertyInfo> *p_list) const { Ref<Theme> theme = Theme::get_default(); - /* Using the default theme since the properties below are meant for editor only - if (data.theme.is_valid()) { - theme = data.theme; - } else { - theme = Theme::get_default(); - }*/ + p_list->push_back(PropertyInfo(Variant::NIL, "Theme Overrides", PROPERTY_HINT_NONE, "theme_override_", PROPERTY_USAGE_GROUP)); { List<StringName> names; - theme->get_icon_list(get_class_name(), &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + theme->get_color_list(get_class_name(), &names); + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.icon_override.has(E->get())) { + if (data.color_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_icons/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage)); + p_list->push_back(PropertyInfo(Variant::COLOR, "theme_override_colors/" + E, PROPERTY_HINT_NONE, "", usage)); } } { List<StringName> names; - theme->get_stylebox_list(get_class_name(), &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + theme->get_constant_list(get_class_name(), &names); + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.style_override.has(E->get())) { + if (data.constant_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_styles/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage)); + p_list->push_back(PropertyInfo(Variant::INT, "theme_override_constants/" + E, PROPERTY_HINT_RANGE, "-16384,16384", usage)); } } { List<StringName> names; theme->get_font_list(get_class_name(), &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.font_override.has(E->get())) { + if (data.font_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_fonts/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Font", usage)); + p_list->push_back(PropertyInfo(Variant::OBJECT, "theme_override_fonts/" + E, PROPERTY_HINT_RESOURCE_TYPE, "Font", usage)); } } { List<StringName> names; theme->get_font_size_list(get_class_name(), &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.font_size_override.has(E->get())) { + if (data.font_size_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::INT, "custom_font_sizes/" + E->get(), PROPERTY_HINT_NONE, "", usage)); + p_list->push_back(PropertyInfo(Variant::INT, "theme_override_font_sizes/" + E, PROPERTY_HINT_NONE, "", usage)); } } { List<StringName> names; - theme->get_color_list(get_class_name(), &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + theme->get_icon_list(get_class_name(), &names); + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.color_override.has(E->get())) { + if (data.icon_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::COLOR, "custom_colors/" + E->get(), PROPERTY_HINT_NONE, "", usage)); + p_list->push_back(PropertyInfo(Variant::OBJECT, "theme_override_icons/" + E, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage)); } } { List<StringName> names; - theme->get_constant_list(get_class_name(), &names); - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + theme->get_stylebox_list(get_class_name(), &names); + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - if (data.constant_override.has(E->get())) { + if (data.style_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; } - p_list->push_back(PropertyInfo(Variant::INT, "custom_constants/" + E->get(), PROPERTY_HINT_RANGE, "-16384,16384", usage)); + p_list->push_back(PropertyInfo(Variant::OBJECT, "theme_override_styles/" + E, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage)); } } } +void Control::_validate_property(PropertyInfo &property) const { + if (property.name == "theme_type_variation") { + List<StringName> names; + + // Only the default theme and the project theme are used for the list of options. + // This is an imposed limitation to simplify the logic needed to leverage those options. + Theme::get_default()->get_type_variation_list(get_class_name(), &names); + if (Theme::get_project_default().is_valid()) { + Theme::get_project_default()->get_type_variation_list(get_class_name(), &names); + } + names.sort_custom<StringName::AlphCompare>(); + + Vector<StringName> unique_names; + String hint_string; + for (const StringName &E : names) { + // Skip duplicate values. + if (unique_names.has(E)) { + continue; + } + + hint_string += String(E) + ","; + unique_names.append(E); + } + + property.hint_string = hint_string; + } + if (!Object::cast_to<Container>(get_parent())) { + return; + } + // Disable the property if it's managed by the parent container. + bool property_is_managed_by_container = false; + for (unsigned i = 0; i < properties_managed_by_container_count; i++) { + property_is_managed_by_container = properties_managed_by_container[i] == property.name; + if (property_is_managed_by_container) { + break; + } + } + if (property_is_managed_by_container) { + property.usage |= PROPERTY_USAGE_READ_ONLY; + } +} + Control *Control::get_parent_control() const { return data.parent; } +Window *Control::get_parent_window() const { + return data.parent_window; +} + void Control::set_layout_direction(Control::LayoutDirection p_direction) { ERR_FAIL_INDEX((int)p_direction, 4); data.layout_dir = p_direction; + data.is_rtl_dirty = true; + propagate_notification(NOTIFICATION_LAYOUT_DIRECTION_CHANGED); } @@ -437,29 +495,49 @@ Control::LayoutDirection Control::get_layout_direction() const { } bool Control::is_layout_rtl() const { - if (data.layout_dir == LAYOUT_DIRECTION_INHERITED) { - Window *parent_window = Object::cast_to<Window>(get_parent()); - Control *parent_control = get_parent_control(); - if (parent_control) { - return parent_control->is_layout_rtl(); - } else if (parent_window) { - return parent_window->is_layout_rtl(); - } else { - if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) { - return true; + if (data.is_rtl_dirty) { + const_cast<Control *>(this)->data.is_rtl_dirty = false; + if (data.layout_dir == LAYOUT_DIRECTION_INHERITED) { + Window *parent_window = get_parent_window(); + Control *parent_control = get_parent_control(); + if (parent_control) { + const_cast<Control *>(this)->data.is_rtl = parent_control->is_layout_rtl(); + } else if (parent_window) { + const_cast<Control *>(this)->data.is_rtl = parent_window->is_layout_rtl(); + } else { + if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { + const_cast<Control *>(this)->data.is_rtl = true; + } else { + String locale = TranslationServer::get_singleton()->get_tool_locale(); + const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale); + } } - String locale = TranslationServer::get_singleton()->get_tool_locale(); - return TS->is_locale_right_to_left(locale); - } - } else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) { - if (GLOBAL_GET("internationalization/rendering/force_right_to_left_layout_direction")) { - return true; + } else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) { + if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { + const_cast<Control *>(this)->data.is_rtl = true; + } else { + String locale = TranslationServer::get_singleton()->get_tool_locale(); + const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale); + } + } else { + const_cast<Control *>(this)->data.is_rtl = (data.layout_dir == LAYOUT_DIRECTION_RTL); } - String locale = TranslationServer::get_singleton()->get_tool_locale(); - return TS->is_locale_right_to_left(locale); - } else { - return (data.layout_dir == LAYOUT_DIRECTION_RTL); } + return data.is_rtl; +} + +void Control::set_auto_translate(bool p_enable) { + if (p_enable == data.auto_translate) { + return; + } + + data.auto_translate = p_enable; + + notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED); +} + +bool Control::is_auto_translating() const { + return data.auto_translate; } void Control::_clear_size_warning() { @@ -509,17 +587,22 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_POST_ENTER_TREE: { data.minimum_size_valid = false; + data.is_rtl_dirty = true; _size_changed(); } break; case NOTIFICATION_EXIT_TREE: { get_viewport()->_gui_remove_control(this); } break; case NOTIFICATION_READY: { +#ifdef DEBUG_ENABLED connect("ready", callable_mp(this, &Control::_clear_size_warning), varray(), CONNECT_DEFERRED | CONNECT_ONESHOT); +#endif } break; case NOTIFICATION_ENTER_CANVAS: { data.parent = Object::cast_to<Control>(get_parent()); + data.parent_window = Object::cast_to<Window>(get_parent()); + data.is_rtl_dirty = true; Node *parent = this; //meh Control *parent_control = nullptr; @@ -584,6 +667,8 @@ void Control::_notification(int p_notification) { data.parent = nullptr; data.parent_canvas_item = nullptr; + data.parent_window = nullptr; + data.is_rtl_dirty = true; } break; case NOTIFICATION_MOVED_IN_PARENT: { @@ -643,32 +728,17 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_TRANSLATION_CHANGED: case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { + data.is_rtl_dirty = true; _size_changed(); } break; } } -bool Control::clips_input() const { - if (get_script_instance()) { - return get_script_instance()->call(SceneStringNames::get_singleton()->_clips_input); - } - return false; -} - bool Control::has_point(const Point2 &p_point) const { - if (get_script_instance()) { - Variant v = p_point; - const Variant *p = &v; - Callable::CallError ce; - Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->has_point, &p, 1, ce); - if (ce.error == Callable::CallError::CALL_OK) { - return ret; - } - } - /*if (has_stylebox("mask")) { - Ref<StyleBox> mask = get_stylebox("mask"); - return mask->test_mask(p_point,Rect2(Point2(),get_size())); - }*/ + bool ret; + if (GDVIRTUAL_CALL(_has_point, p_point, ret)) { + return ret; + } return Rect2(Point2(), get_size()).has_point(p_point); } @@ -685,18 +755,13 @@ Variant Control::get_drag_data(const Point2 &p_point) { Object *obj = ObjectDB::get_instance(data.drag_owner); if (obj) { Control *c = Object::cast_to<Control>(obj); - return c->call("get_drag_data_fw", p_point, this); + return c->call("_get_drag_data_fw", p_point, this); } } - if (get_script_instance()) { - Variant v = p_point; - const Variant *p = &v; - Callable::CallError ce; - Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->get_drag_data, &p, 1, ce); - if (ce.error == Callable::CallError::CALL_OK) { - return ret; - } + Variant dd; + if (GDVIRTUAL_CALL(_get_drag_data, p_point, dd)) { + return dd; } return Variant(); @@ -707,20 +772,14 @@ bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const Object *obj = ObjectDB::get_instance(data.drag_owner); if (obj) { Control *c = Object::cast_to<Control>(obj); - return c->call("can_drop_data_fw", p_point, p_data, this); + return c->call("_can_drop_data_fw", p_point, p_data, this); } } - if (get_script_instance()) { - Variant v = p_point; - const Variant *p[2] = { &v, &p_data }; - Callable::CallError ce; - Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->can_drop_data, p, 2, ce); - if (ce.error == Callable::CallError::CALL_OK) { - return ret; - } + bool ret; + if (GDVIRTUAL_CALL(_can_drop_data, p_point, p_data, ret)) { + return ret; } - return false; } @@ -729,20 +788,12 @@ void Control::drop_data(const Point2 &p_point, const Variant &p_data) { Object *obj = ObjectDB::get_instance(data.drag_owner); if (obj) { Control *c = Object::cast_to<Control>(obj); - c->call("drop_data_fw", p_point, p_data, this); + c->call("_drop_data_fw", p_point, p_data, this); return; } } - if (get_script_instance()) { - Variant v = p_point; - const Variant *p[2] = { &v, &p_data }; - Callable::CallError ce; - Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->drop_data, p, 2, ce); - if (ce.error == Callable::CallError::CALL_OK) { - return; - } - } + GDVIRTUAL_CALL(_drop_data, p_point, p_data); } void Control::force_drag(const Variant &p_data, Control *p_control) { @@ -758,16 +809,26 @@ void Control::set_drag_preview(Control *p_control) { get_viewport()->_gui_set_drag_preview(this, p_control); } +void Control::_call_gui_input(const Ref<InputEvent> &p_event) { + emit_signal(SceneStringNames::get_singleton()->gui_input, p_event); //signal should be first, so it's possible to override an event (and then accept it) + if (!is_inside_tree() || get_viewport()->is_input_handled()) { + return; //input was handled, abort + } + GDVIRTUAL_CALL(_gui_input, p_event); + if (!is_inside_tree() || get_viewport()->is_input_handled()) { + return; //input was handled, abort + } + gui_input(p_event); +} +void Control::gui_input(const Ref<InputEvent> &p_event) { +} + Size2 Control::get_minimum_size() const { - ScriptInstance *si = const_cast<Control *>(this)->get_script_instance(); - if (si) { - Callable::CallError ce; - Variant s = si->call(SceneStringNames::get_singleton()->_get_minimum_size, nullptr, 0, ce); - if (ce.error == Callable::CallError::CALL_OK) { - return s; - } + Vector2 ms; + if (GDVIRTUAL_CALL(_get_minimum_size, ms)) { + return ms; } - return Size2(); + return Vector2(); } template <class T> @@ -780,13 +841,13 @@ T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { - for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { - if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E->get())) { - return theme_owner->data.theme->get_theme_item(p_data_type, p_name, E->get()); + for (const StringName &E : p_theme_types) { + if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { + return theme_owner->data.theme->get_theme_item(p_data_type, p_name, E); } - if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E->get())) { - return theme_owner_window->theme->get_theme_item(p_data_type, p_name, E->get()); + if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { + return theme_owner_window->theme->get_theme_item(p_data_type, p_name, E); } } @@ -809,17 +870,17 @@ T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner // Secondly, check the project-defined Theme resource. if (Theme::get_project_default().is_valid()) { - for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { - if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E->get())) { - return Theme::get_project_default()->get_theme_item(p_data_type, p_name, E->get()); + for (const StringName &E : p_theme_types) { + if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { + return Theme::get_project_default()->get_theme_item(p_data_type, p_name, E); } } } // Lastly, fall back on the items defined in the default Theme, if they exist. - for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { - if (Theme::get_default()->has_theme_item(p_data_type, p_name, E->get())) { - return Theme::get_default()->get_theme_item(p_data_type, p_name, E->get()); + for (const StringName &E : p_theme_types) { + if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { + return Theme::get_default()->get_theme_item(p_data_type, p_name, E); } } // If they don't exist, use any type to return the default/empty value. @@ -835,12 +896,12 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow Window *theme_owner_window = p_theme_owner_window; while (theme_owner || theme_owner_window) { - for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { - if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E->get())) { + for (const StringName &E : p_theme_types) { + if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { return true; } - if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E->get())) { + if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { return true; } } @@ -864,16 +925,16 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow // Secondly, check the project-defined Theme resource. if (Theme::get_project_default().is_valid()) { - for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { - if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E->get())) { + for (const StringName &E : p_theme_types) { + if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { return true; } } } // Lastly, fall back on the items defined in the default Theme, if they exist. - for (List<StringName>::Element *E = p_theme_types.front(); E; E = E->next()) { - if (Theme::get_default()->has_theme_item(p_data_type, p_name, E->get())) { + for (const StringName &E : p_theme_types) { + if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { return true; } } @@ -881,18 +942,19 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow } void Control::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { - if (data.theme_custom_type != StringName()) { - p_list->push_back(data.theme_custom_type); + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(data.theme_type_variation) != StringName()) { + Theme::get_project_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); + } else { + Theme::get_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); } - Theme::get_type_dependencies(get_class_name(), p_list); } else { - Theme::get_type_dependencies(p_theme_type, p_list); + Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list); } } Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); if (tex) { return *tex; @@ -905,7 +967,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 { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { const Ref<StyleBox> *style = data.style_override.getptr(p_name); if (style) { return *style; @@ -918,7 +980,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 { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { const Ref<Font> *font = data.font_override.getptr(p_name); if (font) { return *font; @@ -931,7 +993,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 { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { const int *font_size = data.font_size_override.getptr(p_name); if (font_size) { return *font_size; @@ -944,7 +1006,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 { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { const Color *color = data.color_override.getptr(p_name); if (color) { return *color; @@ -957,7 +1019,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 { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { const int *constant = data.constant_override.getptr(p_name); if (constant) { return *constant; @@ -1000,7 +1062,7 @@ bool Control::has_theme_constant_override(const StringName &p_name) const { } bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { if (has_theme_icon_override(p_name)) { return true; } @@ -1012,7 +1074,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 { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { if (has_theme_stylebox_override(p_name)) { return true; } @@ -1024,7 +1086,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 { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { if (has_theme_font_override(p_name)) { return true; } @@ -1036,7 +1098,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 { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { if (has_theme_font_size_override(p_name)) { return true; } @@ -1048,7 +1110,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 { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { if (has_theme_color_override(p_name)) { return true; } @@ -1060,7 +1122,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 { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { if (has_theme_constant_override(p_name)) { return true; } @@ -1082,7 +1144,7 @@ Rect2 Control::get_parent_anchorable_rect() const { } else { #ifdef TOOLS_ENABLED Node *edited_root = get_tree()->get_edited_scene_root(); - if (edited_root && (this == edited_root || edited_root->is_a_parent_of(this))) { + if (edited_root && (this == edited_root || edited_root->is_ancestor_of(this))) { parent_rect.size = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); } else { parent_rect = get_viewport()->get_visible_rect(); @@ -1502,7 +1564,7 @@ Point2 Control::get_global_position() const { Point2 Control::get_screen_position() const { ERR_FAIL_COND_V(!is_inside_tree(), Point2()); - Point2 global_pos = get_global_position(); + Point2 global_pos = get_viewport()->get_canvas_transform().xform(get_global_position()); Window *w = Object::cast_to<Window>(get_viewport()); if (w && !w->is_embedding_subwindows()) { global_pos += w->get_position(); @@ -1579,8 +1641,8 @@ void Control::set_rect(const Rect2 &p_rect) { void Control::_set_size(const Size2 &p_size) { #ifdef DEBUG_ENABLED - if (data.size_warning) { - WARN_PRINT("Adjusting the size of Control nodes before they are fully initialized is unreliable. Consider deferring it with set_deferred()."); + if (data.size_warning && (data.anchor[SIDE_LEFT] != data.anchor[SIDE_RIGHT] || data.anchor[SIDE_TOP] != data.anchor[SIDE_BOTTOM])) { + WARN_PRINT("Nodes with non-equal opposite anchors will have their size overridden after _ready(). \nIf you want to set size, change the anchors or consider using set_deferred()."); } #endif set_size(p_size); @@ -1644,6 +1706,17 @@ Rect2 Control::get_anchorable_rect() const { return Rect2(Point2(), get_size()); } +void Control::begin_bulk_theme_override() { + data.bulk_theme_override = true; +} + +void Control::end_bulk_theme_override() { + ERR_FAIL_COND(!data.bulk_theme_override); + + data.bulk_theme_override = false; + _notify_theme_changed(); +} + void Control::add_theme_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon) { ERR_FAIL_COND(!p_icon.is_valid()); @@ -1653,7 +1726,7 @@ void Control::add_theme_icon_override(const StringName &p_name, const Ref<Textur data.icon_override[p_name] = p_icon; data.icon_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) { @@ -1665,7 +1738,7 @@ void Control::add_theme_style_override(const StringName &p_name, const Ref<Style data.style_override[p_name] = p_style; data.style_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::add_theme_font_override(const StringName &p_name, const Ref<Font> &p_font) { @@ -1677,22 +1750,22 @@ void Control::add_theme_font_override(const StringName &p_name, const Ref<Font> data.font_override[p_name] = p_font; data.font_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::add_theme_font_size_override(const StringName &p_name, int p_font_size) { data.font_size_override[p_name] = p_font_size; - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::add_theme_color_override(const StringName &p_name, const Color &p_color) { data.color_override[p_name] = p_color; - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::add_theme_constant_override(const StringName &p_name, int p_constant) { data.constant_override[p_name] = p_constant; - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::remove_theme_icon_override(const StringName &p_name) { @@ -1701,7 +1774,7 @@ void Control::remove_theme_icon_override(const StringName &p_name) { } data.icon_override.erase(p_name); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::remove_theme_style_override(const StringName &p_name) { @@ -1710,7 +1783,7 @@ void Control::remove_theme_style_override(const StringName &p_name) { } data.style_override.erase(p_name); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::remove_theme_font_override(const StringName &p_name) { @@ -1719,22 +1792,22 @@ void Control::remove_theme_font_override(const StringName &p_name) { } data.font_override.erase(p_name); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::remove_theme_font_size_override(const StringName &p_name) { data.font_size_override.erase(p_name); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::remove_theme_color_override(const StringName &p_name) { data.color_override.erase(p_name); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::remove_theme_constant_override(const StringName &p_name) { data.constant_override.erase(p_name); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_changed(); } void Control::set_focus_mode(FocusMode p_focus_mode) { @@ -2007,6 +2080,12 @@ void Control::_theme_changed() { _propagate_theme_changed(this, this, nullptr, false); } +void Control::_notify_theme_changed() { + if (!data.bulk_theme_override) { + notification(NOTIFICATION_THEME_CHANGED); + } +} + void Control::set_theme(const Ref<Theme> &p_theme) { if (data.theme == p_theme) { return; @@ -2045,13 +2124,13 @@ Ref<Theme> Control::get_theme() const { return data.theme; } -void Control::set_theme_custom_type(const StringName &p_theme_type) { - data.theme_custom_type = p_theme_type; +void Control::set_theme_type_variation(const StringName &p_theme_type) { + data.theme_type_variation = p_theme_type; _propagate_theme_changed(this, data.theme_owner, data.theme_owner_window); } -StringName Control::get_theme_custom_type() const { - return data.theme_custom_type; +StringName Control::get_theme_type_variation() const { + return data.theme_type_variation; } void Control::set_tooltip(const String &p_tooltip) { @@ -2064,8 +2143,9 @@ String Control::get_tooltip(const Point2 &p_pos) const { } Control *Control::make_custom_tooltip(const String &p_text) const { - if (get_script_instance()) { - return const_cast<Control *>(this)->call("_make_custom_tooltip", p_text); + Object *ret = nullptr; + if (GDVIRTUAL_CALL(_make_custom_tooltip, p_text, ret)) { + return Object::cast_to<Control>(ret); } return nullptr; } @@ -2440,14 +2520,11 @@ Vector<Vector2i> Control::structured_text_parser(StructuredTextParser p_theme_ty } } break; case STRUCTURED_TEXT_CUSTOM: { - if (get_script_instance()) { - Variant data = get_script_instance()->call(SceneStringNames::get_singleton()->_structured_text_parser, p_args, p_text); - if (data.get_type() == Variant::ARRAY) { - Array _data = data; - for (int i = 0; i < _data.size(); i++) { - if (_data[i].get_type() == Variant::VECTOR2I) { - ret.push_back(Vector2i(_data[i])); - } + Array r; + if (GDVIRTUAL_CALL(_structured_text_parser, p_args, p_text, r)) { + for (int i = 0; i < r.size(); i++) { + if (r[i].get_type() == Variant::VECTOR2I) { + ret.push_back(Vector2i(r[i])); } } } @@ -2471,14 +2548,6 @@ real_t Control::get_rotation() const { return data.rotation; } -void Control::set_rotation_degrees(real_t p_degrees) { - set_rotation(Math::deg2rad(p_degrees)); -} - -real_t Control::get_rotation_degrees() const { - return Math::rad2deg(get_rotation()); -} - void Control::_override_changed() { notification(NOTIFICATION_THEME_CHANGED); emit_signal(SceneStringNames::get_singleton()->theme_changed); @@ -2551,7 +2620,7 @@ bool Control::is_visibility_clip_disabled() const { void Control::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { #ifdef TOOLS_ENABLED - const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\""; + const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; #else const String quote_style = "\""; #endif @@ -2574,8 +2643,8 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List } sn.sort_custom<StringName::AlphCompare>(); - for (List<StringName>::Element *E = sn.front(); E; E = E->next()) { - r_options->push_back(quote_style + E->get() + quote_style); + for (const StringName &name : sn) { + r_options->push_back(String(name).quote(quote_style)); } } } @@ -2646,7 +2715,6 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("set_global_position", "position", "keep_offsets"), &Control::set_global_position, DEFVAL(false)); ClassDB::bind_method(D_METHOD("_set_global_position", "position"), &Control::_set_global_position); ClassDB::bind_method(D_METHOD("set_rotation", "radians"), &Control::set_rotation); - ClassDB::bind_method(D_METHOD("set_rotation_degrees", "degrees"), &Control::set_rotation_degrees); ClassDB::bind_method(D_METHOD("set_scale", "scale"), &Control::set_scale); ClassDB::bind_method(D_METHOD("set_pivot_offset", "pivot_offset"), &Control::set_pivot_offset); ClassDB::bind_method(D_METHOD("get_offset", "offset"), &Control::get_offset); @@ -2655,7 +2723,6 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("get_position"), &Control::get_position); ClassDB::bind_method(D_METHOD("get_size"), &Control::get_size); ClassDB::bind_method(D_METHOD("get_rotation"), &Control::get_rotation); - ClassDB::bind_method(D_METHOD("get_rotation_degrees"), &Control::get_rotation_degrees); ClassDB::bind_method(D_METHOD("get_scale"), &Control::get_scale); ClassDB::bind_method(D_METHOD("get_pivot_offset"), &Control::get_pivot_offset); ClassDB::bind_method(D_METHOD("get_custom_minimum_size"), &Control::get_custom_minimum_size); @@ -2684,8 +2751,11 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("set_theme", "theme"), &Control::set_theme); ClassDB::bind_method(D_METHOD("get_theme"), &Control::get_theme); - ClassDB::bind_method(D_METHOD("set_theme_custom_type", "theme_type"), &Control::set_theme_custom_type); - ClassDB::bind_method(D_METHOD("get_theme_custom_type"), &Control::get_theme_custom_type); + ClassDB::bind_method(D_METHOD("set_theme_type_variation", "theme_type"), &Control::set_theme_type_variation); + ClassDB::bind_method(D_METHOD("get_theme_type_variation"), &Control::get_theme_type_variation); + + ClassDB::bind_method(D_METHOD("begin_bulk_theme_override"), &Control::begin_bulk_theme_override); + ClassDB::bind_method(D_METHOD("end_bulk_theme_override"), &Control::end_bulk_theme_override); ClassDB::bind_method(D_METHOD("add_theme_icon_override", "name", "texture"), &Control::add_theme_icon_override); ClassDB::bind_method(D_METHOD("add_theme_stylebox_override", "name", "stylebox"), &Control::add_theme_style_override); @@ -2768,21 +2838,8 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("get_layout_direction"), &Control::get_layout_direction); ClassDB::bind_method(D_METHOD("is_layout_rtl"), &Control::is_layout_rtl); - BIND_VMETHOD(MethodInfo("_structured_text_parser", PropertyInfo(Variant::ARRAY, "args"), PropertyInfo(Variant::STRING, "text"))); - - BIND_VMETHOD(MethodInfo("_gui_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); - BIND_VMETHOD(MethodInfo(Variant::VECTOR2, "_get_minimum_size")); - - MethodInfo get_drag_data = MethodInfo("get_drag_data", PropertyInfo(Variant::VECTOR2, "position")); - get_drag_data.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; - BIND_VMETHOD(get_drag_data); - - BIND_VMETHOD(MethodInfo(Variant::BOOL, "can_drop_data", PropertyInfo(Variant::VECTOR2, "position"), PropertyInfo(Variant::NIL, "data"))); - BIND_VMETHOD(MethodInfo("drop_data", PropertyInfo(Variant::VECTOR2, "position"), PropertyInfo(Variant::NIL, "data"))); - BIND_VMETHOD(MethodInfo( - PropertyInfo(Variant::OBJECT, "control", PROPERTY_HINT_RESOURCE_TYPE, "Control"), - "_make_custom_tooltip", PropertyInfo(Variant::STRING, "for_text"))); - BIND_VMETHOD(MethodInfo(Variant::BOOL, "_clips_input")); + ClassDB::bind_method(D_METHOD("set_auto_translate", "enable"), &Control::set_auto_translate); + ClassDB::bind_method(D_METHOD("is_auto_translating"), &Control::is_auto_translating); ADD_GROUP("Anchor", "anchor_"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_left", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", SIDE_LEFT); @@ -2803,13 +2860,15 @@ void Control::_bind_methods() { ADD_GROUP("Layout Direction", "layout_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-Right,Right-to-Left"), "set_layout_direction", "get_layout_direction"); + ADD_GROUP("Auto Translate", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_translate"), "set_auto_translate", "is_auto_translating"); + ADD_GROUP("Rect", "rect_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_position", "get_position"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_global_position", PROPERTY_HINT_NONE, "", 0), "_set_global_position", "get_global_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_global_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "_set_global_position", "get_global_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_min_size"), "set_custom_minimum_size", "get_custom_minimum_size"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rect_rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rect_rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater"), "set_rotation_degrees", "get_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rect_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_scale"), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_pivot_offset"), "set_pivot_offset", "get_pivot_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rect_clip_content"), "set_clip_contents", "is_clipping_contents"); @@ -2834,10 +2893,10 @@ void Control::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_horizontal", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_h_size_flags", "get_h_size_flags"); ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_vertical", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_v_size_flags", "get_v_size_flags"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size_flags_stretch_ratio", PROPERTY_HINT_RANGE, "0,20,0.01,or_greater"), "set_stretch_ratio", "get_stretch_ratio"); + ADD_GROUP("Theme", "theme_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_custom_type"), "set_theme_custom_type", "get_theme_custom_type"); - ADD_GROUP("", ""); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_type_variation", PROPERTY_HINT_ENUM_SUGGESTION), "set_theme_type_variation", "get_theme_type_variation"); BIND_ENUM_CONSTANT(FOCUS_NONE); BIND_ENUM_CONSTANT(FOCUS_CLICK); @@ -2938,5 +2997,14 @@ void Control::_bind_methods() { ADD_SIGNAL(MethodInfo("minimum_size_changed")); ADD_SIGNAL(MethodInfo("theme_changed")); - BIND_VMETHOD(MethodInfo(Variant::BOOL, "has_point", PropertyInfo(Variant::VECTOR2, "point"))); + GDVIRTUAL_BIND(_has_point, "position"); + GDVIRTUAL_BIND(_structured_text_parser, "args", "text"); + GDVIRTUAL_BIND(_get_minimum_size); + + GDVIRTUAL_BIND(_get_drag_data, "at_position"); + GDVIRTUAL_BIND(_can_drop_data, "at_position", "data"); + GDVIRTUAL_BIND(_drop_data, "at_position", "data"); + GDVIRTUAL_BIND(_make_custom_tooltip, "for_text"); + + GDVIRTUAL_BIND(_gui_input, "event"); } |