diff options
author | Zac <zacary.gillerat@connect.qut.edu.au> | 2020-11-13 15:29:55 +1000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-11-19 21:59:13 +0100 |
commit | 6a569bbdd76a23d0875fa06c10e4ddb5838b0259 (patch) | |
tree | d1be050bec229e311ec7bf7ebcebbf1846ee096a | |
parent | f72f4c5bcad207c6f3436bb6640422e6853f3b68 (diff) | |
download | serenity-6a569bbdd76a23d0875fa06c10e4ddb5838b0259.zip |
TextEditor: Change cursor behaviour when clicking empty space
When clicking empty space (beneath any used lines) in the TextEditor,
the cursor would jump to the start of the last line, rather than the
correct column, or the end of the line where appropriate. This was
because in the for_each_visual_line callback would return
IterationDecision::Continue if the clicked point wasn't in the line's
rect. Thus the callback would continue on each iteration and at the
end, would set the cursor to the default column of 0. To fix this I
added a bool to the callback's signature which tells the callback if
the for_each_visual_line method is on the last visual line. The
callback now does not return IterationDecision:Continue if
for_each_visual_line method is on the last line and the correct column
is then calculated with the line passed.
-rw-r--r-- | Libraries/LibGUI/TextEditor.cpp | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/Libraries/LibGUI/TextEditor.cpp b/Libraries/LibGUI/TextEditor.cpp index 5fe09d27af..67db277df3 100644 --- a/Libraries/LibGUI/TextEditor.cpp +++ b/Libraries/LibGUI/TextEditor.cpp @@ -170,8 +170,8 @@ TextPosition TextEditor::text_position_at(const Gfx::IntPoint& a_position) const size_t column_index = 0; switch (m_text_alignment) { case Gfx::TextAlignment::CenterLeft: - for_each_visual_line(line_index, [&](const Gfx::IntRect& rect, auto& view, size_t start_of_line) { - if (is_multi_line() && !rect.contains_vertically(position.y())) + for_each_visual_line(line_index, [&](const Gfx::IntRect& rect, auto& view, size_t start_of_line, [[maybe_unused]] bool is_last_visual_line) { + if (is_multi_line() && !rect.contains_vertically(position.y()) && !is_last_visual_line) return IterationDecision::Continue; column_index = start_of_line; if (position.x() <= 0) { @@ -459,7 +459,7 @@ void TextEditor::paint_event(PaintEvent& event) size_t selection_end_column_within_line = selection.end().line() == line_index ? selection.end().column() : line.length(); size_t visual_line_index = 0; - for_each_visual_line(line_index, [&](const Gfx::IntRect& visual_line_rect, auto& visual_line_text, size_t start_of_visual_line) { + for_each_visual_line(line_index, [&](const Gfx::IntRect& visual_line_rect, auto& visual_line_text, size_t start_of_visual_line, [[maybe_unused]] bool is_last_visual_line) { if (is_multi_line() && line_index == m_cursor.line()) painter.fill_rect(visual_line_rect, widget_background_color.darkened(0.9f)); #ifdef DEBUG_TEXTEDITOR @@ -1051,7 +1051,7 @@ int TextEditor::content_x_for_position(const TextPosition& position) const int x_offset = 0; switch (m_text_alignment) { case Gfx::TextAlignment::CenterLeft: - for_each_visual_line(position.line(), [&](const Gfx::IntRect&, auto& visual_line_view, size_t start_of_visual_line) { + for_each_visual_line(position.line(), [&](const Gfx::IntRect&, auto& visual_line_view, size_t start_of_visual_line, [[maybe_unused]] bool is_last_visual_line) { size_t offset_in_visual_line = position.column() - start_of_visual_line; if (position.column() >= start_of_visual_line && (offset_in_visual_line <= visual_line_view.length())) { if (offset_in_visual_line == 0) { @@ -1090,7 +1090,7 @@ Gfx::IntRect TextEditor::content_rect_for_position(const TextPosition& position) } Gfx::IntRect rect; - for_each_visual_line(position.line(), [&](const Gfx::IntRect& visual_line_rect, auto& view, size_t start_of_visual_line) { + for_each_visual_line(position.line(), [&](const Gfx::IntRect& visual_line_rect, auto& view, size_t start_of_visual_line, [[maybe_unused]] bool is_last_visual_line) { if (position.column() >= start_of_visual_line && ((position.column() - start_of_visual_line) <= view.length())) { // NOTE: We have to subtract the horizontal padding here since it's part of the visual line rect // *and* included in what we get from content_x_for_position(). @@ -1566,7 +1566,7 @@ void TextEditor::ensure_cursor_is_valid() size_t TextEditor::visual_line_containing(size_t line_index, size_t column) const { size_t visual_line_index = 0; - for_each_visual_line(line_index, [&](const Gfx::IntRect&, auto& view, size_t start_of_visual_line) { + for_each_visual_line(line_index, [&](const Gfx::IntRect&, auto& view, size_t start_of_visual_line, [[maybe_unused]] bool is_last_visual_line) { if (column >= start_of_visual_line && ((column - start_of_visual_line) < view.length())) return IterationDecision::Break; ++visual_line_index; @@ -1633,7 +1633,7 @@ void TextEditor::for_each_visual_line(size_t line_index, Callback callback) cons if (m_icon) visual_line_rect.move_by(icon_size() + icon_padding(), 0); } - if (callback(visual_line_rect, visual_line_view, start_of_line) == IterationDecision::Break) + if (callback(visual_line_rect, visual_line_view, start_of_line, visual_line_index == visual_data.visual_line_breaks.size() - 1) == IterationDecision::Break) break; start_of_line = visual_line_break; ++visual_line_index; |