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.cpp69
-rw-r--r--scene/gui/color_picker.h2
-rw-r--r--scene/gui/control.cpp34
-rw-r--r--scene/gui/graph_edit.cpp8
-rw-r--r--scene/gui/item_list.cpp4
-rw-r--r--scene/gui/line_edit.cpp29
-rw-r--r--scene/gui/line_edit.h7
-rw-r--r--scene/gui/rich_text_effect.cpp6
-rw-r--r--scene/gui/rich_text_label.cpp32
-rw-r--r--scene/gui/rich_text_label.h2
-rw-r--r--scene/gui/spin_box.cpp17
-rw-r--r--scene/gui/spin_box.h3
-rw-r--r--scene/gui/text_edit.cpp196
-rw-r--r--scene/gui/text_edit.h10
-rw-r--r--scene/gui/texture_progress_bar.cpp26
17 files changed, 384 insertions, 161 deletions
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index e77a826d6a..5f8f25154c 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -2874,7 +2874,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);
}
@@ -2986,7 +2988,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;
}
@@ -3092,7 +3096,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();
@@ -3109,7 +3115,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 929bf27be6..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);
@@ -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 2ec0a48278..c5cb7157e8 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -633,7 +633,7 @@ Rect2 Control::get_parent_anchorable_rect() const {
#ifdef TOOLS_ENABLED
Node *edited_root = get_tree()->get_edited_scene_root();
if (edited_root && (this == edited_root || edited_root->is_ancestor_of(this))) {
- parent_rect.size = Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height"));
+ parent_rect.size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height"));
} else {
parent_rect = get_viewport()->get_visible_rect();
}
@@ -1551,10 +1551,8 @@ bool Control::is_minimum_size_adjust_blocked() const {
Size2 Control::get_minimum_size() const {
Vector2 ms;
- if (GDVIRTUAL_CALL(_get_minimum_size, ms)) {
- return ms;
- }
- return Vector2();
+ GDVIRTUAL_CALL(_get_minimum_size, ms);
+ return ms;
}
void Control::set_custom_minimum_size(const Size2 &p_custom) {
@@ -1799,11 +1797,8 @@ Variant Control::get_drag_data(const Point2 &p_point) {
}
Variant dd;
- if (GDVIRTUAL_CALL(_get_drag_data, p_point, dd)) {
- return dd;
- }
-
- return Variant();
+ GDVIRTUAL_CALL(_get_drag_data, p_point, dd);
+ return dd;
}
bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
@@ -1815,10 +1810,8 @@ bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const
}
bool ret = false;
- if (GDVIRTUAL_CALL(_can_drop_data, p_point, p_data, ret)) {
- return ret;
- }
- return false;
+ GDVIRTUAL_CALL(_can_drop_data, p_point, p_data, ret);
+ return ret;
}
void Control::drop_data(const Point2 &p_point, const Variant &p_data) {
@@ -2725,11 +2718,8 @@ void Control::end_bulk_theme_override() {
TypedArray<Vector2i> Control::structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const {
if (p_parser_type == TextServer::STRUCTURED_TEXT_CUSTOM) {
TypedArray<Vector2i> ret;
- if (GDVIRTUAL_CALL(_structured_text_parser, p_args, p_text, ret)) {
- return ret;
- } else {
- return TypedArray<Vector2i>();
- }
+ GDVIRTUAL_CALL(_structured_text_parser, p_args, p_text, ret);
+ return ret;
} else {
return TS->parse_structured_text(p_parser_type, p_args, p_text);
}
@@ -2814,10 +2804,8 @@ String Control::get_tooltip(const Point2 &p_pos) const {
Control *Control::make_custom_tooltip(const String &p_text) const {
Object *ret = nullptr;
- if (GDVIRTUAL_CALL(_make_custom_tooltip, p_text, ret)) {
- return Object::cast_to<Control>(ret);
- }
- return nullptr;
+ GDVIRTUAL_CALL(_make_custom_tooltip, p_text, ret);
+ return Object::cast_to<Control>(ret);
}
// Base object overrides.
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index caf8db4515..46b712379d 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -1475,11 +1475,9 @@ void GraphEdit::force_connection_drag_end() {
}
bool GraphEdit::is_node_hover_valid(const StringName &p_from, const int p_from_port, const StringName &p_to, const int p_to_port) {
- bool valid = false;
- if (GDVIRTUAL_CALL(_is_node_hover_valid, p_from, p_from_port, p_to, p_to_port, valid)) {
- return valid;
- }
- return true;
+ bool valid = true;
+ GDVIRTUAL_CALL(_is_node_hover_valid, p_from, p_from_port, p_to, p_to_port, valid);
+ return valid;
}
void GraphEdit::set_panning_scheme(PanningScheme p_scheme) {
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 223428906a..d6b5557a3f 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -733,7 +733,7 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
uint64_t now = OS::get_singleton()->get_ticks_msec();
uint64_t diff = now - search_time_msec;
- if (diff < uint64_t(ProjectSettings::get_singleton()->get("gui/timers/incremental_search_max_interval_msec")) * 2) {
+ if (diff < uint64_t(GLOBAL_GET("gui/timers/incremental_search_max_interval_msec")) * 2) {
for (int i = current - 1; i >= 0; i--) {
if (CAN_SELECT(i) && items[i].text.begins_with(search_string)) {
set_current(i);
@@ -771,7 +771,7 @@ void ItemList::gui_input(const Ref<InputEvent> &p_event) {
uint64_t now = OS::get_singleton()->get_ticks_msec();
uint64_t diff = now - search_time_msec;
- if (diff < uint64_t(ProjectSettings::get_singleton()->get("gui/timers/incremental_search_max_interval_msec")) * 2) {
+ if (diff < uint64_t(GLOBAL_GET("gui/timers/incremental_search_max_interval_msec")) * 2) {
for (int i = current + 1; i < items.size(); i++) {
if (CAN_SELECT(i) && items[i].text.begins_with(search_string)) {
set_current(i);
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_effect.cpp b/scene/gui/rich_text_effect.cpp
index c9516ed6b9..0dece1c287 100644
--- a/scene/gui/rich_text_effect.cpp
+++ b/scene/gui/rich_text_effect.cpp
@@ -56,10 +56,8 @@ Variant RichTextEffect::get_bbcode() const {
bool RichTextEffect::_process_effect_impl(Ref<CharFXTransform> p_cfx) {
bool return_value = false;
- if (GDVIRTUAL_CALL(_process_custom_fx, p_cfx, return_value)) {
- return return_value;
- }
- return false;
+ GDVIRTUAL_CALL(_process_custom_fx, p_cfx, return_value);
+ return return_value;
}
RichTextEffect::RichTextEffect() {
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/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 b1c2676bc1..cc9fc99b9c 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -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,16 @@ 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_text_remove_secondary_carets", true) && _should_remove_secondary_carets()) {
+ remove_secondary_carets();
+ accept_event();
+ return;
+ }
if (k->is_action("ui_cut", true)) {
cut();
accept_event();
@@ -2089,6 +2099,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 +2824,55 @@ void TextEdit::_move_caret_document_end(bool p_select) {
}
}
+bool TextEdit::_should_remove_secondary_carets() {
+ return carets.size() > 1;
+}
+
+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 +2931,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 +3881,9 @@ void TextEdit::undo() {
return;
}
+ if (in_action) {
+ pending_action_end = true;
+ }
_push_current_op();
if (undo_stack_pos == nullptr) {
@@ -3871,6 +3945,9 @@ void TextEdit::redo() {
return;
}
+ if (in_action) {
+ pending_action_end = true;
+ }
_push_current_op();
if (undo_stack_pos == nullptr) {
@@ -4504,6 +4581,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 +4878,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 +4963,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 +6129,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 +6163,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 +6332,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..263a36aba8 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;
@@ -597,6 +597,10 @@ private:
void _delete(bool p_word = false, bool p_all_to_right = false);
void _move_caret_document_start(bool p_select);
void _move_caret_document_end(bool p_select);
+ bool _should_remove_secondary_carets();
+
+ // 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 +820,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 +856,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);