summaryrefslogtreecommitdiff
path: root/scene/gui/control.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/control.cpp')
-rw-r--r--scene/gui/control.cpp599
1 files changed, 252 insertions, 347 deletions
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 2e391adf2c..5afe813ee0 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -168,6 +168,12 @@ Size2 Control::_edit_get_minimum_size() const {
}
#endif
+void Control::accept_event() {
+ if (is_inside_tree()) {
+ get_viewport()->_gui_accept_event();
+ }
+}
+
void Control::set_custom_minimum_size(const Size2 &p_custom) {
if (p_custom == data.custom_minimum_size) {
return;
@@ -290,15 +296,11 @@ void Control::_update_minimum_size() {
}
Size2 minsize = get_combined_minimum_size();
- if (minsize.x > data.size_cache.x ||
- minsize.y > data.size_cache.y) {
- _size_changed();
- }
-
data.updating_last_minimum_size = false;
if (minsize != data.last_minimum_size) {
data.last_minimum_size = minsize;
+ _size_changed();
emit_signal(SceneStringNames::get_singleton()->minimum_size_changed);
}
}
@@ -327,7 +329,6 @@ bool Control::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = data.color_override.has(name) ? Variant(data.color_override[name]) : Variant();
} else if (sname.begins_with("custom_constants/")) {
String name = sname.get_slicec('/', 1);
-
r_ret = data.constant_override.has(name) ? Variant(data.constant_override[name]) : Variant();
} else {
return false;
@@ -350,72 +351,72 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
theme->get_icon_list(get_class_name(), &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
- uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
+ uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
if (data.icon_override.has(E->get())) {
- hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_icons/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", hint));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_icons/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage));
}
}
{
List<StringName> names;
theme->get_stylebox_list(get_class_name(), &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
- uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
+ uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
if (data.style_override.has(E->get())) {
- hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_styles/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", hint));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_styles/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage));
}
}
{
List<StringName> names;
theme->get_font_list(get_class_name(), &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
- uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
+ uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
if (data.font_override.has(E->get())) {
- hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_fonts/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Font", hint));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_fonts/" + E->get(), 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()) {
- uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
+ uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
if (data.font_size_override.has(E->get())) {
- hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::INT, "custom_font_sizes/" + E->get(), PROPERTY_HINT_NONE, "", hint));
+ p_list->push_back(PropertyInfo(Variant::INT, "custom_font_sizes/" + E->get(), 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()) {
- uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
+ uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
if (data.color_override.has(E->get())) {
- hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::COLOR, "custom_colors/" + E->get(), PROPERTY_HINT_NONE, "", hint));
+ p_list->push_back(PropertyInfo(Variant::COLOR, "custom_colors/" + E->get(), PROPERTY_HINT_NONE, "", usage));
}
}
{
List<StringName> names;
theme->get_constant_list(get_class_name(), &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
- uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
+ uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
if (data.constant_override.has(E->get())) {
- hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
}
- p_list->push_back(PropertyInfo(Variant::INT, "custom_constants/" + E->get(), PROPERTY_HINT_RANGE, "-16384,16384", hint));
+ p_list->push_back(PropertyInfo(Variant::INT, "custom_constants/" + E->get(), PROPERTY_HINT_RANGE, "-16384,16384", usage));
}
}
}
@@ -514,7 +515,9 @@ void Control::_notification(int p_notification) {
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: {
@@ -770,32 +773,27 @@ Size2 Control::get_minimum_size() const {
}
template <class T>
-bool Control::_find_theme_item(Control *p_theme_owner, Window *p_theme_owner_window, T &r_ret, T (Theme::*get_func)(const StringName &, const StringName &) const, bool (Theme::*has_func)(const StringName &, const StringName &) const, const StringName &p_name, const StringName &p_node_type) {
- // try with custom themes
+T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) {
+ ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, T(), "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.
+ // For each control iterate through its inheritance chain and see if p_name exists in any of them.
Control *theme_owner = p_theme_owner;
Window *theme_owner_window = p_theme_owner_window;
while (theme_owner || theme_owner_window) {
- StringName class_name = p_node_type;
-
- while (class_name != StringName()) {
- if (theme_owner && (theme_owner->data.theme.operator->()->*has_func)(p_name, class_name)) {
- r_ret = (theme_owner->data.theme.operator->()->*get_func)(p_name, class_name);
- return true;
+ 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());
}
- if (theme_owner_window && (theme_owner_window->theme.operator->()->*has_func)(p_name, class_name)) {
- r_ret = (theme_owner_window->theme.operator->()->*get_func)(p_name, class_name);
- return true;
+ 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());
}
-
- class_name = ClassDB::get_parent_class_nocheck(class_name);
}
Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent();
-
Control *parent_c = Object::cast_to<Control>(parent);
-
if (parent_c) {
theme_owner = parent_c->data.theme_owner;
theme_owner_window = parent_c->data.theme_owner_window;
@@ -810,33 +808,47 @@ bool Control::_find_theme_item(Control *p_theme_owner, Window *p_theme_owner_win
}
}
}
- return false;
+
+ // 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());
+ }
+ }
+ }
+
+ // 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());
+ }
+ }
+ // If they don't exist, use any type to return the default/empty value.
+ return Theme::get_default()->get_theme_item(p_data_type, p_name, p_theme_types[0]);
}
-bool Control::_has_theme_item(Control *p_theme_owner, Window *p_theme_owner_window, bool (Theme::*has_func)(const StringName &, const StringName &) const, const StringName &p_name, const StringName &p_node_type) {
- // try with custom themes
+bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) {
+ ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, 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.
+ // For each control iterate through its inheritance chain and see if p_name exists in any of them.
Control *theme_owner = p_theme_owner;
Window *theme_owner_window = p_theme_owner_window;
while (theme_owner || theme_owner_window) {
- StringName class_name = p_node_type;
-
- while (class_name != StringName()) {
- if (theme_owner && (theme_owner->data.theme.operator->()->*has_func)(p_name, class_name)) {
+ 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 true;
}
- if (theme_owner_window && (theme_owner_window->theme.operator->()->*has_func)(p_name, class_name)) {
+ if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E->get())) {
return true;
}
-
- class_name = ClassDB::get_parent_class_nocheck(class_name);
}
Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent();
-
Control *parent_c = Object::cast_to<Control>(parent);
-
if (parent_c) {
theme_owner = parent_c->data.theme_owner;
theme_owner_window = parent_c->data.theme_owner_window;
@@ -851,179 +863,112 @@ bool Control::_has_theme_item(Control *p_theme_owner, Window *p_theme_owner_wind
}
}
}
- return false;
-}
-Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_node_type) const {
- if (p_node_type == StringName() || p_node_type == get_class_name()) {
- const Ref<Texture2D> *tex = data.icon_override.getptr(p_name);
- if (tex) {
- return *tex;
+ // 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 true;
+ }
}
}
- StringName type = p_node_type ? p_node_type : get_class_name();
-
- return get_icons(data.theme_owner, data.theme_owner_window, p_name, type);
+ // 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 true;
+ }
+ }
+ return false;
}
-Ref<Texture2D> Control::get_icons(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) {
- Ref<Texture2D> icon;
-
- if (_find_theme_item(p_theme_owner, p_theme_owner_window, icon, &Theme::get_icon, &Theme::has_icon, p_name, p_node_type)) {
- return icon;
+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);
+ }
+ Theme::get_type_dependencies(get_class_name(), p_list);
+ } else {
+ Theme::get_type_dependencies(p_theme_type, p_list);
}
+}
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_icon(p_name, p_node_type)) {
- return Theme::get_project_default()->get_icon(p_name, p_node_type);
+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) {
+ const Ref<Texture2D> *tex = data.icon_override.getptr(p_name);
+ if (tex) {
+ return *tex;
}
}
- return Theme::get_default()->get_icon(p_name, p_node_type);
+ List<StringName> theme_types;
+ _get_theme_type_dependencies(p_theme_type, &theme_types);
+ return get_theme_item_in_types<Ref<Texture2D>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types);
}
-Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const StringName &p_node_type) const {
- if (p_node_type == StringName() || p_node_type == get_class_name()) {
+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) {
const Ref<StyleBox> *style = data.style_override.getptr(p_name);
if (style) {
return *style;
}
}
- StringName type = p_node_type ? p_node_type : get_class_name();
-
- return get_styleboxs(data.theme_owner, data.theme_owner_window, p_name, type);
-}
-
-Ref<StyleBox> Control::get_styleboxs(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) {
- Ref<StyleBox> stylebox;
-
- if (_find_theme_item(p_theme_owner, p_theme_owner_window, stylebox, &Theme::get_stylebox, &Theme::has_stylebox, p_name, p_node_type)) {
- return stylebox;
- }
-
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_stylebox(p_name, p_node_type)) {
- return Theme::get_project_default()->get_stylebox(p_name, p_node_type);
- }
- }
-
- return Theme::get_default()->get_stylebox(p_name, p_node_type);
+ List<StringName> theme_types;
+ _get_theme_type_dependencies(p_theme_type, &theme_types);
+ return get_theme_item_in_types<Ref<StyleBox>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types);
}
-Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_node_type) const {
- if (p_node_type == StringName() || p_node_type == get_class_name()) {
+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) {
const Ref<Font> *font = data.font_override.getptr(p_name);
if (font) {
return *font;
}
}
- StringName type = p_node_type ? p_node_type : get_class_name();
-
- return get_fonts(data.theme_owner, data.theme_owner_window, p_name, type);
+ List<StringName> theme_types;
+ _get_theme_type_dependencies(p_theme_type, &theme_types);
+ return get_theme_item_in_types<Ref<Font>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types);
}
-int Control::get_theme_font_size(const StringName &p_name, const StringName &p_node_type) const {
- if (p_node_type == StringName() || p_node_type == get_class_name()) {
+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) {
const int *font_size = data.font_size_override.getptr(p_name);
if (font_size) {
return *font_size;
}
}
- StringName type = p_node_type ? p_node_type : get_class_name();
-
- return get_font_sizes(data.theme_owner, data.theme_owner_window, p_name, type);
+ List<StringName> theme_types;
+ _get_theme_type_dependencies(p_theme_type, &theme_types);
+ return get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types);
}
-Ref<Font> Control::get_fonts(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) {
- Ref<Font> font;
-
- if (_find_theme_item(p_theme_owner, p_theme_owner_window, font, &Theme::get_font, &Theme::has_font, p_name, p_node_type)) {
- return font;
- }
-
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_font(p_name, p_node_type)) {
- return Theme::get_project_default()->get_font(p_name, p_node_type);
- }
- }
-
- return Theme::get_default()->get_font(p_name, p_node_type);
-}
-
-int Control::get_font_sizes(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) {
- int font_size;
-
- if (_find_theme_item(p_theme_owner, p_theme_owner_window, font_size, &Theme::get_font_size, &Theme::has_font_size, p_name, p_node_type)) {
- return font_size;
- }
-
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_font_size(p_name, p_node_type)) {
- return Theme::get_project_default()->get_font_size(p_name, p_node_type);
- }
- }
-
- return Theme::get_default()->get_font_size(p_name, p_node_type);
-}
-
-Color Control::get_theme_color(const StringName &p_name, const StringName &p_node_type) const {
- if (p_node_type == StringName() || p_node_type == get_class_name()) {
+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) {
const Color *color = data.color_override.getptr(p_name);
if (color) {
return *color;
}
}
- StringName type = p_node_type ? p_node_type : get_class_name();
-
- return get_colors(data.theme_owner, data.theme_owner_window, p_name, type);
-}
-
-Color Control::get_colors(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) {
- Color color;
-
- if (_find_theme_item(p_theme_owner, p_theme_owner_window, color, &Theme::get_color, &Theme::has_color, p_name, p_node_type)) {
- return color;
- }
-
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_color(p_name, p_node_type)) {
- return Theme::get_project_default()->get_color(p_name, p_node_type);
- }
- }
- return Theme::get_default()->get_color(p_name, p_node_type);
+ List<StringName> theme_types;
+ _get_theme_type_dependencies(p_theme_type, &theme_types);
+ return get_theme_item_in_types<Color>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types);
}
-int Control::get_theme_constant(const StringName &p_name, const StringName &p_node_type) const {
- if (p_node_type == StringName() || p_node_type == get_class_name()) {
+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) {
const int *constant = data.constant_override.getptr(p_name);
if (constant) {
return *constant;
}
}
- StringName type = p_node_type ? p_node_type : get_class_name();
-
- return get_constants(data.theme_owner, data.theme_owner_window, p_name, type);
-}
-
-int Control::get_constants(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) {
- int constant;
-
- if (_find_theme_item(p_theme_owner, p_theme_owner_window, constant, &Theme::get_constant, &Theme::has_constant, p_name, p_node_type)) {
- return constant;
- }
-
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_constant(p_name, p_node_type)) {
- return Theme::get_project_default()->get_constant(p_name, p_node_type);
- }
- }
- return Theme::get_default()->get_constant(p_name, p_node_type);
+ List<StringName> theme_types;
+ _get_theme_type_dependencies(p_theme_type, &theme_types);
+ return get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types);
}
bool Control::has_theme_icon_override(const StringName &p_name) const {
@@ -1056,154 +1001,76 @@ bool Control::has_theme_constant_override(const StringName &p_name) const {
return constant != nullptr;
}
-bool Control::has_theme_icon(const StringName &p_name, const StringName &p_node_type) const {
- if (p_node_type == StringName() || p_node_type == get_class_name()) {
+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 (has_theme_icon_override(p_name)) {
return true;
}
}
- StringName type = p_node_type ? p_node_type : get_class_name();
-
- return has_icons(data.theme_owner, data.theme_owner_window, p_name, type);
-}
-
-bool Control::has_icons(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) {
- if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_icon, p_name, p_node_type)) {
- return true;
- }
-
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_color(p_name, p_node_type)) {
- return true;
- }
- }
- return Theme::get_default()->has_icon(p_name, p_node_type);
+ List<StringName> theme_types;
+ _get_theme_type_dependencies(p_theme_type, &theme_types);
+ return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types);
}
-bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_node_type) const {
- if (p_node_type == StringName() || p_node_type == get_class_name()) {
+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 (has_theme_stylebox_override(p_name)) {
return true;
}
}
- StringName type = p_node_type ? p_node_type : get_class_name();
-
- return has_styleboxs(data.theme_owner, data.theme_owner_window, p_name, type);
+ List<StringName> theme_types;
+ _get_theme_type_dependencies(p_theme_type, &theme_types);
+ return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types);
}
-bool Control::has_styleboxs(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) {
- if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_stylebox, p_name, p_node_type)) {
- return true;
- }
-
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_stylebox(p_name, p_node_type)) {
- return true;
- }
- }
- return Theme::get_default()->has_stylebox(p_name, p_node_type);
-}
-
-bool Control::has_theme_font(const StringName &p_name, const StringName &p_node_type) const {
- if (p_node_type == StringName() || p_node_type == get_class_name()) {
+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 (has_theme_font_override(p_name)) {
return true;
}
}
- StringName type = p_node_type ? p_node_type : get_class_name();
-
- return has_fonts(data.theme_owner, data.theme_owner_window, p_name, type);
+ List<StringName> theme_types;
+ _get_theme_type_dependencies(p_theme_type, &theme_types);
+ return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types);
}
-bool Control::has_fonts(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) {
- if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_font, p_name, p_node_type)) {
- return true;
- }
-
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_font(p_name, p_node_type)) {
- return true;
- }
- }
- return Theme::get_default()->has_font(p_name, p_node_type);
-}
-
-bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_node_type) const {
- if (p_node_type == StringName() || p_node_type == get_class_name()) {
+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 (has_theme_font_size_override(p_name)) {
return true;
}
}
- StringName type = p_node_type ? p_node_type : get_class_name();
-
- return has_font_sizes(data.theme_owner, data.theme_owner_window, p_name, type);
+ List<StringName> theme_types;
+ _get_theme_type_dependencies(p_theme_type, &theme_types);
+ return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types);
}
-bool Control::has_font_sizes(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) {
- if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_font_size, p_name, p_node_type)) {
- return true;
- }
-
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_font_size(p_name, p_node_type)) {
- return true;
- }
- }
- return Theme::get_default()->has_font_size(p_name, p_node_type);
-}
-
-bool Control::has_theme_color(const StringName &p_name, const StringName &p_node_type) const {
- if (p_node_type == StringName() || p_node_type == get_class_name()) {
+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 (has_theme_color_override(p_name)) {
return true;
}
}
- StringName type = p_node_type ? p_node_type : get_class_name();
-
- return has_colors(data.theme_owner, data.theme_owner_window, p_name, type);
-}
-
-bool Control::has_colors(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) {
- if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_color, p_name, p_node_type)) {
- return true;
- }
-
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_color(p_name, p_node_type)) {
- return true;
- }
- }
- return Theme::get_default()->has_color(p_name, p_node_type);
+ List<StringName> theme_types;
+ _get_theme_type_dependencies(p_theme_type, &theme_types);
+ return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types);
}
-bool Control::has_theme_constant(const StringName &p_name, const StringName &p_node_type) const {
- if (p_node_type == StringName() || p_node_type == get_class_name()) {
+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 (has_theme_constant_override(p_name)) {
return true;
}
}
- StringName type = p_node_type ? p_node_type : get_class_name();
-
- return has_constants(data.theme_owner, data.theme_owner_window, p_name, p_node_type);
-}
-
-bool Control::has_constants(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_node_type) {
- if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_constant, p_name, p_node_type)) {
- return true;
- }
-
- if (Theme::get_project_default().is_valid()) {
- if (Theme::get_project_default()->has_constant(p_name, p_node_type)) {
- return true;
- }
- }
- return Theme::get_default()->has_constant(p_name, p_node_type);
+ List<StringName> theme_types;
+ _get_theme_type_dependencies(p_theme_type, &theme_types);
+ return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types);
}
Rect2 Control::get_parent_anchorable_rect() const {
@@ -1714,8 +1581,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 overriden after _ready(). \nIf you want to set size, change the anchors or consider using set_deferred().");
}
#endif
set_size(p_size);
@@ -1780,53 +1647,38 @@ Rect2 Control::get_anchorable_rect() const {
}
void Control::add_theme_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon) {
+ ERR_FAIL_COND(!p_icon.is_valid());
+
if (data.icon_override.has(p_name)) {
data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
}
- // clear if "null" is passed instead of an icon
- if (p_icon.is_null()) {
- data.icon_override.erase(p_name);
- } else {
- data.icon_override[p_name] = p_icon;
- if (data.icon_override[p_name].is_valid()) {
- data.icon_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED);
- }
- }
+ 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);
}
void Control::add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) {
+ ERR_FAIL_COND(!p_style.is_valid());
+
if (data.style_override.has(p_name)) {
data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
}
- // clear if "null" is passed instead of a style
- if (p_style.is_null()) {
- data.style_override.erase(p_name);
- } else {
- data.style_override[p_name] = p_style;
- if (data.style_override[p_name].is_valid()) {
- data.style_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED);
- }
- }
+ 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);
}
void Control::add_theme_font_override(const StringName &p_name, const Ref<Font> &p_font) {
+ ERR_FAIL_COND(!p_font.is_valid());
+
if (data.font_override.has(p_name)) {
data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
}
- // clear if "null" is passed instead of a font
- if (p_font.is_null()) {
- data.font_override.erase(p_name);
- } else {
- data.font_override[p_name] = p_font;
- if (data.font_override[p_name].is_valid()) {
- data.font_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED);
- }
- }
+ 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);
}
@@ -1845,6 +1697,48 @@ void Control::add_theme_constant_override(const StringName &p_name, int p_consta
notification(NOTIFICATION_THEME_CHANGED);
}
+void Control::remove_theme_icon_override(const StringName &p_name) {
+ if (data.icon_override.has(p_name)) {
+ data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
+ }
+
+ data.icon_override.erase(p_name);
+ notification(NOTIFICATION_THEME_CHANGED);
+}
+
+void Control::remove_theme_style_override(const StringName &p_name) {
+ if (data.style_override.has(p_name)) {
+ data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
+ }
+
+ data.style_override.erase(p_name);
+ notification(NOTIFICATION_THEME_CHANGED);
+}
+
+void Control::remove_theme_font_override(const StringName &p_name) {
+ if (data.font_override.has(p_name)) {
+ data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
+ }
+
+ data.font_override.erase(p_name);
+ notification(NOTIFICATION_THEME_CHANGED);
+}
+
+void Control::remove_theme_font_size_override(const StringName &p_name) {
+ data.font_size_override.erase(p_name);
+ notification(NOTIFICATION_THEME_CHANGED);
+}
+
+void Control::remove_theme_color_override(const StringName &p_name) {
+ data.color_override.erase(p_name);
+ notification(NOTIFICATION_THEME_CHANGED);
+}
+
+void Control::remove_theme_constant_override(const StringName &p_name) {
+ data.constant_override.erase(p_name);
+ notification(NOTIFICATION_THEME_CHANGED);
+}
+
void Control::set_focus_mode(FocusMode p_focus_mode) {
ERR_FAIL_INDEX((int)p_focus_mode, 3);
@@ -2149,19 +2043,22 @@ void Control::set_theme(const Ref<Theme> &p_theme) {
}
}
-void Control::accept_event() {
- if (is_inside_tree()) {
- get_viewport()->_gui_accept_event();
- }
-}
-
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;
+ _propagate_theme_changed(this, data.theme_owner, data.theme_owner_window);
+}
+
+StringName Control::get_theme_custom_type() const {
+ return data.theme_custom_type;
+}
+
void Control::set_tooltip(const String &p_tooltip) {
data.tooltip = p_tooltip;
- update_configuration_warning();
+ update_configuration_warnings();
}
String Control::get_tooltip(const Point2 &p_pos) const {
@@ -2446,7 +2343,7 @@ int Control::get_v_size_flags() const {
void Control::set_mouse_filter(MouseFilter p_filter) {
ERR_FAIL_INDEX(p_filter, 3);
data.mouse_filter = p_filter;
- update_configuration_warning();
+ update_configuration_warnings();
}
Control::MouseFilter Control::get_mouse_filter() const {
@@ -2477,9 +2374,9 @@ bool Control::is_text_field() const {
return false;
}
-Vector<Vector2i> Control::structured_text_parser(StructuredTextParser p_node_type, const Array &p_args, const String p_text) const {
+Vector<Vector2i> Control::structured_text_parser(StructuredTextParser p_theme_type, const Array &p_args, const String p_text) const {
Vector<Vector2i> ret;
- switch (p_node_type) {
+ switch (p_theme_type) {
case STRUCTURED_TEXT_URI: {
int prev = 0;
for (int i = 0; i < p_text.length(); i++) {
@@ -2666,15 +2563,15 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List
if (p_idx == 0) {
List<StringName> sn;
String pf = p_function;
- if (pf == "add_color_override" || pf == "has_color" || pf == "has_color_override" || pf == "get_color") {
+ if (pf == "add_theme_color_override" || pf == "has_theme_color" || pf == "has_theme_color_override" || pf == "get_theme_color") {
Theme::get_default()->get_color_list(get_class(), &sn);
- } else if (pf == "add_style_override" || pf == "has_style" || pf == "has_style_override" || pf == "get_style") {
+ } else if (pf == "add_theme_style_override" || pf == "has_theme_style" || pf == "has_theme_style_override" || pf == "get_theme_style") {
Theme::get_default()->get_stylebox_list(get_class(), &sn);
- } else if (pf == "add_font_override" || pf == "has_font" || pf == "has_font_override" || pf == "get_font") {
+ } else if (pf == "add_theme_font_override" || pf == "has_theme_font" || pf == "has_theme_font_override" || pf == "get_theme_font") {
Theme::get_default()->get_font_list(get_class(), &sn);
- } else if (pf == "add_font_size_override" || pf == "has_font_size" || pf == "has_font_size_override" || pf == "get_font_size") {
+ } else if (pf == "add_theme_font_size_override" || pf == "has_theme_font_size" || pf == "has_theme_font_size_override" || pf == "get_theme_font_size") {
Theme::get_default()->get_font_size_list(get_class(), &sn);
- } else if (pf == "add_constant_override" || pf == "has_constant" || pf == "has_constant_override" || pf == "get_constant") {
+ } else if (pf == "add_theme_constant_override" || pf == "has_theme_constant" || pf == "has_theme_constant_override" || pf == "get_theme_constant") {
Theme::get_default()->get_constant_list(get_class(), &sn);
}
@@ -2685,17 +2582,14 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List
}
}
-String Control::get_configuration_warning() const {
- String warning = CanvasItem::get_configuration_warning();
+TypedArray<String> Control::get_configuration_warnings() const {
+ TypedArray<String> warnings = Node::get_configuration_warnings();
if (data.mouse_filter == MOUSE_FILTER_IGNORE && data.tooltip != "") {
- if (!warning.is_empty()) {
- warning += "\n\n";
- }
- warning += TTR("The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\".");
+ warnings.push_back(TTR("The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."));
}
- return warning;
+ return warnings;
}
void Control::set_clip_contents(bool p_clip) {
@@ -2792,6 +2686,9 @@ 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("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);
ClassDB::bind_method(D_METHOD("add_theme_font_override", "name", "font"), &Control::add_theme_font_override);
@@ -2799,12 +2696,19 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_theme_color_override", "name", "color"), &Control::add_theme_color_override);
ClassDB::bind_method(D_METHOD("add_theme_constant_override", "name", "constant"), &Control::add_theme_constant_override);
- ClassDB::bind_method(D_METHOD("get_theme_icon", "name", "node_type"), &Control::get_theme_icon, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("get_theme_stylebox", "name", "node_type"), &Control::get_theme_stylebox, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("get_theme_font", "name", "node_type"), &Control::get_theme_font, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("get_theme_font_size", "name", "node_type"), &Control::get_theme_font_size, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("get_theme_color", "name", "node_type"), &Control::get_theme_color, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("get_theme_constant", "name", "node_type"), &Control::get_theme_constant, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("remove_theme_icon_override", "name"), &Control::remove_theme_icon_override);
+ ClassDB::bind_method(D_METHOD("remove_theme_stylebox_override", "name"), &Control::remove_theme_style_override);
+ ClassDB::bind_method(D_METHOD("remove_theme_font_override", "name"), &Control::remove_theme_font_override);
+ ClassDB::bind_method(D_METHOD("remove_theme_font_size_override", "name"), &Control::remove_theme_font_size_override);
+ ClassDB::bind_method(D_METHOD("remove_theme_color_override", "name"), &Control::remove_theme_color_override);
+ ClassDB::bind_method(D_METHOD("remove_theme_constant_override", "name"), &Control::remove_theme_constant_override);
+
+ ClassDB::bind_method(D_METHOD("get_theme_icon", "name", "theme_type"), &Control::get_theme_icon, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("get_theme_stylebox", "name", "theme_type"), &Control::get_theme_stylebox, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("get_theme_font", "name", "theme_type"), &Control::get_theme_font, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("get_theme_font_size", "name", "theme_type"), &Control::get_theme_font_size, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("get_theme_color", "name", "theme_type"), &Control::get_theme_color, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("get_theme_constant", "name", "theme_type"), &Control::get_theme_constant, DEFVAL(""));
ClassDB::bind_method(D_METHOD("has_theme_icon_override", "name"), &Control::has_theme_icon_override);
ClassDB::bind_method(D_METHOD("has_theme_stylebox_override", "name"), &Control::has_theme_stylebox_override);
@@ -2813,12 +2717,12 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_theme_color_override", "name"), &Control::has_theme_color_override);
ClassDB::bind_method(D_METHOD("has_theme_constant_override", "name"), &Control::has_theme_constant_override);
- ClassDB::bind_method(D_METHOD("has_theme_icon", "name", "node_type"), &Control::has_theme_icon, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("has_theme_stylebox", "name", "node_type"), &Control::has_theme_stylebox, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("has_theme_font", "name", "node_type"), &Control::has_theme_font, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("has_theme_font_size", "name", "node_type"), &Control::has_theme_font_size, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("has_theme_color", "name", "node_type"), &Control::has_theme_color, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("has_theme_constant", "name", "node_type"), &Control::has_theme_constant, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("has_theme_icon", "name", "theme_type"), &Control::has_theme_icon, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("has_theme_stylebox", "name", "theme_type"), &Control::has_theme_stylebox, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("has_theme_font", "name", "theme_type"), &Control::has_theme_font, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("has_theme_font_size", "name", "theme_type"), &Control::has_theme_font_size, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("has_theme_color", "name", "theme_type"), &Control::has_theme_color, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("has_theme_constant", "name", "theme_type"), &Control::has_theme_constant, DEFVAL(""));
ClassDB::bind_method(D_METHOD("get_parent_control"), &Control::get_parent_control);
@@ -2899,7 +2803,7 @@ void Control::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "grow_vertical", PROPERTY_HINT_ENUM, "Begin,End,Both"), "set_v_grow_direction", "get_v_grow_direction");
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_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("Rect", "rect_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_position", "get_position");
@@ -2926,14 +2830,15 @@ void Control::_bind_methods() {
ADD_GROUP("Mouse", "mouse_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_filter", PROPERTY_HINT_ENUM, "Stop,Pass,Ignore"), "set_mouse_filter", "get_mouse_filter");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_default_cursor_shape", PROPERTY_HINT_ENUM, "Arrow,Ibeam,Pointing hand,Cross,Wait,Busy,Drag,Can drop,Forbidden,Vertical resize,Horizontal resize,Secondary diagonal resize,Main diagonal resize,Move,Vertical split,Horizontal split,Help"), "set_default_cursor_shape", "get_default_cursor_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_default_cursor_shape", PROPERTY_HINT_ENUM, "Arrow,I-Beam,Pointing Hand,Cross,Wait,Busy,Drag,Can Drop,Forbidden,Vertical Resize,Horizontal Resize,Secondary Diagonal Resize,Main Diagonal Resize,Move,Vertical Split,Horizontal Split,Help"), "set_default_cursor_shape", "get_default_cursor_shape");
ADD_GROUP("Size Flags", "size_flags_");
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", "");
+ 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("", "");
BIND_ENUM_CONSTANT(FOCUS_NONE);