summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/base_button.h2
-rw-r--r--scene/gui/button.cpp2
-rw-r--r--scene/gui/button.h2
-rw-r--r--scene/gui/code_edit.cpp2
-rw-r--r--scene/gui/code_edit.h6
-rw-r--r--scene/gui/color_picker.cpp4
-rw-r--r--scene/gui/color_picker.h1
-rw-r--r--scene/gui/control.cpp28
-rw-r--r--scene/gui/control.h4
-rw-r--r--scene/gui/dialogs.cpp28
-rw-r--r--scene/gui/dialogs.h9
-rw-r--r--scene/gui/file_dialog.cpp28
-rw-r--r--scene/gui/file_dialog.h4
-rw-r--r--scene/gui/gradient_edit.cpp4
-rw-r--r--scene/gui/gradient_edit.h1
-rw-r--r--scene/gui/graph_edit.cpp2
-rw-r--r--scene/gui/graph_edit.h2
-rw-r--r--scene/gui/grid_container.cpp5
-rw-r--r--scene/gui/item_list.cpp12
-rw-r--r--scene/gui/item_list.h6
-rw-r--r--scene/gui/label.cpp91
-rw-r--r--scene/gui/label.h9
-rw-r--r--scene/gui/line_edit.h2
-rw-r--r--scene/gui/link_button.h6
-rw-r--r--scene/gui/menu_button.h2
-rw-r--r--scene/gui/option_button.h2
-rw-r--r--scene/gui/popup.h2
-rw-r--r--scene/gui/popup_menu.cpp4
-rw-r--r--scene/gui/popup_menu.h2
-rw-r--r--scene/gui/range.h2
-rw-r--r--scene/gui/rich_text_label.cpp268
-rw-r--r--scene/gui/rich_text_label.h8
-rw-r--r--scene/gui/scroll_bar.h2
-rw-r--r--scene/gui/scroll_container.cpp28
-rw-r--r--scene/gui/scroll_container.h2
-rw-r--r--scene/gui/separator.h2
-rw-r--r--scene/gui/slider.cpp14
-rw-r--r--scene/gui/slider.h8
-rw-r--r--scene/gui/spin_box.cpp4
-rw-r--r--scene/gui/spin_box.h4
-rw-r--r--scene/gui/subviewport_container.h6
-rw-r--r--scene/gui/tab_container.cpp11
-rw-r--r--scene/gui/tab_container.h1
-rw-r--r--scene/gui/text_edit.cpp4
-rw-r--r--scene/gui/texture_button.h1
-rw-r--r--scene/gui/tree.cpp29
-rw-r--r--scene/gui/tree.h3
-rw-r--r--scene/gui/video_stream_player.cpp2
48 files changed, 438 insertions, 233 deletions
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index ba3852ec98..7cf8de6432 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -155,4 +155,4 @@ public:
ButtonGroup();
};
-#endif
+#endif // BASE_BUTTON_H
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index d8de22d27c..a67f850a86 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -526,7 +526,7 @@ void Button::_bind_methods() {
Button::Button(const String &p_text) {
text_buf.instantiate();
- text_buf->set_flags(TextServer::BREAK_MANDATORY);
+ text_buf->set_break_flags(TextServer::BREAK_MANDATORY);
set_mouse_filter(MOUSE_FILTER_STOP);
set_text(p_text);
diff --git a/scene/gui/button.h b/scene/gui/button.h
index 7a29cba677..9d8d457f7c 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -98,4 +98,4 @@ public:
~Button();
};
-#endif
+#endif // BUTTON_H
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 22f968eac7..8968c1cc17 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -407,7 +407,7 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
}
/* Ctrl + Hover symbols */
-#ifdef OSX_ENABLED
+#ifdef MACOS_ENABLED
if (k->get_keycode() == Key::META) {
#else
if (k->get_keycode() == Key::CTRL) {
diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h
index a431d8a5b2..08bd91a368 100644
--- a/scene/gui/code_edit.h
+++ b/scene/gui/code_edit.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CODEEDIT_H
-#define CODEEDIT_H
+#ifndef CODE_EDIT_H
+#define CODE_EDIT_H
#include "scene/gui/text_edit.h"
@@ -433,4 +433,4 @@ public:
VARIANT_ENUM_CAST(CodeEdit::CodeCompletionKind);
-#endif // CODEEDIT_H
+#endif // CODE_EDIT_H
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 492a81f933..bfe5ee335b 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -1071,7 +1071,7 @@ void ColorPicker::_screen_pick_pressed() {
screen = memnew(Control);
r->add_child(screen);
screen->set_as_top_level(true);
- screen->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ screen->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
screen->set_default_cursor_shape(CURSOR_POINTING_HAND);
screen->connect("gui_input", callable_mp(this, &ColorPicker::_screen_input));
// It immediately toggles off in the first press otherwise.
@@ -1456,7 +1456,7 @@ void ColorPickerButton::_update_picker() {
popup = memnew(PopupPanel);
popup->set_wrap_controls(true);
picker = memnew(ColorPicker);
- picker->set_anchors_and_offsets_preset(PRESET_WIDE);
+ picker->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
popup->add_child(picker);
add_child(popup, false, INTERNAL_MODE_FRONT);
picker->connect("color_changed", callable_mp(this, &ColorPickerButton::_color_changed));
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index e219c78319..8e65ee1861 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -276,4 +276,5 @@ public:
VARIANT_ENUM_CAST(ColorPicker::PickerShapeType);
VARIANT_ENUM_CAST(ColorPicker::ColorModeType);
+
#endif // COLOR_PICKER_H
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 15ff1d3ed6..686045901c 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -1642,7 +1642,7 @@ void Control::_set_anchors_layout_preset(int p_preset) {
case PRESET_BOTTOM_WIDE:
case PRESET_VCENTER_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_offsets_preset(preset, LayoutPresetMode::PRESET_MODE_MINSIZE);
break;
}
@@ -1718,7 +1718,7 @@ int Control::_get_anchors_layout_preset() const {
}
if (left == ANCHOR_BEGIN && right == ANCHOR_END && top == ANCHOR_BEGIN && bottom == ANCHOR_END) {
- return (int)LayoutPreset::PRESET_WIDE;
+ return (int)LayoutPreset::PRESET_FULL_RECT;
}
// Does not match any preset, return "Custom".
@@ -1737,7 +1737,7 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_offsets) {
case PRESET_BOTTOM_WIDE:
case PRESET_LEFT_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_anchor(SIDE_LEFT, ANCHOR_BEGIN, p_keep_offsets);
break;
@@ -1765,7 +1765,7 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_offsets) {
case PRESET_RIGHT_WIDE:
case PRESET_TOP_WIDE:
case PRESET_VCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_anchor(SIDE_TOP, ANCHOR_BEGIN, p_keep_offsets);
break;
@@ -1807,7 +1807,7 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_offsets) {
case PRESET_RIGHT_WIDE:
case PRESET_BOTTOM_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_anchor(SIDE_RIGHT, ANCHOR_END, p_keep_offsets);
break;
}
@@ -1835,7 +1835,7 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_offsets) {
case PRESET_RIGHT_WIDE:
case PRESET_BOTTOM_WIDE:
case PRESET_VCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_anchor(SIDE_BOTTOM, ANCHOR_END, p_keep_offsets);
break;
}
@@ -1870,7 +1870,7 @@ void Control::set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz
case PRESET_BOTTOM_WIDE:
case PRESET_LEFT_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
data.offset[0] = x * (0.0 - data.anchor[0]) + p_margin + parent_rect.position.x;
break;
@@ -1898,7 +1898,7 @@ void Control::set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz
case PRESET_RIGHT_WIDE:
case PRESET_TOP_WIDE:
case PRESET_VCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
data.offset[1] = parent_rect.size.y * (0.0 - data.anchor[1]) + p_margin + parent_rect.position.y;
break;
@@ -1940,7 +1940,7 @@ void Control::set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz
case PRESET_RIGHT_WIDE:
case PRESET_BOTTOM_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
data.offset[2] = x * (1.0 - data.anchor[2]) - p_margin + parent_rect.position.x;
break;
}
@@ -1968,7 +1968,7 @@ void Control::set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz
case PRESET_RIGHT_WIDE:
case PRESET_BOTTOM_WIDE:
case PRESET_VCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
data.offset[3] = parent_rect.size.y * (1.0 - data.anchor[3]) - p_margin + parent_rect.position.y;
break;
}
@@ -2003,7 +2003,7 @@ void Control::set_grow_direction_preset(LayoutPreset p_preset) {
case PRESET_BOTTOM_WIDE:
case PRESET_VCENTER_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_h_grow_direction(GrowDirection::GROW_DIRECTION_BOTH);
break;
}
@@ -2031,7 +2031,7 @@ void Control::set_grow_direction_preset(LayoutPreset p_preset) {
case PRESET_RIGHT_WIDE:
case PRESET_VCENTER_WIDE:
case PRESET_HCENTER_WIDE:
- case PRESET_WIDE:
+ case PRESET_FULL_RECT:
set_v_grow_direction(GrowDirection::GROW_DIRECTION_BOTH);
break;
}
@@ -3300,7 +3300,7 @@ void Control::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_mode", PROPERTY_HINT_ENUM, "Position,Anchors,Container,Uncontrolled", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_layout_mode", "_get_layout_mode");
ADD_PROPERTY_DEFAULT("layout_mode", LayoutMode::LAYOUT_MODE_POSITION);
- const String anchors_presets_options = "Custom:-1,PresetWide:15,"
+ const String anchors_presets_options = "Custom:-1,PresetFullRect:15,"
"PresetTopLeft:0,PresetTopRight:1,PresetBottomRight:3,PresetBottomLeft:2,"
"PresetCenterLeft:4,PresetCenterTop:5,PresetCenterRight:6,PresetCenterBottom:7,PresetCenter:8,"
"PresetLeftWide:9,PresetTopWide:10,PresetRightWide:11,PresetBottomWide:12,PresetVCenterWide:13,PresetHCenterWide:14";
@@ -3408,7 +3408,7 @@ void Control::_bind_methods() {
BIND_ENUM_CONSTANT(PRESET_BOTTOM_WIDE);
BIND_ENUM_CONSTANT(PRESET_VCENTER_WIDE);
BIND_ENUM_CONSTANT(PRESET_HCENTER_WIDE);
- BIND_ENUM_CONSTANT(PRESET_WIDE);
+ BIND_ENUM_CONSTANT(PRESET_FULL_RECT);
BIND_ENUM_CONSTANT(PRESET_MODE_MINSIZE);
BIND_ENUM_CONSTANT(PRESET_MODE_KEEP_WIDTH);
diff --git a/scene/gui/control.h b/scene/gui/control.h
index f18dd99bff..d9c29a9c87 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -116,7 +116,7 @@ public:
PRESET_BOTTOM_WIDE,
PRESET_VCENTER_WIDE,
PRESET_HCENTER_WIDE,
- PRESET_WIDE
+ PRESET_FULL_RECT
};
enum LayoutPresetMode {
@@ -574,4 +574,4 @@ VARIANT_ENUM_CAST(Control::LayoutMode);
VARIANT_ENUM_CAST(Control::LayoutDirection);
VARIANT_ENUM_CAST(Control::TextDirection);
-#endif
+#endif // CONTROL_H
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index a2b05ee50d..44e2bb89eb 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -161,6 +161,14 @@ bool AcceptDialog::has_autowrap() {
return label->get_autowrap_mode() != TextServer::AUTOWRAP_OFF;
}
+void AcceptDialog::set_ok_button_text(String p_ok_button_text) {
+ ok->set_text(p_ok_button_text);
+}
+
+String AcceptDialog::get_ok_button_text() const {
+ return ok->get_text();
+}
+
void AcceptDialog::register_text_enter(Control *p_line_edit) {
ERR_FAIL_NULL(p_line_edit);
LineEdit *line_edit = Object::cast_to<LineEdit>(p_line_edit);
@@ -262,7 +270,7 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin
Button *AcceptDialog::add_cancel_button(const String &p_cancel) {
String c = p_cancel;
if (p_cancel.is_empty()) {
- c = RTR("Cancel");
+ c = "Cancel";
}
Button *b = swap_cancel_ok ? add_button(c, true) : add_button(c);
b->connect("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed));
@@ -306,11 +314,15 @@ void AcceptDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_text"), &AcceptDialog::get_text);
ClassDB::bind_method(D_METHOD("set_autowrap", "autowrap"), &AcceptDialog::set_autowrap);
ClassDB::bind_method(D_METHOD("has_autowrap"), &AcceptDialog::has_autowrap);
+ ClassDB::bind_method(D_METHOD("set_ok_button_text", "text"), &AcceptDialog::set_ok_button_text);
+ ClassDB::bind_method(D_METHOD("get_ok_button_text"), &AcceptDialog::get_ok_button_text);
ADD_SIGNAL(MethodInfo("confirmed"));
ADD_SIGNAL(MethodInfo("cancelled"));
ADD_SIGNAL(MethodInfo("custom_action", PropertyInfo(Variant::STRING_NAME, "action")));
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "ok_button_text"), "set_ok_button_text", "get_ok_button_text");
+
ADD_GROUP("Dialog", "dialog");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "dialog_text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dialog_hide_on_ok"), "set_hide_on_ok", "get_hide_on_ok");
@@ -349,7 +361,7 @@ AcceptDialog::AcceptDialog() {
hbc->add_spacer();
ok = memnew(Button);
- ok->set_text(RTR("OK"));
+ ok->set_text("OK");
hbc->add_child(ok);
hbc->add_spacer();
@@ -365,8 +377,20 @@ AcceptDialog::~AcceptDialog() {
// ConfirmationDialog
+void ConfirmationDialog::set_cancel_button_text(String p_cancel_button_text) {
+ cancel->set_text(p_cancel_button_text);
+}
+
+String ConfirmationDialog::get_cancel_button_text() const {
+ return cancel->get_text();
+}
+
void ConfirmationDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_cancel_button"), &ConfirmationDialog::get_cancel_button);
+ ClassDB::bind_method(D_METHOD("set_cancel_button_text"), &ConfirmationDialog::set_cancel_button_text);
+ ClassDB::bind_method(D_METHOD("get_cancel_button_text"), &ConfirmationDialog::get_cancel_button_text);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "cancel_button_text"), "set_cancel_button_text", "get_cancel_button_text");
}
Button *ConfirmationDialog::get_cancel_button() {
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index 41fd9c0a10..9ebf5ddfb2 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -97,6 +97,9 @@ public:
void set_autowrap(bool p_autowrap);
bool has_autowrap();
+ void set_ok_button_text(String p_ok_button_text);
+ String get_ok_button_text() const;
+
AcceptDialog();
~AcceptDialog();
};
@@ -110,7 +113,11 @@ protected:
public:
Button *get_cancel_button();
+
+ void set_cancel_button_text(String p_cancel_button_text);
+ String get_cancel_button_text() const;
+
ConfirmationDialog();
};
-#endif
+#endif // DIALOGS_H
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 6bb4ac9c6f..65bc359e2e 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -419,10 +419,10 @@ void FileDialog::deselect_all() {
switch (mode) {
case FILE_MODE_OPEN_FILE:
case FILE_MODE_OPEN_FILES:
- get_ok_button()->set_text(RTR("Open"));
+ set_ok_button_text(RTR("Open"));
break;
case FILE_MODE_OPEN_DIR:
- get_ok_button()->set_text(RTR("Select Current Folder"));
+ set_ok_button_text(RTR("Select Current Folder"));
break;
case FILE_MODE_OPEN_ANY:
case FILE_MODE_SAVE_FILE:
@@ -446,7 +446,7 @@ void FileDialog::_tree_selected() {
if (!d["dir"]) {
file->set_text(d["name"]);
} else if (mode == FILE_MODE_OPEN_DIR) {
- get_ok_button()->set_text(RTR("Select This Folder"));
+ set_ok_button_text(RTR("Select This Folder"));
}
get_ok_button()->set_disabled(_is_open_should_be_disabled());
@@ -673,9 +673,13 @@ void FileDialog::clear_filters() {
invalidate();
}
-void FileDialog::add_filter(const String &p_filter) {
+void FileDialog::add_filter(const String &p_filter, const String &p_description) {
ERR_FAIL_COND_MSG(p_filter.begins_with("."), "Filter must be \"filename.extension\", can't start with dot.");
- filters.push_back(p_filter);
+ if (p_description.is_empty()) {
+ filters.push_back(p_filter);
+ } else {
+ filters.push_back(vformat("%s ; %s", p_filter, p_description));
+ }
update_filters();
invalidate();
}
@@ -764,35 +768,35 @@ void FileDialog::set_file_mode(FileMode p_mode) {
mode = p_mode;
switch (mode) {
case FILE_MODE_OPEN_FILE:
- get_ok_button()->set_text(RTR("Open"));
+ set_ok_button_text(RTR("Open"));
if (mode_overrides_title) {
set_title(TTRC("Open a File"));
}
makedir->hide();
break;
case FILE_MODE_OPEN_FILES:
- get_ok_button()->set_text(RTR("Open"));
+ set_ok_button_text(RTR("Open"));
if (mode_overrides_title) {
set_title(TTRC("Open File(s)"));
}
makedir->hide();
break;
case FILE_MODE_OPEN_DIR:
- get_ok_button()->set_text(RTR("Select Current Folder"));
+ set_ok_button_text(RTR("Select Current Folder"));
if (mode_overrides_title) {
set_title(TTRC("Open a Directory"));
}
makedir->show();
break;
case FILE_MODE_OPEN_ANY:
- get_ok_button()->set_text(RTR("Open"));
+ set_ok_button_text(RTR("Open"));
if (mode_overrides_title) {
set_title(TTRC("Open a File or Directory"));
}
makedir->show();
break;
case FILE_MODE_SAVE_FILE:
- get_ok_button()->set_text(RTR("Save"));
+ set_ok_button_text(RTR("Save"));
if (mode_overrides_title) {
set_title(TTRC("Save a File"));
}
@@ -919,7 +923,7 @@ void FileDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("_cancel_pressed"), &FileDialog::_cancel_pressed);
ClassDB::bind_method(D_METHOD("clear_filters"), &FileDialog::clear_filters);
- ClassDB::bind_method(D_METHOD("add_filter", "filter"), &FileDialog::add_filter);
+ ClassDB::bind_method(D_METHOD("add_filter", "filter", "description"), &FileDialog::add_filter, DEFVAL(""));
ClassDB::bind_method(D_METHOD("set_filters", "filters"), &FileDialog::set_filters);
ClassDB::bind_method(D_METHOD("get_filters"), &FileDialog::get_filters);
ClassDB::bind_method(D_METHOD("get_current_dir"), &FileDialog::get_current_dir);
@@ -1056,7 +1060,7 @@ FileDialog::FileDialog() {
message = memnew(Label);
message->hide();
- message->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ message->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
message->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
tree->add_child(message);
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 8b8d93920c..4945094086 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -151,7 +151,7 @@ protected:
public:
void popup_file_dialog();
void clear_filters();
- void add_filter(const String &p_filter);
+ void add_filter(const String &p_filter, const String &p_description = "");
void set_filters(const Vector<String> &p_filters);
Vector<String> get_filters() const;
@@ -196,4 +196,4 @@ public:
VARIANT_ENUM_CAST(FileDialog::FileMode);
VARIANT_ENUM_CAST(FileDialog::Access);
-#endif
+#endif // FILE_DIALOG_H
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index 9459bed63b..cc27a6b7c2 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -437,6 +437,10 @@ ColorPicker *GradientEdit::get_picker() {
return picker;
}
+PopupPanel *GradientEdit::get_popup() {
+ return popup;
+}
+
void GradientEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("ramp_changed"));
}
diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h
index 3badcd45ba..b7c99f1f1c 100644
--- a/scene/gui/gradient_edit.h
+++ b/scene/gui/gradient_edit.h
@@ -75,6 +75,7 @@ public:
void set_interpolation_mode(Gradient::InterpolationMode p_interp_mode);
Gradient::InterpolationMode get_interpolation_mode();
ColorPicker *get_picker();
+ PopupPanel *get_popup();
virtual Size2 get_minimum_size() const override;
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index c219eafbf7..e30759aa3e 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -2376,7 +2376,7 @@ GraphEdit::GraphEdit() {
top_layer = memnew(GraphEditFilter(this));
add_child(top_layer, false, INTERNAL_MODE_BACK);
top_layer->set_mouse_filter(MOUSE_FILTER_PASS);
- top_layer->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ top_layer->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
top_layer->connect("draw", callable_mp(this, &GraphEdit::_top_layer_draw));
top_layer->connect("gui_input", callable_mp(this, &GraphEdit::_top_layer_input));
top_layer->connect("focus_exited", callable_mp(panner.ptr(), &ViewPanner::release_pan_key));
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 02e90e4717..beb17ec4cf 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -365,4 +365,4 @@ public:
VARIANT_ENUM_CAST(GraphEdit::PanningScheme);
-#endif // GRAPHEdit_H
+#endif // GRAPH_EDIT_H
diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp
index 6f8518a7b0..eaa6943ad2 100644
--- a/scene/gui/grid_container.cpp
+++ b/scene/gui/grid_container.cpp
@@ -41,8 +41,6 @@ void GridContainer::_notification(int p_what) {
int hsep = get_theme_constant(SNAME("h_separation"));
int vsep = get_theme_constant(SNAME("v_separation"));
- int max_col = MIN(get_child_count(), columns);
- int max_row = ceil((float)get_child_count() / (float)columns);
// Compute the per-column/per-row data.
int valid_controls_index = 0;
@@ -79,6 +77,9 @@ void GridContainer::_notification(int p_what) {
}
}
+ int max_col = MIN(valid_controls_index, columns);
+ int max_row = ceil((float)valid_controls_index / (float)columns);
+
// Consider all empty columns expanded.
for (int i = valid_controls_index; i < columns; i++) {
col_expanded.insert(i);
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 1d4ca4d196..d0a25972f8 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -45,9 +45,9 @@ void ItemList::_shape(int p_idx) {
}
item.text_buf->add_string(item.text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), item.language);
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
- item.text_buf->set_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
+ item.text_buf->set_break_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
} else {
- item.text_buf->set_flags(TextServer::BREAK_NONE);
+ item.text_buf->set_break_flags(TextServer::BREAK_NONE);
}
item.text_buf->set_text_overrun_behavior(text_overrun_behavior);
item.text_buf->set_max_lines_visible(max_text_lines);
@@ -470,10 +470,10 @@ void ItemList::set_max_text_lines(int p_lines) {
max_text_lines = p_lines;
for (int i = 0; i < items.size(); i++) {
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
- items.write[i].text_buf->set_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
+ items.write[i].text_buf->set_break_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
items.write[i].text_buf->set_max_lines_visible(p_lines);
} else {
- items.write[i].text_buf->set_flags(TextServer::BREAK_NONE);
+ items.write[i].text_buf->set_break_flags(TextServer::BREAK_NONE);
}
}
shape_changed = true;
@@ -511,9 +511,9 @@ void ItemList::set_icon_mode(IconMode p_mode) {
icon_mode = p_mode;
for (int i = 0; i < items.size(); i++) {
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
- items.write[i].text_buf->set_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
+ items.write[i].text_buf->set_break_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
} else {
- items.write[i].text_buf->set_flags(TextServer::BREAK_NONE);
+ items.write[i].text_buf->set_break_flags(TextServer::BREAK_NONE);
}
}
shape_changed = true;
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index c7d87da0b5..21bd22759c 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef ITEMLIST_H
-#define ITEMLIST_H
+#ifndef ITEM_LIST_H
+#define ITEM_LIST_H
#include "scene/gui/control.h"
#include "scene/gui/scroll_bar.h"
@@ -259,4 +259,4 @@ public:
VARIANT_ENUM_CAST(ItemList::SelectMode);
VARIANT_ENUM_CAST(ItemList::IconMode);
-#endif // ITEMLIST_H
+#endif // ITEM_LIST_H
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 5dec1df4a5..8094812203 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -31,6 +31,7 @@
#include "label.h"
#include "core/config/project_settings.h"
+#include "core/core_string_names.h"
#include "core/string/print_string.h"
#include "core/string/translation.h"
@@ -64,7 +65,7 @@ bool Label::is_uppercase() const {
}
int Label::get_line_height(int p_line) const {
- Ref<Font> font = get_theme_font(SNAME("font"));
+ Ref<Font> font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font"));
if (p_line >= 0 && p_line < lines_rid.size()) {
return TS->shaped_text_get_size(lines_rid[p_line]).y;
} else if (lines_rid.size() > 0) {
@@ -74,7 +75,8 @@ int Label::get_line_height(int p_line) const {
}
return h;
} else {
- return font->get_height(get_theme_font_size(SNAME("font_size")));
+ int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size"));
+ return font->get_height(font_size);
}
}
@@ -91,8 +93,8 @@ void Label::_shape() {
} else {
TS->shaped_text_set_direction(text_rid, (TextServer::Direction)text_direction);
}
- const Ref<Font> &font = get_theme_font(SNAME("font"));
- int font_size = get_theme_font_size(SNAME("font_size"));
+ const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font"));
+ int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size"));
ERR_FAIL_COND(font.is_null());
String text = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text;
if (visible_chars >= 0 && visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) {
@@ -121,10 +123,10 @@ void Label::_shape() {
}
lines_rid.clear();
- uint16_t autowrap_flags = TextServer::BREAK_MANDATORY;
+ BitField<TextServer::LineBreakFlag> autowrap_flags = TextServer::BREAK_MANDATORY;
switch (autowrap_mode) {
case TextServer::AUTOWRAP_WORD_SMART:
- autowrap_flags = TextServer::BREAK_WORD_BOUND_ADAPTIVE | TextServer::BREAK_MANDATORY;
+ autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_ADAPTIVE | TextServer::BREAK_MANDATORY;
break;
case TextServer::AUTOWRAP_WORD:
autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_MANDATORY;
@@ -158,23 +160,23 @@ void Label::_shape() {
}
if (lines_dirty) {
- uint16_t overrun_flags = TextServer::OVERRUN_NO_TRIM;
+ BitField<TextServer::TextOverrunFlag> overrun_flags = TextServer::OVERRUN_NO_TRIM;
switch (overrun_behavior) {
case TextServer::OVERRUN_TRIM_WORD_ELLIPSIS:
- overrun_flags |= TextServer::OVERRUN_TRIM;
- overrun_flags |= TextServer::OVERRUN_TRIM_WORD_ONLY;
- overrun_flags |= TextServer::OVERRUN_ADD_ELLIPSIS;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY);
+ overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS);
break;
case TextServer::OVERRUN_TRIM_ELLIPSIS:
- overrun_flags |= TextServer::OVERRUN_TRIM;
- overrun_flags |= TextServer::OVERRUN_ADD_ELLIPSIS;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
+ overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS);
break;
case TextServer::OVERRUN_TRIM_WORD:
- overrun_flags |= TextServer::OVERRUN_TRIM;
- overrun_flags |= TextServer::OVERRUN_TRIM_WORD_ONLY;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY);
break;
case TextServer::OVERRUN_TRIM_CHAR:
- overrun_flags |= TextServer::OVERRUN_TRIM;
+ overrun_flags.set_flag(TextServer::OVERRUN_TRIM);
break;
case TextServer::OVERRUN_NO_TRIMMING:
break;
@@ -186,7 +188,7 @@ void Label::_shape() {
int visible_lines = get_visible_line_count();
bool lines_hidden = visible_lines > 0 && visible_lines < lines_rid.size();
if (lines_hidden) {
- overrun_flags |= TextServer::OVERRUN_ENFORCE_ELLIPSIS;
+ overrun_flags.set_flag(TextServer::OVERRUN_ENFORCE_ELLIPSIS);
}
if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) {
for (int i = 0; i < lines_rid.size(); i++) {
@@ -204,7 +206,7 @@ void Label::_shape() {
for (int i = 0; i < lines_rid.size(); i++) {
if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) {
TS->shaped_text_fit_to_width(lines_rid[i], width);
- overrun_flags |= TextServer::OVERRUN_JUSTIFICATION_AWARE;
+ overrun_flags.set_flag(TextServer::OVERRUN_JUSTIFICATION_AWARE);
TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags);
TS->shaped_text_fit_to_width(lines_rid[i], width, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS);
} else {
@@ -223,9 +225,8 @@ void Label::_shape() {
}
void Label::_update_visible() {
- int line_spacing = get_theme_constant(SNAME("line_spacing"), SNAME("Label"));
+ int line_spacing = settings.is_valid() ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing"), SNAME("Label"));
Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"), SNAME("Label"));
- Ref<Font> font = get_theme_font(SNAME("font"));
int lines_visible = lines_rid.size();
if (max_lines_visible >= 0 && lines_visible > max_lines_visible) {
@@ -295,17 +296,19 @@ void Label::_notification(int p_what) {
RID ci = get_canvas_item();
+ bool has_settings = settings.is_valid();
+
Size2 string_size;
Size2 size = get_size();
Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"));
- Ref<Font> font = get_theme_font(SNAME("font"));
- Color font_color = get_theme_color(SNAME("font_color"));
- Color font_shadow_color = get_theme_color(SNAME("font_shadow_color"));
- Point2 shadow_ofs(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y")));
- int line_spacing = get_theme_constant(SNAME("line_spacing"));
- Color font_outline_color = get_theme_color(SNAME("font_outline_color"));
- int outline_size = get_theme_constant(SNAME("outline_size"));
- int shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size"));
+ Ref<Font> font = (has_settings && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font"));
+ Color font_color = has_settings ? settings->get_font_color() : get_theme_color(SNAME("font_color"));
+ Color font_shadow_color = has_settings ? settings->get_shadow_color() : get_theme_color(SNAME("font_shadow_color"));
+ Point2 shadow_ofs = has_settings ? settings->get_shadow_offset() : Point2(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y")));
+ int line_spacing = has_settings ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing"));
+ Color font_outline_color = has_settings ? settings->get_outline_color() : get_theme_color(SNAME("font_outline_color"));
+ int outline_size = has_settings ? settings->get_outline_size() : get_theme_constant(SNAME("outline_size"));
+ int shadow_outline_size = has_settings ? settings->get_shadow_size() : get_theme_constant(SNAME("shadow_outline_size"));
bool rtl = (TS->shaped_text_get_inferred_direction(text_rid) == TextServer::DIRECTION_RTL);
bool rtl_layout = is_layout_rtl();
@@ -552,8 +555,10 @@ Size2 Label::get_minimum_size() const {
Size2 min_size = minsize;
- Ref<Font> font = get_theme_font(SNAME("font"));
- min_size.height = MAX(min_size.height, font->get_height(get_theme_font_size(SNAME("font_size"))));
+ const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font"));
+ int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size"));
+
+ min_size.height = MAX(min_size.height, font->get_height(font_size) + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM));
Size2 min_style = get_theme_stylebox(SNAME("normal"))->get_minimum_size();
if (autowrap_mode != TextServer::AUTOWRAP_OFF) {
@@ -578,9 +583,8 @@ int Label::get_line_count() const {
}
int Label::get_visible_line_count() const {
- Ref<Font> font = get_theme_font(SNAME("font"));
Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"));
- int line_spacing = get_theme_constant(SNAME("line_spacing"));
+ int line_spacing = settings.is_valid() ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing"));
int lines_visible = 0;
float total_h = 0.0;
for (int64_t i = lines_skipped; i < lines_rid.size(); i++) {
@@ -641,6 +645,28 @@ void Label::set_text(const String &p_string) {
update_minimum_size();
}
+void Label::_invalidate() {
+ font_dirty = true;
+ update();
+}
+
+void Label::set_label_settings(const Ref<LabelSettings> &p_settings) {
+ if (settings != p_settings) {
+ if (settings.is_valid()) {
+ settings->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Label::_invalidate));
+ }
+ settings = p_settings;
+ if (settings.is_valid()) {
+ settings->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Label::_invalidate), varray(), CONNECT_REFERENCE_COUNTED);
+ }
+ _invalidate();
+ }
+}
+
+Ref<LabelSettings> Label::get_label_settings() const {
+ return settings;
+}
+
void Label::set_text_direction(Control::TextDirection p_text_direction) {
ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3);
if (text_direction != p_text_direction) {
@@ -804,6 +830,8 @@ void Label::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_vertical_alignment"), &Label::get_vertical_alignment);
ClassDB::bind_method(D_METHOD("set_text", "text"), &Label::set_text);
ClassDB::bind_method(D_METHOD("get_text"), &Label::get_text);
+ ClassDB::bind_method(D_METHOD("set_label_settings", "settings"), &Label::set_label_settings);
+ ClassDB::bind_method(D_METHOD("get_label_settings"), &Label::get_label_settings);
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &Label::set_text_direction);
ClassDB::bind_method(D_METHOD("get_text_direction"), &Label::get_text_direction);
ClassDB::bind_method(D_METHOD("set_language", "language"), &Label::set_language);
@@ -836,6 +864,7 @@ void Label::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_structured_text_bidi_override_options"), &Label::get_structured_text_bidi_override_options);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "label_settings", PROPERTY_HINT_RESOURCE_TYPE, "LabelSettings"), "set_label_settings", "get_label_settings");
ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_alignment", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_vertical_alignment", "get_vertical_alignment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode");
diff --git a/scene/gui/label.h b/scene/gui/label.h
index a59d35950d..cab5b36d68 100644
--- a/scene/gui/label.h
+++ b/scene/gui/label.h
@@ -32,6 +32,7 @@
#define LABEL_H
#include "scene/gui/control.h"
+#include "scene/resources/label_settings.h"
class Label : public Control {
GDCLASS(Label, Control);
@@ -65,8 +66,11 @@ private:
int lines_skipped = 0;
int max_lines_visible = -1;
+ Ref<LabelSettings> settings;
+
void _update_visible();
void _shape();
+ void _invalidate();
protected:
void _notification(int p_what);
@@ -85,6 +89,9 @@ public:
void set_text(const String &p_string);
String get_text() const;
+ void set_label_settings(const Ref<LabelSettings> &p_settings);
+ Ref<LabelSettings> get_label_settings() const;
+
void set_text_direction(TextDirection p_text_direction);
TextDirection get_text_direction() const;
@@ -133,4 +140,4 @@ public:
~Label();
};
-#endif
+#endif // LABEL_H
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 557da35bfd..6aa1694f1f 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -336,4 +336,4 @@ public:
VARIANT_ENUM_CAST(LineEdit::MenuItems);
-#endif
+#endif // LINE_EDIT_H
diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h
index 54a31f06ce..12a6a7618f 100644
--- a/scene/gui/link_button.h
+++ b/scene/gui/link_button.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef LINKBUTTON_H
-#define LINKBUTTON_H
+#ifndef LINK_BUTTON_H
+#define LINK_BUTTON_H
#include "scene/gui/base_button.h"
#include "scene/resources/text_line.h"
@@ -86,4 +86,4 @@ public:
VARIANT_ENUM_CAST(LinkButton::UnderlineMode);
-#endif // LINKBUTTON_H
+#endif // LINK_BUTTON_H
diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h
index 0a6b46c796..97c0d21f1e 100644
--- a/scene/gui/menu_button.h
+++ b/scene/gui/menu_button.h
@@ -71,4 +71,4 @@ public:
~MenuButton();
};
-#endif
+#endif // MENU_BUTTON_H
diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h
index 7896132626..5665296699 100644
--- a/scene/gui/option_button.h
+++ b/scene/gui/option_button.h
@@ -105,4 +105,4 @@ public:
~OptionButton();
};
-#endif
+#endif // OPTION_BUTTON_H
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index b53c8be50f..70eb8722d0 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -79,4 +79,4 @@ public:
PopupPanel();
};
-#endif
+#endif // POPUP_H
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 3a31246b17..928bab8842 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -1909,7 +1909,7 @@ void PopupMenu::popup(const Rect2 &p_bounds) {
PopupMenu::PopupMenu() {
// Margin Container
margin_container = memnew(MarginContainer);
- margin_container->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ margin_container->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
add_child(margin_container, false, INTERNAL_MODE_FRONT);
margin_container->connect("draw", callable_mp(this, &PopupMenu::_draw_background));
@@ -1921,7 +1921,7 @@ PopupMenu::PopupMenu() {
// The control which will display the items
control = memnew(Control);
control->set_clip_contents(false);
- control->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ control->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
control->set_h_size_flags(Control::SIZE_EXPAND_FILL);
control->set_v_size_flags(Control::SIZE_EXPAND_FILL);
scroll_container->add_child(control, false, INTERNAL_MODE_FRONT);
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index daa38b0e6d..e203793c2e 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -260,4 +260,4 @@ public:
~PopupMenu();
};
-#endif
+#endif // POPUP_MENU_H
diff --git a/scene/gui/range.h b/scene/gui/range.h
index 1274821bd1..87bd0d88af 100644
--- a/scene/gui/range.h
+++ b/scene/gui/range.h
@@ -106,4 +106,4 @@ public:
~Range();
};
-#endif
+#endif // RANGE_H
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 05824d54f1..8e424977c4 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -149,7 +149,12 @@ RichTextLabel::Item *RichTextLabel::_get_item_at_pos(RichTextLabel::Item *p_item
return it;
}
} break;
- case ITEM_NEWLINE:
+ case ITEM_NEWLINE: {
+ offset += 1;
+ if (offset == p_position) {
+ return it;
+ }
+ } break;
case ITEM_IMAGE:
case ITEM_TABLE: {
offset += 1;
@@ -219,13 +224,21 @@ void RichTextLabel::_update_line_font(ItemFrame *p_frame, int p_line, const Ref<
for (int i = 0; i < spans; i++) {
ItemText *it = reinterpret_cast<ItemText *>((uint64_t)TS->shaped_get_span_meta(t, i));
if (it) {
- Ref<Font> font = _find_font(it);
- if (font.is_null()) {
- font = p_base_font;
+ Ref<Font> font = p_base_font;
+ int font_size = p_base_font_size;
+
+ ItemFont *font_it = _find_font(it);
+ if (font_it) {
+ if (font_it->font.is_valid()) {
+ font = font_it->font;
+ }
+ if (font_it->font_size > 0) {
+ font_size = font_it->font_size;
+ }
}
- int font_size = _find_font_size(it);
- if (font_size == -1) {
- font_size = p_base_font_size;
+ ItemFontSize *font_size_it = _find_font_size(it);
+ if (font_size_it && font_size_it->font_size > 0) {
+ font_size = font_size_it->font_size;
}
TS->shaped_set_span_update_font(t, i, font->get_rids(), font_size, font->get_opentype_features());
for (int j = 0; j < TextServer::SPACING_MAX; j++) {
@@ -426,10 +439,10 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
Line &l = p_frame->lines[p_line];
MutexLock lock(l.text_buf->get_mutex());
- uint16_t autowrap_flags = TextServer::BREAK_MANDATORY;
+ BitField<TextServer::LineBreakFlag> autowrap_flags = TextServer::BREAK_MANDATORY;
switch (autowrap_mode) {
case TextServer::AUTOWRAP_WORD_SMART:
- autowrap_flags = TextServer::BREAK_WORD_BOUND_ADAPTIVE | TextServer::BREAK_MANDATORY;
+ autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_ADAPTIVE | TextServer::BREAK_MANDATORY;
break;
case TextServer::AUTOWRAP_WORD:
autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_MANDATORY;
@@ -443,7 +456,8 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
// Clear cache.
l.text_buf->clear();
- l.text_buf->set_flags(autowrap_flags | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_TRIM_EDGE_SPACES);
+ l.text_buf->set_break_flags(autowrap_flags);
+ l.text_buf->set_justification_flags(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_TRIM_EDGE_SPACES);
l.char_offset = *r_char_offset;
l.char_count = 0;
@@ -477,13 +491,21 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
l.dc_ol_color = dc->ol_color;
} break;
case ITEM_NEWLINE: {
- Ref<Font> font = _find_font(it);
- if (font.is_null()) {
- font = p_base_font;
+ Ref<Font> font = p_base_font;
+ int font_size = p_base_font_size;
+
+ ItemFont *font_it = _find_font(it);
+ if (font_it) {
+ if (font_it->font.is_valid()) {
+ font = font_it->font;
+ }
+ if (font_it->font_size > 0) {
+ font_size = font_it->font_size;
+ }
}
- int font_size = _find_font_size(it);
- if (font_size == -1) {
- font_size = p_base_font_size;
+ ItemFontSize *font_size_it = _find_font_size(it);
+ if (font_size_it && font_size_it->font_size > 0) {
+ font_size = font_size_it->font_size;
}
l.text_buf->add_string("\n", font, font_size);
text += "\n";
@@ -492,13 +514,21 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
} break;
case ITEM_TEXT: {
ItemText *t = static_cast<ItemText *>(it);
- Ref<Font> font = _find_font(it);
- if (font.is_null()) {
- font = p_base_font;
+ Ref<Font> font = p_base_font;
+ int font_size = p_base_font_size;
+
+ ItemFont *font_it = _find_font(it);
+ if (font_it) {
+ if (font_it->font.is_valid()) {
+ font = font_it->font;
+ }
+ if (font_it->font_size > 0) {
+ font_size = font_it->font_size;
+ }
}
- int font_size = _find_font_size(it);
- if (font_size == -1) {
- font_size = p_base_font_size;
+ ItemFontSize *font_size_it = _find_font_size(it);
+ if (font_size_it && font_size_it->font_size > 0) {
+ font_size = font_size_it->font_size;
}
String lang = _find_language(it);
String tx = t->text;
@@ -744,13 +774,21 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
}
}
if (!prefix.is_empty()) {
- Ref<Font> font = _find_font(l.from);
- if (font.is_null()) {
- font = get_theme_font(SNAME("normal_font"));
+ Ref<Font> font = get_theme_font(SNAME("normal_font"));
+ int font_size = get_theme_font_size(SNAME("normal_font_size"));
+
+ ItemFont *font_it = _find_font(l.from);
+ if (font_it) {
+ if (font_it->font.is_valid()) {
+ font = font_it->font;
+ }
+ if (font_it->font_size > 0) {
+ font_size = font_it->font_size;
+ }
}
- int font_size = _find_font_size(l.from);
- if (font_size == -1) {
- font_size = get_theme_font_size(SNAME("normal_font_size"));
+ ItemFontSize *font_size_it = _find_font_size(l.from);
+ if (font_size_it && font_size_it->font_size > 0) {
+ font_size = font_size_it->font_size;
}
if (rtl) {
float offx = 0.0f;
@@ -1344,6 +1382,8 @@ 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) {
Vector2 off;
+ bool line_clicked = false;
+ float text_rect_begin = 0.0;
int char_pos = -1;
Line &l = p_frame->lines[p_line];
MutexLock lock(l.text_buf->get_mutex());
@@ -1469,7 +1509,11 @@ 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) {
- char_pos = TS->shaped_text_hit_test_position(rid, p_click.x - rect.position.x);
+ 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);
+ }
+ line_clicked = true;
+ text_rect_begin = rtl ? rect.position.x + rect.size.x : rect.position.x;
}
// If table hit was detected, and line hit is in the table bounds use table hit.
@@ -1496,23 +1540,45 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
}
// Text line hit.
- if (char_pos >= 0) {
+ if (line_clicked) {
// Find item.
if (r_click_item != nullptr) {
Item *it = p_frame->lines[p_line].from;
Item *it_to = (p_line + 1 < (int)p_frame->lines.size()) ? p_frame->lines[p_line + 1].from : nullptr;
- if (char_pos == p_frame->lines[p_line].char_count) {
- // Selection after the end of line, select last item.
- if (it_to != nullptr) {
- *r_click_item = _get_prev_item(it_to);
- } else {
- for (Item *i = it; i; i = _get_next_item(i)) {
- *r_click_item = i;
+ if (char_pos >= 0) {
+ *r_click_item = _get_item_at_pos(it, it_to, char_pos);
+ } else {
+ int stop = text_rect_begin;
+ *r_click_item = _find_indentable(it);
+ while (*r_click_item) {
+ Ref<Font> font = get_theme_font(SNAME("normal_font"));
+ int font_size = get_theme_font_size(SNAME("normal_font_size"));
+ ItemFont *font_it = _find_font(*r_click_item);
+ if (font_it) {
+ if (font_it->font.is_valid()) {
+ font = font_it->font;
+ }
+ if (font_it->font_size > 0) {
+ font_size = font_it->font_size;
+ }
}
+ ItemFontSize *font_size_it = _find_font_size(*r_click_item);
+ if (font_size_it && font_size_it->font_size > 0) {
+ font_size = font_size_it->font_size;
+ }
+ if (rtl) {
+ stop += tab_size * font->get_char_size(' ', font_size).width;
+ if (stop > p_click.x) {
+ break;
+ }
+ } else {
+ stop -= tab_size * font->get_char_size(' ', font_size).width;
+ if (stop < p_click.x) {
+ break;
+ }
+ }
+ *r_click_item = _find_indentable((*r_click_item)->parent);
}
- } else {
- // Selection in the line.
- *r_click_item = _get_item_at_pos(it, it_to, char_pos);
}
}
@@ -2069,34 +2135,47 @@ void RichTextLabel::_find_frame(Item *p_item, ItemFrame **r_frame, int *r_line)
}
}
-Ref<Font> RichTextLabel::_find_font(Item *p_item) {
+RichTextLabel::Item *RichTextLabel::_find_indentable(Item *p_item) {
+ Item *indentable = p_item;
+
+ while (indentable) {
+ if (indentable->type == ITEM_INDENT || indentable->type == ITEM_LIST) {
+ return indentable;
+ }
+ indentable = indentable->parent;
+ }
+
+ return indentable;
+}
+
+RichTextLabel::ItemFont *RichTextLabel::_find_font(Item *p_item) {
Item *fontitem = p_item;
while (fontitem) {
if (fontitem->type == ITEM_FONT) {
ItemFont *fi = static_cast<ItemFont *>(fontitem);
- return fi->font;
+ return fi;
}
fontitem = fontitem->parent;
}
- return Ref<Font>();
+ return nullptr;
}
-int RichTextLabel::_find_font_size(Item *p_item) {
+RichTextLabel::ItemFontSize *RichTextLabel::_find_font_size(Item *p_item) {
Item *sizeitem = p_item;
while (sizeitem) {
if (sizeitem->type == ITEM_FONT_SIZE) {
ItemFontSize *fi = static_cast<ItemFontSize *>(sizeitem);
- return fi->font_size;
+ return fi;
}
sizeitem = sizeitem->parent;
}
- return -1;
+ return nullptr;
}
int RichTextLabel::_find_outline_size(Item *p_item, int p_default) {
@@ -2182,24 +2261,40 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int
while (item) {
if (item->type == ITEM_INDENT) {
- Ref<Font> font = _find_font(item);
- if (font.is_null()) {
- font = p_base_font;
+ Ref<Font> font = p_base_font;
+ int font_size = p_base_font_size;
+
+ ItemFont *font_it = _find_font(item);
+ if (font_it) {
+ if (font_it->font.is_valid()) {
+ font = font_it->font;
+ }
+ if (font_it->font_size > 0) {
+ font_size = font_it->font_size;
+ }
}
- int font_size = _find_font_size(item);
- if (font_size == -1) {
- font_size = p_base_font_size;
+ ItemFontSize *font_size_it = _find_font_size(item);
+ if (font_size_it && font_size_it->font_size > 0) {
+ font_size = font_size_it->font_size;
}
margin += tab_size * font->get_char_size(' ', font_size).width;
} else if (item->type == ITEM_LIST) {
- Ref<Font> font = _find_font(item);
- if (font.is_null()) {
- font = p_base_font;
+ Ref<Font> font = p_base_font;
+ int font_size = p_base_font_size;
+
+ ItemFont *font_it = _find_font(item);
+ if (font_it) {
+ if (font_it->font.is_valid()) {
+ font = font_it->font;
+ }
+ if (font_it->font_size > 0) {
+ font_size = font_it->font_size;
+ }
}
- int font_size = _find_font_size(item);
- if (font_size == -1) {
- font_size = p_base_font_size;
+ ItemFontSize *font_size_it = _find_font_size(item);
+ if (font_size_it && font_size_it->font_size > 0) {
+ font_size = font_size_it->font_size;
}
margin += tab_size * font->get_char_size(' ', font_size).width;
}
@@ -2878,7 +2973,7 @@ void RichTextLabel::push_dropcap(const String &p_string, const Ref<Font> &p_font
_add_item(item, false);
}
-void RichTextLabel::push_font(const Ref<Font> &p_font) {
+void RichTextLabel::push_font(const Ref<Font> &p_font, int p_size) {
_stop_thread();
MutexLock data_lock(data_mutex);
@@ -2887,6 +2982,7 @@ void RichTextLabel::push_font(const Ref<Font> &p_font) {
ItemFont *item = memnew(ItemFont);
item->font = p_font;
+ item->font_size = p_size;
_add_item(item, true);
}
@@ -2894,35 +2990,35 @@ void RichTextLabel::push_normal() {
Ref<Font> normal_font = get_theme_font(SNAME("normal_font"));
ERR_FAIL_COND(normal_font.is_null());
- push_font(normal_font);
+ push_font(normal_font, get_theme_font_size(SNAME("normal_font_size")));
}
void RichTextLabel::push_bold() {
Ref<Font> bold_font = get_theme_font(SNAME("bold_font"));
ERR_FAIL_COND(bold_font.is_null());
- push_font(bold_font);
+ push_font(bold_font, get_theme_font_size(SNAME("bold_font_size")));
}
void RichTextLabel::push_bold_italics() {
Ref<Font> bold_italics_font = get_theme_font(SNAME("bold_italics_font"));
ERR_FAIL_COND(bold_italics_font.is_null());
- push_font(bold_italics_font);
+ push_font(bold_italics_font, get_theme_font_size(SNAME("bold_italics_font_size")));
}
void RichTextLabel::push_italics() {
Ref<Font> italics_font = get_theme_font(SNAME("italics_font"));
ERR_FAIL_COND(italics_font.is_null());
- push_font(italics_font);
+ push_font(italics_font, get_theme_font_size(SNAME("italics_font_size")));
}
void RichTextLabel::push_mono() {
Ref<Font> mono_font = get_theme_font(SNAME("mono_font"));
ERR_FAIL_COND(mono_font.is_null());
- push_font(mono_font);
+ push_font(mono_font, get_theme_font_size(SNAME("mono_font_size")));
}
void RichTextLabel::push_font_size(int p_font_size) {
@@ -3512,9 +3608,9 @@ void RichTextLabel::append_text(const String &p_bbcode) {
//use bold font
in_bold = true;
if (in_italics) {
- push_font(bold_italics_font);
+ push_font(bold_italics_font, get_theme_font_size(SNAME("bold_italics_font_size")));
} else {
- push_font(bold_font);
+ push_font(bold_font, get_theme_font_size(SNAME("bold_font_size")));
}
pos = brk_end + 1;
tag_stack.push_front(tag);
@@ -3522,15 +3618,15 @@ void RichTextLabel::append_text(const String &p_bbcode) {
//use italics font
in_italics = true;
if (in_bold) {
- push_font(bold_italics_font);
+ push_font(bold_italics_font, get_theme_font_size(SNAME("bold_italics_font_size")));
} else {
- push_font(italics_font);
+ push_font(italics_font, get_theme_font_size(SNAME("italics_font_size")));
}
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "code") {
//use monospace font
- push_font(mono_font);
+ push_font(mono_font, get_theme_font_size(SNAME("mono_font_size")));
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag.begins_with("table=")) {
@@ -3959,9 +4055,16 @@ void RichTextLabel::append_text(const String &p_bbcode) {
String fnt_ftr = tag.substr(18, tag.length());
Vector<String> subtag = fnt_ftr.split(",");
if (subtag.size() > 0) {
- Ref<Font> font = _find_font(current);
- if (font.is_null()) {
- font = normal_font;
+ Ref<Font> font = normal_font;
+ int font_size = 0;
+ ItemFont *font_it = _find_font(current);
+ if (font_it) {
+ if (font_it->font.is_valid()) {
+ font = font_it->font;
+ }
+ if (font_it->font_size > 0) {
+ font_size = font_it->font_size;
+ }
}
Ref<FontVariation> fc;
fc.instantiate();
@@ -3976,7 +4079,7 @@ void RichTextLabel::append_text(const String &p_bbcode) {
}
}
fc->set_opentype_features(features);
- push_font(fc);
+ push_font(fc, font_size);
}
pos = brk_end + 1;
tag_stack.push_front("opentype_features");
@@ -3997,6 +4100,7 @@ void RichTextLabel::append_text(const String &p_bbcode) {
Ref<FontVariation> fc;
fc.instantiate();
+ int fnt_size = 0;
for (int i = 1; i < subtag.size(); i++) {
Vector<String> subtag_a = subtag[i].split("=", true, 2);
if (subtag_a.size() == 2) {
@@ -4007,10 +4111,7 @@ void RichTextLabel::append_text(const String &p_bbcode) {
fc->set_base_font(font_data);
}
} else if (subtag_a[0] == "size" || subtag_a[0] == "s") {
- int fnt_size = subtag_a[1].to_int();
- if (fnt_size > 0) {
- push_font_size(fnt_size);
- }
+ fnt_size = subtag_a[1].to_int();
} else if (subtag_a[0] == "glyph_spacing" || subtag_a[0] == "gl") {
int spacing = subtag_a[1].to_int();
fc->set_spacing(TextServer::SPACING_GLYPH, spacing);
@@ -4061,7 +4162,7 @@ void RichTextLabel::append_text(const String &p_bbcode) {
}
}
}
- push_font(fc);
+ push_font(fc, fnt_size);
pos = brk_end + 1;
tag_stack.push_front("font");
@@ -4843,11 +4944,10 @@ void RichTextLabel::install_effect(const Variant effect) {
Ref<RichTextEffect> rteffect;
rteffect = effect;
- if (rteffect.is_valid()) {
- custom_effects.push_back(effect);
- if ((!text.is_empty()) && use_bbcode) {
- parse_bbcode(text);
- }
+ ERR_FAIL_COND_MSG(rteffect.is_null(), "Invalid RichTextEffect resource.");
+ custom_effects.push_back(effect);
+ if ((!text.is_empty()) && use_bbcode) {
+ parse_bbcode(text);
}
}
@@ -4890,7 +4990,7 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height", "color", "inline_align"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(INLINE_ALIGNMENT_CENTER));
ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline);
ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line);
- ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font);
+ ClassDB::bind_method(D_METHOD("push_font", "font", "font_size"), &RichTextLabel::push_font);
ClassDB::bind_method(D_METHOD("push_font_size", "font_size"), &RichTextLabel::push_font_size);
ClassDB::bind_method(D_METHOD("push_normal"), &RichTextLabel::push_normal);
ClassDB::bind_method(D_METHOD("push_bold"), &RichTextLabel::push_bold);
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 3b6175e9cf..e5f0469c01 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -178,6 +178,7 @@ private:
struct ItemFont : public Item {
Ref<Font> font;
+ int font_size = 0;
ItemFont() { type = ITEM_FONT; }
};
@@ -459,10 +460,11 @@ private:
String _roman(int p_num, bool p_capitalize) const;
String _letters(int p_num, bool p_capitalize) const;
+ Item *_find_indentable(Item *p_item);
Item *_get_item_at_pos(Item *p_item_from, Item *p_item_to, int p_position);
void _find_frame(Item *p_item, ItemFrame **r_frame, int *r_line);
- int _find_font_size(Item *p_item);
- Ref<Font> _find_font(Item *p_item);
+ ItemFontSize *_find_font_size(Item *p_item);
+ ItemFont *_find_font(Item *p_item);
int _find_outline_size(Item *p_item, int p_default);
ItemList *_find_list_item(Item *p_item);
ItemDropcap *_find_dc_item(Item *p_item);
@@ -517,7 +519,7 @@ public:
void add_newline();
bool remove_line(const int p_line);
void push_dropcap(const String &p_string, const Ref<Font> &p_font, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Color &p_color = Color(1, 1, 1), int p_ol_size = 0, const Color &p_ol_color = Color(0, 0, 0, 0));
- void push_font(const Ref<Font> &p_font);
+ void push_font(const Ref<Font> &p_font, int p_size = 0);
void push_font_size(int p_font_size);
void push_outline_size(int p_font_size);
void push_normal();
diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h
index 651edd1a74..1823f86a67 100644
--- a/scene/gui/scroll_bar.h
+++ b/scene/gui/scroll_bar.h
@@ -128,4 +128,4 @@ public:
ScrollBar(VERTICAL) { set_h_size_flags(0); }
};
-#endif
+#endif // SCROLL_BAR_H
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 871cc520e9..9efab27e3a 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -37,10 +37,11 @@
Size2 ScrollContainer::get_minimum_size() const {
Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg"));
Size2 min_size;
+ Size2 content_min_size;
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c) {
+ if (!c || !c->is_visible()) {
continue;
}
if (c->is_set_as_top_level()) {
@@ -51,20 +52,26 @@ Size2 ScrollContainer::get_minimum_size() const {
}
Size2 minsize = c->get_combined_minimum_size();
- if (horizontal_scroll_mode == SCROLL_MODE_DISABLED) {
- min_size.x = MAX(min_size.x, minsize.x);
- }
- if (vertical_scroll_mode == SCROLL_MODE_DISABLED) {
- min_size.y = MAX(min_size.y, minsize.y);
- }
+ content_min_size.x = MAX(content_min_size.x, minsize.x);
+ content_min_size.y = MAX(content_min_size.y, minsize.y);
+ }
+
+ if (horizontal_scroll_mode == SCROLL_MODE_DISABLED) {
+ min_size.x = MAX(min_size.x, content_min_size.x);
+ }
+ if (vertical_scroll_mode == SCROLL_MODE_DISABLED) {
+ min_size.y = MAX(min_size.y, content_min_size.y);
}
- if (h_scroll->is_visible_in_tree()) {
+ bool h_scroll_show = horizontal_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (horizontal_scroll_mode == SCROLL_MODE_AUTO && content_min_size.x > min_size.x);
+ bool v_scroll_show = vertical_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (vertical_scroll_mode == SCROLL_MODE_AUTO && content_min_size.y > min_size.y);
+ if (h_scroll_show) {
min_size.y += h_scroll->get_minimum_size().y;
}
- if (v_scroll->is_visible_in_tree()) {
+ if (v_scroll_show) {
min_size.x += v_scroll->get_minimum_size().x;
}
+
min_size += sb->get_minimum_size();
return min_size;
}
@@ -274,7 +281,7 @@ void ScrollContainer::_update_dimensions() {
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c) {
+ if (!c || !c->is_visible()) {
continue;
}
if (c->is_set_as_top_level()) {
@@ -312,6 +319,7 @@ void ScrollContainer::_update_dimensions() {
fit_child_in_rect(c, r);
}
+ update_scrollbars();
update();
}
diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h
index b9fcf64db6..7c8690538d 100644
--- a/scene/gui/scroll_container.h
+++ b/scene/gui/scroll_container.h
@@ -116,4 +116,4 @@ public:
VARIANT_ENUM_CAST(ScrollContainer::ScrollMode);
-#endif
+#endif // SCROLL_CONTAINER_H
diff --git a/scene/gui/separator.h b/scene/gui/separator.h
index 1621bb3351..e6578a4d04 100644
--- a/scene/gui/separator.h
+++ b/scene/gui/separator.h
@@ -60,4 +60,4 @@ public:
HSeparator();
};
-#endif
+#endif // SEPARATOR_H
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 4b680f72cf..64c07007dc 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -96,15 +96,15 @@ void Slider::gui_input(const Ref<InputEvent> &p_event) {
if (grab.active) {
Size2i size = get_size();
Ref<Texture2D> grabber = get_theme_icon(SNAME("grabber"));
- float motion = (orientation == VERTICAL ? mm->get_position().y : mm->get_position().x) - grab.pos;
+ double motion = (orientation == VERTICAL ? mm->get_position().y : mm->get_position().x) - grab.pos;
if (orientation == VERTICAL) {
motion = -motion;
}
- float areasize = orientation == VERTICAL ? size.height - grabber->get_size().height : size.width - grabber->get_size().width;
+ double areasize = orientation == VERTICAL ? size.height - grabber->get_size().height : size.width - grabber->get_size().width;
if (areasize <= 0) {
return;
}
- float umotion = motion / float(areasize);
+ double umotion = motion / double(areasize);
set_as_ratio(grab.uvalue + umotion);
}
}
@@ -180,7 +180,7 @@ void Slider::_notification(int p_what) {
if (orientation == VERTICAL) {
int widget_width = style->get_minimum_size().width + style->get_center_size().width;
- float areasize = size.height - grabber->get_size().height;
+ double areasize = size.height - grabber->get_size().height;
style->draw(ci, Rect2i(Point2i(size.width / 2 - widget_width / 2, 0), Size2i(widget_width, size.height)));
grabber_area->draw(ci, Rect2i(Point2i((size.width - widget_width) / 2, size.height - areasize * ratio - grabber->get_size().height / 2), Size2i(widget_width, areasize * ratio + grabber->get_size().height / 2)));
@@ -197,7 +197,7 @@ void Slider::_notification(int p_what) {
grabber->draw(ci, Point2i(size.width / 2 - grabber->get_size().width / 2, size.height - ratio * areasize - grabber->get_size().height));
} else {
int widget_height = style->get_minimum_size().height + style->get_center_size().height;
- float areasize = size.width - grabber->get_size().width;
+ double areasize = size.width - grabber->get_size().width;
style->draw(ci, Rect2i(Point2i(0, (size.height - widget_height) / 2), Size2i(size.width, widget_height)));
grabber_area->draw(ci, Rect2i(Point2i(0, (size.height - widget_height) / 2), Size2i(areasize * ratio + grabber->get_size().width / 2, widget_height)));
@@ -218,11 +218,11 @@ void Slider::_notification(int p_what) {
}
}
-void Slider::set_custom_step(float p_custom_step) {
+void Slider::set_custom_step(double p_custom_step) {
custom_step = p_custom_step;
}
-float Slider::get_custom_step() const {
+double Slider::get_custom_step() const {
return custom_step;
}
diff --git a/scene/gui/slider.h b/scene/gui/slider.h
index 5fbfee2aec..5abaee27aa 100644
--- a/scene/gui/slider.h
+++ b/scene/gui/slider.h
@@ -38,14 +38,14 @@ class Slider : public Range {
struct Grab {
int pos = 0;
- float uvalue = 0.0;
+ double uvalue = 0.0;
bool active = false;
} grab;
int ticks = 0;
bool mouse_inside = false;
Orientation orientation;
- float custom_step = -1.0;
+ double custom_step = -1.0;
bool editable = true;
bool scrollable = true;
@@ -58,8 +58,8 @@ protected:
public:
virtual Size2 get_minimum_size() const override;
- void set_custom_step(float p_custom_step);
- float get_custom_step() const;
+ void set_custom_step(double p_custom_step);
+ double get_custom_step() const;
void set_ticks(int p_count);
int get_ticks() const;
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 890e349afb..a4733c455f 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -167,7 +167,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) {
if (drag.enabled) {
drag.diff_y += mm->get_relative().y;
- float diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8f) * SIGN(drag.diff_y);
+ double diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8) * SIGN(drag.diff_y);
set_value(CLAMP(drag.base_val + get_step() * diff_y, get_min(), get_max()));
} else if (drag.allowed && drag.capture_pos.distance_to(mm->get_position()) > 2) {
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
@@ -319,7 +319,7 @@ SpinBox::SpinBox() {
line_edit = memnew(LineEdit);
add_child(line_edit, false, INTERNAL_MODE_FRONT);
- line_edit->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ line_edit->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
line_edit->set_mouse_filter(MOUSE_FILTER_PASS);
line_edit->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT);
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index d118b28334..1b1abbcf8e 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -56,11 +56,11 @@ class SpinBox : public Range {
void _line_edit_input(const Ref<InputEvent> &p_event);
struct Drag {
- float base_val = 0.0;
+ double base_val = 0.0;
bool allowed = false;
bool enabled = false;
Vector2 capture_pos;
- float diff_y = 0.0;
+ double diff_y = 0.0;
} drag;
void _line_edit_focus_exit();
diff --git a/scene/gui/subviewport_container.h b/scene/gui/subviewport_container.h
index 55b7802aa4..5b488fb79e 100644
--- a/scene/gui/subviewport_container.h
+++ b/scene/gui/subviewport_container.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef VIEWPORTCONTAINER_H
-#define VIEWPORTCONTAINER_H
+#ifndef SUBVIEWPORT_CONTAINER_H
+#define SUBVIEWPORT_CONTAINER_H
#include "scene/gui/container.h"
@@ -63,4 +63,4 @@ public:
SubViewportContainer();
};
-#endif // VIEWPORTCONTAINER_H
+#endif // SUBVIEWPORT_CONTAINER_H
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index fa929344d4..12f91a9873 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -233,7 +233,7 @@ void TabContainer::_repaint() {
if (i == current) {
c->show();
- c->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ c->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
if (tabs_visible) {
c->set_offset(SIDE_TOP, _get_top_margin());
@@ -312,7 +312,7 @@ Vector<Control *> TabContainer::_get_tab_controls() const {
Vector<Control *> controls;
for (int i = 0; i < get_child_count(); i++) {
Control *control = Object::cast_to<Control>(get_child(i));
- if (!control || control->is_set_as_top_level() || control == tab_bar) {
+ if (!control || control->is_set_as_top_level() || control == tab_bar || control == child_removing) {
continue;
}
@@ -549,7 +549,12 @@ void TabContainer::remove_child_notify(Node *p_child) {
return;
}
- tab_bar->remove_tab(get_tab_idx_from_control(c));
+ int idx = get_tab_idx_from_control(c);
+
+ // Before this, the tab control has not changed; after this, the tab control has changed.
+ child_removing = p_child;
+ tab_bar->remove_tab(idx);
+ child_removing = nullptr;
_update_margins();
if (get_tab_count() == 0) {
diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h
index 9adaa0d844..60c8130939 100644
--- a/scene/gui/tab_container.h
+++ b/scene/gui/tab_container.h
@@ -46,6 +46,7 @@ class TabContainer : public Container {
bool drag_to_rearrange_enabled = false;
bool use_hidden_tabs_for_min_size = false;
bool theme_changing = false;
+ Node *child_removing = nullptr;
int _get_top_margin() const;
Vector<Control *> _get_tab_controls() const;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 9c6cd6bdb2..06553cd0f6 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1217,7 +1217,7 @@ void TextEdit::_notification(int p_what) {
if (brace_open_mismatch) {
current_color = brace_mismatch_color;
}
- Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, font->get_underline_thickness(font_size));
+ Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, MAX(font->get_underline_thickness(font_size) * get_theme_default_base_scale(), 1));
draw_rect(rect, current_color);
}
@@ -1226,7 +1226,7 @@ void TextEdit::_notification(int p_what) {
if (brace_close_mismatch) {
current_color = brace_mismatch_color;
}
- Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, font->get_underline_thickness(font_size));
+ Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, MAX(font->get_underline_thickness(font_size) * get_theme_default_base_scale(), 1));
draw_rect(rect, current_color);
}
}
diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h
index 5762949acd..9f6f7c1515 100644
--- a/scene/gui/texture_button.h
+++ b/scene/gui/texture_button.h
@@ -101,4 +101,5 @@ public:
};
VARIANT_ENUM_CAST(TextureButton::StretchMode);
+
#endif // TEXTURE_BUTTON_H
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 4bb8208679..1eb6c5a554 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -723,7 +723,12 @@ TreeItem *TreeItem::get_next_visible(bool p_wrap) {
TreeItem *TreeItem::get_child(int p_idx) {
_create_children_cache();
+
+ if (p_idx < 0) {
+ p_idx += children_cache.size();
+ }
ERR_FAIL_INDEX_V(p_idx, children_cache.size(), nullptr);
+
return children_cache.get(p_idx);
}
@@ -1844,15 +1849,16 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
p_item->set_meta("__focus_rect", Rect2(r.position, r.size));
- if (rtl) {
- r.position.x = get_size().width - r.position.x - r.size.x;
- }
-
- if (p_item->cells[i].selected) {
- if (has_focus()) {
- cache.selected_focus->draw(ci, r);
- } else {
- cache.selected->draw(ci, r);
+ if (select_mode != SELECT_ROW) {
+ if (rtl) {
+ r.position.x = get_size().width - r.position.x - r.size.x;
+ }
+ if (p_item->cells[i].selected) {
+ if (has_focus()) {
+ cache.selected_focus->draw(ci, r);
+ } else {
+ cache.selected->draw(ci, r);
+ }
}
}
}
@@ -2815,6 +2821,9 @@ void Tree::value_editor_changed(double p_value) {
TreeItem::Cell &c = popup_edited_item->cells.write[popup_edited_item_col];
c.val = p_value;
+
+ text_editor->set_text(String::num(c.val, Math::range_step_decimals(c.step)));
+
item_edited(popup_edited_item_col, popup_edited_item);
update();
}
@@ -5015,7 +5024,7 @@ Tree::Tree() {
popup_editor_vb = memnew(VBoxContainer);
popup_editor->add_child(popup_editor_vb);
popup_editor_vb->add_theme_constant_override("separation", 0);
- popup_editor_vb->set_anchors_and_offsets_preset(PRESET_WIDE);
+ popup_editor_vb->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
text_editor = memnew(LineEdit);
popup_editor_vb->add_child(text_editor);
text_editor->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 1690e7ac57..f0819e2980 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -719,4 +719,5 @@ public:
VARIANT_ENUM_CAST(Tree::SelectMode);
VARIANT_ENUM_CAST(Tree::DropModeFlags);
-#endif
+
+#endif // TREE_H
diff --git a/scene/gui/video_stream_player.cpp b/scene/gui/video_stream_player.cpp
index 86334882fa..f20a2ad67b 100644
--- a/scene/gui/video_stream_player.cpp
+++ b/scene/gui/video_stream_player.cpp
@@ -225,7 +225,7 @@ void VideoStreamPlayer::set_stream(const Ref<VideoStream> &p_stream) {
stream = p_stream;
if (stream.is_valid()) {
stream->set_audio_track(audio_track);
- playback = stream->instance_playback();
+ playback = stream->instantiate_playback();
} else {
playback = Ref<VideoStreamPlayback>();
}