summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <remi@verschelde.fr>2021-11-18 15:56:06 +0100
committerGitHub <noreply@github.com>2021-11-18 15:56:06 +0100
commit395558c02110f7779ba2881baf083f0ac3b47b47 (patch)
treec560fdcd22ab0a420fb57569e012d462ff39f22c /scene
parent8ea92b9c1fb42af5d371e59c785bbb03d872a4ce (diff)
parent2a302f709738dbb0c43bc6f15a40ba8f6b9aa4e8 (diff)
Merge pull request #54462 from Paulb23/the-last-hidden-line
Diffstat (limited to 'scene')
-rw-r--r--scene/gui/code_edit.cpp20
-rw-r--r--scene/gui/text_edit.cpp88
-rw-r--r--scene/gui/text_edit.h3
3 files changed, 68 insertions, 43 deletions
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 324b21c6d0..7fba94da4c 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -296,11 +296,11 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
mpos.x = get_size().x - mpos.x;
}
- Point2i pos = get_line_column_at_pos(mpos);
+ Point2i pos = get_line_column_at_pos(mpos, false);
int line = pos.y;
int col = pos.x;
- if (mb->get_button_index() == MouseButton::LEFT) {
+ if (line != -1 && mb->get_button_index() == MouseButton::LEFT) {
if (is_line_folded(line)) {
int wrap_index = get_line_wrap_index_at_column(line, col);
if (wrap_index == get_line_wrap_count(line)) {
@@ -321,11 +321,13 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
mpos.x = get_size().x - mpos.x;
}
- Point2i pos = get_line_column_at_pos(mpos);
+ Point2i pos = get_line_column_at_pos(mpos, false);
int line = pos.y;
int col = pos.x;
- emit_signal(SNAME("symbol_lookup"), symbol_lookup_word, line, col);
+ if (line != -1) {
+ emit_signal(SNAME("symbol_lookup"), symbol_lookup_word, line, col);
+ }
return;
}
}
@@ -536,11 +538,11 @@ Control::CursorShape CodeEdit::get_cursor_shape(const Point2 &p_pos) const {
return CURSOR_ARROW;
}
- Point2i pos = get_line_column_at_pos(p_pos);
+ Point2i pos = get_line_column_at_pos(p_pos, false);
int line = pos.y;
int col = pos.x;
- if (is_line_folded(line)) {
+ if (line != -1 && is_line_folded(line)) {
int wrap_index = get_line_wrap_index_at_column(line, col);
if (wrap_index == get_line_wrap_count(line)) {
int eol_icon_width = folded_eol_icon->get_width();
@@ -2016,10 +2018,14 @@ bool CodeEdit::is_symbol_lookup_on_click_enabled() const {
String CodeEdit::get_text_for_symbol_lookup() {
Point2i mp = get_local_mouse_pos();
- Point2i pos = get_line_column_at_pos(mp);
+ Point2i pos = get_line_column_at_pos(mp, false);
int line = pos.y;
int col = pos.x;
+ if (line == -1) {
+ return String();
+ }
+
StringBuilder lookup_text;
const int text_size = get_line_count();
for (int i = 0; i < text_size; i++) {
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index fbfeea5722..74268707ff 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -2878,6 +2878,16 @@ Point2i TextEdit::get_next_visible_line_index_offset_from(int p_line_from, int p
}
}
wrap_index = get_line_wrap_count(MIN(i, text.size() - 1)) - MAX(0, num_visible - p_visible_amount);
+
+ // If we are a hidden line, then we are the last line as we cannot reach "p_visible_amount".
+ // This means we need to backtrack to get last visible line.
+ // Currently, line 0 cannot be hidden so this should always be valid.
+ int line = (p_line_from + num_total) - 1;
+ if (_is_line_hidden(line)) {
+ Point2i backtrack = get_next_visible_line_index_offset_from(line, 0, -1);
+ num_total = num_total - (backtrack.x - 1);
+ wrap_index = backtrack.y;
+ }
} else {
p_visible_amount = ABS(p_visible_amount);
int i;
@@ -3386,7 +3396,7 @@ String TextEdit::get_word_at_pos(const Vector2 &p_pos) const {
return String();
}
-Point2i TextEdit::get_line_column_at_pos(const Point2i &p_pos) const {
+Point2i TextEdit::get_line_column_at_pos(const Point2i &p_pos, bool p_allow_out_of_bounds) const {
float rows = p_pos.y;
rows -= style_normal->get_margin(SIDE_TOP);
rows /= get_line_height();
@@ -3398,6 +3408,7 @@ Point2i TextEdit::get_line_column_at_pos(const Point2i &p_pos) const {
if (get_line_wrapping_mode() != LineWrappingMode::LINE_WRAPPING_NONE || _is_hiding_enabled()) {
Point2i f_ofs = get_next_visible_line_index_offset_from(first_vis_line, caret.wrap_ofs, rows + (1 * SIGN(rows)));
wrap_index = f_ofs.y;
+
if (rows < 0) {
row = first_vis_line - (f_ofs.x - 1);
} else {
@@ -3409,33 +3420,39 @@ Point2i TextEdit::get_line_column_at_pos(const Point2i &p_pos) const {
row = 0;
}
- int col = 0;
-
if (row >= text.size()) {
row = text.size() - 1;
- col = text[row].size();
- } else {
- int colx = p_pos.x - (style_normal->get_margin(SIDE_LEFT) + gutters_width + gutter_padding);
- colx += caret.x_ofs;
- col = _get_char_pos_for_line(colx, row, wrap_index);
- if (get_line_wrapping_mode() != LineWrappingMode::LINE_WRAPPING_NONE && wrap_index < get_line_wrap_count(row)) {
- // Move back one if we are at the end of the row.
- Vector<String> rows2 = get_line_wrapped_text(row);
- int row_end_col = 0;
- for (int i = 0; i < wrap_index + 1; i++) {
- row_end_col += rows2[i].length();
- }
- if (col >= row_end_col) {
- col -= 1;
- }
+ }
+
+ int visible_lines = get_visible_line_count_in_range(first_vis_line, row);
+ if (rows > visible_lines) {
+ if (!p_allow_out_of_bounds) {
+ return Point2i(-1, -1);
}
+ return Point2i(text[row].size(), row);
+ }
- RID text_rid = text.get_line_data(row)->get_line_rid(wrap_index);
- if (is_layout_rtl()) {
- colx = TS->shaped_text_get_size(text_rid).x - colx;
+ int col = 0;
+ int colx = p_pos.x - (style_normal->get_margin(SIDE_LEFT) + gutters_width + gutter_padding);
+ colx += caret.x_ofs;
+ col = _get_char_pos_for_line(colx, row, wrap_index);
+ if (get_line_wrapping_mode() != LineWrappingMode::LINE_WRAPPING_NONE && wrap_index < get_line_wrap_count(row)) {
+ // Move back one if we are at the end of the row.
+ Vector<String> rows2 = get_line_wrapped_text(row);
+ int row_end_col = 0;
+ for (int i = 0; i < wrap_index + 1; i++) {
+ row_end_col += rows2[i].length();
}
- col = TS->shaped_text_hit_test_position(text_rid, colx);
+ if (col >= row_end_col) {
+ col -= 1;
+ }
+ }
+
+ RID text_rid = text.get_line_data(row)->get_line_rid(wrap_index);
+ if (is_layout_rtl()) {
+ colx = TS->shaped_text_get_size(text_rid).x - colx;
}
+ col = TS->shaped_text_hit_test_position(text_rid, colx);
return Point2i(col, row);
}
@@ -4012,15 +4029,7 @@ double TextEdit::get_scroll_pos_for_line(int p_line, int p_wrap_index) const {
return p_line;
}
- // Count the number of visible lines up to this line.
- double new_line_scroll_pos = 0.0;
- int to = CLAMP(p_line, 0, text.size() - 1);
- for (int i = 0; i < to; i++) {
- if (!text.is_hidden(i)) {
- new_line_scroll_pos++;
- new_line_scroll_pos += get_line_wrap_count(i);
- }
- }
+ double new_line_scroll_pos = get_visible_line_count_in_range(0, CLAMP(p_line, 0, text.size() - 1));
new_line_scroll_pos += p_wrap_index;
return new_line_scroll_pos;
}
@@ -4077,14 +4086,18 @@ int TextEdit::get_visible_line_count() const {
return _get_control_height() / get_line_height();
}
-int TextEdit::get_total_visible_line_count() const {
+int TextEdit::get_visible_line_count_in_range(int p_from_line, int p_to_line) const {
+ ERR_FAIL_INDEX_V(p_from_line, text.size(), 0);
+ ERR_FAIL_INDEX_V(p_to_line, text.size(), 0);
+ ERR_FAIL_COND_V(p_from_line > p_to_line, 0);
+
/* Returns the total number of (lines + wrapped - hidden). */
if (!_is_hiding_enabled() && get_line_wrapping_mode() == LineWrappingMode::LINE_WRAPPING_NONE) {
- return text.size();
+ return p_to_line - p_from_line;
}
int total_rows = 0;
- for (int i = 0; i < text.size(); i++) {
+ for (int i = p_from_line; i <= p_to_line; i++) {
if (!text.is_hidden(i)) {
total_rows++;
total_rows += get_line_wrap_count(i);
@@ -4093,6 +4106,10 @@ int TextEdit::get_total_visible_line_count() const {
return total_rows;
}
+int TextEdit::get_total_visible_line_count() const {
+ return get_visible_line_count_in_range(0, text.size() - 1);
+}
+
// Auto adjust
void TextEdit::adjust_viewport_to_caret() {
// Make sure Caret is visible on the screen.
@@ -4683,7 +4700,7 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_word_at_pos", "position"), &TextEdit::get_word_at_pos);
- ClassDB::bind_method(D_METHOD("get_line_column_at_pos", "position"), &TextEdit::get_line_column_at_pos);
+ ClassDB::bind_method(D_METHOD("get_line_column_at_pos", "position", "allow_out_of_bounds"), &TextEdit::get_line_column_at_pos, DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_minimap_line_at_pos", "position"), &TextEdit::get_minimap_line_at_pos);
ClassDB::bind_method(D_METHOD("is_dragging_cursor"), &TextEdit::is_dragging_cursor);
@@ -4807,6 +4824,7 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_last_full_visible_line_wrap_index"), &TextEdit::get_last_full_visible_line_wrap_index);
ClassDB::bind_method(D_METHOD("get_visible_line_count"), &TextEdit::get_visible_line_count);
+ ClassDB::bind_method(D_METHOD("get_visible_line_count_in_range", "from_line", "to_line"), &TextEdit::get_visible_line_count_in_range);
ClassDB::bind_method(D_METHOD("get_total_visible_line_count"), &TextEdit::get_total_visible_line_count);
// Auto adjust
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 1a7dc851b5..09315ae395 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -716,7 +716,7 @@ public:
String get_word_at_pos(const Vector2 &p_pos) const;
- Point2i get_line_column_at_pos(const Point2i &p_pos) const;
+ Point2i get_line_column_at_pos(const Point2i &p_pos, bool p_allow_out_of_bounds = true) const;
int get_minimap_line_at_pos(const Point2i &p_pos) const;
bool is_dragging_cursor() const;
@@ -822,6 +822,7 @@ public:
int get_last_full_visible_line_wrap_index() const;
int get_visible_line_count() const;
+ int get_visible_line_count_in_range(int p_from, int p_to) const;
int get_total_visible_line_count() const;
// Auto Adjust