diff options
Diffstat (limited to 'scene/gui')
-rw-r--r-- | scene/gui/code_edit.cpp | 6 | ||||
-rw-r--r-- | scene/gui/control.cpp | 80 | ||||
-rw-r--r-- | scene/gui/control.h | 2 | ||||
-rw-r--r-- | scene/gui/file_dialog.cpp | 2 | ||||
-rw-r--r-- | scene/gui/graph_edit.cpp | 10 | ||||
-rw-r--r-- | scene/gui/menu_button.cpp | 45 | ||||
-rw-r--r-- | scene/gui/menu_button.h | 2 | ||||
-rw-r--r-- | scene/gui/popup_menu.cpp | 4 |
8 files changed, 94 insertions, 57 deletions
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 6e3d0e2767..be5e0bf4e5 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -2128,7 +2128,7 @@ int CodeEdit::_is_in_delimiter(int p_line, int p_column, DelimiterType p_type) c int region = (p_line <= 0 || delimiter_cache[p_line - 1].size() < 1) ? -1 : delimiter_cache[p_line - 1].back()->value(); bool in_region = region != -1 && delimiters[region].type == p_type; for (Map<int, int>::Element *E = delimiter_cache[p_line].front(); E; E = E->next()) { - /* If column is specified, loop untill the key is larger then the column. */ + /* If column is specified, loop until the key is larger then the column. */ if (p_column != -1) { if (E->key() > p_column) { break; @@ -2138,7 +2138,7 @@ int CodeEdit::_is_in_delimiter(int p_line, int p_column, DelimiterType p_type) c continue; } - /* If no column, calulate if the entire line is a region */ + /* If no column, calculate if the entire line is a region */ /* excluding whitespace. */ const String line = get_line(p_line); if (!in_region) { @@ -2288,7 +2288,7 @@ void CodeEdit::_filter_code_completion_candidates() { TypedArray<Dictionary> completion_options_sources; completion_options_sources.resize(code_completion_option_sources.size()); int i = 0; - for (ScriptCodeCompletionOption &E : code_completion_option_sources) { + for (const ScriptCodeCompletionOption &E : code_completion_option_sources) { Dictionary option; option["kind"] = E.kind; option["display_text"] = E.display; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index ae1f4b2f65..c19ee849d3 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -343,7 +343,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const { { List<StringName> names; theme->get_icon_list(get_class_name(), &names); - for (StringName &E : names) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; if (data.icon_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; @@ -355,7 +355,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const { { List<StringName> names; theme->get_stylebox_list(get_class_name(), &names); - for (StringName &E : names) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; if (data.style_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; @@ -367,7 +367,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const { { List<StringName> names; theme->get_font_list(get_class_name(), &names); - for (StringName &E : names) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; if (data.font_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; @@ -379,7 +379,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const { { List<StringName> names; theme->get_font_size_list(get_class_name(), &names); - for (StringName &E : names) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; if (data.font_size_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; @@ -391,7 +391,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const { { List<StringName> names; theme->get_color_list(get_class_name(), &names); - for (StringName &E : names) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; if (data.color_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; @@ -403,7 +403,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const { { List<StringName> names; theme->get_constant_list(get_class_name(), &names); - for (StringName &E : names) { + for (const StringName &E : names) { uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; if (data.constant_override.has(E)) { usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; @@ -428,7 +428,7 @@ void Control::_validate_property(PropertyInfo &property) const { Vector<StringName> unique_names; String hint_string; - for (StringName &E : names) { + for (const StringName &E : names) { // Skip duplicate values. if (unique_names.has(E)) { continue; @@ -454,6 +454,8 @@ 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); } @@ -462,29 +464,35 @@ Control::LayoutDirection Control::get_layout_direction() const { } bool Control::is_layout_rtl() const { - if (data.layout_dir == LAYOUT_DIRECTION_INHERITED) { - Window *parent_window = get_parent_window(); - 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 (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); + } + } + } else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) { if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { - return true; + 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(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { - return true; + } 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::_clear_size_warning() { @@ -534,6 +542,7 @@ 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: { @@ -548,6 +557,7 @@ void Control::_notification(int p_notification) { 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; @@ -613,6 +623,7 @@ 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: { @@ -672,6 +683,7 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_TRANSLATION_CHANGED: case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { + data.is_rtl_dirty = true; _size_changed(); } break; } @@ -793,7 +805,7 @@ 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 (StringName &E : p_theme_types) { + 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); } @@ -822,7 +834,7 @@ 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 (StringName &E : p_theme_types) { + 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); } @@ -830,7 +842,7 @@ T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner } // Lastly, fall back on the items defined in the default Theme, if they exist. - for (StringName &E : p_theme_types) { + 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); } @@ -848,7 +860,7 @@ 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 (StringName &E : p_theme_types) { + 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; } @@ -877,7 +889,7 @@ 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 (StringName &E : p_theme_types) { + for (const StringName &E : p_theme_types) { if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { return true; } @@ -885,7 +897,7 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow } // Lastly, fall back on the items defined in the default Theme, if they exist. - for (StringName &E : p_theme_types) { + for (const StringName &E : p_theme_types) { if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { return true; } @@ -1594,7 +1606,7 @@ void Control::set_rect(const Rect2 &p_rect) { void Control::_set_size(const Size2 &p_size) { #ifdef DEBUG_ENABLED 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()."); + 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); @@ -2580,7 +2592,7 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List } sn.sort_custom<StringName::AlphCompare>(); - for (StringName &E : sn) { + for (const StringName &E : sn) { r_options->push_back(quote_style + E + quote_style); } } diff --git a/scene/gui/control.h b/scene/gui/control.h index 51b454b334..3779f9b308 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -179,6 +179,8 @@ private: GrowDirection v_grow = GROW_DIRECTION_END; LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED; + bool is_rtl_dirty = true; + bool is_rtl = false; real_t rotation = 0.0; Vector2 scale = Vector2(1, 1); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 67cb6f04a7..2e4204e171 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -552,7 +552,7 @@ void FileDialog::update_file_list() { bool match = patterns.is_empty(); String match_str; - for (String &E : patterns) { + for (const String &E : patterns) { if (files.front()->get().matchn(E)) { match_str = E; match = true; diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 8ad4d04b7f..1fac2b9129 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -217,7 +217,7 @@ Error GraphEdit::connect_node(const StringName &p_from, int p_from_port, const S } bool GraphEdit::is_node_connected(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port) { - for (Connection &E : connections) { + for (const Connection &E : connections) { if (E.from == p_from && E.from_port == p_from_port && E.to == p_to && E.to_port == p_to_port) { return true; } @@ -561,7 +561,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { if (is_in_hot_zone(pos / zoom, click_pos)) { if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) { //check disconnect - for (Connection &E : connections) { + for (const Connection &E : connections) { if (E.from == gn->get_name() && E.from_port == j) { Node *to = get_node(String(E.to)); if (Object::cast_to<GraphNode>(to)) { @@ -603,7 +603,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { if (is_in_hot_zone(pos / zoom, click_pos)) { if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) { //check disconnect - for (Connection &E : connections) { + for (const Connection &E : connections) { if (E.to == gn->get_name() && E.to_port == j) { Node *fr = get_node(String(E.from)); if (Object::cast_to<GraphNode>(fr)) { @@ -1001,7 +1001,7 @@ void GraphEdit::_minimap_draw() { // Draw node connections. Color activity_color = get_theme_color(SNAME("activity")); - for (Connection &E : connections) { + for (const Connection &E : connections) { NodePath fromnp(E.from); Node *from = get_node(fromnp); @@ -1500,7 +1500,7 @@ Array GraphEdit::_get_connection_list() const { List<Connection> conns; get_connection_list(&conns); Array arr; - for (Connection &E : conns) { + for (const Connection &E : conns) { Dictionary d; d["from"] = E.from; d["from_port"] = E.from_port; diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 73034dee5a..cf1f41d0fc 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -57,7 +57,32 @@ void MenuButton::_unhandled_key_input(Ref<InputEvent> p_event) { void MenuButton::_popup_visibility_changed(bool p_visible) { set_pressed(p_visible); - set_process_internal(p_visible); + + if (!p_visible) { + set_process_internal(false); + return; + } + + if (switch_on_hover) { + Window *window = Object::cast_to<Window>(get_viewport()); + if (window) { + mouse_pos_adjusted = window->get_position(); + + if (window->is_embedded()) { + Window *window_parent = Object::cast_to<Window>(window->get_parent()->get_viewport()); + while (window_parent) { + if (!window_parent->is_embedded()) { + mouse_pos_adjusted += window_parent->get_position(); + break; + } + + window_parent = Object::cast_to<Window>(window_parent->get_parent()->get_viewport()); + } + } + + set_process_internal(true); + } + } } void MenuButton::pressed() { @@ -106,17 +131,13 @@ void MenuButton::_notification(int p_what) { } } break; case NOTIFICATION_INTERNAL_PROCESS: { - if (switch_on_hover) { - Window *window = Object::cast_to<Window>(get_viewport()); - if (window) { - Vector2i mouse_pos = DisplayServer::get_singleton()->mouse_get_position() - window->get_position(); - MenuButton *menu_btn_other = Object::cast_to<MenuButton>(window->gui_find_control(mouse_pos)); - if (menu_btn_other && menu_btn_other != this && menu_btn_other->is_switch_on_hover() && !menu_btn_other->is_disabled() && - (get_parent()->is_ancestor_of(menu_btn_other) || menu_btn_other->get_parent()->is_ancestor_of(popup))) { - popup->hide(); - menu_btn_other->pressed(); - } - } + Vector2i mouse_pos = DisplayServer::get_singleton()->mouse_get_position() - mouse_pos_adjusted; + MenuButton *menu_btn_other = Object::cast_to<MenuButton>(get_viewport()->gui_find_control(mouse_pos)); + + if (menu_btn_other && menu_btn_other != this && menu_btn_other->is_switch_on_hover() && !menu_btn_other->is_disabled() && + (get_parent()->is_ancestor_of(menu_btn_other) || menu_btn_other->get_parent()->is_ancestor_of(popup))) { + popup->hide(); + menu_btn_other->pressed(); } } break; } diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h index 301769b008..cc2ca117c4 100644 --- a/scene/gui/menu_button.h +++ b/scene/gui/menu_button.h @@ -42,6 +42,8 @@ class MenuButton : public Button { bool disable_shortcuts = false; PopupMenu *popup; + Vector2i mouse_pos_adjusted; + Array _get_items() const; void _set_items(const Array &p_items); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index ae3db4a983..7790a0970c 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -397,7 +397,7 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> m = p_event; if (m.is_valid()) { - for (Rect2 &E : autohide_areas) { + for (const Rect2 &E : autohide_areas) { if (!Rect2(Point2(), get_size()).has_point(m->get_position()) && E.has_point(m->get_position())) { _close_pressed(); return; @@ -751,7 +751,7 @@ void PopupMenu::_notification(int p_what) { Point2 mouse_pos = DisplayServer::get_singleton()->mouse_get_position(); mouse_pos -= get_position(); - for (Rect2 &E : autohide_areas) { + for (const Rect2 &E : autohide_areas) { if (!Rect2(Point2(), get_size()).has_point(mouse_pos) && E.has_point(mouse_pos)) { _close_pressed(); return; |