summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/code_edit.cpp6
-rw-r--r--scene/gui/control.cpp80
-rw-r--r--scene/gui/control.h2
-rw-r--r--scene/gui/file_dialog.cpp2
-rw-r--r--scene/gui/graph_edit.cpp10
-rw-r--r--scene/gui/menu_button.cpp45
-rw-r--r--scene/gui/menu_button.h2
-rw-r--r--scene/gui/popup_menu.cpp4
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;