summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/aspect_ratio_container.cpp12
-rw-r--r--scene/gui/base_button.cpp10
-rw-r--r--scene/gui/base_button.h4
-rw-r--r--scene/gui/box_container.cpp3
-rw-r--r--scene/gui/button.cpp10
-rw-r--r--scene/gui/check_box.cpp2
-rw-r--r--scene/gui/check_button.cpp2
-rw-r--r--scene/gui/code_edit.cpp14
-rw-r--r--scene/gui/code_edit.h8
-rw-r--r--scene/gui/color_picker.cpp18
-rw-r--r--scene/gui/color_rect.cpp3
-rw-r--r--scene/gui/control.cpp70
-rw-r--r--scene/gui/control.h5
-rw-r--r--scene/gui/dialogs.cpp3
-rw-r--r--scene/gui/file_dialog.cpp14
-rw-r--r--scene/gui/graph_edit.cpp19
-rw-r--r--scene/gui/graph_edit.h2
-rw-r--r--scene/gui/graph_node.cpp52
-rw-r--r--scene/gui/graph_node.h2
-rw-r--r--scene/gui/grid_container.cpp5
-rw-r--r--scene/gui/item_list.cpp79
-rw-r--r--scene/gui/label.cpp55
-rw-r--r--scene/gui/line_edit.cpp36
-rw-r--r--scene/gui/link_button.cpp4
-rw-r--r--scene/gui/menu_button.cpp9
-rw-r--r--scene/gui/nine_patch_rect.cpp17
-rw-r--r--scene/gui/option_button.cpp5
-rw-r--r--scene/gui/popup_menu.cpp86
-rw-r--r--scene/gui/range.cpp20
-rw-r--r--scene/gui/reference_rect.cpp15
-rw-r--r--scene/gui/rich_text_label.cpp62
-rw-r--r--scene/gui/rich_text_label.h4
-rw-r--r--scene/gui/slider.cpp12
-rw-r--r--scene/gui/spin_box.cpp8
-rw-r--r--scene/gui/split_container.cpp12
-rw-r--r--scene/gui/split_container.h1
-rw-r--r--scene/gui/subviewport_container.cpp4
-rw-r--r--scene/gui/tab_bar.cpp40
-rw-r--r--scene/gui/tab_container.cpp30
-rw-r--r--scene/gui/text_edit.cpp115
-rw-r--r--scene/gui/text_edit.h3
-rw-r--r--scene/gui/texture_button.cpp35
-rw-r--r--scene/gui/texture_progress_bar.cpp59
-rw-r--r--scene/gui/texture_rect.cpp16
-rw-r--r--scene/gui/tree.cpp224
-rw-r--r--scene/gui/tree.h9
-rw-r--r--scene/gui/video_stream_player.cpp8
47 files changed, 1115 insertions, 111 deletions
diff --git a/scene/gui/aspect_ratio_container.cpp b/scene/gui/aspect_ratio_container.cpp
index 75f19ac452..e4a79c7aa3 100644
--- a/scene/gui/aspect_ratio_container.cpp
+++ b/scene/gui/aspect_ratio_container.cpp
@@ -51,21 +51,33 @@ Size2 AspectRatioContainer::get_minimum_size() const {
}
void AspectRatioContainer::set_ratio(float p_ratio) {
+ if (ratio == p_ratio) {
+ return;
+ }
ratio = p_ratio;
queue_sort();
}
void AspectRatioContainer::set_stretch_mode(StretchMode p_mode) {
+ if (stretch_mode == p_mode) {
+ return;
+ }
stretch_mode = p_mode;
queue_sort();
}
void AspectRatioContainer::set_alignment_horizontal(AlignmentMode p_alignment_horizontal) {
+ if (alignment_horizontal == p_alignment_horizontal) {
+ return;
+ }
alignment_horizontal = p_alignment_horizontal;
queue_sort();
}
void AspectRatioContainer::set_alignment_vertical(AlignmentMode p_alignment_vertical) {
+ if (alignment_vertical == p_alignment_vertical) {
+ return;
+ }
alignment_vertical = p_alignment_vertical;
queue_sort();
}
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 776623f7ce..87a7355bb2 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -64,6 +64,8 @@ void BaseButton::gui_input(const Ref<InputEvent> &p_event) {
bool button_masked = mouse_button.is_valid() && (mouse_button_to_mask(mouse_button->get_button_index()) & button_mask) != MouseButton::NONE;
if (button_masked || ui_accept) {
+ was_mouse_pressed = button_masked;
+
on_action_event(p_event);
return;
}
@@ -417,6 +419,10 @@ bool BaseButton::_is_focus_owner_in_shortcut_context() const {
return ctx_node && vp_focus && (ctx_node == vp_focus || ctx_node->is_ancestor_of(vp_focus));
}
+bool BaseButton::_was_pressed_by_mouse() const {
+ return was_mouse_pressed;
+}
+
void BaseButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &BaseButton::set_pressed);
ClassDB::bind_method(D_METHOD("is_pressed"), &BaseButton::is_pressed);
@@ -490,8 +496,8 @@ void ButtonGroup::get_buttons(List<BaseButton *> *r_buttons) {
}
}
-Array ButtonGroup::_get_buttons() {
- Array btns;
+TypedArray<BaseButton> ButtonGroup::_get_buttons() {
+ TypedArray<BaseButton> btns;
for (const BaseButton *E : buttons) {
btns.push_back(E);
}
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index 7cf8de6432..c83b08aadf 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -49,6 +49,7 @@ private:
MouseButton button_mask = MouseButton::MASK_LEFT;
bool toggle_mode = false;
bool shortcut_in_tooltip = true;
+ bool was_mouse_pressed = false;
bool keep_pressed_outside = false;
Ref<Shortcut> shortcut;
ObjectID shortcut_context;
@@ -81,6 +82,7 @@ protected:
void _notification(int p_what);
bool _is_focus_owner_in_shortcut_context() const;
+ bool _was_pressed_by_mouse() const;
GDVIRTUAL0(_pressed)
GDVIRTUAL1(_toggled, bool)
@@ -151,7 +153,7 @@ protected:
public:
BaseButton *get_pressed_button();
void get_buttons(List<BaseButton *> *r_buttons);
- Array _get_buttons();
+ TypedArray<BaseButton> _get_buttons();
ButtonGroup();
};
diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp
index df695feba8..a56a51a547 100644
--- a/scene/gui/box_container.cpp
+++ b/scene/gui/box_container.cpp
@@ -308,6 +308,9 @@ void BoxContainer::_notification(int p_what) {
}
void BoxContainer::set_alignment(AlignmentMode p_alignment) {
+ if (alignment == p_alignment) {
+ return;
+ }
alignment = p_alignment;
_resort();
}
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 0a163b65ff..e163f4355c 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -34,11 +34,9 @@
#include "servers/rendering_server.h"
Size2 Button::get_minimum_size() const {
- Ref<Texture2D> _icon;
- if (icon.is_null() && has_theme_icon(SNAME("icon"))) {
+ Ref<Texture2D> _icon = icon;
+ if (_icon.is_null() && has_theme_icon(SNAME("icon"))) {
_icon = Control::get_theme_icon(SNAME("icon"));
- } else {
- _icon = icon;
}
return get_minimum_size_for_text_and_icon("", _icon);
@@ -342,13 +340,13 @@ Size2 Button::get_minimum_size_for_text_and_icon(const String &p_text, Ref<Textu
minsize.width = 0;
}
- if (!expand_icon && !p_icon.is_null()) {
+ if (!expand_icon && p_icon.is_valid()) {
minsize.height = MAX(minsize.height, p_icon->get_height());
if (icon_alignment != HORIZONTAL_ALIGNMENT_CENTER) {
minsize.width += p_icon->get_width();
if (!xl_text.is_empty() || !p_text.is_empty()) {
- minsize.width += get_theme_constant(SNAME("hseparation"));
+ minsize.width += MAX(0, get_theme_constant(SNAME("h_separation")));
}
} else {
minsize.width = MAX(minsize.width, p_icon->get_width());
diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp
index cb80f5b5ef..26edc1f1b0 100644
--- a/scene/gui/check_box.cpp
+++ b/scene/gui/check_box.cpp
@@ -75,7 +75,7 @@ Size2 CheckBox::get_minimum_size() const {
Size2 tex_size = get_icon_size();
minsize.width += tex_size.width;
if (get_text().length() > 0) {
- minsize.width += get_theme_constant(SNAME("h_separation"));
+ minsize.width += MAX(0, get_theme_constant(SNAME("h_separation")));
}
Ref<StyleBox> sb = get_theme_stylebox(SNAME("normal"));
minsize.height = MAX(minsize.height, tex_size.height + sb->get_margin(SIDE_TOP) + sb->get_margin(SIDE_BOTTOM));
diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp
index a09873ea4f..b9674ca41e 100644
--- a/scene/gui/check_button.cpp
+++ b/scene/gui/check_button.cpp
@@ -52,7 +52,7 @@ Size2 CheckButton::get_minimum_size() const {
Size2 tex_size = get_icon_size();
minsize.width += tex_size.width;
if (get_text().length() > 0) {
- minsize.width += get_theme_constant(SNAME("h_separation"));
+ minsize.width += MAX(0, get_theme_constant(SNAME("h_separation")));
}
Ref<StyleBox> sb = get_theme_stylebox(SNAME("normal"));
minsize.height = MAX(minsize.height, tex_size.height + sb->get_margin(SIDE_TOP) + sb->get_margin(SIDE_BOTTOM));
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 8968c1cc17..e54ba7ce13 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -1280,8 +1280,8 @@ void CodeEdit::clear_breakpointed_lines() {
}
}
-Array CodeEdit::get_breakpointed_lines() const {
- Array ret;
+PackedInt32Array CodeEdit::get_breakpointed_lines() const {
+ PackedInt32Array ret;
for (int i = 0; i < get_line_count(); i++) {
if (is_line_breakpointed(i)) {
ret.append(i);
@@ -1309,8 +1309,8 @@ void CodeEdit::clear_bookmarked_lines() {
}
}
-Array CodeEdit::get_bookmarked_lines() const {
- Array ret;
+PackedInt32Array CodeEdit::get_bookmarked_lines() const {
+ PackedInt32Array ret;
for (int i = 0; i < get_line_count(); i++) {
if (is_line_bookmarked(i)) {
ret.append(i);
@@ -1338,8 +1338,8 @@ void CodeEdit::clear_executing_lines() {
}
}
-Array CodeEdit::get_executing_lines() const {
- Array ret;
+PackedInt32Array CodeEdit::get_executing_lines() const {
+ PackedInt32Array ret;
for (int i = 0; i < get_line_count(); i++) {
if (is_line_executing(i)) {
ret.append(i);
@@ -2769,7 +2769,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
i++;
}
- Array completion_options;
+ TypedArray<Dictionary> completion_options;
GDVIRTUAL_CALL(_filter_code_completion_candidates, completion_options_sources, completion_options);
diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h
index 08bd91a368..2065f3e681 100644
--- a/scene/gui/code_edit.h
+++ b/scene/gui/code_edit.h
@@ -266,7 +266,7 @@ protected:
GDVIRTUAL1(_confirm_code_completion, bool)
GDVIRTUAL1(_request_code_completion, bool)
- GDVIRTUAL1RC(Array, _filter_code_completion_candidates, TypedArray<Dictionary>)
+ GDVIRTUAL1RC(TypedArray<Dictionary>, _filter_code_completion_candidates, TypedArray<Dictionary>)
public:
/* General overrides */
@@ -322,19 +322,19 @@ public:
void set_line_as_breakpoint(int p_line, bool p_breakpointed);
bool is_line_breakpointed(int p_line) const;
void clear_breakpointed_lines();
- Array get_breakpointed_lines() const;
+ PackedInt32Array get_breakpointed_lines() const;
// bookmarks
void set_line_as_bookmarked(int p_line, bool p_bookmarked);
bool is_line_bookmarked(int p_line) const;
void clear_bookmarked_lines();
- Array get_bookmarked_lines() const;
+ PackedInt32Array get_bookmarked_lines() const;
// executing lines
void set_line_as_executing(int p_line, bool p_executing);
bool is_line_executing(int p_line) const;
void clear_executing_lines();
- Array get_executing_lines() const;
+ PackedInt32Array get_executing_lines() const;
/* Line numbers */
void set_draw_line_numbers(bool p_draw);
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 8cbe14c492..9eef45f412 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -292,6 +292,9 @@ bool ColorPicker::is_displaying_old_color() const {
}
void ColorPicker::set_edit_alpha(bool p_show) {
+ if (edit_alpha == p_show) {
+ return;
+ }
edit_alpha = p_show;
_update_controls();
@@ -509,6 +512,9 @@ Color ColorPicker::get_pick_color() const {
void ColorPicker::set_picker_shape(PickerShapeType p_shape) {
ERR_FAIL_INDEX(p_shape, SHAPE_MAX);
+ if (current_shape == p_shape) {
+ return;
+ }
current_shape = p_shape;
_copy_color_to_hsv();
@@ -1131,6 +1137,9 @@ void ColorPicker::_html_focus_exit() {
}
void ColorPicker::set_presets_enabled(bool p_enabled) {
+ if (presets_enabled == p_enabled) {
+ return;
+ }
presets_enabled = p_enabled;
if (!p_enabled) {
btn_add_preset->set_disabled(true);
@@ -1146,6 +1155,9 @@ bool ColorPicker::are_presets_enabled() const {
}
void ColorPicker::set_presets_visible(bool p_visible) {
+ if (presets_visible == p_visible) {
+ return;
+ }
presets_visible = p_visible;
preset_separator->set_visible(p_visible);
preset_container->set_visible(p_visible);
@@ -1419,6 +1431,9 @@ void ColorPickerButton::_notification(int p_what) {
}
void ColorPickerButton::set_pick_color(const Color &p_color) {
+ if (color == p_color) {
+ return;
+ }
color = p_color;
if (picker) {
picker->set_pick_color(p_color);
@@ -1432,6 +1447,9 @@ Color ColorPickerButton::get_pick_color() const {
}
void ColorPickerButton::set_edit_alpha(bool p_show) {
+ if (edit_alpha == p_show) {
+ return;
+ }
edit_alpha = p_show;
if (picker) {
picker->set_edit_alpha(p_show);
diff --git a/scene/gui/color_rect.cpp b/scene/gui/color_rect.cpp
index 2955f74a0c..c30fa8461a 100644
--- a/scene/gui/color_rect.cpp
+++ b/scene/gui/color_rect.cpp
@@ -31,6 +31,9 @@
#include "color_rect.h"
void ColorRect::set_color(const Color &p_color) {
+ if (color == p_color) {
+ return;
+ }
color = p_color;
update();
}
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 545c39a605..03fcef17f5 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -723,6 +723,9 @@ real_t Control::get_anchor(Side p_side) const {
void Control::set_offset(Side p_side, real_t p_value) {
ERR_FAIL_INDEX((int)p_side, 4);
+ if (data.offset[p_side] == p_value) {
+ return;
+ }
data.offset[p_side] = p_value;
_size_changed();
@@ -740,6 +743,10 @@ void Control::set_anchor_and_offset(Side p_side, real_t p_anchor, real_t p_pos,
}
void Control::set_begin(const Size2 &p_point) {
+ if (data.offset[0] == p_point.x && data.offset[1] == p_point.y) {
+ return;
+ }
+
data.offset[0] = p_point.x;
data.offset[1] = p_point.y;
_size_changed();
@@ -750,6 +757,10 @@ Size2 Control::get_begin() const {
}
void Control::set_end(const Size2 &p_point) {
+ if (data.offset[2] == p_point.x && data.offset[3] == p_point.y) {
+ return;
+ }
+
data.offset[2] = p_point.x;
data.offset[3] = p_point.y;
_size_changed();
@@ -760,6 +771,10 @@ Size2 Control::get_end() const {
}
void Control::set_h_grow_direction(GrowDirection p_direction) {
+ if (data.h_grow == p_direction) {
+ return;
+ }
+
ERR_FAIL_INDEX((int)p_direction, 3);
data.h_grow = p_direction;
@@ -771,6 +786,10 @@ Control::GrowDirection Control::get_h_grow_direction() const {
}
void Control::set_v_grow_direction(GrowDirection p_direction) {
+ if (data.v_grow == p_direction) {
+ return;
+ }
+
ERR_FAIL_INDEX((int)p_direction, 3);
data.v_grow = p_direction;
@@ -1427,6 +1446,10 @@ Rect2 Control::get_anchorable_rect() const {
}
void Control::set_scale(const Vector2 &p_scale) {
+ if (data.scale == p_scale) {
+ return;
+ }
+
data.scale = p_scale;
// Avoid having 0 scale values, can lead to errors in physics and rendering.
if (data.scale.x == 0) {
@@ -1444,6 +1467,10 @@ Vector2 Control::get_scale() const {
}
void Control::set_rotation(real_t p_radians) {
+ if (data.rotation == p_radians) {
+ return;
+ }
+
data.rotation = p_radians;
update();
_notify_transform();
@@ -1454,6 +1481,10 @@ real_t Control::get_rotation() const {
}
void Control::set_pivot_offset(const Vector2 &p_pivot) {
+ if (data.pivot_offset == p_pivot) {
+ return;
+ }
+
data.pivot_offset = p_pivot;
update();
_notify_transform();
@@ -2204,6 +2235,9 @@ Control::CursorShape Control::get_cursor_shape(const Point2 &p_pos) const {
}
void Control::set_disable_visibility_clip(bool p_ignore) {
+ if (data.disable_visibility_clip == p_ignore) {
+ return;
+ }
data.disable_visibility_clip = p_ignore;
update();
}
@@ -2213,6 +2247,9 @@ bool Control::is_visibility_clip_disabled() const {
}
void Control::set_clip_contents(bool p_clip) {
+ if (data.clip_contents == p_clip) {
+ return;
+ }
data.clip_contents = p_clip;
update();
}
@@ -2331,6 +2368,9 @@ Ref<Theme> Control::get_theme() const {
}
void Control::set_theme_type_variation(const StringName &p_theme_type) {
+ if (data.theme_type_variation == p_theme_type) {
+ return;
+ }
data.theme_type_variation = p_theme_type;
_propagate_theme_changed(this, data.theme_owner, data.theme_owner_window);
}
@@ -2946,13 +2986,13 @@ void Control::end_bulk_theme_override() {
// Internationalization.
-Array Control::structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const {
+TypedArray<Vector2i> Control::structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const {
if (p_parser_type == TextServer::STRUCTURED_TEXT_CUSTOM) {
- Array ret;
+ TypedArray<Vector2i> ret;
if (GDVIRTUAL_CALL(_structured_text_parser, p_args, p_text, ret)) {
return ret;
} else {
- return Array();
+ return TypedArray<Vector2i>();
}
} else {
return TS->parse_structured_text(p_parser_type, p_args, p_text);
@@ -2960,6 +3000,9 @@ Array Control::structured_text_parser(TextServer::StructuredTextParser p_parser_
}
void Control::set_layout_direction(Control::LayoutDirection p_direction) {
+ if (data.layout_dir == p_direction) {
+ return;
+ }
ERR_FAIL_INDEX((int)p_direction, 4);
data.layout_dir = p_direction;
@@ -3579,3 +3622,24 @@ void Control::_bind_methods() {
GDVIRTUAL_BIND(_gui_input, "event");
}
+
+Control::~Control() {
+ // Resources need to be disconnected.
+ for (KeyValue<StringName, Ref<Texture2D>> &E : data.icon_override) {
+ E.value->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed));
+ }
+ for (KeyValue<StringName, Ref<StyleBox>> &E : data.style_override) {
+ E.value->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed));
+ }
+ for (KeyValue<StringName, Ref<Font>> &E : data.font_override) {
+ E.value->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed));
+ }
+
+ // Then override maps can be simply cleared.
+ data.icon_override.clear();
+ data.style_override.clear();
+ data.font_override.clear();
+ data.font_size_override.clear();
+ data.color_override.clear();
+ data.constant_override.clear();
+}
diff --git a/scene/gui/control.h b/scene/gui/control.h
index a50c66b634..c69067f82f 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -328,7 +328,7 @@ protected:
// Internationalization.
- virtual Array structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const;
+ virtual TypedArray<Vector2i> structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const;
// Base object overrides.
@@ -341,7 +341,7 @@ protected:
// Exposed virtual methods.
GDVIRTUAL1RC(bool, _has_point, Vector2)
- GDVIRTUAL2RC(Array, _structured_text_parser, Array, String)
+ GDVIRTUAL2RC(TypedArray<Vector2i>, _structured_text_parser, Array, String)
GDVIRTUAL0RC(Vector2, _get_minimum_size)
GDVIRTUAL1RC(Variant, _get_drag_data, Vector2)
@@ -610,6 +610,7 @@ public:
virtual Control *make_custom_tooltip(const String &p_text) const;
Control() {}
+ ~Control();
};
VARIANT_ENUM_CAST(Control::FocusMode);
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index f075510aa4..b4e0747ab8 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -130,6 +130,9 @@ String AcceptDialog::get_text() const {
}
void AcceptDialog::set_text(String p_text) {
+ if (label->get_text() == p_text) {
+ return;
+ }
label->set_text(p_text);
child_controls_changed();
if (is_visible()) {
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index e26976a402..7965b12edd 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -685,6 +685,9 @@ void FileDialog::add_filter(const String &p_filter, const String &p_description)
}
void FileDialog::set_filters(const Vector<String> &p_filters) {
+ if (filters == p_filters) {
+ return;
+ }
filters = p_filters;
update_filters();
invalidate();
@@ -708,10 +711,14 @@ String FileDialog::get_current_path() const {
void FileDialog::set_current_dir(const String &p_dir) {
_change_dir(p_dir);
+
_push_history();
}
void FileDialog::set_current_file(const String &p_file) {
+ if (file->get_text() == p_file) {
+ return;
+ }
file->set_text(p_file);
update_dir();
invalidate();
@@ -764,7 +771,9 @@ bool FileDialog::is_mode_overriding_title() const {
void FileDialog::set_file_mode(FileMode p_mode) {
ERR_FAIL_INDEX((int)p_mode, 5);
-
+ if (mode == p_mode) {
+ return;
+ }
mode = p_mode;
switch (mode) {
case FILE_MODE_OPEN_FILE:
@@ -977,6 +986,9 @@ void FileDialog::_bind_methods() {
}
void FileDialog::set_show_hidden_files(bool p_show) {
+ if (show_hidden_files == p_show) {
+ return;
+ }
show_hidden_files = p_show;
invalidate();
}
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 8d3a61b52e..e6198b44ff 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -1591,10 +1591,10 @@ void GraphEdit::remove_valid_left_disconnect_type(int p_type) {
valid_left_disconnect_types.erase(p_type);
}
-Array GraphEdit::_get_connection_list() const {
+TypedArray<Dictionary> GraphEdit::_get_connection_list() const {
List<Connection> conns;
get_connection_list(&conns);
- Array arr;
+ TypedArray<Dictionary> arr;
for (const Connection &E : conns) {
Dictionary d;
d["from"] = E.from;
@@ -1640,6 +1640,9 @@ bool GraphEdit::is_valid_connection_type(int p_type, int p_with_type) const {
}
void GraphEdit::set_use_snap(bool p_enable) {
+ if (snap_button->is_pressed() == p_enable) {
+ return;
+ }
snap_button->set_pressed(p_enable);
update();
}
@@ -1683,6 +1686,9 @@ Vector2 GraphEdit::get_minimap_size() const {
}
void GraphEdit::set_minimap_opacity(float p_opacity) {
+ if (minimap->get_modulate().a == p_opacity) {
+ return;
+ }
minimap->set_modulate(Color(1, 1, 1, p_opacity));
minimap->update();
}
@@ -1693,6 +1699,9 @@ float GraphEdit::get_minimap_opacity() const {
}
void GraphEdit::set_minimap_enabled(bool p_enable) {
+ if (minimap_button->is_pressed() == p_enable) {
+ return;
+ }
minimap_button->set_pressed(p_enable);
_minimap_toggled();
minimap->update();
@@ -1721,6 +1730,9 @@ float GraphEdit::get_connection_lines_curvature() const {
}
void GraphEdit::set_connection_lines_thickness(float p_thickness) {
+ if (lines_thickness == p_thickness) {
+ return;
+ }
lines_thickness = p_thickness;
update();
}
@@ -1730,6 +1742,9 @@ float GraphEdit::get_connection_lines_thickness() const {
}
void GraphEdit::set_connection_lines_antialiased(bool p_antialiased) {
+ if (lines_antialiased == p_antialiased) {
+ return;
+ }
lines_antialiased = p_antialiased;
update();
}
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index cf35aeb8b2..b8c9be9983 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -206,7 +206,7 @@ private:
void _minimap_draw();
void _update_scroll_offset();
- Array _get_connection_list() const;
+ TypedArray<Dictionary> _get_connection_list() const;
bool lines_on_bg = false;
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 582519e70f..7d31e929dc 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -32,9 +32,7 @@
#include "core/string/translation.h"
-#ifdef TOOLS_ENABLED
#include "graph_edit.h"
-#endif
struct _MinSizeCache {
int min_size;
@@ -445,6 +443,7 @@ void GraphNode::_edit_set_position(const Point2 &p_position) {
}
set_position(p_position);
}
+#endif
void GraphNode::_validate_property(PropertyInfo &p_property) const {
GraphEdit *graph = Object::cast_to<GraphEdit>(get_parent());
@@ -454,7 +453,6 @@ void GraphNode::_validate_property(PropertyInfo &p_property) const {
}
}
}
-#endif
void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left, const Ref<Texture2D> &p_custom_right, bool p_draw_stylebox) {
ERR_FAIL_COND_MSG(p_idx < 0, vformat("Cannot set slot with p_idx (%d) lesser than zero.", p_idx));
@@ -505,6 +503,10 @@ bool GraphNode::is_slot_enabled_left(int p_idx) const {
void GraphNode::set_slot_enabled_left(int p_idx, bool p_enable_left) {
ERR_FAIL_COND_MSG(p_idx < 0, vformat("Cannot set enable_left for the slot with p_idx (%d) lesser than zero.", p_idx));
+ if (slot_info[p_idx].enable_left == p_enable_left) {
+ return;
+ }
+
slot_info[p_idx].enable_left = p_enable_left;
update();
connpos_dirty = true;
@@ -515,6 +517,10 @@ void GraphNode::set_slot_enabled_left(int p_idx, bool p_enable_left) {
void GraphNode::set_slot_type_left(int p_idx, int p_type_left) {
ERR_FAIL_COND_MSG(!slot_info.has(p_idx), vformat("Cannot set type_left for the slot '%d' because it hasn't been enabled.", p_idx));
+ if (slot_info[p_idx].type_left == p_type_left) {
+ return;
+ }
+
slot_info[p_idx].type_left = p_type_left;
update();
connpos_dirty = true;
@@ -532,6 +538,10 @@ int GraphNode::get_slot_type_left(int p_idx) const {
void GraphNode::set_slot_color_left(int p_idx, const Color &p_color_left) {
ERR_FAIL_COND_MSG(!slot_info.has(p_idx), vformat("Cannot set color_left for the slot '%d' because it hasn't been enabled.", p_idx));
+ if (slot_info[p_idx].color_left == p_color_left) {
+ return;
+ }
+
slot_info[p_idx].color_left = p_color_left;
update();
connpos_dirty = true;
@@ -556,6 +566,10 @@ bool GraphNode::is_slot_enabled_right(int p_idx) const {
void GraphNode::set_slot_enabled_right(int p_idx, bool p_enable_right) {
ERR_FAIL_COND_MSG(p_idx < 0, vformat("Cannot set enable_right for the slot with p_idx (%d) lesser than zero.", p_idx));
+ if (slot_info[p_idx].enable_right == p_enable_right) {
+ return;
+ }
+
slot_info[p_idx].enable_right = p_enable_right;
update();
connpos_dirty = true;
@@ -566,6 +580,10 @@ void GraphNode::set_slot_enabled_right(int p_idx, bool p_enable_right) {
void GraphNode::set_slot_type_right(int p_idx, int p_type_right) {
ERR_FAIL_COND_MSG(!slot_info.has(p_idx), vformat("Cannot set type_right for the slot '%d' because it hasn't been enabled.", p_idx));
+ if (slot_info[p_idx].type_right == p_type_right) {
+ return;
+ }
+
slot_info[p_idx].type_right = p_type_right;
update();
connpos_dirty = true;
@@ -583,6 +601,10 @@ int GraphNode::get_slot_type_right(int p_idx) const {
void GraphNode::set_slot_color_right(int p_idx, const Color &p_color_right) {
ERR_FAIL_COND_MSG(!slot_info.has(p_idx), vformat("Cannot set color_right for the slot '%d' because it hasn't been enabled.", p_idx));
+ if (slot_info[p_idx].color_right == p_color_right) {
+ return;
+ }
+
slot_info[p_idx].color_right = p_color_right;
update();
connpos_dirty = true;
@@ -700,6 +722,10 @@ String GraphNode::get_language() const {
}
void GraphNode::set_position_offset(const Vector2 &p_offset) {
+ if (position_offset == p_offset) {
+ return;
+ }
+
position_offset = p_offset;
emit_signal(SNAME("position_offset_changed"));
update();
@@ -710,6 +736,10 @@ Vector2 GraphNode::get_position_offset() const {
}
void GraphNode::set_selected(bool p_selected) {
+ if (selected == p_selected) {
+ return;
+ }
+
selected = p_selected;
update();
}
@@ -731,6 +761,10 @@ Vector2 GraphNode::get_drag_from() {
}
void GraphNode::set_show_close_button(bool p_enable) {
+ if (show_close == p_enable) {
+ return;
+ }
+
show_close = p_enable;
update();
}
@@ -931,6 +965,10 @@ void GraphNode::gui_input(const Ref<InputEvent> &p_ev) {
}
void GraphNode::set_overlay(Overlay p_overlay) {
+ if (overlay == p_overlay) {
+ return;
+ }
+
overlay = p_overlay;
update();
}
@@ -940,6 +978,10 @@ GraphNode::Overlay GraphNode::get_overlay() const {
}
void GraphNode::set_comment(bool p_enable) {
+ if (comment == p_enable) {
+ return;
+ }
+
comment = p_enable;
update();
}
@@ -949,6 +991,10 @@ bool GraphNode::is_comment() const {
}
void GraphNode::set_resizable(bool p_enable) {
+ if (resizable == p_enable) {
+ return;
+ }
+
resizable = p_enable;
update();
}
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index 6d5bb4361e..d575b6ceed 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -101,7 +101,6 @@ private:
#ifdef TOOLS_ENABLED
void _edit_set_position(const Point2 &p_position) override;
- void _validate_property(PropertyInfo &p_property) const;
#endif
protected:
@@ -112,6 +111,7 @@ protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ void _validate_property(PropertyInfo &p_property) const;
public:
bool has_point(const Point2 &p_point) const override;
diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp
index eaa6943ad2..3163d17846 100644
--- a/scene/gui/grid_container.cpp
+++ b/scene/gui/grid_container.cpp
@@ -246,6 +246,11 @@ void GridContainer::_notification(int p_what) {
void GridContainer::set_columns(int p_columns) {
ERR_FAIL_COND(p_columns < 1);
+
+ if (columns == p_columns) {
+ return;
+ }
+
columns = p_columns;
queue_sort();
update_minimum_size();
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index e3e9499705..086f729603 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -88,6 +88,10 @@ void ItemList::set_item_text(int p_idx, const String &p_text) {
}
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].text == p_text) {
+ return;
+ }
+
items.write[p_idx].text = p_text;
_shape(p_idx);
update();
@@ -153,6 +157,10 @@ void ItemList::set_item_tooltip(int p_idx, const String &p_tooltip) {
}
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].tooltip == p_tooltip) {
+ return;
+ }
+
items.write[p_idx].tooltip = p_tooltip;
update();
shape_changed = true;
@@ -169,6 +177,10 @@ void ItemList::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
}
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].icon == p_icon) {
+ return;
+ }
+
items.write[p_idx].icon = p_icon;
update();
shape_changed = true;
@@ -186,6 +198,10 @@ void ItemList::set_item_icon_transposed(int p_idx, const bool p_transposed) {
}
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].icon_transposed == p_transposed) {
+ return;
+ }
+
items.write[p_idx].icon_transposed = p_transposed;
update();
shape_changed = true;
@@ -203,6 +219,10 @@ void ItemList::set_item_icon_region(int p_idx, const Rect2 &p_region) {
}
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].icon_region == p_region) {
+ return;
+ }
+
items.write[p_idx].icon_region = p_region;
update();
shape_changed = true;
@@ -220,6 +240,10 @@ void ItemList::set_item_icon_modulate(int p_idx, const Color &p_modulate) {
}
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].icon_modulate == p_modulate) {
+ return;
+ }
+
items.write[p_idx].icon_modulate = p_modulate;
update();
}
@@ -236,6 +260,10 @@ void ItemList::set_item_custom_bg_color(int p_idx, const Color &p_custom_bg_colo
}
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].custom_bg == p_custom_bg_color) {
+ return;
+ }
+
items.write[p_idx].custom_bg = p_custom_bg_color;
update();
}
@@ -252,6 +280,10 @@ void ItemList::set_item_custom_fg_color(int p_idx, const Color &p_custom_fg_colo
}
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].custom_fg == p_custom_fg_color) {
+ return;
+ }
+
items.write[p_idx].custom_fg = p_custom_fg_color;
update();
}
@@ -268,6 +300,10 @@ void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture2D> &p_tag_icon) {
}
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].tag_icon == p_tag_icon) {
+ return;
+ }
+
items.write[p_idx].tag_icon = p_tag_icon;
update();
shape_changed = true;
@@ -299,6 +335,10 @@ void ItemList::set_item_disabled(int p_idx, bool p_disabled) {
}
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].disabled == p_disabled) {
+ return;
+ }
+
items.write[p_idx].disabled = p_disabled;
update();
}
@@ -314,6 +354,10 @@ void ItemList::set_item_metadata(int p_idx, const Variant &p_metadata) {
}
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].metadata == p_metadata) {
+ return;
+ }
+
items.write[p_idx].metadata = p_metadata;
update();
shape_changed = true;
@@ -379,6 +423,10 @@ bool ItemList::is_selected(int p_idx) const {
void ItemList::set_current(int p_current) {
ERR_FAIL_INDEX(p_current, items.size());
+ if (current == p_current) {
+ return;
+ }
+
if (select_mode == SELECT_SINGLE) {
select(p_current, true);
} else {
@@ -410,6 +458,11 @@ void ItemList::move_item(int p_from_idx, int p_to_idx) {
void ItemList::set_item_count(int p_count) {
ERR_FAIL_COND(p_count < 0);
+
+ if (items.size() == p_count) {
+ return;
+ }
+
items.resize(p_count);
update();
shape_changed = true;
@@ -445,6 +498,11 @@ void ItemList::clear() {
void ItemList::set_fixed_column_width(int p_size) {
ERR_FAIL_COND(p_size < 0);
+
+ if (fixed_column_width == p_size) {
+ return;
+ }
+
fixed_column_width = p_size;
update();
shape_changed = true;
@@ -455,6 +513,10 @@ int ItemList::get_fixed_column_width() const {
}
void ItemList::set_same_column_width(bool p_enable) {
+ if (same_column_width == p_enable) {
+ return;
+ }
+
same_column_width = p_enable;
update();
shape_changed = true;
@@ -487,6 +549,11 @@ int ItemList::get_max_text_lines() const {
void ItemList::set_max_columns(int p_amount) {
ERR_FAIL_COND(p_amount < 0);
+
+ if (max_columns == p_amount) {
+ return;
+ }
+
max_columns = p_amount;
update();
shape_changed = true;
@@ -497,6 +564,10 @@ int ItemList::get_max_columns() const {
}
void ItemList::set_select_mode(SelectMode p_mode) {
+ if (select_mode == p_mode) {
+ return;
+ }
+
select_mode = p_mode;
update();
}
@@ -526,6 +597,10 @@ ItemList::IconMode ItemList::get_icon_mode() const {
}
void ItemList::set_fixed_icon_size(const Size2 &p_size) {
+ if (fixed_icon_size == p_size) {
+ return;
+ }
+
fixed_icon_size = p_size;
update();
}
@@ -1512,6 +1587,10 @@ void ItemList::set_autoscroll_to_bottom(const bool p_enable) {
}
void ItemList::set_auto_height(bool p_enable) {
+ if (auto_height == p_enable) {
+ return;
+ }
+
auto_height = p_enable;
shape_changed = true;
update();
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 4ef1e48a32..7a88afaa3b 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -38,10 +38,12 @@
#include "servers/text_server.h"
void Label::set_autowrap_mode(TextServer::AutowrapMode p_mode) {
- if (autowrap_mode != p_mode) {
- autowrap_mode = p_mode;
- lines_dirty = true;
+ if (autowrap_mode == p_mode) {
+ return;
}
+
+ autowrap_mode = p_mode;
+ lines_dirty = true;
update();
if (clip || overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) {
@@ -54,6 +56,10 @@ TextServer::AutowrapMode Label::get_autowrap_mode() const {
}
void Label::set_uppercase(bool p_uppercase) {
+ if (uppercase == p_uppercase) {
+ return;
+ }
+
uppercase = p_uppercase;
dirty = true;
@@ -608,12 +614,15 @@ int Label::get_visible_line_count() const {
void Label::set_horizontal_alignment(HorizontalAlignment p_alignment) {
ERR_FAIL_INDEX((int)p_alignment, 4);
- if (horizontal_alignment != p_alignment) {
- if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL || p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
- lines_dirty = true; // Reshape lines.
- }
- horizontal_alignment = p_alignment;
+ if (horizontal_alignment == p_alignment) {
+ return;
}
+
+ if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL || p_alignment == HORIZONTAL_ALIGNMENT_FILL) {
+ lines_dirty = true; // Reshape lines.
+ }
+ horizontal_alignment = p_alignment;
+
update();
}
@@ -623,6 +632,11 @@ HorizontalAlignment Label::get_horizontal_alignment() const {
void Label::set_vertical_alignment(VerticalAlignment p_alignment) {
ERR_FAIL_INDEX((int)p_alignment, 4);
+
+ if (vertical_alignment == p_alignment) {
+ return;
+ }
+
vertical_alignment = p_alignment;
update();
}
@@ -689,6 +703,10 @@ TextServer::StructuredTextParser Label::get_structured_text_bidi_override() cons
}
void Label::set_structured_text_bidi_override_options(Array p_args) {
+ if (st_args == p_args) {
+ return;
+ }
+
st_args = p_args;
dirty = true;
update();
@@ -715,6 +733,10 @@ String Label::get_language() const {
}
void Label::set_clip_text(bool p_clip) {
+ if (clip == p_clip) {
+ return;
+ }
+
clip = p_clip;
update();
update_minimum_size();
@@ -725,10 +747,12 @@ bool Label::is_clipping_text() const {
}
void Label::set_text_overrun_behavior(TextServer::OverrunBehavior p_behavior) {
- if (overrun_behavior != p_behavior) {
- overrun_behavior = p_behavior;
- lines_dirty = true;
+ if (overrun_behavior == p_behavior) {
+ return;
}
+
+ overrun_behavior = p_behavior;
+ lines_dirty = true;
update();
if (clip || overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) {
update_minimum_size();
@@ -800,6 +824,11 @@ void Label::set_visible_characters_behavior(TextServer::VisibleCharactersBehavio
void Label::set_lines_skipped(int p_lines) {
ERR_FAIL_COND(p_lines < 0);
+
+ if (lines_skipped == p_lines) {
+ return;
+ }
+
lines_skipped = p_lines;
_update_visible();
update();
@@ -810,6 +839,10 @@ int Label::get_lines_skipped() const {
}
void Label::set_max_lines_visible(int p_lines) {
+ if (max_lines_visible == p_lines) {
+ return;
+ }
+
max_lines_visible = p_lines;
_update_visible();
update();
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index b523c2bb8b..cc39b0e57a 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -607,10 +607,12 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) {
void LineEdit::set_horizontal_alignment(HorizontalAlignment p_alignment) {
ERR_FAIL_INDEX((int)p_alignment, 4);
- if (alignment != p_alignment) {
- alignment = p_alignment;
- _shape();
+ if (alignment == p_alignment) {
+ return;
}
+
+ alignment = p_alignment;
+ _shape();
update();
}
@@ -1525,6 +1527,10 @@ String LineEdit::get_text() const {
}
void LineEdit::set_placeholder(String p_text) {
+ if (placeholder == p_text) {
+ return;
+ }
+
placeholder = p_text;
placeholder_translated = atr(placeholder);
_shape();
@@ -1781,10 +1787,12 @@ bool LineEdit::is_editable() const {
}
void LineEdit::set_secret(bool p_secret) {
- if (pass != p_secret) {
- pass = p_secret;
- _shape();
+ if (pass == p_secret) {
+ return;
}
+
+ pass = p_secret;
+ _shape();
update();
}
@@ -1797,10 +1805,12 @@ void LineEdit::set_secret_character(const String &p_string) {
// It also wouldn't make sense to use multiple characters as the secret character.
ERR_FAIL_COND_MSG(p_string.length() != 1, "Secret character must be exactly one character long (" + itos(p_string.length()) + " characters given).");
- if (secret_character != p_string) {
- secret_character = p_string;
- _shape();
+ if (secret_character == p_string) {
+ return;
}
+
+ secret_character = p_string;
+ _shape();
update();
}
@@ -2057,6 +2067,10 @@ bool LineEdit::is_middle_mouse_paste_enabled() const {
}
void LineEdit::set_selecting_enabled(bool p_enabled) {
+ if (selecting_enabled == p_enabled) {
+ return;
+ }
+
selecting_enabled = p_enabled;
if (!selecting_enabled) {
@@ -2069,6 +2083,10 @@ bool LineEdit::is_selecting_enabled() const {
}
void LineEdit::set_deselect_on_focus_loss_enabled(const bool p_enabled) {
+ if (deselect_on_focus_loss_enabled == p_enabled) {
+ return;
+ }
+
deselect_on_focus_loss_enabled = p_enabled;
if (p_enabled && selection.enabled && !has_focus()) {
deselect();
diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp
index 30c0bb3321..ee3f64e0e5 100644
--- a/scene/gui/link_button.cpp
+++ b/scene/gui/link_button.cpp
@@ -109,6 +109,10 @@ String LinkButton::get_language() const {
}
void LinkButton::set_underline_mode(UnderlineMode p_underline_mode) {
+ if (underline_mode == p_underline_mode) {
+ return;
+ }
+
underline_mode = p_underline_mode;
update();
}
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index 0252f25888..a03db82332 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -99,9 +99,7 @@ void MenuButton::pressed() {
popup->set_parent_rect(Rect2(Point2(gp - popup->get_position()), size));
// If not triggered by the mouse, start the popup with its first item selected.
- if (popup->get_item_count() > 0 &&
- ((get_action_mode() == ActionMode::ACTION_MODE_BUTTON_PRESS && Input::get_singleton()->is_action_just_pressed("ui_accept")) ||
- (get_action_mode() == ActionMode::ACTION_MODE_BUTTON_RELEASE && Input::get_singleton()->is_action_just_released("ui_accept")))) {
+ if (popup->get_item_count() > 0 && !_was_pressed_by_mouse()) {
popup->set_current_index(0);
}
@@ -130,6 +128,11 @@ bool MenuButton::is_switch_on_hover() {
void MenuButton::set_item_count(int p_count) {
ERR_FAIL_COND(p_count < 0);
+
+ if (popup->get_item_count() == p_count) {
+ return;
+ }
+
popup->set_item_count(p_count);
notify_property_list_changed();
}
diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp
index 8fee10b19a..a7e86dd5de 100644
--- a/scene/gui/nine_patch_rect.cpp
+++ b/scene/gui/nine_patch_rect.cpp
@@ -105,6 +105,11 @@ Ref<Texture2D> NinePatchRect::get_texture() const {
void NinePatchRect::set_patch_margin(Side p_side, int p_size) {
ERR_FAIL_INDEX((int)p_side, 4);
+
+ if (margin[p_side] == p_size) {
+ return;
+ }
+
margin[p_side] = p_size;
update();
update_minimum_size();
@@ -130,6 +135,10 @@ Rect2 NinePatchRect::get_region_rect() const {
}
void NinePatchRect::set_draw_center(bool p_enabled) {
+ if (draw_center == p_enabled) {
+ return;
+ }
+
draw_center = p_enabled;
update();
}
@@ -139,6 +148,10 @@ bool NinePatchRect::is_draw_center_enabled() const {
}
void NinePatchRect::set_h_axis_stretch_mode(AxisStretchMode p_mode) {
+ if (axis_h == p_mode) {
+ return;
+ }
+
axis_h = p_mode;
update();
}
@@ -148,6 +161,10 @@ NinePatchRect::AxisStretchMode NinePatchRect::get_h_axis_stretch_mode() const {
}
void NinePatchRect::set_v_axis_stretch_mode(AxisStretchMode p_mode) {
+ if (axis_v == p_mode) {
+ return;
+ }
+
axis_v = p_mode;
update();
}
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 851d425bfc..931dffe3bb 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -47,7 +47,7 @@ Size2 OptionButton::get_minimum_size() const {
const Size2 arrow_size = Control::get_theme_icon(SNAME("arrow"))->get_size();
Size2 content_size = minsize - padding;
- content_size.width += arrow_size.width + get_theme_constant(SNAME("h_separation"));
+ content_size.width += arrow_size.width + MAX(0, get_theme_constant(SNAME("h_separation")));
content_size.height = MAX(content_size.height, arrow_size.height);
minsize = content_size + padding;
@@ -204,8 +204,7 @@ void OptionButton::pressed() {
// If not triggered by the mouse, start the popup with the checked item selected.
if (popup->get_item_count() > 0) {
- if ((get_action_mode() == ActionMode::ACTION_MODE_BUTTON_PRESS && Input::get_singleton()->is_action_just_pressed("ui_accept")) ||
- (get_action_mode() == ActionMode::ACTION_MODE_BUTTON_RELEASE && Input::get_singleton()->is_action_just_released("ui_accept"))) {
+ if (!_was_pressed_by_mouse()) {
popup->set_current_index(current > -1 ? current : 0);
} else {
popup->scroll_to_item(current > -1 ? current : 0);
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 6ef8158302..4e2aec0278 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -1144,6 +1144,11 @@ void PopupMenu::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ if (items[p_idx].icon == p_icon) {
+ return;
+ }
+
items.write[p_idx].icon = p_icon;
control->update();
@@ -1157,6 +1162,10 @@ void PopupMenu::set_item_checked(int p_idx, bool p_checked) {
}
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].checked == p_checked) {
+ return;
+ }
+
items.write[p_idx].checked = p_checked;
control->update();
@@ -1169,6 +1178,11 @@ void PopupMenu::set_item_id(int p_idx, int p_id) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ if (items[p_idx].id == p_id) {
+ return;
+ }
+
items.write[p_idx].id = p_id;
control->update();
@@ -1181,6 +1195,11 @@ void PopupMenu::set_item_accelerator(int p_idx, Key p_accel) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ if (items[p_idx].accel == p_accel) {
+ return;
+ }
+
items.write[p_idx].accel = p_accel;
items.write[p_idx].dirty = true;
@@ -1194,6 +1213,11 @@ void PopupMenu::set_item_metadata(int p_idx, const Variant &p_meta) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ if (items[p_idx].metadata == p_meta) {
+ return;
+ }
+
items.write[p_idx].metadata = p_meta;
control->update();
child_controls_changed();
@@ -1205,6 +1229,11 @@ void PopupMenu::set_item_disabled(int p_idx, bool p_disabled) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ if (items[p_idx].disabled == p_disabled) {
+ return;
+ }
+
items.write[p_idx].disabled = p_disabled;
control->update();
child_controls_changed();
@@ -1216,6 +1245,11 @@ void PopupMenu::set_item_submenu(int p_idx, const String &p_submenu) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ if (items[p_idx].submenu == p_submenu) {
+ return;
+ }
+
items.write[p_idx].submenu = p_submenu;
control->update();
child_controls_changed();
@@ -1330,6 +1364,11 @@ void PopupMenu::set_item_as_separator(int p_idx, bool p_separator) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ if (items[p_idx].separator == p_separator) {
+ return;
+ }
+
items.write[p_idx].separator = p_separator;
control->update();
}
@@ -1344,6 +1383,12 @@ void PopupMenu::set_item_as_checkable(int p_idx, bool p_checkable) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ int type = (int)(p_checkable ? Item::CHECKABLE_TYPE_CHECK_BOX : Item::CHECKABLE_TYPE_NONE);
+ if (type == items[p_idx].checkable_type) {
+ return;
+ }
+
items.write[p_idx].checkable_type = p_checkable ? Item::CHECKABLE_TYPE_CHECK_BOX : Item::CHECKABLE_TYPE_NONE;
control->update();
_menu_changed();
@@ -1354,6 +1399,12 @@ void PopupMenu::set_item_as_radio_checkable(int p_idx, bool p_radio_checkable) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ int type = (int)(p_radio_checkable ? Item::CHECKABLE_TYPE_RADIO_BUTTON : Item::CHECKABLE_TYPE_NONE);
+ if (type == items[p_idx].checkable_type) {
+ return;
+ }
+
items.write[p_idx].checkable_type = p_radio_checkable ? Item::CHECKABLE_TYPE_RADIO_BUTTON : Item::CHECKABLE_TYPE_NONE;
control->update();
_menu_changed();
@@ -1364,6 +1415,11 @@ void PopupMenu::set_item_tooltip(int p_idx, const String &p_tooltip) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ if (items[p_idx].tooltip == p_tooltip) {
+ return;
+ }
+
items.write[p_idx].tooltip = p_tooltip;
control->update();
_menu_changed();
@@ -1374,6 +1430,11 @@ void PopupMenu::set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bo
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ if (items[p_idx].shortcut == p_shortcut && items[p_idx].shortcut_is_global == p_global && items[p_idx].shortcut.is_valid() == p_shortcut.is_valid()) {
+ return;
+ }
+
if (items[p_idx].shortcut.is_valid()) {
_unref_shortcut(items[p_idx].shortcut);
}
@@ -1394,7 +1455,12 @@ void PopupMenu::set_item_indent(int p_idx, int p_indent) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ if (items.write[p_idx].indent == p_indent) {
+ return;
+ }
items.write[p_idx].indent = p_indent;
+
control->update();
child_controls_changed();
_menu_changed();
@@ -1405,6 +1471,11 @@ void PopupMenu::set_item_multistate(int p_idx, int p_state) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ if (items[p_idx].state == p_state) {
+ return;
+ }
+
items.write[p_idx].state = p_state;
control->update();
_menu_changed();
@@ -1415,6 +1486,11 @@ void PopupMenu::set_item_shortcut_disabled(int p_idx, bool p_disabled) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+
+ if (items[p_idx].shortcut_is_disabled == p_disabled) {
+ return;
+ }
+
items.write[p_idx].shortcut_is_disabled = p_disabled;
control->update();
_menu_changed();
@@ -1457,6 +1533,11 @@ bool PopupMenu::is_item_shortcut_disabled(int p_idx) const {
void PopupMenu::set_current_index(int p_idx) {
ERR_FAIL_INDEX(p_idx, items.size());
+
+ if (mouse_over == p_idx) {
+ return;
+ }
+
mouse_over = p_idx;
scroll_to_item(mouse_over);
control->update();
@@ -1469,6 +1550,11 @@ int PopupMenu::get_current_index() const {
void PopupMenu::set_item_count(int p_count) {
ERR_FAIL_COND(p_count < 0);
int prev_size = items.size();
+
+ if (prev_size == p_count) {
+ return;
+ }
+
items.resize(p_count);
if (prev_size < p_count) {
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index fae6688452..0fb1f27802 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -106,6 +106,10 @@ void Range::set_value(double p_val) {
}
void Range::set_min(double p_min) {
+ if (shared->min == p_min) {
+ return;
+ }
+
shared->min = p_min;
set_value(shared->val);
_validate_values();
@@ -116,6 +120,10 @@ void Range::set_min(double p_min) {
}
void Range::set_max(double p_max) {
+ if (shared->max == p_max) {
+ return;
+ }
+
shared->max = p_max;
set_value(shared->val);
_validate_values();
@@ -124,11 +132,19 @@ void Range::set_max(double p_max) {
}
void Range::set_step(double p_step) {
+ if (shared->step == p_step) {
+ return;
+ }
+
shared->step = p_step;
shared->emit_changed("step");
}
void Range::set_page(double p_page) {
+ if (shared->page == p_page) {
+ return;
+ }
+
shared->page = p_page;
set_value(shared->val);
_validate_values();
@@ -300,6 +316,10 @@ bool Range::is_using_rounded_values() const {
}
void Range::set_exp_ratio(bool p_enable) {
+ if (shared->exp_ratio == p_enable) {
+ return;
+ }
+
shared->exp_ratio = p_enable;
update_configuration_warnings();
diff --git a/scene/gui/reference_rect.cpp b/scene/gui/reference_rect.cpp
index 5190a5a7d2..05dfe4b118 100644
--- a/scene/gui/reference_rect.cpp
+++ b/scene/gui/reference_rect.cpp
@@ -46,6 +46,10 @@ void ReferenceRect::_notification(int p_what) {
}
void ReferenceRect::set_border_color(const Color &p_color) {
+ if (border_color == p_color) {
+ return;
+ }
+
border_color = p_color;
update();
}
@@ -55,7 +59,12 @@ Color ReferenceRect::get_border_color() const {
}
void ReferenceRect::set_border_width(float p_width) {
- border_width = MAX(0.0, p_width);
+ float width_max = MAX(0.0, p_width);
+ if (border_width == width_max) {
+ return;
+ }
+
+ border_width = width_max;
update();
}
@@ -64,6 +73,10 @@ float ReferenceRect::get_border_width() const {
}
void ReferenceRect::set_editor_only(const bool &p_enabled) {
+ if (editor_only == p_enabled) {
+ return;
+ }
+
editor_only = p_enabled;
update();
}
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index ab466089a7..6ab3cdcb69 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1346,7 +1346,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
return line_count;
}
-void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool *r_outside) {
+void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool *r_outside, bool p_meta) {
if (r_click_item) {
*r_click_item = nullptr;
}
@@ -1369,7 +1369,7 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item
Point2 ofs = text_rect.get_position() + Vector2(0, main->lines[from_line].offset.y - vofs);
while (ofs.y < size.height && from_line < to_line) {
MutexLock lock(main->lines[from_line].text_buf->get_mutex());
- _find_click_in_line(p_frame, from_line, ofs, text_rect.size.x, p_click, r_click_frame, r_click_line, r_click_item, r_click_char);
+ _find_click_in_line(p_frame, from_line, ofs, text_rect.size.x, p_click, r_click_frame, r_click_line, r_click_item, r_click_char, false, p_meta);
ofs.y += main->lines[from_line].text_buf->get_size().y + main->lines[from_line].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation"));
if (((r_click_item != nullptr) && ((*r_click_item) != nullptr)) || ((r_click_frame != nullptr) && ((*r_click_frame) != nullptr))) {
if (r_outside != nullptr) {
@@ -1381,7 +1381,7 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item
}
}
-float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool p_table) {
+float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame, int *r_click_line, Item **r_click_item, int *r_click_char, bool p_table, bool p_meta) {
Vector2 off;
bool line_clicked = false;
@@ -1479,7 +1479,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
}
if (crect.has_point(p_click)) {
for (int j = 0; j < (int)frame->lines.size(); j++) {
- _find_click_in_line(frame, j, rect.position + Vector2(0, frame->lines[j].offset.y), rect.size.x, p_click, &table_click_frame, &table_click_line, &table_click_item, &table_click_char, true);
+ _find_click_in_line(frame, j, rect.position + Vector2(0, frame->lines[j].offset.y), rect.size.x, p_click, &table_click_frame, &table_click_line, &table_click_item, &table_click_char, true, p_meta);
if (table_click_frame && table_click_item) {
// Save cell detected cell hit data.
table_range = Vector2i(INT32_MAX, 0);
@@ -1512,7 +1512,15 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
if (p_click.y >= rect.position.y && p_click.y <= rect.position.y + rect.size.y) {
if ((!rtl && p_click.x >= rect.position.x) || (rtl && p_click.x <= rect.position.x + rect.size.x)) {
- char_pos = TS->shaped_text_hit_test_position(rid, p_click.x - rect.position.x);
+ if (p_meta) {
+ int64_t glyph_idx = TS->shaped_text_hit_test_grapheme(rid, p_click.x - rect.position.x);
+ if (glyph_idx >= 0) {
+ const Glyph *glyphs = TS->shaped_text_get_glyphs(rid);
+ char_pos = glyphs[glyph_idx].start;
+ }
+ } else {
+ char_pos = TS->shaped_text_hit_test_position(rid, p_click.x - rect.position.x);
+ }
}
line_clicked = true;
text_rect_begin = rtl ? rect.position.x + rect.size.x : rect.position.x;
@@ -1825,7 +1833,7 @@ Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const
Item *item = nullptr;
bool outside = true;
- const_cast<RichTextLabel *>(this)->_find_click(main, p_pos, nullptr, nullptr, &item, nullptr, &outside);
+ const_cast<RichTextLabel *>(this)->_find_click(main, p_pos, nullptr, nullptr, &item, nullptr, &outside, true);
if (item && !outside && const_cast<RichTextLabel *>(this)->_find_meta(item, nullptr)) {
return CURSOR_POINTING_HAND;
@@ -1850,7 +1858,7 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
selection.drag_attempt = false;
- _find_click(main, b->get_position(), &c_frame, &c_line, &c_item, &c_index, &outside);
+ _find_click(main, b->get_position(), &c_frame, &c_line, &c_item, &c_index, &outside, false);
if (c_item != nullptr) {
if (selection.enabled) {
selection.click_frame = c_frame;
@@ -1888,7 +1896,7 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
selection.drag_attempt = false;
- _find_click(main, b->get_position(), &c_frame, &c_line, &c_item, &c_index, &outside);
+ _find_click(main, b->get_position(), &c_frame, &c_line, &c_item, &c_index, &outside, false);
if (c_frame) {
const Line &l = c_frame->lines[c_line];
@@ -1938,7 +1946,7 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
Item *c_item = nullptr;
bool outside = true;
- _find_click(main, b->get_position(), nullptr, nullptr, &c_item, nullptr, &outside);
+ _find_click(main, b->get_position(), nullptr, nullptr, &c_item, nullptr, &outside, true);
if (c_item) {
Variant meta;
@@ -2044,7 +2052,7 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
int c_index = 0;
bool outside;
- _find_click(main, m->get_position(), &c_frame, &c_line, &c_item, &c_index, &outside);
+ _find_click(main, m->get_position(), &c_frame, &c_line, &c_item, &c_index, &outside, false);
if (selection.click_item && c_item) {
selection.from_frame = selection.click_frame;
selection.from_line = selection.click_line;
@@ -2102,7 +2110,7 @@ String RichTextLabel::get_tooltip(const Point2 &p_pos) const {
Item *c_item = nullptr;
bool outside;
- const_cast<RichTextLabel *>(this)->_find_click(main, p_pos, nullptr, nullptr, &c_item, nullptr, &outside);
+ const_cast<RichTextLabel *>(this)->_find_click(main, p_pos, nullptr, nullptr, &c_item, nullptr, &outside, true);
String description;
if (c_item && !outside && const_cast<RichTextLabel *>(this)->_find_hint(c_item, &description)) {
@@ -3370,6 +3378,10 @@ void RichTextLabel::clear() {
}
void RichTextLabel::set_tab_size(int p_spaces) {
+ if (tab_size == p_spaces) {
+ return;
+ }
+
_stop_thread();
tab_size = p_spaces;
@@ -3393,6 +3405,10 @@ bool RichTextLabel::is_fit_content_height_enabled() const {
}
void RichTextLabel::set_meta_underline(bool p_underline) {
+ if (underline_meta == p_underline) {
+ return;
+ }
+
underline_meta = p_underline;
update();
}
@@ -4320,6 +4336,8 @@ void RichTextLabel::append_text(const String &p_bbcode) {
}
void RichTextLabel::scroll_to_paragraph(int p_paragraph) {
+ _validate_line_caches();
+
if (p_paragraph <= 0) {
vscroll->set_value(0);
} else if (p_paragraph >= main->first_invalid_line.load()) {
@@ -4341,6 +4359,8 @@ int RichTextLabel::get_visible_paragraph_count() const {
}
void RichTextLabel::scroll_to_line(int p_line) {
+ _validate_line_caches();
+
if (p_line <= 0) {
vscroll->set_value(0);
return;
@@ -4405,6 +4425,10 @@ int RichTextLabel::get_visible_line_count() const {
}
void RichTextLabel::set_selection_enabled(bool p_enabled) {
+ if (selection.enabled == p_enabled) {
+ return;
+ }
+
selection.enabled = p_enabled;
if (!p_enabled) {
if (selection.active) {
@@ -4417,6 +4441,10 @@ void RichTextLabel::set_selection_enabled(bool p_enabled) {
}
void RichTextLabel::set_deselect_on_focus_loss_enabled(const bool p_enabled) {
+ if (deselect_on_focus_loss_enabled == p_enabled) {
+ return;
+ }
+
deselect_on_focus_loss_enabled = p_enabled;
if (p_enabled && selection.active && !has_focus()) {
deselect();
@@ -4784,6 +4812,10 @@ int RichTextLabel::get_selection_to() const {
}
void RichTextLabel::set_text(const String &p_bbcode) {
+ if (text == p_bbcode) {
+ return;
+ }
+
text = p_bbcode;
if (use_bbcode) {
parse_bbcode(p_bbcode);
@@ -4958,6 +4990,8 @@ void RichTextLabel::install_effect(const Variant effect) {
}
int RichTextLabel::get_content_height() const {
+ const_cast<RichTextLabel *>(this)->_validate_line_caches();
+
int total_height = 0;
int to_line = main->first_invalid_line.load();
if (to_line) {
@@ -4968,6 +5002,8 @@ int RichTextLabel::get_content_height() const {
}
int RichTextLabel::get_content_width() const {
+ const_cast<RichTextLabel *>(this)->_validate_line_caches();
+
int total_width = 0;
int to_line = main->first_invalid_line.load();
for (int i = 0; i < to_line; i++) {
@@ -5316,6 +5352,10 @@ int RichTextLabel::get_total_glyph_count() const {
}
void RichTextLabel::set_fixed_size_to_width(int p_width) {
+ if (fixed_width == p_width) {
+ return;
+ }
+
fixed_width = p_width;
update_minimum_size();
}
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index e5f0469c01..95e55bf1a1 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -444,7 +444,7 @@ private:
TextServer::VisibleCharactersBehavior visible_chars_behavior = TextServer::VC_CHARS_BEFORE_SHAPING;
bool _is_click_inside_selection() const;
- void _find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool *r_outside = nullptr);
+ void _find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool *r_outside = nullptr, bool p_meta = false);
String _get_line_text(ItemFrame *p_frame, int p_line, Selection p_sel) const;
bool _search_line(ItemFrame *p_frame, int p_line, const String &p_string, int p_char_idx, bool p_reverse_search);
@@ -455,7 +455,7 @@ private:
void _update_line_font(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size);
int _draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_shadow_color, int p_shadow_outline_size, const Point2 &p_shadow_ofs, int &r_processed_glyphs);
- float _find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool p_table = false);
+ float _find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool p_table = false, bool p_meta = false);
String _roman(int p_num, bool p_capitalize) const;
String _letters(int p_num, bool p_capitalize) const;
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 64c07007dc..2695ad1f14 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -227,6 +227,10 @@ double Slider::get_custom_step() const {
}
void Slider::set_ticks(int p_count) {
+ if (ticks == p_count) {
+ return;
+ }
+
ticks = p_count;
update();
}
@@ -240,11 +244,19 @@ bool Slider::get_ticks_on_borders() const {
}
void Slider::set_ticks_on_borders(bool _tob) {
+ if (ticks_on_borders == _tob) {
+ return;
+ }
+
ticks_on_borders = _tob;
update();
}
void Slider::set_editable(bool p_editable) {
+ if (editable == p_editable) {
+ return;
+ }
+
editable = p_editable;
update();
}
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 8a7f52b0d9..517c83545c 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -250,6 +250,10 @@ HorizontalAlignment SpinBox::get_horizontal_alignment() const {
}
void SpinBox::set_suffix(const String &p_suffix) {
+ if (suffix == p_suffix) {
+ return;
+ }
+
suffix = p_suffix;
_value_changed(0);
}
@@ -259,6 +263,10 @@ String SpinBox::get_suffix() const {
}
void SpinBox::set_prefix(const String &p_prefix) {
+ if (prefix == p_prefix) {
+ return;
+ }
+
prefix = p_prefix;
_value_changed(0);
}
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index d7aa516ee6..b6073ce265 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -95,14 +95,18 @@ void SplitContainer::_resort() {
no_offset_middle_sep = ms_first[axis];
}
- // Compute the final middle separation
+ // Compute the final middle separation.
middle_sep = no_offset_middle_sep;
+ if (prev_no_offset_middle_sep != INT_MAX) {
+ split_offset -= middle_sep - prev_no_offset_middle_sep;
+ }
+ prev_no_offset_middle_sep = middle_sep;
+
if (!collapsed) {
int clamped_split_offset = CLAMP(split_offset, ms_first[axis] - no_offset_middle_sep, (get_size()[axis] - ms_second[axis] - sep) - no_offset_middle_sep);
middle_sep += clamped_split_offset;
if (should_clamp_split_offset) {
split_offset = clamped_split_offset;
-
should_clamp_split_offset = false;
}
}
@@ -327,6 +331,10 @@ void SplitContainer::set_collapsed(bool p_collapsed) {
}
void SplitContainer::set_dragger_visibility(DraggerVisibility p_visibility) {
+ if (dragger_visibility == p_visibility) {
+ return;
+ }
+
dragger_visibility = p_visibility;
queue_sort();
update();
diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h
index a69ffe4de9..dd15362199 100644
--- a/scene/gui/split_container.h
+++ b/scene/gui/split_container.h
@@ -47,6 +47,7 @@ private:
bool should_clamp_split_offset = false;
int split_offset = 0;
int middle_sep = 0;
+ int prev_no_offset_middle_sep = INT_MAX;
bool vertical = false;
bool dragging = false;
int drag_from = 0;
diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp
index 68281b6a72..869683e427 100644
--- a/scene/gui/subviewport_container.cpp
+++ b/scene/gui/subviewport_container.cpp
@@ -53,6 +53,10 @@ Size2 SubViewportContainer::get_minimum_size() const {
}
void SubViewportContainer::set_stretch(bool p_enable) {
+ if (stretch == p_enable) {
+ return;
+ }
+
stretch = p_enable;
update_minimum_size();
queue_sort();
diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp
index d36a364677..e0739f909f 100644
--- a/scene/gui/tab_bar.cpp
+++ b/scene/gui/tab_bar.cpp
@@ -634,6 +634,11 @@ bool TabBar::get_offset_buttons_visible() const {
void TabBar::set_tab_title(int p_tab, const String &p_title) {
ERR_FAIL_INDEX(p_tab, tabs.size());
+
+ if (tabs[p_tab].text == p_title) {
+ return;
+ }
+
tabs.write[p_tab].text = p_title;
_shape(p_tab);
@@ -690,6 +695,11 @@ String TabBar::get_tab_language(int p_tab) const {
void TabBar::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) {
ERR_FAIL_INDEX(p_tab, tabs.size());
+
+ if (tabs[p_tab].icon == p_icon) {
+ return;
+ }
+
tabs.write[p_tab].icon = p_icon;
_update_cache();
@@ -708,6 +718,11 @@ Ref<Texture2D> TabBar::get_tab_icon(int p_tab) const {
void TabBar::set_tab_disabled(int p_tab, bool p_disabled) {
ERR_FAIL_INDEX(p_tab, tabs.size());
+
+ if (tabs[p_tab].disabled == p_disabled) {
+ return;
+ }
+
tabs.write[p_tab].disabled = p_disabled;
_update_cache();
@@ -726,6 +741,11 @@ bool TabBar::is_tab_disabled(int p_tab) const {
void TabBar::set_tab_hidden(int p_tab, bool p_hidden) {
ERR_FAIL_INDEX(p_tab, tabs.size());
+
+ if (tabs[p_tab].hidden == p_hidden) {
+ return;
+ }
+
tabs.write[p_tab].hidden = p_hidden;
_update_cache();
@@ -744,6 +764,11 @@ bool TabBar::is_tab_hidden(int p_tab) const {
void TabBar::set_tab_button_icon(int p_tab, const Ref<Texture2D> &p_icon) {
ERR_FAIL_INDEX(p_tab, tabs.size());
+
+ if (tabs[p_tab].right_button == p_icon) {
+ return;
+ }
+
tabs.write[p_tab].right_button = p_icon;
_update_cache();
@@ -1155,6 +1180,11 @@ int TabBar::get_tab_idx_at_point(const Point2 &p_point) const {
void TabBar::set_tab_alignment(AlignmentMode p_alignment) {
ERR_FAIL_INDEX(p_alignment, ALIGNMENT_MAX);
+
+ if (tab_alignment == p_alignment) {
+ return;
+ }
+
tab_alignment = p_alignment;
_update_cache();
@@ -1374,6 +1404,11 @@ Rect2 TabBar::get_tab_rect(int p_tab) const {
void TabBar::set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy) {
ERR_FAIL_INDEX(p_policy, CLOSE_BUTTON_MAX);
+
+ if (cb_displaypolicy == p_policy) {
+ return;
+ }
+
cb_displaypolicy = p_policy;
_update_cache();
@@ -1391,6 +1426,11 @@ TabBar::CloseButtonDisplayPolicy TabBar::get_tab_close_display_policy() const {
void TabBar::set_max_tab_width(int p_width) {
ERR_FAIL_COND(p_width < 0);
+
+ if (max_width == p_width) {
+ return;
+ }
+
max_width = p_width;
_update_cache();
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 12f91a9873..10a6d18330 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -618,6 +618,10 @@ int TabContainer::get_tab_idx_from_control(Control *p_child) const {
}
void TabContainer::set_tab_alignment(TabBar::AlignmentMode p_alignment) {
+ if (tab_bar->get_tab_alignment() == p_alignment) {
+ return;
+ }
+
tab_bar->set_tab_alignment(p_alignment);
_update_margins();
}
@@ -679,6 +683,10 @@ void TabContainer::set_tab_title(int p_tab, const String &p_title) {
Control *child = get_tab_control(p_tab);
ERR_FAIL_COND(!child);
+ if (tab_bar->get_tab_title(p_tab) == p_title) {
+ return;
+ }
+
tab_bar->set_tab_title(p_tab, p_title);
if (p_title == child->get_name()) {
@@ -698,6 +706,10 @@ String TabContainer::get_tab_title(int p_tab) const {
}
void TabContainer::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) {
+ if (tab_bar->get_tab_icon(p_tab) == p_icon) {
+ return;
+ }
+
tab_bar->set_tab_icon(p_tab, p_icon);
_update_margins();
@@ -709,6 +721,10 @@ Ref<Texture2D> TabContainer::get_tab_icon(int p_tab) const {
}
void TabContainer::set_tab_disabled(int p_tab, bool p_disabled) {
+ if (tab_bar->is_tab_disabled(p_tab) == p_disabled) {
+ return;
+ }
+
tab_bar->set_tab_disabled(p_tab, p_disabled);
_update_margins();
@@ -725,6 +741,10 @@ void TabContainer::set_tab_hidden(int p_tab, bool p_hidden) {
Control *child = get_tab_control(p_tab);
ERR_FAIL_COND(!child);
+ if (tab_bar->is_tab_hidden(p_tab) == p_hidden) {
+ return;
+ }
+
tab_bar->set_tab_hidden(p_tab, p_hidden);
child->hide();
@@ -811,7 +831,11 @@ void TabContainer::set_popup(Node *p_popup) {
bool had_popup = get_popup();
Popup *popup = Object::cast_to<Popup>(p_popup);
- popup_obj_id = popup ? popup->get_instance_id() : ObjectID();
+ ObjectID popup_id = popup ? popup->get_instance_id() : ObjectID();
+ if (popup_obj_id == popup_id) {
+ return;
+ }
+ popup_obj_id = popup_id;
if (had_popup != bool(popup)) {
update();
@@ -855,6 +879,10 @@ int TabContainer::get_tabs_rearrange_group() const {
}
void TabContainer::set_use_hidden_tabs_for_min_size(bool p_use_hidden_tabs) {
+ if (use_hidden_tabs_for_min_size == p_use_hidden_tabs) {
+ return;
+ }
+
use_hidden_tabs_for_min_size = p_use_hidden_tabs;
update_minimum_size();
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 3755a8fa34..097eb1fd95 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -2889,6 +2889,10 @@ TextServer::StructuredTextParser TextEdit::get_structured_text_bidi_override() c
}
void TextEdit::set_structured_text_bidi_override_options(Array p_args) {
+ if (st_args == p_args) {
+ return;
+ }
+
st_args = p_args;
for (int i = 0; i < text.size(); i++) {
text.set(i, text[i], structured_text_parser(st_parser, st_args, text[i]));
@@ -2917,6 +2921,10 @@ int TextEdit::get_tab_size() const {
// User controls
void TextEdit::set_overtype_mode_enabled(const bool p_enabled) {
+ if (overtype_mode == p_enabled) {
+ return;
+ }
+
overtype_mode = p_enabled;
update();
}
@@ -3036,6 +3044,10 @@ int TextEdit::get_line_count() const {
}
void TextEdit::set_placeholder(const String &p_text) {
+ if (placeholder_text == p_text) {
+ return;
+ }
+
placeholder_text = p_text;
_update_placeholder();
update();
@@ -3945,6 +3957,10 @@ bool TextEdit::is_mouse_over_selection(bool p_edges) const {
/* Caret */
void TextEdit::set_caret_type(CaretType p_type) {
+ if (caret_type == p_type) {
+ return;
+ }
+
caret_type = p_type;
update();
}
@@ -3954,6 +3970,10 @@ TextEdit::CaretType TextEdit::get_caret_type() const {
}
void TextEdit::set_caret_blink_enabled(const bool p_enabled) {
+ if (caret_blink_enabled == p_enabled) {
+ return;
+ }
+
caret_blink_enabled = p_enabled;
if (has_focus()) {
@@ -4114,6 +4134,10 @@ String TextEdit::get_word_under_caret() const {
/* Selection. */
void TextEdit::set_selecting_enabled(const bool p_enabled) {
+ if (selecting_enabled == p_enabled) {
+ return;
+ }
+
selecting_enabled = p_enabled;
if (!selecting_enabled) {
@@ -4126,6 +4150,10 @@ bool TextEdit::is_selecting_enabled() const {
}
void TextEdit::set_deselect_on_focus_loss_enabled(const bool p_enabled) {
+ if (deselect_on_focus_loss_enabled == p_enabled) {
+ return;
+ }
+
deselect_on_focus_loss_enabled = p_enabled;
if (p_enabled && selection.active && !has_focus()) {
deselect();
@@ -4431,6 +4459,10 @@ bool TextEdit::is_smooth_scroll_enabled() const {
}
void TextEdit::set_scroll_past_end_of_file_enabled(const bool p_enabled) {
+ if (scroll_past_end_of_file_enabled == p_enabled) {
+ return;
+ }
+
scroll_past_end_of_file_enabled = p_enabled;
update();
}
@@ -4714,10 +4746,12 @@ void TextEdit::center_viewport_to_caret() {
/* Minimap */
void TextEdit::set_draw_minimap(bool p_enabled) {
- if (draw_minimap != p_enabled) {
- draw_minimap = p_enabled;
- _update_wrap_at_column();
+ if (draw_minimap == p_enabled) {
+ return;
}
+
+ draw_minimap = p_enabled;
+ _update_wrap_at_column();
update();
}
@@ -4726,10 +4760,12 @@ bool TextEdit::is_drawing_minimap() const {
}
void TextEdit::set_minimap_width(int p_minimap_width) {
- if (minimap_width != p_minimap_width) {
- minimap_width = p_minimap_width;
- _update_wrap_at_column();
+ if (minimap_width == p_minimap_width) {
+ return;
}
+
+ minimap_width = p_minimap_width;
+ _update_wrap_at_column();
update();
}
@@ -4780,6 +4816,11 @@ String TextEdit::get_gutter_name(int p_gutter) const {
void TextEdit::set_gutter_type(int p_gutter, GutterType p_type) {
ERR_FAIL_INDEX(p_gutter, gutters.size());
+
+ if (gutters[p_gutter].type == p_type) {
+ return;
+ }
+
gutters.write[p_gutter].type = p_type;
update();
}
@@ -4823,6 +4864,11 @@ bool TextEdit::is_gutter_drawn(int p_gutter) const {
void TextEdit::set_gutter_clickable(int p_gutter, bool p_clickable) {
ERR_FAIL_INDEX(p_gutter, gutters.size());
+
+ if (gutters[p_gutter].clickable == p_clickable) {
+ return;
+ }
+
gutters.write[p_gutter].clickable = p_clickable;
update();
}
@@ -4878,6 +4924,10 @@ void TextEdit::merge_gutters(int p_from_line, int p_to_line) {
void TextEdit::set_gutter_custom_draw(int p_gutter, const Callable &p_draw_callback) {
ERR_FAIL_INDEX(p_gutter, gutters.size());
+ if (gutters[p_gutter].custom_draw_callback == p_draw_callback) {
+ return;
+ }
+
gutters.write[p_gutter].custom_draw_callback = p_draw_callback;
update();
}
@@ -4898,6 +4948,11 @@ Variant TextEdit::get_line_gutter_metadata(int p_line, int p_gutter) const {
void TextEdit::set_line_gutter_text(int p_line, int p_gutter, const String &p_text) {
ERR_FAIL_INDEX(p_line, text.size());
ERR_FAIL_INDEX(p_gutter, gutters.size());
+
+ if (text.get_line_gutter_text(p_line, p_gutter) == p_text) {
+ return;
+ }
+
text.set_line_gutter_text(p_line, p_gutter, p_text);
update();
}
@@ -4911,6 +4966,11 @@ String TextEdit::get_line_gutter_text(int p_line, int p_gutter) const {
void TextEdit::set_line_gutter_icon(int p_line, int p_gutter, const Ref<Texture2D> &p_icon) {
ERR_FAIL_INDEX(p_line, text.size());
ERR_FAIL_INDEX(p_gutter, gutters.size());
+
+ if (text.get_line_gutter_icon(p_line, p_gutter) == p_icon) {
+ return;
+ }
+
text.set_line_gutter_icon(p_line, p_gutter, p_icon);
update();
}
@@ -4924,6 +4984,11 @@ Ref<Texture2D> TextEdit::get_line_gutter_icon(int p_line, int p_gutter) const {
void TextEdit::set_line_gutter_item_color(int p_line, int p_gutter, const Color &p_color) {
ERR_FAIL_INDEX(p_line, text.size());
ERR_FAIL_INDEX(p_gutter, gutters.size());
+
+ if (text.get_line_gutter_item_color(p_line, p_gutter) == p_color) {
+ return;
+ }
+
text.set_line_gutter_item_color(p_line, p_gutter, p_color);
update();
}
@@ -4949,6 +5014,11 @@ bool TextEdit::is_line_gutter_clickable(int p_line, int p_gutter) const {
// Line style
void TextEdit::set_line_background_color(int p_line, const Color &p_color) {
ERR_FAIL_INDEX(p_line, text.size());
+
+ if (text.get_line_background_color(p_line) == p_color) {
+ return;
+ }
+
text.set_line_background_color(p_line, p_color);
update();
}
@@ -4960,6 +5030,10 @@ Color TextEdit::get_line_background_color(int p_line) const {
/* Syntax Highlighting. */
void TextEdit::set_syntax_highlighter(Ref<SyntaxHighlighter> p_syntax_highlighter) {
+ if (syntax_highlighter == p_syntax_highlighter && syntax_highlighter.is_valid() == p_syntax_highlighter.is_valid()) {
+ return;
+ }
+
syntax_highlighter = p_syntax_highlighter;
if (syntax_highlighter.is_valid()) {
syntax_highlighter->set_text_edit(this);
@@ -4973,6 +5047,10 @@ Ref<SyntaxHighlighter> TextEdit::get_syntax_highlighter() const {
/* Visual. */
void TextEdit::set_highlight_current_line(bool p_enabled) {
+ if (highlight_current_line == p_enabled) {
+ return;
+ }
+
highlight_current_line = p_enabled;
update();
}
@@ -4982,6 +5060,10 @@ bool TextEdit::is_highlight_current_line_enabled() const {
}
void TextEdit::set_highlight_all_occurrences(const bool p_enabled) {
+ if (highlight_all_occurrences == p_enabled) {
+ return;
+ }
+
highlight_all_occurrences = p_enabled;
update();
}
@@ -5008,6 +5090,10 @@ bool TextEdit::get_draw_control_chars() const {
}
void TextEdit::set_draw_tabs(bool p_enabled) {
+ if (draw_tabs == p_enabled) {
+ return;
+ }
+
draw_tabs = p_enabled;
update();
}
@@ -5017,6 +5103,10 @@ bool TextEdit::is_drawing_tabs() const {
}
void TextEdit::set_draw_spaces(bool p_enabled) {
+ if (draw_spaces == p_enabled) {
+ return;
+ }
+
draw_spaces = p_enabled;
update();
}
@@ -5462,6 +5552,10 @@ void TextEdit::_bind_methods() {
/* Internal API for CodeEdit. */
// Line hiding.
void TextEdit::_set_hiding_enabled(bool p_enabled) {
+ if (hiding_enabled == p_enabled) {
+ return;
+ }
+
if (!p_enabled) {
_unhide_all_lines();
}
@@ -5488,6 +5582,11 @@ void TextEdit::_unhide_all_lines() {
void TextEdit::_set_line_as_hidden(int p_line, bool p_hidden) {
ERR_FAIL_INDEX(p_line, text.size());
+
+ if (text.is_hidden(p_line) == p_hidden) {
+ return;
+ }
+
if (_is_hiding_enabled() || !p_hidden) {
text.set_hidden(p_line, p_hidden);
}
@@ -5496,6 +5595,10 @@ void TextEdit::_set_line_as_hidden(int p_line, bool p_hidden) {
// Symbol lookup.
void TextEdit::_set_symbol_lookup_word(const String &p_symbol) {
+ if (lookup_symbol_word == p_symbol) {
+ return;
+ }
+
lookup_symbol_word = p_symbol;
update();
}
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 6711cf8c7f..f97f99075c 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -195,6 +195,9 @@ private:
void set(int p_line, const String &p_text, const Array &p_bidi_override);
void set_hidden(int p_line, bool p_hidden) {
+ if (text[p_line].hidden == p_hidden) {
+ return;
+ }
text.write[p_line].hidden = p_hidden;
if (!p_hidden && text[p_line].width > max_width) {
max_width = text[p_line].width;
diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp
index 26acfaaa70..916bb2981e 100644
--- a/scene/gui/texture_button.cpp
+++ b/scene/gui/texture_button.cpp
@@ -294,29 +294,48 @@ void TextureButton::_bind_methods() {
}
void TextureButton::set_normal_texture(const Ref<Texture2D> &p_normal) {
+ if (normal == p_normal) {
+ return;
+ }
+
normal = p_normal;
update();
update_minimum_size();
}
void TextureButton::set_pressed_texture(const Ref<Texture2D> &p_pressed) {
+ if (pressed == p_pressed) {
+ return;
+ }
+
pressed = p_pressed;
update();
update_minimum_size();
}
void TextureButton::set_hover_texture(const Ref<Texture2D> &p_hover) {
+ if (hover == p_hover) {
+ return;
+ }
+
hover = p_hover;
update();
update_minimum_size();
}
void TextureButton::set_disabled_texture(const Ref<Texture2D> &p_disabled) {
+ if (disabled == p_disabled) {
+ return;
+ }
+
disabled = p_disabled;
update();
}
void TextureButton::set_click_mask(const Ref<BitMap> &p_click_mask) {
+ if (click_mask == p_click_mask) {
+ return;
+ }
click_mask = p_click_mask;
update();
update_minimum_size();
@@ -355,12 +374,20 @@ bool TextureButton::get_ignore_texture_size() const {
}
void TextureButton::set_ignore_texture_size(bool p_ignore) {
+ if (ignore_texture_size == p_ignore) {
+ return;
+ }
+
ignore_texture_size = p_ignore;
update_minimum_size();
update();
}
void TextureButton::set_stretch_mode(StretchMode p_stretch_mode) {
+ if (stretch_mode == p_stretch_mode) {
+ return;
+ }
+
stretch_mode = p_stretch_mode;
update();
}
@@ -370,6 +397,10 @@ TextureButton::StretchMode TextureButton::get_stretch_mode() const {
}
void TextureButton::set_flip_h(bool p_flip) {
+ if (hflip == p_flip) {
+ return;
+ }
+
hflip = p_flip;
update();
}
@@ -379,6 +410,10 @@ bool TextureButton::is_flipped_h() const {
}
void TextureButton::set_flip_v(bool p_flip) {
+ if (vflip == p_flip) {
+ return;
+ }
+
vflip = p_flip;
update();
}
diff --git a/scene/gui/texture_progress_bar.cpp b/scene/gui/texture_progress_bar.cpp
index 94e0a6f226..2a9e1a8990 100644
--- a/scene/gui/texture_progress_bar.cpp
+++ b/scene/gui/texture_progress_bar.cpp
@@ -33,6 +33,10 @@
#include "core/config/engine.h"
void TextureProgressBar::set_under_texture(const Ref<Texture2D> &p_texture) {
+ if (under == p_texture) {
+ return;
+ }
+
under = p_texture;
update();
update_minimum_size();
@@ -43,6 +47,10 @@ Ref<Texture2D> TextureProgressBar::get_under_texture() const {
}
void TextureProgressBar::set_over_texture(const Ref<Texture2D> &p_texture) {
+ if (over == p_texture) {
+ return;
+ }
+
over = p_texture;
update();
if (under.is_null()) {
@@ -56,6 +64,11 @@ Ref<Texture2D> TextureProgressBar::get_over_texture() const {
void TextureProgressBar::set_stretch_margin(Side p_side, int p_size) {
ERR_FAIL_INDEX((int)p_side, 4);
+
+ if (stretch_margin[p_side] == p_size) {
+ return;
+ }
+
stretch_margin[p_side] = p_size;
update();
update_minimum_size();
@@ -67,6 +80,10 @@ int TextureProgressBar::get_stretch_margin(Side p_side) const {
}
void TextureProgressBar::set_nine_patch_stretch(bool p_stretch) {
+ if (nine_patch_stretch == p_stretch) {
+ return;
+ }
+
nine_patch_stretch = p_stretch;
update();
update_minimum_size();
@@ -91,6 +108,10 @@ Size2 TextureProgressBar::get_minimum_size() const {
}
void TextureProgressBar::set_progress_texture(const Ref<Texture2D> &p_texture) {
+ if (progress == p_texture) {
+ return;
+ }
+
progress = p_texture;
update();
update_minimum_size();
@@ -101,6 +122,10 @@ Ref<Texture2D> TextureProgressBar::get_progress_texture() const {
}
void TextureProgressBar::set_progress_offset(Point2 p_offset) {
+ if (progress_offset == p_offset) {
+ return;
+ }
+
progress_offset = p_offset;
update();
}
@@ -110,6 +135,10 @@ Point2 TextureProgressBar::get_progress_offset() const {
}
void TextureProgressBar::set_tint_under(const Color &p_tint) {
+ if (tint_under == p_tint) {
+ return;
+ }
+
tint_under = p_tint;
update();
}
@@ -119,6 +148,10 @@ Color TextureProgressBar::get_tint_under() const {
}
void TextureProgressBar::set_tint_progress(const Color &p_tint) {
+ if (tint_progress == p_tint) {
+ return;
+ }
+
tint_progress = p_tint;
update();
}
@@ -128,6 +161,10 @@ Color TextureProgressBar::get_tint_progress() const {
}
void TextureProgressBar::set_tint_over(const Color &p_tint) {
+ if (tint_over == p_tint) {
+ return;
+ }
+
tint_over = p_tint;
update();
}
@@ -548,6 +585,11 @@ void TextureProgressBar::_notification(int p_what) {
void TextureProgressBar::set_fill_mode(int p_fill) {
ERR_FAIL_INDEX(p_fill, FILL_MODE_MAX);
+
+ if (mode == (FillMode)p_fill) {
+ return;
+ }
+
mode = (FillMode)p_fill;
update();
}
@@ -563,6 +605,11 @@ void TextureProgressBar::set_radial_initial_angle(float p_angle) {
while (p_angle < 0) {
p_angle += 360;
}
+
+ if (rad_init_angle == p_angle) {
+ return;
+ }
+
rad_init_angle = p_angle;
update();
}
@@ -572,7 +619,13 @@ float TextureProgressBar::get_radial_initial_angle() {
}
void TextureProgressBar::set_fill_degrees(float p_angle) {
- rad_max_degrees = CLAMP(p_angle, 0, 360);
+ float angle_clamped = CLAMP(p_angle, 0, 360);
+
+ if (rad_max_degrees == angle_clamped) {
+ return;
+ }
+
+ rad_max_degrees = angle_clamped;
update();
}
@@ -581,6 +634,10 @@ float TextureProgressBar::get_fill_degrees() {
}
void TextureProgressBar::set_radial_center_offset(const Point2 &p_off) {
+ if (rad_center_off == p_off) {
+ return;
+ }
+
rad_center_off = p_off;
update();
}
diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp
index ecdf55caf0..4dd1c74c12 100644
--- a/scene/gui/texture_rect.cpp
+++ b/scene/gui/texture_rect.cpp
@@ -179,6 +179,10 @@ Ref<Texture2D> TextureRect::get_texture() const {
}
void TextureRect::set_ignore_texture_size(bool p_ignore) {
+ if (ignore_texture_size == p_ignore) {
+ return;
+ }
+
ignore_texture_size = p_ignore;
update();
update_minimum_size();
@@ -189,6 +193,10 @@ bool TextureRect::get_ignore_texture_size() const {
}
void TextureRect::set_stretch_mode(StretchMode p_mode) {
+ if (stretch_mode == p_mode) {
+ return;
+ }
+
stretch_mode = p_mode;
update();
}
@@ -198,6 +206,10 @@ TextureRect::StretchMode TextureRect::get_stretch_mode() const {
}
void TextureRect::set_flip_h(bool p_flip) {
+ if (hflip == p_flip) {
+ return;
+ }
+
hflip = p_flip;
update();
}
@@ -207,6 +219,10 @@ bool TextureRect::is_flipped_h() const {
}
void TextureRect::set_flip_v(bool p_flip) {
+ if (vflip == p_flip) {
+ return;
+ }
+
vflip = p_flip;
update();
}
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 1eb6c5a554..2b19ee4d0b 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -141,6 +141,10 @@ void TreeItem::_change_tree(Tree *p_tree) {
void TreeItem::set_cell_mode(int p_column, TreeCellMode p_mode) {
ERR_FAIL_INDEX(p_column, cells.size());
+ if (cells[p_column].mode == p_mode) {
+ return;
+ }
+
Cell &c = cells.write[p_column];
c.mode = p_mode;
c.min = 0;
@@ -166,6 +170,10 @@ TreeItem::TreeCellMode TreeItem::get_cell_mode(int p_column) const {
void TreeItem::set_checked(int p_column, bool p_checked) {
ERR_FAIL_INDEX(p_column, cells.size());
+ if (cells[p_column].checked == p_checked) {
+ return;
+ }
+
cells.write[p_column].checked = p_checked;
cells.write[p_column].indeterminate = false;
cells.write[p_column].cached_minimum_size_dirty = true;
@@ -259,6 +267,11 @@ void TreeItem::_propagate_check_through_parents(int p_column, bool p_emit_signal
void TreeItem::set_text(int p_column, String p_text) {
ERR_FAIL_INDEX(p_column, cells.size());
+
+ if (cells[p_column].text == p_text) {
+ return;
+ }
+
cells.write[p_column].text = p_text;
cells.write[p_column].dirty = true;
@@ -290,11 +303,14 @@ String TreeItem::get_text(int p_column) const {
void TreeItem::set_text_direction(int p_column, Control::TextDirection p_text_direction) {
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3);
- if (cells[p_column].text_direction != p_text_direction) {
- cells.write[p_column].text_direction = p_text_direction;
- cells.write[p_column].dirty = true;
- _changed_notify(p_column);
+
+ if (cells[p_column].text_direction == p_text_direction) {
+ return;
}
+
+ cells.write[p_column].text_direction = p_text_direction;
+ cells.write[p_column].dirty = true;
+ _changed_notify(p_column);
cells.write[p_column].cached_minimum_size_dirty = true;
}
@@ -323,6 +339,10 @@ TextServer::StructuredTextParser TreeItem::get_structured_text_bidi_override(int
void TreeItem::set_structured_text_bidi_override_options(int p_column, Array p_args) {
ERR_FAIL_INDEX(p_column, cells.size());
+ if (cells[p_column].st_args == p_args) {
+ return;
+ }
+
cells.write[p_column].st_args = p_args;
cells.write[p_column].dirty = true;
cells.write[p_column].cached_minimum_size_dirty = true;
@@ -355,6 +375,10 @@ String TreeItem::get_language(int p_column) const {
void TreeItem::set_suffix(int p_column, String p_suffix) {
ERR_FAIL_INDEX(p_column, cells.size());
+ if (cells[p_column].suffix == p_suffix) {
+ return;
+ }
+
cells.write[p_column].suffix = p_suffix;
cells.write[p_column].cached_minimum_size_dirty = true;
@@ -369,6 +393,10 @@ String TreeItem::get_suffix(int p_column) const {
void TreeItem::set_icon(int p_column, const Ref<Texture2D> &p_icon) {
ERR_FAIL_INDEX(p_column, cells.size());
+ if (cells[p_column].icon == p_icon) {
+ return;
+ }
+
cells.write[p_column].icon = p_icon;
cells.write[p_column].cached_minimum_size_dirty = true;
@@ -383,6 +411,10 @@ Ref<Texture2D> TreeItem::get_icon(int p_column) const {
void TreeItem::set_icon_region(int p_column, const Rect2 &p_icon_region) {
ERR_FAIL_INDEX(p_column, cells.size());
+ if (cells[p_column].icon_region == p_icon_region) {
+ return;
+ }
+
cells.write[p_column].icon_region = p_icon_region;
cells.write[p_column].cached_minimum_size_dirty = true;
@@ -396,6 +428,11 @@ Rect2 TreeItem::get_icon_region(int p_column) const {
void TreeItem::set_icon_modulate(int p_column, const Color &p_modulate) {
ERR_FAIL_INDEX(p_column, cells.size());
+
+ if (cells[p_column].icon_color == p_modulate) {
+ return;
+ }
+
cells.write[p_column].icon_color = p_modulate;
_changed_notify(p_column);
}
@@ -408,6 +445,10 @@ Color TreeItem::get_icon_modulate(int p_column) const {
void TreeItem::set_icon_max_width(int p_column, int p_max) {
ERR_FAIL_INDEX(p_column, cells.size());
+ if (cells[p_column].icon_max_w == p_max) {
+ return;
+ }
+
cells.write[p_column].icon_max_w = p_max;
cells.write[p_column].cached_minimum_size_dirty = true;
@@ -432,6 +473,10 @@ void TreeItem::set_range(int p_column, double p_value) {
p_value = cells[p_column].max;
}
+ if (cells[p_column].val == p_value) {
+ return;
+ }
+
cells.write[p_column].val = p_value;
cells.write[p_column].dirty = true;
_changed_notify(p_column);
@@ -449,6 +494,11 @@ bool TreeItem::is_range_exponential(int p_column) const {
void TreeItem::set_range_config(int p_column, double p_min, double p_max, double p_step, bool p_exp) {
ERR_FAIL_INDEX(p_column, cells.size());
+
+ if (cells[p_column].min == p_min && cells[p_column].max == p_max && cells[p_column].step == p_step && cells[p_column].expr == p_exp) {
+ return;
+ }
+
cells.write[p_column].min = p_min;
cells.write[p_column].max = p_max;
cells.write[p_column].step = p_step;
@@ -537,6 +587,10 @@ void TreeItem::uncollapse_tree() {
}
void TreeItem::set_custom_minimum_height(int p_height) {
+ if (custom_min_height == p_height) {
+ return;
+ }
+
custom_min_height = p_height;
for (Cell &c : cells) {
@@ -748,9 +802,10 @@ int TreeItem::get_child_count() {
return children_cache.size();
}
-Array TreeItem::get_children() {
+TypedArray<TreeItem> TreeItem::get_children() {
+ // Don't need to explicitly create children cache, because get_child_count creates it.
int size = get_child_count();
- Array arr;
+ TypedArray<TreeItem> arr;
arr.resize(size);
for (int i = 0; i < size; i++) {
arr[i] = children_cache[i];
@@ -770,6 +825,22 @@ int TreeItem::get_index() {
return idx - 1;
}
+#ifdef DEV_ENABLED
+void TreeItem::validate_cache() const {
+ if (!parent || parent->children_cache.is_empty()) {
+ return;
+ }
+ TreeItem *scan = parent->first_child;
+ int index = 0;
+ while (scan) {
+ DEV_ASSERT(parent->children_cache[index] == scan);
+ ++index;
+ scan = scan->get_next();
+ }
+ DEV_ASSERT(index == parent->children_cache.size());
+}
+#endif
+
void TreeItem::move_before(TreeItem *p_item) {
ERR_FAIL_NULL(p_item);
ERR_FAIL_COND(is_root);
@@ -797,7 +868,11 @@ void TreeItem::move_before(TreeItem *p_item) {
parent->children_cache.clear();
} else {
parent->first_child = this;
- parent->children_cache.insert(0, this);
+ // If the cache is empty, it has not been built but there
+ // are items in the tree (note p_item != nullptr,) so we cannot update it.
+ if (!parent->children_cache.is_empty()) {
+ parent->children_cache.insert(0, this);
+ }
}
prev = item_prev;
@@ -807,6 +882,8 @@ void TreeItem::move_before(TreeItem *p_item) {
if (tree && old_tree == tree) {
tree->update();
}
+
+ validate_cache();
}
void TreeItem::move_after(TreeItem *p_item) {
@@ -839,12 +916,17 @@ void TreeItem::move_after(TreeItem *p_item) {
if (next) {
parent->children_cache.clear();
} else {
- parent->children_cache.append(this);
+ // If the cache is empty, it has not been built but there
+ // are items in the tree (note p_item != nullptr,) so we cannot update it.
+ if (!parent->children_cache.is_empty()) {
+ parent->children_cache.append(this);
+ }
}
if (tree && old_tree == tree) {
tree->update();
}
+ validate_cache();
}
void TreeItem::remove_child(TreeItem *p_item) {
@@ -859,6 +941,7 @@ void TreeItem::remove_child(TreeItem *p_item) {
if (tree) {
tree->update();
}
+ validate_cache();
}
void TreeItem::set_selectable(int p_column, bool p_selectable) {
@@ -884,6 +967,9 @@ void TreeItem::set_as_cursor(int p_column) {
if (tree->select_mode != Tree::SELECT_MULTI) {
return;
}
+ if (tree->selected_col == p_column) {
+ return;
+ }
tree->selected_item = this;
tree->selected_col = p_column;
tree->update();
@@ -961,6 +1047,11 @@ void TreeItem::set_button(int p_column, int p_idx, const Ref<Texture2D> &p_butto
ERR_FAIL_COND(p_button.is_null());
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_INDEX(p_idx, cells[p_column].buttons.size());
+
+ if (cells[p_column].buttons[p_idx].texture == p_button) {
+ return;
+ }
+
cells.write[p_column].buttons.write[p_idx].texture = p_button;
cells.write[p_column].cached_minimum_size_dirty = true;
@@ -970,6 +1061,11 @@ void TreeItem::set_button(int p_column, int p_idx, const Ref<Texture2D> &p_butto
void TreeItem::set_button_color(int p_column, int p_idx, const Color &p_color) {
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_INDEX(p_idx, cells[p_column].buttons.size());
+
+ if (cells[p_column].buttons[p_idx].color == p_color) {
+ return;
+ }
+
cells.write[p_column].buttons.write[p_idx].color = p_color;
_changed_notify(p_column);
}
@@ -978,6 +1074,10 @@ void TreeItem::set_button_disabled(int p_column, int p_idx, bool p_disabled) {
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_INDEX(p_idx, cells[p_column].buttons.size());
+ if (cells[p_column].buttons[p_idx].disabled == p_disabled) {
+ return;
+ }
+
cells.write[p_column].buttons.write[p_idx].disabled = p_disabled;
cells.write[p_column].cached_minimum_size_dirty = true;
@@ -994,6 +1094,10 @@ bool TreeItem::is_button_disabled(int p_column, int p_idx) const {
void TreeItem::set_editable(int p_column, bool p_editable) {
ERR_FAIL_INDEX(p_column, cells.size());
+ if (cells[p_column].editable == p_editable) {
+ return;
+ }
+
cells.write[p_column].editable = p_editable;
cells.write[p_column].cached_minimum_size_dirty = true;
@@ -1007,6 +1111,11 @@ bool TreeItem::is_editable(int p_column) {
void TreeItem::set_custom_color(int p_column, const Color &p_color) {
ERR_FAIL_INDEX(p_column, cells.size());
+
+ if (cells[p_column].custom_color == true) {
+ return;
+ }
+
cells.write[p_column].custom_color = true;
cells.write[p_column].color = p_color;
_changed_notify(p_column);
@@ -1063,6 +1172,11 @@ String TreeItem::get_tooltip(int p_column) const {
void TreeItem::set_custom_bg_color(int p_column, const Color &p_color, bool p_bg_outline) {
ERR_FAIL_INDEX(p_column, cells.size());
+
+ if (cells[p_column].custom_bg_color && cells[p_column].custom_bg_outline == p_bg_outline && cells[p_column].bg_color == p_color) {
+ return;
+ }
+
cells.write[p_column].custom_bg_color = true;
cells.write[p_column].custom_bg_outline = p_bg_outline;
cells.write[p_column].bg_color = p_color;
@@ -1099,6 +1213,10 @@ bool TreeItem::is_custom_set_as_button(int p_column) const {
void TreeItem::set_text_alignment(int p_column, HorizontalAlignment p_alignment) {
ERR_FAIL_INDEX(p_column, cells.size());
+ if (cells[p_column].text_alignment == p_alignment) {
+ return;
+ }
+
cells.write[p_column].text_alignment = p_alignment;
cells.write[p_column].cached_minimum_size_dirty = true;
@@ -1113,6 +1231,10 @@ HorizontalAlignment TreeItem::get_text_alignment(int p_column) const {
void TreeItem::set_expand_right(int p_column, bool p_enable) {
ERR_FAIL_INDEX(p_column, cells.size());
+ if (cells[p_column].expand_right == p_enable) {
+ return;
+ }
+
cells.write[p_column].expand_right = p_enable;
cells.write[p_column].cached_minimum_size_dirty = true;
@@ -1125,6 +1247,10 @@ bool TreeItem::get_expand_right(int p_column) const {
}
void TreeItem::set_disable_folding(bool p_disable) {
+ if (disable_folding == p_disable) {
+ return;
+ }
+
disable_folding = p_disable;
for (Cell &c : cells) {
@@ -1396,6 +1522,7 @@ TreeItem::TreeItem(Tree *p_tree) {
TreeItem::~TreeItem() {
_unlink_from_tree();
+ validate_cache();
prev = nullptr;
clear_children();
_change_tree(nullptr);
@@ -3310,7 +3437,8 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) {
bool rtl = is_layout_rtl();
if (!mb->is_pressed()) {
- if (mb->get_button_index() == MouseButton::LEFT) {
+ if (mb->get_button_index() == MouseButton::LEFT ||
+ mb->get_button_index() == MouseButton::RIGHT) {
Point2 pos = mb->get_position();
if (rtl) {
pos.x = get_size().width - pos.x;
@@ -3324,14 +3452,16 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) {
int len = 0;
for (int i = 0; i < columns.size(); i++) {
len += get_column_width(i);
- if (pos.x < len) {
- emit_signal(SNAME("column_title_pressed"), i);
+ if (pos.x < static_cast<real_t>(len)) {
+ emit_signal(SNAME("column_title_clicked"), i, mb->get_button_index());
break;
}
}
}
}
+ }
+ if (mb->get_button_index() == MouseButton::LEFT) {
if (single_select_defer) {
select_single_item(single_select_defer, root, single_select_defer_column);
single_select_defer = nullptr;
@@ -3419,18 +3549,15 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) {
pos.y -= _get_title_button_height();
if (pos.y < 0) {
- if (mb->get_button_index() == MouseButton::LEFT) {
- pos.x += cache.offset.x;
- int len = 0;
- for (int i = 0; i < columns.size(); i++) {
- len += get_column_width(i);
- if (pos.x < len) {
- cache.click_type = Cache::CLICK_TITLE;
- cache.click_index = i;
- //cache.click_id=;
- update();
- break;
- }
+ pos.x += cache.offset.x;
+ int len = 0;
+ for (int i = 0; i < columns.size(); i++) {
+ len += get_column_width(i);
+ if (pos.x < static_cast<real_t>(len)) {
+ cache.click_type = Cache::CLICK_TITLE;
+ cache.click_index = i;
+ update();
+ break;
}
}
break;
@@ -3591,12 +3718,17 @@ bool Tree::edit_selected() {
} else if (c.mode == TreeItem::CELL_MODE_STRING || c.mode == TreeItem::CELL_MODE_RANGE) {
Rect2 popup_rect;
- Vector2 ofs(0, (text_editor->get_size().height - rect.size.height) / 2);
+ Vector2 ofs(0, Math::floor((text_editor->get_size().height - rect.size.height) / 2)); // "floor()" centers vertically.
Point2i textedpos = get_screen_position() + rect.position - ofs;
cache.text_editor_position = textedpos;
popup_rect.position = textedpos;
popup_rect.size = rect.size;
+
+ // Account for icon.
+ popup_rect.position.x += c.get_icon_size().x;
+ popup_rect.size.x -= c.get_icon_size().x;
+
text_editor->clear();
text_editor->set_text(c.mode == TreeItem::CELL_MODE_STRING ? c.text : String::num(c.val, Math::range_step_decimals(c.step)));
text_editor->select_all();
@@ -4068,6 +4200,10 @@ void Tree::clear() {
};
void Tree::set_hide_root(bool p_enabled) {
+ if (hide_root == p_enabled) {
+ return;
+ }
+
hide_root = p_enabled;
update();
}
@@ -4079,6 +4215,10 @@ bool Tree::is_root_hidden() const {
void Tree::set_column_custom_minimum_width(int p_column, int p_min_width) {
ERR_FAIL_INDEX(p_column, columns.size());
+ if (columns[p_column].custom_min_width == p_min_width) {
+ return;
+ }
+
if (p_min_width < 0) {
return;
}
@@ -4089,12 +4229,21 @@ void Tree::set_column_custom_minimum_width(int p_column, int p_min_width) {
void Tree::set_column_expand(int p_column, bool p_expand) {
ERR_FAIL_INDEX(p_column, columns.size());
+ if (columns[p_column].expand == p_expand) {
+ return;
+ }
+
columns.write[p_column].expand = p_expand;
update();
}
void Tree::set_column_expand_ratio(int p_column, int p_ratio) {
ERR_FAIL_INDEX(p_column, columns.size());
+
+ if (columns[p_column].expand_ratio == p_ratio) {
+ return;
+ }
+
columns.write[p_column].expand_ratio = p_ratio;
update();
}
@@ -4102,6 +4251,10 @@ void Tree::set_column_expand_ratio(int p_column, int p_ratio) {
void Tree::set_column_clip_content(int p_column, bool p_fit) {
ERR_FAIL_INDEX(p_column, columns.size());
+ if (columns[p_column].clip_content == p_fit) {
+ return;
+ }
+
columns.write[p_column].clip_content = p_fit;
update();
}
@@ -4424,6 +4577,10 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column, int p_button) const {
}
void Tree::set_column_titles_visible(bool p_show) {
+ if (show_column_titles == p_show) {
+ return;
+ }
+
show_column_titles = p_show;
update();
}
@@ -4434,6 +4591,11 @@ bool Tree::are_column_titles_visible() const {
void Tree::set_column_title(int p_column, const String &p_title) {
ERR_FAIL_INDEX(p_column, columns.size());
+
+ if (columns[p_column].title == p_title) {
+ return;
+ }
+
if (cache.font.is_null()) { // avoid a strange case that may corrupt stuff
update_cache();
}
@@ -4515,6 +4677,10 @@ void Tree::scroll_to_item(TreeItem *p_item, bool p_center_on_item) {
}
void Tree::set_h_scroll_enabled(bool p_enable) {
+ if (h_scroll_enabled == p_enable) {
+ return;
+ }
+
h_scroll_enabled = p_enable;
update_minimum_size();
}
@@ -4524,6 +4690,10 @@ bool Tree::is_h_scroll_enabled() const {
}
void Tree::set_v_scroll_enabled(bool p_enable) {
+ if (v_scroll_enabled == p_enable) {
+ return;
+ }
+
v_scroll_enabled = p_enable;
update_minimum_size();
}
@@ -4852,6 +5022,10 @@ void Tree::set_cursor_can_exit_tree(bool p_enable) {
}
void Tree::set_hide_folding(bool p_hide) {
+ if (hide_folding == p_hide) {
+ return;
+ }
+
hide_folding = p_hide;
update();
}
@@ -4997,7 +5171,7 @@ void Tree::_bind_methods() {
ADD_SIGNAL(MethodInfo("button_clicked", PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "TreeItem"), PropertyInfo(Variant::INT, "column"), PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::INT, "mouse_button_index")));
ADD_SIGNAL(MethodInfo("custom_popup_edited", PropertyInfo(Variant::BOOL, "arrow_clicked")));
ADD_SIGNAL(MethodInfo("item_activated"));
- ADD_SIGNAL(MethodInfo("column_title_pressed", PropertyInfo(Variant::INT, "column")));
+ ADD_SIGNAL(MethodInfo("column_title_clicked", PropertyInfo(Variant::INT, "column"), PropertyInfo(Variant::INT, "mouse_button_index")));
ADD_SIGNAL(MethodInfo("nothing_selected"));
BIND_ENUM_CONSTANT(SELECT_SINGLE);
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index f0819e2980..7f9c00b1b9 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -339,9 +339,16 @@ public:
TreeItem *get_child(int p_idx);
int get_visible_child_count();
int get_child_count();
- Array get_children();
+ TypedArray<TreeItem> get_children();
int get_index();
+#ifdef DEV_ENABLED
+ // This debugging code can be removed once the current refactoring of this class is complete.
+ void validate_cache() const;
+#else
+ void validate_cache() const {}
+#endif
+
void move_before(TreeItem *p_item);
void move_after(TreeItem *p_item);
diff --git a/scene/gui/video_stream_player.cpp b/scene/gui/video_stream_player.cpp
index f20a2ad67b..7baa4d44aa 100644
--- a/scene/gui/video_stream_player.cpp
+++ b/scene/gui/video_stream_player.cpp
@@ -208,6 +208,10 @@ Size2 VideoStreamPlayer::get_minimum_size() const {
}
void VideoStreamPlayer::set_expand(bool p_expand) {
+ if (expand == p_expand) {
+ return;
+ }
+
expand = p_expand;
update();
update_minimum_size();
@@ -306,6 +310,10 @@ bool VideoStreamPlayer::is_playing() const {
}
void VideoStreamPlayer::set_paused(bool p_paused) {
+ if (paused == p_paused) {
+ return;
+ }
+
paused = p_paused;
if (!p_paused && !can_process()) {
paused_from_tree = true;