summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac <zacary.gillerat@connect.qut.edu.au>2020-11-13 15:29:55 +1000
committerAndreas Kling <kling@serenityos.org>2020-11-19 21:59:13 +0100
commit6a569bbdd76a23d0875fa06c10e4ddb5838b0259 (patch)
treed1be050bec229e311ec7bf7ebcebbf1846ee096a
parentf72f4c5bcad207c6f3436bb6640422e6853f3b68 (diff)
downloadserenity-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.cpp14
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;