summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/button.cpp2
-rw-r--r--scene/gui/control.cpp6
-rw-r--r--scene/gui/file_dialog.cpp8
-rw-r--r--scene/gui/file_dialog.h1
-rw-r--r--scene/gui/flow_container.cpp9
-rw-r--r--scene/gui/graph_edit.cpp2
-rw-r--r--scene/gui/item_list.cpp48
-rw-r--r--scene/gui/label.cpp6
-rw-r--r--scene/gui/line_edit.cpp2
-rw-r--r--scene/gui/option_button.cpp16
-rw-r--r--scene/gui/option_button.h3
-rw-r--r--scene/gui/popup_menu.cpp64
-rw-r--r--scene/gui/range.cpp5
-rw-r--r--scene/gui/range.h4
-rw-r--r--scene/gui/rich_text_label.cpp153
-rw-r--r--scene/gui/rich_text_label.h13
-rw-r--r--scene/gui/spin_box.cpp3
-rw-r--r--scene/gui/spin_box.h2
-rw-r--r--scene/gui/tab_bar.cpp2
-rw-r--r--scene/gui/tab_bar.h2
-rw-r--r--scene/gui/text_edit.cpp6
21 files changed, 315 insertions, 42 deletions
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 724714b93b..29a0681f9c 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -293,7 +293,7 @@ void Button::_notification(int p_what) {
int text_clip = size.width - style->get_minimum_size().width - icon_ofs.width;
text_buf->set_width(clip_text ? text_clip : -1);
- int text_width = clip_text ? MIN(text_clip, text_buf->get_size().x) : text_buf->get_size().x;
+ int text_width = MAX(1, clip_text ? MIN(text_clip, text_buf->get_size().x) : text_buf->get_size().x);
if (_internal_margin[SIDE_LEFT] > 0) {
text_clip -= _internal_margin[SIDE_LEFT] + get_theme_constant(SNAME("hseparation"));
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 2866a5ad6c..d2d1b5e9b7 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -2663,11 +2663,6 @@ void Control::set_default_cursor_shape(CursorShape p_shape) {
ERR_FAIL_INDEX(int(p_shape), CURSOR_MAX);
data.default_cursor = p_shape;
-
- if (!is_inside_tree()) {
- return;
- }
- get_viewport()->get_base_window()->update_mouse_cursor_shape();
}
Control::CursorShape Control::get_default_cursor_shape() const {
@@ -3229,6 +3224,7 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_custom_minimum_size"), &Control::get_custom_minimum_size);
ClassDB::bind_method(D_METHOD("get_parent_area_size"), &Control::get_parent_area_size);
ClassDB::bind_method(D_METHOD("get_global_position"), &Control::get_global_position);
+ ClassDB::bind_method(D_METHOD("get_screen_position"), &Control::get_screen_position);
ClassDB::bind_method(D_METHOD("get_rect"), &Control::get_rect);
ClassDB::bind_method(D_METHOD("get_global_rect"), &Control::get_global_rect);
ClassDB::bind_method(D_METHOD("set_focus_mode", "mode"), &Control::set_focus_mode);
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 678229683f..e71ab64535 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -176,7 +176,7 @@ void FileDialog::update_dir() {
if (dir_access->get_current_dir().is_network_share_path()) {
_update_drives(false);
drives->add_item(RTR("Network"));
- drives->set_item_disabled(drives->get_item_count() - 1, true);
+ drives->set_item_disabled(-1, true);
drives->select(drives->get_item_count() - 1);
} else {
drives->select(dir_access->get_current_drive());
@@ -919,9 +919,9 @@ void FileDialog::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "access", PROPERTY_HINT_ENUM, "Resources,User data,File system"), "set_access", "get_access");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "filters"), "set_filters", "get_filters");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_hidden_files"), "set_show_hidden_files", "is_showing_hidden_files");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_dir"), "set_current_dir", "get_current_dir");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_file"), "set_current_file", "get_current_file");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_path"), "set_current_path", "get_current_path");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_dir", PROPERTY_HINT_DIR, "", PROPERTY_USAGE_NONE), "set_current_dir", "get_current_dir");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_file", PROPERTY_HINT_FILE, "*", PROPERTY_USAGE_NONE), "set_current_file", "get_current_file");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_current_path", "get_current_path");
ADD_SIGNAL(MethodInfo("file_selected", PropertyInfo(Variant::STRING, "path")));
ADD_SIGNAL(MethodInfo("files_selected", PropertyInfo(Variant::PACKED_STRING_ARRAY, "paths")));
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 36a6b262b0..7a50efe40f 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -70,7 +70,6 @@ private:
Button *makedir;
Access access = ACCESS_RESOURCES;
- //Button *action;
VBoxContainer *vbox;
FileMode mode;
LineEdit *dir;
diff --git a/scene/gui/flow_container.cpp b/scene/gui/flow_container.cpp
index 3bd21f96b2..40aca555db 100644
--- a/scene/gui/flow_container.cpp
+++ b/scene/gui/flow_container.cpp
@@ -39,6 +39,11 @@ struct _LineData {
};
void FlowContainer::_resort() {
+ // Avoid resorting if invisible.
+ if (!is_visible_in_tree()) {
+ return;
+ }
+
int separation_horizontal = get_theme_constant(SNAME("hseparation"));
int separation_vertical = get_theme_constant(SNAME("vseparation"));
@@ -58,7 +63,7 @@ void FlowContainer::_resort() {
// First pass for line wrapping and minimum size calculation.
for (int i = 0; i < get_child_count(); i++) {
Control *child = Object::cast_to<Control>(get_child(i));
- if (!child || !child->is_visible_in_tree()) {
+ if (!child || !child->is_visible()) {
continue;
}
if (child->is_set_as_top_level()) {
@@ -128,7 +133,7 @@ void FlowContainer::_resort() {
for (int i = 0; i < get_child_count(); i++) {
Control *child = Object::cast_to<Control>(get_child(i));
- if (!child || !child->is_visible_in_tree()) {
+ if (!child || !child->is_visible()) {
continue;
}
if (child->is_set_as_top_level()) {
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index ab21c747cf..1394b4192f 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -1170,7 +1170,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
if (connecting) {
force_connection_drag_end();
} else {
- emit_signal(SNAME("popup_request"), get_screen_position() + b->get_position());
+ emit_signal(SNAME("popup_request"), b->get_position());
}
}
}
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index e83524b06c..8c0f696a9f 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -83,6 +83,9 @@ int ItemList::add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable) {
}
void ItemList::set_item_text(int p_idx, const String &p_text) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].text = p_text;
@@ -97,6 +100,9 @@ String ItemList::get_item_text(int p_idx) const {
}
void ItemList::set_item_text_direction(int p_idx, Control::TextDirection p_text_direction) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3);
if (items[p_idx].text_direction != p_text_direction) {
@@ -119,6 +125,9 @@ void ItemList::clear_item_opentype_features(int p_idx) {
}
void ItemList::set_item_opentype_feature(int p_idx, const String &p_name, int p_value) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
int32_t tag = TS->name_to_tag(p_name);
if (!items[p_idx].opentype_features.has(tag) || (int)items[p_idx].opentype_features[tag] != p_value) {
@@ -138,6 +147,9 @@ int ItemList::get_item_opentype_feature(int p_idx, const String &p_name) const {
}
void ItemList::set_item_language(int p_idx, const String &p_language) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
if (items[p_idx].language != p_language) {
items.write[p_idx].language = p_language;
@@ -152,6 +164,9 @@ String ItemList::get_item_language(int p_idx) const {
}
void ItemList::set_item_tooltip_enabled(int p_idx, const bool p_enabled) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].tooltip_enabled = p_enabled;
}
@@ -162,6 +177,9 @@ bool ItemList::is_item_tooltip_enabled(int p_idx) const {
}
void ItemList::set_item_tooltip(int p_idx, const String &p_tooltip) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].tooltip = p_tooltip;
@@ -175,6 +193,9 @@ String ItemList::get_item_tooltip(int p_idx) const {
}
void ItemList::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].icon = p_icon;
@@ -189,6 +210,9 @@ Ref<Texture2D> ItemList::get_item_icon(int p_idx) const {
}
void ItemList::set_item_icon_transposed(int p_idx, const bool p_transposed) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].icon_transposed = p_transposed;
@@ -203,6 +227,9 @@ bool ItemList::is_item_icon_transposed(int p_idx) const {
}
void ItemList::set_item_icon_region(int p_idx, const Rect2 &p_region) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].icon_region = p_region;
@@ -217,6 +244,9 @@ Rect2 ItemList::get_item_icon_region(int p_idx) const {
}
void ItemList::set_item_icon_modulate(int p_idx, const Color &p_modulate) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].icon_modulate = p_modulate;
@@ -230,6 +260,9 @@ Color ItemList::get_item_icon_modulate(int p_idx) const {
}
void ItemList::set_item_custom_bg_color(int p_idx, const Color &p_custom_bg_color) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].custom_bg = p_custom_bg_color;
@@ -243,6 +276,9 @@ Color ItemList::get_item_custom_bg_color(int p_idx) const {
}
void ItemList::set_item_custom_fg_color(int p_idx, const Color &p_custom_fg_color) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].custom_fg = p_custom_fg_color;
@@ -256,6 +292,9 @@ Color ItemList::get_item_custom_fg_color(int p_idx) const {
}
void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture2D> &p_tag_icon) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].tag_icon = p_tag_icon;
@@ -270,6 +309,9 @@ Ref<Texture2D> ItemList::get_item_tag_icon(int p_idx) const {
}
void ItemList::set_item_selectable(int p_idx, bool p_selectable) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].selectable = p_selectable;
@@ -281,6 +323,9 @@ bool ItemList::is_item_selectable(int p_idx) const {
}
void ItemList::set_item_disabled(int p_idx, bool p_disabled) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].disabled = p_disabled;
@@ -293,6 +338,9 @@ bool ItemList::is_item_disabled(int p_idx) const {
}
void ItemList::set_item_metadata(int p_idx, const Variant &p_metadata) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].metadata = p_metadata;
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 419901d5ea..cd6fc168c2 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -115,7 +115,7 @@ void Label::_shape() {
if (lines_dirty) {
for (int i = 0; i < lines_rid.size(); i++) {
- TS->free(lines_rid[i]);
+ TS->free_rid(lines_rid[i]);
}
lines_rid.clear();
@@ -960,8 +960,8 @@ Label::Label(const String &p_text) {
Label::~Label() {
for (int i = 0; i < lines_rid.size(); i++) {
- TS->free(lines_rid[i]);
+ TS->free_rid(lines_rid[i]);
}
lines_rid.clear();
- TS->free(text_rid);
+ TS->free_rid(text_rid);
}
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index da39a3d387..e063d3aeba 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -2458,5 +2458,5 @@ LineEdit::LineEdit(const String &p_placeholder) {
}
LineEdit::~LineEdit() {
- TS->free(text_rid);
+ TS->free_rid(text_rid);
}
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index b3804e73d9..1e8a149e11 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -240,6 +240,10 @@ void OptionButton::set_item_metadata(int p_idx, const Variant &p_metadata) {
popup->set_item_metadata(p_idx, p_metadata);
}
+void OptionButton::set_item_tooltip(int p_idx, const String &p_tooltip) {
+ popup->set_item_tooltip(p_idx, p_tooltip);
+}
+
void OptionButton::set_item_disabled(int p_idx, bool p_disabled) {
popup->set_item_disabled(p_idx, p_disabled);
}
@@ -268,6 +272,10 @@ Variant OptionButton::get_item_metadata(int p_idx) const {
return popup->get_item_metadata(p_idx);
}
+String OptionButton::get_item_tooltip(int p_idx) const {
+ return popup->get_item_tooltip(p_idx);
+}
+
bool OptionButton::is_item_disabled(int p_idx) const {
return popup->is_item_disabled(p_idx);
}
@@ -377,6 +385,12 @@ void OptionButton::get_translatable_strings(List<String> *p_strings) const {
popup->get_translatable_strings(p_strings);
}
+void OptionButton::_validate_property(PropertyInfo &property) const {
+ if (property.name == "text" || property.name == "icon") {
+ property.usage = PROPERTY_USAGE_NONE;
+ }
+}
+
void OptionButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_item", "label", "id"), &OptionButton::add_item, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("add_icon_item", "texture", "label", "id"), &OptionButton::add_icon_item, DEFVAL(-1));
@@ -385,11 +399,13 @@ void OptionButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_item_disabled", "idx", "disabled"), &OptionButton::set_item_disabled);
ClassDB::bind_method(D_METHOD("set_item_id", "idx", "id"), &OptionButton::set_item_id);
ClassDB::bind_method(D_METHOD("set_item_metadata", "idx", "metadata"), &OptionButton::set_item_metadata);
+ ClassDB::bind_method(D_METHOD("set_item_tooltip", "idx", "tooltip"), &OptionButton::set_item_tooltip);
ClassDB::bind_method(D_METHOD("get_item_text", "idx"), &OptionButton::get_item_text);
ClassDB::bind_method(D_METHOD("get_item_icon", "idx"), &OptionButton::get_item_icon);
ClassDB::bind_method(D_METHOD("get_item_id", "idx"), &OptionButton::get_item_id);
ClassDB::bind_method(D_METHOD("get_item_index", "id"), &OptionButton::get_item_index);
ClassDB::bind_method(D_METHOD("get_item_metadata", "idx"), &OptionButton::get_item_metadata);
+ ClassDB::bind_method(D_METHOD("get_item_tooltip", "idx"), &OptionButton::get_item_tooltip);
ClassDB::bind_method(D_METHOD("is_item_disabled", "idx"), &OptionButton::is_item_disabled);
ClassDB::bind_method(D_METHOD("add_separator"), &OptionButton::add_separator);
ClassDB::bind_method(D_METHOD("clear"), &OptionButton::clear);
diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h
index 5352fe18a6..732730e0f4 100644
--- a/scene/gui/option_button.h
+++ b/scene/gui/option_button.h
@@ -53,6 +53,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;
+ virtual void _validate_property(PropertyInfo &property) const override;
static void _bind_methods();
public:
@@ -68,6 +69,7 @@ public:
void set_item_id(int p_idx, int p_id);
void set_item_metadata(int p_idx, const Variant &p_metadata);
void set_item_disabled(int p_idx, bool p_disabled);
+ void set_item_tooltip(int p_idx, const String &p_tooltip);
String get_item_text(int p_idx) const;
Ref<Texture2D> get_item_icon(int p_idx) const;
@@ -75,6 +77,7 @@ public:
int get_item_index(int p_id) const;
Variant get_item_metadata(int p_idx) const;
bool is_item_disabled(int p_idx) const;
+ String get_item_tooltip(int p_idx) const;
void set_item_count(int p_count);
int get_item_count() const;
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 840c3d5c31..9fc1fb072c 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -999,9 +999,16 @@ void PopupMenu::add_submenu_item(const String &p_label, const String &p_submenu,
/* Methods to modify existing items. */
void PopupMenu::set_item_text(int p_idx, const String &p_text) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].text == p_text) {
+ return;
+ }
items.write[p_idx].text = p_text;
items.write[p_idx].xl_text = atr(p_text);
+ items.write[p_idx].dirty = true;
_shape_item(p_idx);
control->update();
@@ -1009,6 +1016,9 @@ void PopupMenu::set_item_text(int p_idx, const String &p_text) {
}
void PopupMenu::set_item_text_direction(int p_item, Control::TextDirection p_text_direction) {
+ if (p_item < 0) {
+ p_item += get_item_count();
+ }
ERR_FAIL_INDEX(p_item, items.size());
ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3);
if (items[p_item].text_direction != p_text_direction) {
@@ -1019,6 +1029,9 @@ void PopupMenu::set_item_text_direction(int p_item, Control::TextDirection p_tex
}
void PopupMenu::clear_item_opentype_features(int p_item) {
+ if (p_item < 0) {
+ p_item += get_item_count();
+ }
ERR_FAIL_INDEX(p_item, items.size());
items.write[p_item].opentype_features.clear();
items.write[p_item].dirty = true;
@@ -1026,6 +1039,9 @@ void PopupMenu::clear_item_opentype_features(int p_item) {
}
void PopupMenu::set_item_opentype_feature(int p_item, const String &p_name, int p_value) {
+ if (p_item < 0) {
+ p_item += get_item_count();
+ }
ERR_FAIL_INDEX(p_item, items.size());
int32_t tag = TS->name_to_tag(p_name);
if (!items[p_item].opentype_features.has(tag) || (int)items[p_item].opentype_features[tag] != p_value) {
@@ -1036,6 +1052,9 @@ void PopupMenu::set_item_opentype_feature(int p_item, const String &p_name, int
}
void PopupMenu::set_item_language(int p_item, const String &p_language) {
+ if (p_item < 0) {
+ p_item += get_item_count();
+ }
ERR_FAIL_INDEX(p_item, items.size());
if (items[p_item].language != p_language) {
items.write[p_item].language = p_language;
@@ -1045,6 +1064,9 @@ void PopupMenu::set_item_language(int p_item, const String &p_language) {
}
void PopupMenu::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].icon = p_icon;
@@ -1053,6 +1075,9 @@ void PopupMenu::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
}
void PopupMenu::set_item_checked(int p_idx, bool p_checked) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].checked = p_checked;
@@ -1062,6 +1087,9 @@ void PopupMenu::set_item_checked(int p_idx, bool p_checked) {
}
void PopupMenu::set_item_id(int p_idx, int p_id) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].id = p_id;
@@ -1070,6 +1098,9 @@ void PopupMenu::set_item_id(int p_idx, int p_id) {
}
void PopupMenu::set_item_accelerator(int p_idx, Key p_accel) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].accel = p_accel;
items.write[p_idx].dirty = true;
@@ -1079,6 +1110,9 @@ void PopupMenu::set_item_accelerator(int p_idx, Key p_accel) {
}
void PopupMenu::set_item_metadata(int p_idx, const Variant &p_meta) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].metadata = p_meta;
control->update();
@@ -1086,6 +1120,9 @@ void PopupMenu::set_item_metadata(int p_idx, const Variant &p_meta) {
}
void PopupMenu::set_item_disabled(int p_idx, bool p_disabled) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].disabled = p_disabled;
control->update();
@@ -1093,6 +1130,9 @@ void PopupMenu::set_item_disabled(int p_idx, bool p_disabled) {
}
void PopupMenu::set_item_submenu(int p_idx, const String &p_submenu) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].submenu = p_submenu;
control->update();
@@ -1201,6 +1241,9 @@ int PopupMenu::get_item_state(int p_idx) const {
}
void PopupMenu::set_item_as_separator(int p_idx, bool p_separator) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].separator = p_separator;
control->update();
@@ -1212,24 +1255,36 @@ bool PopupMenu::is_item_separator(int p_idx) const {
}
void PopupMenu::set_item_as_checkable(int p_idx, bool p_checkable) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].checkable_type = p_checkable ? Item::CHECKABLE_TYPE_CHECK_BOX : Item::CHECKABLE_TYPE_NONE;
control->update();
}
void PopupMenu::set_item_as_radio_checkable(int p_idx, bool p_radio_checkable) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].checkable_type = p_radio_checkable ? Item::CHECKABLE_TYPE_RADIO_BUTTON : Item::CHECKABLE_TYPE_NONE;
control->update();
}
void PopupMenu::set_item_tooltip(int p_idx, const String &p_tooltip) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].tooltip = p_tooltip;
control->update();
}
void PopupMenu::set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bool p_global) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
if (items[p_idx].shortcut.is_valid()) {
_unref_shortcut(items[p_idx].shortcut);
@@ -1246,6 +1301,9 @@ void PopupMenu::set_item_shortcut(int p_idx, const Ref<Shortcut> &p_shortcut, bo
}
void PopupMenu::set_item_h_offset(int p_idx, int p_offset) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].h_ofs = p_offset;
control->update();
@@ -1253,12 +1311,18 @@ void PopupMenu::set_item_h_offset(int p_idx, int p_offset) {
}
void PopupMenu::set_item_multistate(int p_idx, int p_state) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].state = p_state;
control->update();
}
void PopupMenu::set_item_shortcut_disabled(int p_idx, bool p_disabled) {
+ if (p_idx < 0) {
+ p_idx += get_item_count();
+ }
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].shortcut_is_disabled = p_disabled;
control->update();
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index 879f25c8d8..2fb6452a97 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -40,6 +40,9 @@ TypedArray<String> Range::get_configuration_warnings() const {
return warnings;
}
+void Range::_value_changed(double p_value) {
+ GDVIRTUAL_CALL(_value_changed, p_value);
+}
void Range::_value_changed_notify() {
_value_changed(shared->val);
emit_signal(SNAME("value_changed"), shared->val);
@@ -279,6 +282,8 @@ void Range::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_greater"), "set_allow_greater", "is_greater_allowed");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_lesser"), "set_allow_lesser", "is_lesser_allowed");
+ GDVIRTUAL_BIND(_value_changed);
+
ADD_LINKED_PROPERTY("min_value", "value");
ADD_LINKED_PROPERTY("min_value", "max_value");
ADD_LINKED_PROPERTY("min_value", "page");
diff --git a/scene/gui/range.h b/scene/gui/range.h
index c27eeee13c..597c50ca26 100644
--- a/scene/gui/range.h
+++ b/scene/gui/range.h
@@ -62,12 +62,14 @@ class Range : public Control {
void _validate_values();
protected:
- virtual void _value_changed(double) {}
+ virtual void _value_changed(double p_value);
static void _bind_methods();
bool _rounded_values = false;
+ GDVIRTUAL1(_value_changed, double)
+
public:
void set_value(double p_val);
void set_min(double p_min);
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index bad7be7d42..d585fb3a7a 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -699,7 +699,6 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
Item *it_from = l.from;
Item *it_to = (p_line + 1 < p_frame->lines.size()) ? p_frame->lines[p_line + 1].from : nullptr;
- Variant meta;
if (it_from == nullptr) {
return 0;
@@ -902,9 +901,10 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
for (int i = 0; i < gl_size; i++) {
Item *it = _get_item_at_pos(it_from, it_to, glyphs[i].start);
int size = _find_outline_size(it, p_outline_size);
- Color font_color = _find_outline_color(it, p_outline_color);
+ Color font_color = _find_color(it, p_base_color);
+ Color font_outline_color = _find_outline_color(it, p_outline_color);
Color font_shadow_color = p_font_shadow_color;
- if ((size <= 0 || font_color.a == 0) && (font_shadow_color.a == 0)) {
+ if ((size <= 0 || font_outline_color.a == 0) && (font_shadow_color.a == 0)) {
gloff.x += glyphs[i].advance;
continue;
}
@@ -950,11 +950,11 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
faded_visibility -= (float)(glyphs[i].start - fade->starting_index) / (float)fade->length;
faded_visibility = faded_visibility < 0.0f ? 0.0f : faded_visibility;
}
- font_color.a = faded_visibility;
+ font_outline_color.a = faded_visibility;
font_shadow_color.a = faded_visibility;
}
- bool visible = (font_color.a != 0) || (font_shadow_color.a != 0);
+ bool visible = (font_outline_color.a != 0) || (font_shadow_color.a != 0);
for (int j = 0; j < fx_stack.size(); j++) {
ItemFX *item_fx = fx_stack[j];
@@ -1024,18 +1024,20 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
}
// Draw glyph outlines.
+ const Color modulated_outline_color = font_outline_color * Color(1, 1, 1, font_color.a);
+ const Color modulated_shadow_color = font_shadow_color * Color(1, 1, 1, font_color.a);
for (int j = 0; j < glyphs[i].repeat; j++) {
if (visible) {
bool skip = (trim_chars && l.char_offset + glyphs[i].end > visible_characters) || (trim_glyphs_ltr && (processed_glyphs_ol >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_ol < total_glyphs - visible_glyphs));
if (!skip && frid != RID()) {
- if (font_shadow_color.a > 0) {
- TS->font_draw_glyph(frid, ci, glyphs[i].font_size, p_ofs + fx_offset + gloff + p_shadow_ofs, gl, font_shadow_color);
+ if (modulated_shadow_color.a > 0) {
+ TS->font_draw_glyph(frid, ci, glyphs[i].font_size, p_ofs + fx_offset + gloff + p_shadow_ofs, gl, modulated_shadow_color);
}
- if (font_shadow_color.a > 0 && p_shadow_outline_size > 0) {
- TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, p_shadow_outline_size, p_ofs + fx_offset + gloff + p_shadow_ofs, gl, font_shadow_color);
+ if (modulated_shadow_color.a > 0 && p_shadow_outline_size > 0) {
+ TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, p_shadow_outline_size, p_ofs + fx_offset + gloff + p_shadow_ofs, gl, modulated_shadow_color);
}
- if (font_color.a != 0.0 && size > 0) {
- TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff, gl, font_color);
+ if (modulated_outline_color.a != 0.0 && size > 0) {
+ TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff, gl, modulated_outline_color);
}
}
processed_glyphs_ol++;
@@ -1067,23 +1069,60 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
}
}
+ Vector2 ul_start;
+ bool ul_started = false;
+ Color ul_color;
+
+ Vector2 dot_ul_start;
+ bool dot_ul_started = false;
+ Color dot_ul_color;
+
+ Vector2 st_start;
+ bool st_started = false;
+ Color st_color;
+
for (int i = 0; i < gl_size; i++) {
bool selected = selection.active && (sel_start != -1) && (glyphs[i].start >= sel_start) && (glyphs[i].end <= sel_end);
Item *it = _get_item_at_pos(it_from, it_to, glyphs[i].start);
Color font_color = _find_color(it, p_base_color);
- if (_find_underline(it) || (_find_meta(it, &meta) && underline_meta)) {
- Color uc = font_color;
- uc.a *= 0.5;
+ if (_find_underline(it) || (_find_meta(it, nullptr) && underline_meta)) {
+ if (!ul_started) {
+ ul_started = true;
+ ul_start = p_ofs + Vector2(off.x, off.y);
+ ul_color = font_color;
+ ul_color.a *= 0.5;
+ }
+ } else if (ul_started) {
+ ul_started = false;
float y_off = TS->shaped_text_get_underline_position(rid);
float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale();
- draw_line(p_ofs + Vector2(off.x, off.y + y_off), p_ofs + Vector2(off.x + glyphs[i].advance * glyphs[i].repeat, off.y + y_off), uc, underline_width);
+ draw_line(ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), ul_color, underline_width);
+ }
+ if (_find_hint(it, nullptr) && underline_hint) {
+ if (!dot_ul_started) {
+ dot_ul_started = true;
+ dot_ul_start = p_ofs + Vector2(off.x, off.y);
+ dot_ul_color = font_color;
+ dot_ul_color.a *= 0.5;
+ }
+ } else if (dot_ul_started) {
+ dot_ul_started = false;
+ float y_off = TS->shaped_text_get_underline_position(rid);
+ float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale();
+ draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2);
}
if (_find_strikethrough(it)) {
- Color uc = font_color;
- uc.a *= 0.5;
+ if (!st_started) {
+ st_started = true;
+ st_start = p_ofs + Vector2(off.x, off.y);
+ st_color = font_color;
+ st_color.a *= 0.5;
+ }
+ } else if (st_started) {
+ st_started = false;
float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2;
float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale();
- draw_line(p_ofs + Vector2(off.x, off.y + y_off), p_ofs + Vector2(off.x + glyphs[i].advance * glyphs[i].repeat, off.y + y_off), uc, underline_width);
+ draw_line(st_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), st_color, underline_width);
}
// Get FX.
@@ -1219,6 +1258,24 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
off.x += glyphs[i].advance;
}
}
+ if (ul_started) {
+ ul_started = false;
+ float y_off = TS->shaped_text_get_underline_position(rid);
+ float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale();
+ draw_line(ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), ul_color, underline_width);
+ }
+ if (dot_ul_started) {
+ dot_ul_started = false;
+ float y_off = TS->shaped_text_get_underline_position(rid);
+ float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale();
+ draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2);
+ }
+ if (st_started) {
+ st_started = false;
+ float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2;
+ float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale();
+ draw_line(st_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), st_color, underline_width);
+ }
// Draw foreground color box
_draw_fbg_boxes(ci, rid, fbg_line_off, it_from, it_to, chr_range.x, chr_range.y, 1);
@@ -1904,6 +1961,20 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
}
}
+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);
+
+ String description;
+ if (c_item && !outside && const_cast<RichTextLabel *>(this)->_find_hint(c_item, &description)) {
+ return description;
+ } else {
+ return Control::get_tooltip(p_pos);
+ }
+}
+
void RichTextLabel::_find_frame(Item *p_item, ItemFrame **r_frame, int *r_line) {
if (r_frame != nullptr) {
*r_frame = nullptr;
@@ -2241,6 +2312,24 @@ bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item)
return false;
}
+bool RichTextLabel::_find_hint(Item *p_item, String *r_description) {
+ Item *item = p_item;
+
+ while (item) {
+ if (item->type == ITEM_HINT) {
+ ItemHint *hint = static_cast<ItemHint *>(item);
+ if (r_description) {
+ *r_description = hint->description;
+ }
+ return true;
+ }
+
+ item = item->parent;
+ }
+
+ return false;
+}
+
Color RichTextLabel::_find_bgcolor(Item *p_item) {
Item *item = p_item;
@@ -2733,6 +2822,14 @@ void RichTextLabel::push_meta(const Variant &p_meta) {
_add_item(item, true);
}
+void RichTextLabel::push_hint(const String &p_string) {
+ ERR_FAIL_COND(current->type == ITEM_TABLE);
+ ItemHint *item = memnew(ItemHint);
+
+ item->description = p_string;
+ _add_item(item, true);
+}
+
void RichTextLabel::push_table(int p_columns, InlineAlignment p_alignment) {
ERR_FAIL_COND(p_columns < 1);
ItemTable *item = memnew(ItemTable);
@@ -2927,6 +3024,15 @@ bool RichTextLabel::is_meta_underlined() const {
return underline_meta;
}
+void RichTextLabel::set_hint_underline(bool p_underline) {
+ underline_hint = p_underline;
+ update();
+}
+
+bool RichTextLabel::is_hint_underlined() const {
+ return underline_hint;
+}
+
void RichTextLabel::set_override_selected_font_color(bool p_override_selected_font_color) {
override_selected_font_color = p_override_selected_font_color;
}
@@ -3364,6 +3470,11 @@ void RichTextLabel::append_text(const String &p_bbcode) {
push_meta(url);
pos = brk_end + 1;
tag_stack.push_front("url");
+ } else if (tag.begins_with("hint=")) {
+ String description = tag.substr(5, tag.length());
+ push_hint(description);
+ pos = brk_end + 1;
+ tag_stack.push_front("hint");
} else if (tag.begins_with("dropcap")) {
Vector<String> subtag = tag.substr(5, tag.length()).split(" ");
Ref<Font> f = get_theme_font(SNAME("normal_font"));
@@ -4284,6 +4395,7 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("push_indent", "level"), &RichTextLabel::push_indent);
ClassDB::bind_method(D_METHOD("push_list", "level", "type", "capitalize"), &RichTextLabel::push_list);
ClassDB::bind_method(D_METHOD("push_meta", "data"), &RichTextLabel::push_meta);
+ ClassDB::bind_method(D_METHOD("push_hint", "description"), &RichTextLabel::push_hint);
ClassDB::bind_method(D_METHOD("push_underline"), &RichTextLabel::push_underline);
ClassDB::bind_method(D_METHOD("push_strikethrough"), &RichTextLabel::push_strikethrough);
ClassDB::bind_method(D_METHOD("push_table", "columns", "inline_align"), &RichTextLabel::push_table, DEFVAL(INLINE_ALIGNMENT_TOP));
@@ -4315,6 +4427,9 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_meta_underline", "enable"), &RichTextLabel::set_meta_underline);
ClassDB::bind_method(D_METHOD("is_meta_underlined"), &RichTextLabel::is_meta_underlined);
+ ClassDB::bind_method(D_METHOD("set_hint_underline", "enable"), &RichTextLabel::set_hint_underline);
+ ClassDB::bind_method(D_METHOD("is_hint_underlined"), &RichTextLabel::is_hint_underlined);
+
ClassDB::bind_method(D_METHOD("set_override_selected_font_color", "override"), &RichTextLabel::set_override_selected_font_color);
ClassDB::bind_method(D_METHOD("is_overriding_selected_font_color"), &RichTextLabel::is_overriding_selected_font_color);
@@ -4398,6 +4513,7 @@ void RichTextLabel::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deselect_on_focus_loss_enabled"), "set_deselect_on_focus_loss_enabled", "is_deselect_on_focus_loss_enabled");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "custom_effects", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "RichTextEffect"), (PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE)), "set_effects", "get_effects");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meta_underlined"), "set_meta_underline", "is_meta_underlined");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hint_underlined"), "set_hint_underline", "is_hint_underlined");
ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode");
// Note: "visible_characters" and "percent_visible" should be set after "text" to be correctly applied.
@@ -4451,6 +4567,7 @@ void RichTextLabel::_bind_methods() {
BIND_ENUM_CONSTANT(ITEM_BGCOLOR);
BIND_ENUM_CONSTANT(ITEM_FGCOLOR);
BIND_ENUM_CONSTANT(ITEM_META);
+ BIND_ENUM_CONSTANT(ITEM_HINT);
BIND_ENUM_CONSTANT(ITEM_DROPCAP);
BIND_ENUM_CONSTANT(ITEM_CUSTOMFX);
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 076b68a0da..c9cbbe9d15 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -78,6 +78,7 @@ public:
ITEM_BGCOLOR,
ITEM_FGCOLOR,
ITEM_META,
+ ITEM_HINT,
ITEM_DROPCAP,
ITEM_CUSTOMFX
};
@@ -218,6 +219,11 @@ private:
ItemMeta() { type = ITEM_META; }
};
+ struct ItemHint : public Item {
+ String description;
+ ItemHint() { type = ITEM_HINT; }
+ };
+
struct ItemParagraph : public Item {
HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT;
String language;
@@ -369,6 +375,7 @@ private:
int tab_size = 4;
bool underline_meta = true;
+ bool underline_hint = true;
bool override_selected_font_color = false;
HorizontalAlignment default_alignment = HORIZONTAL_ALIGNMENT_LEFT;
@@ -452,6 +459,7 @@ private:
bool _find_underline(Item *p_item);
bool _find_strikethrough(Item *p_item);
bool _find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item = nullptr);
+ bool _find_hint(Item *p_item, String *r_description);
Color _find_bgcolor(Item *p_item);
Color _find_fgcolor(Item *p_item);
bool _find_layout_subitem(Item *from, Item *to);
@@ -462,6 +470,7 @@ private:
void _scroll_changed(double);
virtual void gui_input(const Ref<InputEvent> &p_event) override;
+ virtual String get_tooltip(const Point2 &p_pos) const override;
Item *_get_next_item(Item *p_item, bool p_free = false) const;
Item *_get_prev_item(Item *p_item, bool p_free = false) const;
@@ -505,6 +514,7 @@ public:
void push_indent(int p_level);
void push_list(int p_level, ListType p_list, bool p_capitalize);
void push_meta(const Variant &p_meta);
+ void push_hint(const String &p_string);
void push_table(int p_columns, InlineAlignment p_alignment = INLINE_ALIGNMENT_TOP);
void push_fade(int p_start_index, int p_length);
void push_shake(int p_strength, float p_rate);
@@ -530,6 +540,9 @@ public:
void set_meta_underline(bool p_underline);
bool is_meta_underlined() const;
+ void set_hint_underline(bool p_underline);
+ bool is_hint_underlined() const;
+
void set_override_selected_font_color(bool p_override_selected_font_color);
bool is_overriding_selected_font_color() const;
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 5fd31c5416..e50d7e765c 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -39,7 +39,7 @@ Size2 SpinBox::get_minimum_size() const {
return ms;
}
-void SpinBox::_value_changed(double) {
+void SpinBox::_value_changed(double p_value) {
String value = TS->format_number(String::num(get_value(), Math::range_step_decimals(get_step())));
if (!prefix.is_empty()) {
value = prefix + " " + value;
@@ -48,6 +48,7 @@ void SpinBox::_value_changed(double) {
value += " " + suffix;
}
line_edit->set_text(value);
+ Range::_value_changed(p_value);
}
void SpinBox::_text_submitted(const String &p_string) {
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index 0691a4b48d..a15e3fe5f5 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -47,7 +47,7 @@ class SpinBox : public Range {
void _release_mouse();
void _text_submitted(const String &p_string);
- virtual void _value_changed(double) override;
+ virtual void _value_changed(double p_value) override;
void _text_changed(const String &p_string);
String prefix;
diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp
index af314b9545..8128bbd11d 100644
--- a/scene/gui/tab_bar.cpp
+++ b/scene/gui/tab_bar.cpp
@@ -1530,7 +1530,7 @@ void TabBar::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_tab_width", PROPERTY_HINT_RANGE, "0,99999,1"), "set_max_tab_width", "get_max_tab_width");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scrolling_enabled"), "set_scrolling_enabled", "get_scrolling_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tabs_rearrange_group"), "set_tabs_rearrange_group", "get_tabs_rearrange_group");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "tabs_rearrange_group"), "set_tabs_rearrange_group", "get_tabs_rearrange_group");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_to_selected"), "set_scroll_to_selected", "get_scroll_to_selected");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "select_with_rmb"), "set_select_with_rmb", "get_select_with_rmb");
diff --git a/scene/gui/tab_bar.h b/scene/gui/tab_bar.h
index 0f2184aca7..e0c4ba85ef 100644
--- a/scene/gui/tab_bar.h
+++ b/scene/gui/tab_bar.h
@@ -86,7 +86,7 @@ private:
Vector<Tab> tabs;
int current = 0;
int previous = 0;
- AlignmentMode tab_alignment = ALIGNMENT_CENTER;
+ AlignmentMode tab_alignment = ALIGNMENT_LEFT;
bool clip_tabs = true;
int rb_hover = -1;
bool rb_pressing = false;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 05fda7128c..3c80e3f987 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -4469,7 +4469,11 @@ int TextEdit::get_visible_line_count() const {
int TextEdit::get_visible_line_count_in_range(int p_from_line, int p_to_line) const {
ERR_FAIL_INDEX_V(p_from_line, text.size(), 0);
ERR_FAIL_INDEX_V(p_to_line, text.size(), 0);
- ERR_FAIL_COND_V(p_from_line > p_to_line, 0);
+
+ // So we can handle inputs in whatever order
+ if (p_from_line > p_to_line) {
+ SWAP(p_from_line, p_to_line);
+ }
/* Returns the total number of (lines + wrapped - hidden). */
if (!_is_hiding_enabled() && get_line_wrapping_mode() == LineWrappingMode::LINE_WRAPPING_NONE) {