summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/code_edit.cpp16
-rw-r--r--scene/gui/color_mode.cpp84
-rw-r--r--scene/gui/color_picker.cpp71
-rw-r--r--scene/gui/color_picker.h2
-rw-r--r--scene/gui/control.cpp13
-rw-r--r--scene/gui/control.h7
-rw-r--r--scene/gui/line_edit.cpp29
-rw-r--r--scene/gui/line_edit.h7
-rw-r--r--scene/gui/rich_text_label.cpp32
-rw-r--r--scene/gui/rich_text_label.h2
-rw-r--r--scene/gui/scroll_bar.cpp2
-rw-r--r--scene/gui/spin_box.cpp17
-rw-r--r--scene/gui/spin_box.h3
-rw-r--r--scene/gui/text_edit.cpp189
-rw-r--r--scene/gui/text_edit.h9
-rw-r--r--scene/gui/texture_progress_bar.cpp26
16 files changed, 365 insertions, 144 deletions
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 8a5d04f49c..f61fa29a33 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -2859,7 +2859,9 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
offset = line_height;
}
- max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
+ if (font.is_valid()) {
+ max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
+ }
code_completion_options.push_back(option);
}
@@ -2970,7 +2972,9 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
if (string_to_complete.length() == 0) {
code_completion_options.push_back(option);
- max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
+ if (font.is_valid()) {
+ max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
+ }
continue;
}
@@ -3076,7 +3080,9 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
option.matches.append_array(ssq_matches);
completion_options_subseq.push_back(option);
}
- max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
+ if (font.is_valid()) {
+ max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
+ }
} else if (!*ssq_lower) { // Matched the whole subsequence in s_lower.
option.matches.clear();
@@ -3093,7 +3099,9 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
option.matches.append_array(ssq_lower_matches);
completion_options_subseq_casei.push_back(option);
}
- max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
+ if (font.is_valid()) {
+ max_width = MAX(max_width, font->get_string_size(option.display, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).width + offset);
+ }
}
}
diff --git a/scene/gui/color_mode.cpp b/scene/gui/color_mode.cpp
index 3a5013dabe..a063cd344a 100644
--- a/scene/gui/color_mode.cpp
+++ b/scene/gui/color_mode.cpp
@@ -284,46 +284,68 @@ Color ColorModeOKHSL::get_color() const {
}
void ColorModeOKHSL::slider_draw(int p_which) {
- Vector<Vector2> pos;
- pos.resize(4);
- Vector<Color> col;
- col.resize(4);
HSlider *slider = color_picker->get_slider(p_which);
Size2 size = slider->get_size();
- Color left_color;
- Color right_color;
- Color color = color_picker->get_pick_color();
const real_t margin = 16 * color_picker->get_theme_default_base_scale();
- if (p_which == ColorPicker::SLIDER_COUNT) {
- slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, 0), Size2(size.x, margin)), true);
-
- left_color = color;
- left_color.a = 0;
- right_color = color;
- right_color.a = 1;
- } else if (p_which == 0) {
+ if (p_which == 0) { // H
Ref<Texture2D> hue = color_picker->get_theme_icon(SNAME("color_hue"), SNAME("ColorPicker"));
slider->draw_set_transform(Point2(), -Math_PI / 2, Size2(1.0, 1.0));
slider->draw_texture_rect(hue, Rect2(Vector2(margin * -1, 0), Vector2(margin, size.x)), false);
return;
- } else {
- Color s_col;
- Color v_col;
- s_col.set_ok_hsl(color.get_h(), 0, color.get_v());
- left_color = (p_which == 1) ? s_col : Color(0, 0, 0);
- s_col.set_ok_hsl(color.get_h(), 1, color.get_v());
- v_col.set_ok_hsl(color.get_h(), color.get_s(), 1);
- right_color = (p_which == 1) ? s_col : v_col;
}
- col.set(0, left_color);
- col.set(1, right_color);
- col.set(2, right_color);
- col.set(3, left_color);
- pos.set(0, Vector2(0, 0));
- pos.set(1, Vector2(size.x, 0));
- pos.set(2, Vector2(size.x, margin));
- pos.set(3, Vector2(0, margin));
+
+ Vector<Vector2> pos;
+ Vector<Color> col;
+ Color left_color;
+ Color right_color;
+ Color color = color_picker->get_pick_color();
+
+ if (p_which == 2) { // L
+ pos.resize(6);
+ col.resize(6);
+ left_color = Color(0, 0, 0);
+ Color middle_color;
+ middle_color.set_ok_hsl(color.get_ok_hsl_h(), color.get_ok_hsl_s(), 0.5);
+ right_color.set_ok_hsl(color.get_ok_hsl_h(), color.get_ok_hsl_s(), 1);
+
+ col.set(0, left_color);
+ col.set(1, middle_color);
+ col.set(2, right_color);
+ col.set(3, right_color);
+ col.set(4, middle_color);
+ col.set(5, left_color);
+ pos.set(0, Vector2(0, 0));
+ pos.set(1, Vector2(size.x * 0.5, 0));
+ pos.set(2, Vector2(size.x, 0));
+ pos.set(3, Vector2(size.x, margin));
+ pos.set(4, Vector2(size.x * 0.5, margin));
+ pos.set(5, Vector2(0, margin));
+ } else { // A / S
+ pos.resize(4);
+ col.resize(4);
+
+ if (p_which == ColorPicker::SLIDER_COUNT) {
+ slider->draw_texture_rect(color_picker->get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, 0), Size2(size.x, margin)), true);
+
+ left_color = color;
+ left_color.a = 0;
+ right_color = color;
+ right_color.a = 1;
+ } else {
+ left_color.set_ok_hsl(color.get_ok_hsl_h(), 0, color.get_ok_hsl_l());
+ right_color.set_ok_hsl(color.get_ok_hsl_h(), 1, color.get_ok_hsl_l());
+ }
+
+ col.set(0, left_color);
+ col.set(1, right_color);
+ col.set(2, right_color);
+ col.set(3, left_color);
+ pos.set(0, Vector2(0, 0));
+ pos.set(1, Vector2(size.x, 0));
+ pos.set(2, Vector2(size.x, margin));
+ pos.set(3, Vector2(0, margin));
+ }
slider->draw_polygon(pos, col);
}
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index a2c138c0b2..1b87c1d709 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -368,11 +368,10 @@ void ColorPicker::create_slider(GridContainer *gc, int idx) {
SpinBox *val = memnew(SpinBox);
slider->share(val);
+ val->set_select_all_on_focus(true);
gc->add_child(val);
LineEdit *vle = val->get_line_edit();
- vle->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter), CONNECT_DEFERRED);
- vle->connect("focus_exited", callable_mp(this, &ColorPicker::_focus_exit));
vle->connect("text_changed", callable_mp(this, &ColorPicker::_text_changed));
vle->connect("gui_input", callable_mp(this, &ColorPicker::_line_edit_input));
vle->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
@@ -744,7 +743,7 @@ void ColorPicker::add_recent_preset(const Color &p_color) {
if (recent_preset_hbc->get_child_count() >= PRESET_COLUMN_COUNT) {
recent_preset_cache.pop_front();
recent_presets.pop_front();
- recent_preset_hbc->get_child(PRESET_COLUMN_COUNT - 1)->queue_delete();
+ recent_preset_hbc->get_child(PRESET_COLUMN_COUNT - 1)->queue_free();
}
recent_presets.push_back(p_color);
recent_preset_cache.push_back(p_color);
@@ -770,7 +769,7 @@ void ColorPicker::erase_preset(const Color &p_color) {
for (int i = 1; i < preset_container->get_child_count(); i++) {
ColorPresetButton *current_btn = Object::cast_to<ColorPresetButton>(preset_container->get_child(i));
if (current_btn && p_color == current_btn->get_preset_color()) {
- current_btn->queue_delete();
+ current_btn->queue_free();
break;
}
}
@@ -794,7 +793,7 @@ void ColorPicker::erase_recent_preset(const Color &p_color) {
for (int i = 1; i < recent_preset_hbc->get_child_count(); i++) {
ColorPresetButton *current_btn = Object::cast_to<ColorPresetButton>(recent_preset_hbc->get_child(i));
if (current_btn && p_color == current_btn->get_preset_color()) {
- current_btn->queue_delete();
+ current_btn->queue_free();
break;
}
}
@@ -1087,16 +1086,24 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
Vector<Color> colors;
Color col;
col.set_ok_hsl(h, s, 1);
- points.resize(4);
- colors.resize(4);
- points.set(0, Vector2());
- points.set(1, Vector2(c->get_size().x, 0));
+ Color col2;
+ col2.set_ok_hsl(h, s, 0.5);
+ Color col3;
+ col3.set_ok_hsl(h, s, 0);
+ points.resize(6);
+ colors.resize(6);
+ points.set(0, Vector2(c->get_size().x, 0));
+ points.set(1, Vector2(c->get_size().x, c->get_size().y * 0.5));
points.set(2, c->get_size());
points.set(3, Vector2(0, c->get_size().y));
+ points.set(4, Vector2(0, c->get_size().y * 0.5));
+ points.set(5, Vector2());
colors.set(0, col);
- colors.set(1, col);
- colors.set(2, Color(0, 0, 0));
- colors.set(3, Color(0, 0, 0));
+ colors.set(1, col2);
+ colors.set(2, col3);
+ colors.set(3, col3);
+ colors.set(4, col2);
+ colors.set(5, col);
c->draw_polygon(points, colors);
int y = c->get_size().y - c->get_size().y * CLAMP(v, 0, 1);
col.set_ok_hsl(h, 1, v);
@@ -1367,7 +1374,7 @@ void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) {
Ref<Image> img = r->get_texture()->get_image();
if (img.is_valid() && !img->is_empty()) {
- Vector2 ofs = mev->get_global_position() - r->get_visible_rect().get_position();
+ Vector2 ofs = mev->get_global_position();
Color c = img->get_pixel(ofs.x, ofs.y);
set_pick_color(c);
@@ -1407,47 +1414,11 @@ void ColorPicker::_screen_pick_pressed() {
//screen->show_modal();
}
-void ColorPicker::_focus_enter() {
- bool has_ctext_focus = c_text->has_focus();
- if (has_ctext_focus) {
- c_text->select_all();
- } else {
- c_text->select(0, 0);
- }
-
- for (int i = 0; i < current_slider_count; i++) {
- if (values[i]->get_line_edit()->has_focus() && !has_ctext_focus) {
- values[i]->get_line_edit()->select_all();
- } else {
- values[i]->get_line_edit()->select(0, 0);
- }
- }
- if (alpha_value->get_line_edit()->has_focus() && !has_ctext_focus) {
- alpha_value->get_line_edit()->select_all();
- } else {
- alpha_value->get_line_edit()->select(0, 0);
- }
-}
-
-void ColorPicker::_focus_exit() {
- for (int i = 0; i < current_slider_count; i++) {
- if (!values[i]->get_line_edit()->get_menu()->is_visible()) {
- values[i]->get_line_edit()->select(0, 0);
- }
- }
- if (!alpha_value->get_line_edit()->get_menu()->is_visible()) {
- alpha_value->get_line_edit()->select(0, 0);
- }
-
- c_text->select(0, 0);
-}
-
void ColorPicker::_html_focus_exit() {
if (c_text->is_menu_visible()) {
return;
}
_html_submitted(c_text->get_text());
- _focus_exit();
}
void ColorPicker::set_presets_enabled(bool p_enabled) {
@@ -1658,9 +1629,9 @@ ColorPicker::ColorPicker() :
c_text = memnew(LineEdit);
hhb->add_child(c_text);
+ c_text->set_select_all_on_focus(true);
c_text->connect("text_submitted", callable_mp(this, &ColorPicker::_html_submitted));
c_text->connect("text_changed", callable_mp(this, &ColorPicker::_text_changed));
- c_text->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter), CONNECT_DEFERRED);
c_text->connect("focus_exited", callable_mp(this, &ColorPicker::_html_focus_exit));
wheel_edit = memnew(AspectRatioContainer);
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 6c91575893..a0843d6fa2 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -202,8 +202,6 @@ private:
void _text_changed(const String &p_new_text);
void _add_preset_pressed();
void _screen_pick_pressed();
- void _focus_enter();
- void _focus_exit();
void _html_focus_exit();
inline int _get_preset_size();
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index d0085462f0..7f2e7a2855 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -1436,13 +1436,6 @@ Rect2 Control::get_screen_rect() const {
return r;
}
-Rect2 Control::get_window_rect() const {
- ERR_FAIL_COND_V(!is_inside_tree(), Rect2());
- Rect2 gr = get_global_rect();
- gr.position += get_viewport()->get_visible_rect().position;
- return gr;
-}
-
Rect2 Control::get_anchorable_rect() const {
return Rect2(Point2(), get_size());
}
@@ -1562,7 +1555,7 @@ Size2 Control::get_minimum_size() const {
return ms;
}
-void Control::set_custom_minimum_size(const Size2i &p_custom) {
+void Control::set_custom_minimum_size(const Size2 &p_custom) {
if (p_custom == data.custom_minimum_size) {
return;
}
@@ -1570,7 +1563,7 @@ void Control::set_custom_minimum_size(const Size2i &p_custom) {
update_minimum_size();
}
-Size2i Control::get_custom_minimum_size() const {
+Size2 Control::get_custom_minimum_size() const {
return data.custom_minimum_size;
}
@@ -3163,7 +3156,7 @@ void Control::_bind_methods() {
ADD_GROUP("Layout", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_contents"), "set_clip_contents", "is_clipping_contents");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "custom_minimum_size", PROPERTY_HINT_NONE, "suffix:px"), "set_custom_minimum_size", "get_custom_minimum_size");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "custom_minimum_size", PROPERTY_HINT_NONE, "suffix:px"), "set_custom_minimum_size", "get_custom_minimum_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-Right,Right-to-Left"), "set_layout_direction", "get_layout_direction");
ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_mode", PROPERTY_HINT_ENUM, "Position,Anchors,Container,Uncontrolled", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_layout_mode", "_get_layout_mode");
ADD_PROPERTY_DEFAULT("layout_mode", LayoutMode::LAYOUT_MODE_POSITION);
diff --git a/scene/gui/control.h b/scene/gui/control.h
index e526690cbe..72e870930d 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -201,7 +201,7 @@ private:
int h_size_flags = SIZE_FILL;
int v_size_flags = SIZE_FILL;
real_t expand = 1.0;
- Point2i custom_minimum_size;
+ Point2 custom_minimum_size;
// Input events and rendering.
@@ -445,7 +445,6 @@ public:
Rect2 get_rect() const;
Rect2 get_global_rect() const;
Rect2 get_screen_rect() const;
- Rect2 get_window_rect() const; ///< use with care, as it blocks waiting for the rendering server
Rect2 get_anchorable_rect() const override;
void set_scale(const Vector2 &p_scale);
@@ -463,8 +462,8 @@ public:
virtual Size2 get_minimum_size() const;
virtual Size2 get_combined_minimum_size() const;
- void set_custom_minimum_size(const Size2i &p_custom);
- Size2i get_custom_minimum_size() const;
+ void set_custom_minimum_size(const Size2 &p_custom);
+ Size2 get_custom_minimum_size() const;
// Container sizing.
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 65670b7786..fb5ab9f923 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -372,6 +372,11 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) {
selection.drag_attempt = false;
}
+ if (pending_select_all_on_focus) {
+ select_all();
+ pending_select_all_on_focus = false;
+ }
+
show_virtual_keyboard();
}
@@ -1056,6 +1061,15 @@ void LineEdit::_notification(int p_what) {
}
}
+ if (select_all_on_focus) {
+ if (Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) {
+ // Select all when the mouse button is up.
+ pending_select_all_on_focus = true;
+ } else {
+ select_all();
+ }
+ }
+
if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
Point2 column = Point2(get_caret_column(), 1) * get_minimum_size().height;
@@ -2164,6 +2178,18 @@ bool LineEdit::is_flat() const {
return flat;
}
+void LineEdit::set_select_all_on_focus(bool p_enabled) {
+ select_all_on_focus = p_enabled;
+}
+
+bool LineEdit::is_select_all_on_focus() const {
+ return select_all_on_focus;
+}
+
+void LineEdit::clear_pending_select_all_on_focus() {
+ pending_select_all_on_focus = false;
+}
+
void LineEdit::_text_changed() {
_emit_text_change();
_clear_redo();
@@ -2367,6 +2393,8 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_right_icon"), &LineEdit::get_right_icon);
ClassDB::bind_method(D_METHOD("set_flat", "enabled"), &LineEdit::set_flat);
ClassDB::bind_method(D_METHOD("is_flat"), &LineEdit::is_flat);
+ ClassDB::bind_method(D_METHOD("set_select_all_on_focus", "enabled"), &LineEdit::set_select_all_on_focus);
+ ClassDB::bind_method(D_METHOD("is_select_all_on_focus"), &LineEdit::is_select_all_on_focus);
ADD_SIGNAL(MethodInfo("text_changed", PropertyInfo(Variant::STRING, "new_text")));
ADD_SIGNAL(MethodInfo("text_change_rejected", PropertyInfo(Variant::STRING, "rejected_substring")));
@@ -2430,6 +2458,7 @@ void LineEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_right_icon", "get_right_icon");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_control_chars"), "set_draw_control_chars", "get_draw_control_chars");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "select_all_on_focus"), "set_select_all_on_focus", "is_select_all_on_focus");
ADD_GROUP("Caret", "caret_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "set_caret_blink_enabled", "is_caret_blink_enabled");
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 861c7f273b..e0a079b623 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -174,6 +174,9 @@ private:
double caret_blink_timer = 0.0;
bool caret_blinking = false;
+ bool pending_select_all_on_focus = false;
+ bool select_all_on_focus = false;
+
struct ThemeCache {
Ref<StyleBox> normal;
Ref<StyleBox> read_only;
@@ -365,6 +368,10 @@ public:
void set_flat(bool p_enabled);
bool is_flat() const;
+ void set_select_all_on_focus(bool p_enabled);
+ bool is_select_all_on_focus() const;
+ void clear_pending_select_all_on_focus(); // For other controls, e.g. SpinBox.
+
virtual bool is_text_field() const override;
void show_virtual_keyboard();
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index c96d3c763d..7f487175dc 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1087,7 +1087,6 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
_draw_fbg_boxes(ci, rid, fbg_line_off, it_from, it_to, chr_range.x, chr_range.y, 0);
// Draw main text.
- Color selection_fg = theme_cache.font_selected_color;
Color selection_bg = theme_cache.selection_color;
int sel_start = -1;
@@ -1276,8 +1275,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
}
}
- if (selected) {
- font_color = override_selected_font_color ? selection_fg : font_color;
+ if (selected && use_selected_font_color) {
+ font_color = theme_cache.font_selected_color;
}
// Draw glyphs.
@@ -1286,9 +1285,9 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
if (txt_visible) {
if (!skip) {
if (frid != RID()) {
- TS->font_draw_glyph(frid, ci, glyphs[i].font_size, p_ofs + fx_offset + off, gl, selected ? selection_fg : font_color);
+ TS->font_draw_glyph(frid, ci, glyphs[i].font_size, p_ofs + fx_offset + off, gl, font_color);
} else if ((glyphs[i].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
- TS->draw_hex_code_box(ci, glyphs[i].font_size, p_ofs + fx_offset + off, gl, selected ? selection_fg : font_color);
+ TS->draw_hex_code_box(ci, glyphs[i].font_size, p_ofs + fx_offset + off, gl, font_color);
}
}
r_processed_glyphs++;
@@ -1688,6 +1687,7 @@ void RichTextLabel::_update_theme_item_cache() {
theme_cache.default_color = get_theme_color(SNAME("default_color"));
theme_cache.font_selected_color = get_theme_color(SNAME("font_selected_color"));
+ use_selected_font_color = theme_cache.font_selected_color != Color(0, 0, 0, 0);
theme_cache.selection_color = get_theme_color(SNAME("selection_color"));
theme_cache.font_outline_color = get_theme_color(SNAME("font_outline_color"));
theme_cache.font_shadow_color = get_theme_color(SNAME("font_shadow_color"));
@@ -3564,14 +3564,6 @@ 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;
-}
-
-bool RichTextLabel::is_overriding_selected_font_color() const {
- return override_selected_font_color;
-}
-
void RichTextLabel::set_offset(int p_pixel) {
vscroll->set_value(p_pixel);
}
@@ -5294,9 +5286,6 @@ void RichTextLabel::_bind_methods() {
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);
-
ClassDB::bind_method(D_METHOD("set_scroll_active", "active"), &RichTextLabel::set_scroll_active);
ClassDB::bind_method(D_METHOD("is_scroll_active"), &RichTextLabel::is_scroll_active);
@@ -5406,7 +5395,6 @@ void RichTextLabel::_bind_methods() {
ADD_GROUP("Text Selection", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selection_enabled"), "set_selection_enabled", "is_selection_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deselect_on_focus_loss_enabled"), "set_deselect_on_focus_loss_enabled", "is_deselect_on_focus_loss_enabled");
ADD_GROUP("Displayed Text", "");
@@ -5655,6 +5643,8 @@ void RichTextLabel::_draw_fbg_boxes(RID p_ci, RID p_rid, Vector2 line_off, Item
Vector2i fbg_index = Vector2i(end, start);
Color last_color = Color(0, 0, 0, 0);
bool draw_box = false;
+ int hpad = get_theme_constant(SNAME("text_highlight_h_padding"));
+ int vpad = get_theme_constant(SNAME("text_highlight_v_padding"));
// Draw a box based on color tags associated with glyphs
for (int i = start; i < end; i++) {
Item *it = _get_item_at_pos(it_from, it_to, i);
@@ -5684,8 +5674,8 @@ void RichTextLabel::_draw_fbg_boxes(RID p_ci, RID p_rid, Vector2 line_off, Item
if (draw_box) {
Vector<Vector2> sel = TS->shaped_text_get_selection(p_rid, fbg_index.x, fbg_index.y);
for (int j = 0; j < sel.size(); j++) {
- Vector2 rect_off = line_off + Vector2(sel[j].x, -TS->shaped_text_get_ascent(p_rid));
- Vector2 rect_size = Vector2(sel[j].y - sel[j].x, TS->shaped_text_get_size(p_rid).y);
+ Vector2 rect_off = line_off + Vector2(sel[j].x - hpad, -TS->shaped_text_get_ascent(p_rid) - vpad);
+ Vector2 rect_size = Vector2(sel[j].y - sel[j].x + 2 * hpad, TS->shaped_text_get_size(p_rid).y + 2 * vpad);
RenderingServer::get_singleton()->canvas_item_add_rect(p_ci, Rect2(rect_off, rect_size), last_color);
}
fbg_index = Vector2i(end, start);
@@ -5703,8 +5693,8 @@ void RichTextLabel::_draw_fbg_boxes(RID p_ci, RID p_rid, Vector2 line_off, Item
if (last_color.a > 0) {
Vector<Vector2> sel = TS->shaped_text_get_selection(p_rid, fbg_index.x, end);
for (int i = 0; i < sel.size(); i++) {
- Vector2 rect_off = line_off + Vector2(sel[i].x, -TS->shaped_text_get_ascent(p_rid));
- Vector2 rect_size = Vector2(sel[i].y - sel[i].x, TS->shaped_text_get_size(p_rid).y);
+ Vector2 rect_off = line_off + Vector2(sel[i].x - hpad, -TS->shaped_text_get_ascent(p_rid) - vpad);
+ Vector2 rect_size = Vector2(sel[i].y - sel[i].x + 2 * hpad, TS->shaped_text_get_size(p_rid).y + 2 * vpad);
RenderingServer::get_singleton()->canvas_item_add_rect(p_ci, Rect2(rect_off, rect_size), last_color);
}
}
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 04a682349d..d30baaa8d3 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -396,7 +396,7 @@ private:
int tab_size = 4;
bool underline_meta = true;
bool underline_hint = true;
- bool override_selected_font_color = false;
+ bool use_selected_font_color = false;
HorizontalAlignment default_alignment = HORIZONTAL_ALIGNMENT_LEFT;
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index 193c6f1ce7..6899178885 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -338,7 +338,7 @@ void ScrollBar::_notification(int p_what) {
if (scrolling) {
if (get_value() != target_scroll) {
double target = target_scroll - get_value();
- double dist = sqrt(target * target);
+ double dist = abs(target);
double vel = ((target / dist) * 500) * get_physics_process_delta_time();
if (Math::abs(vel) >= dist) {
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index fe14049d93..c4000120c8 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -168,6 +168,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
range_click_timer->stop();
_release_mouse();
drag.allowed = false;
+ line_edit->clear_pending_select_all_on_focus();
}
Ref<InputEventMouseMotion> mm = p_event;
@@ -190,6 +191,11 @@ void SpinBox::_line_edit_focus_enter() {
int col = line_edit->get_caret_column();
_value_changed(0); // Update the LineEdit's text.
line_edit->set_caret_column(col);
+
+ // LineEdit text might change and it clears any selection. Have to re-select here.
+ if (line_edit->is_select_all_on_focus() && !Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) {
+ line_edit->select_all();
+ }
}
void SpinBox::_line_edit_focus_exit() {
@@ -308,6 +314,14 @@ bool SpinBox::get_update_on_text_changed() const {
return update_on_text_changed;
}
+void SpinBox::set_select_all_on_focus(bool p_enabled) {
+ line_edit->set_select_all_on_focus(p_enabled);
+}
+
+bool SpinBox::is_select_all_on_focus() const {
+ return line_edit->is_select_all_on_focus();
+}
+
void SpinBox::set_editable(bool p_enabled) {
line_edit->set_editable(p_enabled);
}
@@ -341,6 +355,8 @@ void SpinBox::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_editable"), &SpinBox::is_editable);
ClassDB::bind_method(D_METHOD("set_update_on_text_changed", "enabled"), &SpinBox::set_update_on_text_changed);
ClassDB::bind_method(D_METHOD("get_update_on_text_changed"), &SpinBox::get_update_on_text_changed);
+ ClassDB::bind_method(D_METHOD("set_select_all_on_focus", "enabled"), &SpinBox::set_select_all_on_focus);
+ ClassDB::bind_method(D_METHOD("is_select_all_on_focus"), &SpinBox::is_select_all_on_focus);
ClassDB::bind_method(D_METHOD("apply"), &SpinBox::apply);
ClassDB::bind_method(D_METHOD("get_line_edit"), &SpinBox::get_line_edit);
@@ -350,6 +366,7 @@ void SpinBox::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "prefix"), "set_prefix", "get_prefix");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "suffix"), "set_suffix", "get_suffix");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "custom_arrow_step"), "set_custom_arrow_step", "get_custom_arrow_step");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "select_all_on_focus"), "set_select_all_on_focus", "is_select_all_on_focus");
}
SpinBox::SpinBox() {
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index c2f2ac3f5a..00f5a95699 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -101,6 +101,9 @@ public:
void set_update_on_text_changed(bool p_enabled);
bool get_update_on_text_changed() const;
+ void set_select_all_on_focus(bool p_enabled);
+ bool is_select_all_on_focus() const;
+
void apply();
void set_custom_arrow_step(const double p_custom_arrow_step);
double get_custom_arrow_step() const;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 90974e31df..144aa2a1ef 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -464,7 +464,7 @@ void TextEdit::_notification(int p_what) {
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (scrolling && get_v_scroll() != target_v_scroll) {
double target_y = target_v_scroll - get_v_scroll();
- double dist = sqrt(target_y * target_y);
+ double dist = abs(target_y);
// To ensure minimap is responsive override the speed setting.
double vel = ((target_y / dist) * ((minimap_clicked) ? 3000 : v_scroll_speed)) * get_physics_process_delta_time();
@@ -1219,7 +1219,7 @@ void TextEdit::_notification(int p_what) {
int sel_from = (line > get_selection_from_line(c)) ? TS->shaped_text_get_range(rid).x : get_selection_from_column(c);
int sel_to = (line < get_selection_to_line(c)) ? TS->shaped_text_get_range(rid).y : get_selection_to_column(c);
- if (glyphs[j].start >= sel_from && glyphs[j].end <= sel_to && override_selected_font_color) {
+ if (glyphs[j].start >= sel_from && glyphs[j].end <= sel_to && use_selected_font_color) {
gl_color = font_selected_color;
}
}
@@ -2051,7 +2051,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (is_shortcut_keys_enabled()) {
- // SELECT ALL, SELECT WORD UNDER CARET, CUT, COPY, PASTE.
+ // SELECT ALL, SELECT WORD UNDER CARET, ADD SELECTION FOR NEXT OCCURRENCE, CUT, COPY, PASTE.
if (k->is_action("ui_text_select_all", true)) {
select_all();
accept_event();
@@ -2062,6 +2062,11 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
accept_event();
return;
}
+ if (k->is_action("ui_text_add_selection_for_next_occurrence", true)) {
+ add_selection_for_next_occurrence();
+ accept_event();
+ return;
+ }
if (k->is_action("ui_cut", true)) {
cut();
accept_event();
@@ -2089,6 +2094,17 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
accept_event();
return;
}
+
+ if (k->is_action("ui_text_caret_add_below", true)) {
+ add_caret_at_carets(true);
+ accept_event();
+ return;
+ }
+ if (k->is_action("ui_text_caret_add_above", true)) {
+ add_caret_at_carets(false);
+ accept_event();
+ return;
+ }
}
// MISC.
@@ -2803,6 +2819,51 @@ void TextEdit::_move_caret_document_end(bool p_select) {
}
}
+void TextEdit::_get_above_below_caret_line_column(int p_old_line, int p_old_wrap_index, int p_old_column, bool p_below, int &p_new_line, int &p_new_column, int p_last_fit_x) const {
+ if (p_last_fit_x == -1) {
+ p_last_fit_x = _get_column_x_offset_for_line(p_old_column, p_old_line, p_old_column);
+ }
+
+ // Calculate the new line and wrap index
+ p_new_line = p_old_line;
+ int caret_wrap_index = p_old_wrap_index;
+ if (p_below) {
+ if (caret_wrap_index < get_line_wrap_count(p_new_line)) {
+ caret_wrap_index++;
+ } else {
+ p_new_line++;
+ caret_wrap_index = 0;
+ }
+ } else {
+ if (caret_wrap_index == 0) {
+ p_new_line--;
+ caret_wrap_index = get_line_wrap_count(p_new_line);
+ } else {
+ caret_wrap_index--;
+ }
+ }
+
+ // Boundary checks
+ if (p_new_line < 0) {
+ p_new_line = 0;
+ }
+ if (p_new_line >= text.size()) {
+ p_new_line = text.size() - 1;
+ }
+
+ p_new_column = _get_char_pos_for_line(p_last_fit_x, p_new_line, caret_wrap_index);
+ if (p_new_column != 0 && get_line_wrapping_mode() != LineWrappingMode::LINE_WRAPPING_NONE && caret_wrap_index < get_line_wrap_count(p_new_line)) {
+ Vector<String> rows = get_line_wrapped_text(p_new_line);
+ int row_end_col = 0;
+ for (int i = 0; i < caret_wrap_index + 1; i++) {
+ row_end_col += rows[i].length();
+ }
+ if (p_new_column >= row_end_col) {
+ p_new_column -= 1;
+ }
+ }
+}
+
void TextEdit::_update_placeholder() {
if (font.is_null() || font_size <= 0) {
return; // Not in tree?
@@ -2861,6 +2922,7 @@ void TextEdit::_update_caches() {
/* Selection */
font_selected_color = get_theme_color(SNAME("font_selected_color"));
selection_color = get_theme_color(SNAME("selection_color"));
+ use_selected_font_color = font_selected_color != Color(0, 0, 0, 0);
/* Visual. */
style_normal = get_theme_stylebox(SNAME("normal"));
@@ -3810,6 +3872,9 @@ void TextEdit::undo() {
return;
}
+ if (in_action) {
+ pending_action_end = true;
+ }
_push_current_op();
if (undo_stack_pos == nullptr) {
@@ -3871,6 +3936,9 @@ void TextEdit::redo() {
return;
}
+ if (in_action) {
+ pending_action_end = true;
+ }
_push_current_op();
if (undo_stack_pos == nullptr) {
@@ -4504,6 +4572,68 @@ int TextEdit::get_caret_count() const {
return carets.size();
}
+void TextEdit::add_caret_at_carets(bool p_below) {
+ Vector<int> caret_edit_order = get_caret_index_edit_order();
+ for (const int &caret_index : caret_edit_order) {
+ const int caret_line = get_caret_line(caret_index);
+ const int caret_column = get_caret_column(caret_index);
+
+ // The last fit x will be cleared if the caret has a selection,
+ // but if it does not have a selection the last fit x will be
+ // transferred to the new caret
+ int caret_from_column = 0, caret_to_column = 0, caret_last_fit_x = carets[caret_index].last_fit_x;
+ if (has_selection(caret_index)) {
+ // If the selection goes over multiple lines, deselect it.
+ if (get_selection_from_line(caret_index) != get_selection_to_line(caret_index)) {
+ deselect(caret_index);
+ } else {
+ caret_from_column = get_selection_from_column(caret_index);
+ caret_to_column = get_selection_to_column(caret_index);
+ caret_last_fit_x = -1;
+ carets.write[caret_index].last_fit_x = _get_column_x_offset_for_line(caret_column, caret_line, caret_column);
+ }
+ }
+
+ // Get the line and column of the new caret as if you would move the caret by pressing the arrow keys
+ int new_caret_line, new_caret_column, new_caret_from_column = 0, new_caret_to_column = 0;
+ _get_above_below_caret_line_column(caret_line, get_caret_wrap_index(caret_index), caret_column, p_below, new_caret_line, new_caret_column, caret_last_fit_x);
+
+ // If the caret does have a selection calculate the new from and to columns
+ if (caret_from_column != caret_to_column) {
+ // We only need to calculate the selection columns if the column of the caret changed
+ if (caret_column != new_caret_column) {
+ int _; // unused placeholder for p_new_line
+ _get_above_below_caret_line_column(caret_line, get_caret_wrap_index(caret_index), caret_from_column, p_below, _, new_caret_from_column);
+ _get_above_below_caret_line_column(caret_line, get_caret_wrap_index(caret_index), caret_to_column, p_below, _, new_caret_to_column);
+ } else {
+ new_caret_from_column = caret_from_column;
+ new_caret_to_column = caret_to_column;
+ }
+ }
+
+ // Add the new caret
+ const int new_caret_index = add_caret(new_caret_line, new_caret_column);
+
+ if (new_caret_index == -1) {
+ continue;
+ }
+ // Also add the selection if there should be one
+ if (new_caret_from_column != new_caret_to_column) {
+ select(new_caret_line, new_caret_from_column, new_caret_line, new_caret_to_column, new_caret_index);
+ // Necessary to properly modify the selection after adding the new caret
+ carets.write[new_caret_index].selection.selecting_line = new_caret_line;
+ carets.write[new_caret_index].selection.selecting_column = new_caret_column == new_caret_from_column ? new_caret_to_column : new_caret_from_column;
+ continue;
+ }
+
+ // Copy the last fit x over
+ carets.write[new_caret_index].last_fit_x = carets[caret_index].last_fit_x;
+ }
+
+ merge_overlapping_carets();
+ queue_redraw();
+}
+
Vector<int> TextEdit::get_caret_index_edit_order() {
if (!caret_index_edit_dirty) {
return caret_index_edit_order;
@@ -4739,14 +4869,6 @@ bool TextEdit::is_drag_and_drop_selection_enabled() const {
return drag_and_drop_selection_enabled;
}
-void TextEdit::set_override_selected_font_color(bool p_override_selected_font_color) {
- override_selected_font_color = p_override_selected_font_color;
-}
-
-bool TextEdit::is_overriding_selected_font_color() const {
- return override_selected_font_color;
-}
-
void TextEdit::set_selection_mode(SelectionMode p_mode, int p_line, int p_column, int p_caret) {
ERR_FAIL_INDEX(p_caret, carets.size());
@@ -4832,6 +4954,45 @@ void TextEdit::select_word_under_caret(int p_caret) {
merge_overlapping_carets();
}
+void TextEdit::add_selection_for_next_occurrence() {
+ if (!selecting_enabled || !is_multiple_carets_enabled()) {
+ return;
+ }
+
+ if (text.size() == 1 && text[0].length() == 0) {
+ return;
+ }
+
+ // Always use the last caret, to correctly search for
+ // the next occurrence that comes after this caret.
+ int caret = get_caret_count() - 1;
+
+ if (!has_selection(caret)) {
+ select_word_under_caret(caret);
+ return;
+ }
+
+ const String &highlighted_text = get_selected_text(caret);
+ int column = get_selection_from_column(caret) + 1;
+ int line = get_caret_line(caret);
+
+ const Point2i next_occurrence = search(highlighted_text, SEARCH_MATCH_CASE, line, column);
+
+ if (next_occurrence.x == -1 || next_occurrence.y == -1) {
+ return;
+ }
+
+ int to_column = get_selection_to_column(caret) + 1;
+ int end = next_occurrence.x + (to_column - column);
+ int new_caret = add_caret(next_occurrence.y, end);
+
+ if (new_caret != -1) {
+ select(next_occurrence.y, next_occurrence.x, next_occurrence.y, end, new_caret);
+ adjust_viewport_to_caret(new_caret);
+ merge_overlapping_carets();
+ }
+}
+
void TextEdit::select(int p_from_line, int p_from_column, int p_to_line, int p_to_column, int p_caret) {
ERR_FAIL_INDEX(p_caret, carets.size());
if (!selecting_enabled) {
@@ -5959,6 +6120,7 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_secondary_carets"), &TextEdit::remove_secondary_carets);
ClassDB::bind_method(D_METHOD("merge_overlapping_carets"), &TextEdit::merge_overlapping_carets);
ClassDB::bind_method(D_METHOD("get_caret_count"), &TextEdit::get_caret_count);
+ ClassDB::bind_method(D_METHOD("add_caret_at_carets", "below"), &TextEdit::add_caret_at_carets);
ClassDB::bind_method(D_METHOD("get_caret_index_edit_order"), &TextEdit::get_caret_index_edit_order);
ClassDB::bind_method(D_METHOD("adjust_carets_after_edit", "caret", "from_line", "from_col", "to_line", "to_col"), &TextEdit::adjust_carets_after_edit);
@@ -5992,14 +6154,12 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_drag_and_drop_selection_enabled", "enable"), &TextEdit::set_drag_and_drop_selection_enabled);
ClassDB::bind_method(D_METHOD("is_drag_and_drop_selection_enabled"), &TextEdit::is_drag_and_drop_selection_enabled);
- ClassDB::bind_method(D_METHOD("set_override_selected_font_color", "override"), &TextEdit::set_override_selected_font_color);
- ClassDB::bind_method(D_METHOD("is_overriding_selected_font_color"), &TextEdit::is_overriding_selected_font_color);
-
ClassDB::bind_method(D_METHOD("set_selection_mode", "mode", "line", "column", "caret_index"), &TextEdit::set_selection_mode, DEFVAL(-1), DEFVAL(-1), DEFVAL(0));
ClassDB::bind_method(D_METHOD("get_selection_mode"), &TextEdit::get_selection_mode);
ClassDB::bind_method(D_METHOD("select_all"), &TextEdit::select_all);
ClassDB::bind_method(D_METHOD("select_word_under_caret", "caret_index"), &TextEdit::select_word_under_caret, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("add_selection_for_next_occurrence"), &TextEdit::add_selection_for_next_occurrence);
ClassDB::bind_method(D_METHOD("select", "from_line", "from_column", "to_line", "to_column", "caret_index"), &TextEdit::select, DEFVAL(0));
ClassDB::bind_method(D_METHOD("has_selection", "caret_index"), &TextEdit::has_selection, DEFVAL(-1));
@@ -6163,7 +6323,6 @@ void TextEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "middle_mouse_paste_enabled"), "set_middle_mouse_paste_enabled", "is_middle_mouse_paste_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "wrap_mode", PROPERTY_HINT_ENUM, "None,Boundary"), "set_line_wrapping_mode", "get_line_wrapping_mode");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), "set_highlight_all_occurrences", "is_highlight_all_occurrences_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_current_line"), "set_highlight_current_line", "is_highlight_current_line_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_control_chars"), "set_draw_control_chars", "get_draw_control_chars");
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index e4af621b73..935f2a7ce8 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -443,9 +443,9 @@ private:
bool deselect_on_focus_loss_enabled = true;
bool drag_and_drop_selection_enabled = true;
- Color font_selected_color = Color(1, 1, 1);
+ Color font_selected_color = Color(0, 0, 0, 0);
Color selection_color = Color(1, 1, 1);
- bool override_selected_font_color = false;
+ bool use_selected_font_color = false;
bool selection_drag_attempt = false;
bool dragging_selection = false;
@@ -598,6 +598,9 @@ private:
void _move_caret_document_start(bool p_select);
void _move_caret_document_end(bool p_select);
+ // Used in add_caret_at_carets
+ void _get_above_below_caret_line_column(int p_old_line, int p_old_wrap_index, int p_old_column, bool p_below, int &p_new_line, int &p_new_column, int p_last_fit_x = -1) const;
+
protected:
void _notification(int p_what);
@@ -816,6 +819,7 @@ public:
void remove_secondary_carets();
void merge_overlapping_carets();
int get_caret_count() const;
+ void add_caret_at_carets(bool p_below);
Vector<int> get_caret_index_edit_order();
void adjust_carets_after_edit(int p_caret, int p_from_line, int p_from_col, int p_to_line, int p_to_col);
@@ -851,6 +855,7 @@ public:
void select_all();
void select_word_under_caret(int p_caret = -1);
+ void add_selection_for_next_occurrence();
void select(int p_from_line, int p_from_column, int p_to_line, int p_to_column, int p_caret = 0);
bool has_selection(int p_caret = -1) const;
diff --git a/scene/gui/texture_progress_bar.cpp b/scene/gui/texture_progress_bar.cpp
index a9982b3ece..48c6dc5cfc 100644
--- a/scene/gui/texture_progress_bar.cpp
+++ b/scene/gui/texture_progress_bar.cpp
@@ -510,18 +510,38 @@ void TextureProgressBar::_notification(int p_what) {
}
pts.append(to);
+ Ref<AtlasTexture> atlas_progress = progress;
+ bool valid_atlas_progress = atlas_progress.is_valid() && atlas_progress->get_atlas().is_valid();
+ Rect2 region_rect;
+ Size2 atlas_size;
+ if (valid_atlas_progress) {
+ region_rect = atlas_progress->get_region();
+ atlas_size = atlas_progress->get_atlas()->get_size();
+ }
+
Vector<Point2> uvs;
Vector<Point2> points;
- uvs.push_back(get_relative_center());
- points.push_back(progress_offset + s * get_relative_center());
for (int i = 0; i < pts.size(); i++) {
Point2 uv = unit_val_to_uv(pts[i]);
if (uvs.find(uv) >= 0) {
continue;
}
- uvs.push_back(uv);
points.push_back(progress_offset + Point2(uv.x * s.x, uv.y * s.y));
+ if (valid_atlas_progress) {
+ uv.x = Math::remap(uv.x, 0, 1, region_rect.position.x / atlas_size.x, (region_rect.position.x + region_rect.size.x) / atlas_size.x);
+ uv.y = Math::remap(uv.y, 0, 1, region_rect.position.y / atlas_size.y, (region_rect.position.y + region_rect.size.y) / atlas_size.y);
+ }
+ uvs.push_back(uv);
+ }
+
+ Point2 center_point = get_relative_center();
+ points.push_back(progress_offset + s * center_point);
+ if (valid_atlas_progress) {
+ center_point.x = Math::remap(center_point.x, 0, 1, region_rect.position.x / atlas_size.x, (region_rect.position.x + region_rect.size.x) / atlas_size.x);
+ center_point.y = Math::remap(center_point.y, 0, 1, region_rect.position.y / atlas_size.y, (region_rect.position.y + region_rect.size.y) / atlas_size.y);
}
+ uvs.push_back(center_point);
+
Vector<Color> colors;
colors.push_back(tint_progress);
draw_polygon(points, colors, uvs, progress);