1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-14 13:41:12 +00:00

Fix TextEdit line wrap indent when disabled

This commit is contained in:
kit
2025-07-22 22:09:30 -04:00
parent 037956dbc9
commit addae393a4
3 changed files with 37 additions and 37 deletions

View File

@@ -760,10 +760,11 @@ void TextEdit::_notification(int p_what) {
const Ref<TextParagraph> &ac_buf = text.get_line_data(i); const Ref<TextParagraph> &ac_buf = text.get_line_data(i);
const Vector<RID> &text_aes = text.get_accessibility_elements(i); const Vector<RID> &text_aes = text.get_accessibility_elements(i);
int first_indent_line = 0; int first_indent_line = 0;
float indent_ofs = 0.0;
if (text.is_indent_wrapped_lines()) { if (text.is_indent_wrapped_lines()) {
_get_wrapped_indent_level(i, first_indent_line); _get_wrapped_indent_level(i, first_indent_line);
indent_ofs = MIN(text.get_indent_offset(i, rtl), wrap_at_column * 0.6);
} }
float indent_ofs = MIN(text.get_indent_offset(i, rtl), wrap_at_column * 0.6);
for (int j = 0; j < text_aes.size(); j++) { for (int j = 0; j < text_aes.size(); j++) {
float text_off_x = 0.0; float text_off_x = 0.0;
float text_off_y = 0.0; float text_off_y = 0.0;
@@ -1345,10 +1346,11 @@ void TextEdit::_notification(int p_what) {
int line_wrap_amount = draw_placeholder ? placeholder_wrapped_rows.size() - 1 : get_line_wrap_count(line); int line_wrap_amount = draw_placeholder ? placeholder_wrapped_rows.size() - 1 : get_line_wrap_count(line);
int first_indent_line = 0; int first_indent_line = 0;
float indent_ofs = 0.0;
if (text.is_indent_wrapped_lines()) { if (text.is_indent_wrapped_lines()) {
_get_wrapped_indent_level(line, first_indent_line); _get_wrapped_indent_level(line, first_indent_line);
indent_ofs = MIN(text.get_indent_offset(line, rtl), wrap_at_column * 0.6);
} }
float indent_ofs = MIN(text.get_indent_offset(line, rtl), wrap_at_column * 0.6);
for (int line_wrap_index = 0; line_wrap_index <= line_wrap_amount; line_wrap_index++) { for (int line_wrap_index = 0; line_wrap_index <= line_wrap_amount; line_wrap_index++) {
if (line_wrap_index != 0) { if (line_wrap_index != 0) {
i++; i++;
@@ -2382,11 +2384,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
if (inline_object_click_handler.is_valid()) { if (inline_object_click_handler.is_valid()) {
int xmargin_beg = Math::ceil(theme_cache.style_normal->get_margin(SIDE_LEFT)) + gutters_width + gutter_padding; int xmargin_beg = Math::ceil(theme_cache.style_normal->get_margin(SIDE_LEFT)) + gutters_width + gutter_padding;
int wrap_i = get_line_wrap_index_at_column(pos.y, pos.x); int wrap_i = get_line_wrap_index_at_column(pos.y, pos.x);
int first_indent_line = 0; const float wrap_indent = _get_wrap_indent_offset(pos.y, wrap_i, is_layout_rtl());
if (text.is_indent_wrapped_lines()) {
_get_wrapped_indent_level(pos.y, first_indent_line);
}
float wrap_indent = wrap_i > first_indent_line ? MIN(text.get_indent_offset(pos.y, is_layout_rtl()), wrap_at_column * 0.6) : 0.0;
Ref<TextParagraph> ldata = text.get_line_data(line); Ref<TextParagraph> ldata = text.get_line_data(line);
for (const Variant &inline_key : ldata->get_line_objects(wrap_i)) { for (const Variant &inline_key : ldata->get_line_objects(wrap_i)) {
@@ -3610,11 +3608,7 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
Point2i pos = get_line_column_at_pos(p_pos); Point2i pos = get_line_column_at_pos(p_pos);
int xmargin_beg = Math::ceil(theme_cache.style_normal->get_margin(SIDE_LEFT)) + gutters_width + gutter_padding; int xmargin_beg = Math::ceil(theme_cache.style_normal->get_margin(SIDE_LEFT)) + gutters_width + gutter_padding;
int wrap_i = get_line_wrap_index_at_column(pos.y, pos.x); int wrap_i = get_line_wrap_index_at_column(pos.y, pos.x);
int first_indent_line = 0; const float wrap_indent = _get_wrap_indent_offset(pos.y, wrap_i, is_layout_rtl());
if (text.is_indent_wrapped_lines()) {
_get_wrapped_indent_level(pos.y, first_indent_line);
}
float wrap_indent = wrap_i > first_indent_line ? MIN(text.get_indent_offset(pos.y, is_layout_rtl()), wrap_at_column * 0.6) : 0.0;
Ref<TextParagraph> ldata = text.get_line_data(pos.y); Ref<TextParagraph> ldata = text.get_line_data(pos.y);
for (Variant k : ldata->get_line_objects(wrap_i)) { for (Variant k : ldata->get_line_objects(wrap_i)) {
@@ -4111,6 +4105,18 @@ int TextEdit::_get_wrapped_indent_level(int p_line, int &r_first_wrap) const {
return tab_count * text.get_tab_size() + whitespace_count; return tab_count * text.get_tab_size() + whitespace_count;
} }
float TextEdit::_get_wrap_indent_offset(int p_line, int p_wrap_index, bool p_rtl) const {
if (!text.is_indent_wrapped_lines()) {
return 0;
}
int first_indent_line = 0;
_get_wrapped_indent_level(p_line, first_indent_line);
if (p_wrap_index > first_indent_line) {
return MIN(text.get_indent_offset(p_line, p_rtl), wrap_at_column * 0.6);
}
return 0;
}
int TextEdit::get_indent_level(int p_line) const { int TextEdit::get_indent_level(int p_line) const {
ERR_FAIL_INDEX_V(p_line, text.size(), 0); ERR_FAIL_INDEX_V(p_line, text.size(), 0);
@@ -4999,11 +5005,8 @@ Point2i TextEdit::get_line_column_at_pos(const Point2i &p_pos, bool p_clamp_line
RID text_rid = text.get_line_data(row)->get_line_rid(wrap_index); RID text_rid = text.get_line_data(row)->get_line_rid(wrap_index);
bool rtl = is_layout_rtl(); bool rtl = is_layout_rtl();
int first_indent_line = 0; const float wrap_indent = _get_wrap_indent_offset(row, wrap_index, rtl);
if (text.is_indent_wrapped_lines()) {
_get_wrapped_indent_level(row, first_indent_line);
}
float wrap_indent = wrap_index > first_indent_line ? MIN(text.get_indent_offset(row, rtl), wrap_at_column * 0.6) : 0.0;
if (rtl) { if (rtl) {
colx = TS->shaped_text_get_size(text_rid).x - colx + wrap_indent; colx = TS->shaped_text_get_size(text_rid).x - colx + wrap_indent;
} else { } else {
@@ -5056,9 +5059,11 @@ Rect2i TextEdit::get_rect_at_line_column(int p_line, int p_column) const {
return Rect2i(-1, -1, 0, 0); return Rect2i(-1, -1, 0, 0);
} }
const float wrap_indent = _get_wrap_indent_offset(p_line, wrap_index, is_layout_rtl());
Point2i pos, size; Point2i pos, size;
pos.y = cache_entry.y_offset + get_line_height() * wrap_index; pos.y = cache_entry.y_offset + get_line_height() * wrap_index;
pos.x = get_total_gutter_width() + Math::ceil(theme_cache.style_normal->get_margin(SIDE_LEFT)) - get_h_scroll(); pos.x = get_total_gutter_width() + Math::ceil(theme_cache.style_normal->get_margin(SIDE_LEFT)) + wrap_indent - get_h_scroll();
RID text_rid = text.get_line_data(p_line)->get_line_rid(wrap_index); RID text_rid = text.get_line_data(p_line)->get_line_rid(wrap_index);
Vector2 col_bounds = TS->shaped_text_get_grapheme_bounds(text_rid, p_column); Vector2 col_bounds = TS->shaped_text_get_grapheme_bounds(text_rid, p_column);
@@ -8168,11 +8173,8 @@ int TextEdit::_get_char_pos_for_line(int p_px, int p_line, int p_wrap_index) con
p_wrap_index = MIN(p_wrap_index, text.get_line_data(p_line)->get_line_count() - 1); p_wrap_index = MIN(p_wrap_index, text.get_line_data(p_line)->get_line_count() - 1);
RID text_rid = text.get_line_data(p_line)->get_line_rid(p_wrap_index); RID text_rid = text.get_line_data(p_line)->get_line_rid(p_wrap_index);
int first_indent_line = 0; const float wrap_indent = _get_wrap_indent_offset(p_line, p_wrap_index, is_layout_rtl());
if (text.is_indent_wrapped_lines()) {
_get_wrapped_indent_level(p_line, first_indent_line);
}
float wrap_indent = p_wrap_index > first_indent_line ? MIN(text.get_indent_offset(p_line, is_layout_rtl()), wrap_at_column * 0.6) : 0.0;
if (is_layout_rtl()) { if (is_layout_rtl()) {
p_px = TS->shaped_text_get_size(text_rid).x - p_px + wrap_indent; p_px = TS->shaped_text_get_size(text_rid).x - p_px + wrap_indent;
} else { } else {
@@ -8231,22 +8233,19 @@ void TextEdit::_toggle_draw_caret() {
int TextEdit::_get_column_x_offset_for_line(int p_char, int p_line, int p_column) const { int TextEdit::_get_column_x_offset_for_line(int p_char, int p_line, int p_column) const {
ERR_FAIL_INDEX_V(p_line, text.size(), 0); ERR_FAIL_INDEX_V(p_line, text.size(), 0);
int row = 0; int wrap_index = 0;
Vector<Vector2i> rows2 = text.get_line_wrap_ranges(p_line); Vector<Vector2i> wrap_ranges = text.get_line_wrap_ranges(p_line);
for (int i = 0; i < rows2.size(); i++) { for (int i = 0; i < wrap_ranges.size(); i++) {
if ((p_char >= rows2[i].x) && (p_char < rows2[i].y || (i == rows2.size() - 1 && p_char == rows2[i].y))) { if ((p_char >= wrap_ranges[i].x) && (p_char < wrap_ranges[i].y || (i == wrap_ranges.size() - 1 && p_char == wrap_ranges[i].y))) {
row = i; wrap_index = i;
break; break;
} }
} }
RID text_rid = text.get_line_data(p_line)->get_line_rid(row); RID text_rid = text.get_line_data(p_line)->get_line_rid(wrap_index);
bool rtl = is_layout_rtl(); bool rtl = is_layout_rtl();
int first_indent_line = 0; const float wrap_indent = _get_wrap_indent_offset(p_line, wrap_index, rtl);
if (text.is_indent_wrapped_lines()) {
_get_wrapped_indent_level(p_line, first_indent_line);
}
float wrap_indent = row > first_indent_line ? MIN(text.get_indent_offset(p_line, rtl), wrap_at_column * 0.6) : 0.0;
CaretInfo ts_caret = TS->shaped_text_get_carets(text_rid, p_column); CaretInfo ts_caret = TS->shaped_text_get_carets(text_rid, p_column);
if ((ts_caret.l_caret != Rect2() && (ts_caret.l_dir == TextServer::DIRECTION_AUTO || ts_caret.l_dir == (TextServer::Direction)input_direction)) || (ts_caret.t_caret == Rect2())) { if ((ts_caret.l_caret != Rect2() && (ts_caret.l_dir == TextServer::DIRECTION_AUTO || ts_caret.l_dir == (TextServer::Direction)input_direction)) || (ts_caret.t_caret == Rect2())) {
return ts_caret.l_caret.position.x + (rtl ? -wrap_indent : wrap_indent); return ts_caret.l_caret.position.x + (rtl ? -wrap_indent : wrap_indent);

View File

@@ -727,6 +727,7 @@ protected:
virtual void _unhide_carets(); virtual void _unhide_carets();
int _get_wrapped_indent_level(int p_line, int &r_first_wrap) const; int _get_wrapped_indent_level(int p_line, int &r_first_wrap) const;
float _get_wrap_indent_offset(int p_line, int p_wrap_index, bool p_rtl) const;
// Symbol lookup. // Symbol lookup.
String lookup_symbol_word; String lookup_symbol_word;

View File

@@ -7382,7 +7382,7 @@ TEST_CASE("[SceneTree][TextEdit] multicaret") {
CHECK(text_edit->get_caret_line(1) == 1); CHECK(text_edit->get_caret_line(1) == 1);
CHECK(text_edit->get_caret_column(1) == 1); CHECK(text_edit->get_caret_column(1) == 1);
CHECK(text_edit->get_caret_line(2) == 0); CHECK(text_edit->get_caret_line(2) == 0);
CHECK(text_edit->get_caret_column(2) == 7); CHECK(text_edit->get_caret_column(2) == 8);
// Add caret above from first line and not first line wrap. // Add caret above from first line and not first line wrap.
text_edit->add_caret_at_carets(false); text_edit->add_caret_at_carets(false);
@@ -7393,9 +7393,9 @@ TEST_CASE("[SceneTree][TextEdit] multicaret") {
CHECK(text_edit->get_caret_line(1) == 1); CHECK(text_edit->get_caret_line(1) == 1);
CHECK(text_edit->get_caret_column(1) == 1); CHECK(text_edit->get_caret_column(1) == 1);
CHECK(text_edit->get_caret_line(2) == 0); CHECK(text_edit->get_caret_line(2) == 0);
CHECK(text_edit->get_caret_column(2) == 7); CHECK(text_edit->get_caret_column(2) == 8);
CHECK(text_edit->get_caret_line(3) == 0); CHECK(text_edit->get_caret_line(3) == 0);
CHECK(text_edit->get_caret_column(3) == 2); CHECK(text_edit->get_caret_column(3) == 4);
// Cannot add caret above from first line first line wrap. // Cannot add caret above from first line first line wrap.
text_edit->remove_secondary_carets(); text_edit->remove_secondary_carets();