1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-19 18:55:07 +00:00

GTextEditor: Add on_selection_changed callback.

This is probably a bit eager and won't coalesce all updates or even
ignore no-op changes to the selection.
This commit is contained in:
Andreas Kling 2019-04-12 02:52:34 +02:00
parent 09339fa912
commit 32e5c8c689
2 changed files with 54 additions and 13 deletions

View file

@ -56,6 +56,7 @@ void GTextEditor::set_text(const String& text)
set_cursor(0, m_lines[0]->length()); set_cursor(0, m_lines[0]->length());
else else
set_cursor(0, 0); set_cursor(0, 0);
did_update_selection();
update(); update();
} }
@ -101,11 +102,12 @@ void GTextEditor::mousedown_event(GMouseEvent& event)
m_selection.set(m_cursor, { }); m_selection.set(m_cursor, { });
} }
if (m_selection.start().is_valid()) if (m_selection.start().is_valid() && m_selection.start() != m_cursor)
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
// FIXME: Only update the relevant rects. // FIXME: Only update the relevant rects.
update(); update();
did_update_selection();
return; return;
} }
} }
@ -125,6 +127,7 @@ void GTextEditor::mousemove_event(GMouseEvent& event)
if (m_in_drag_select) { if (m_in_drag_select) {
set_cursor(text_position_at(event.position())); set_cursor(text_position_at(event.position()));
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
did_update_selection();
update(); update();
return; return;
} }
@ -220,11 +223,13 @@ void GTextEditor::toggle_selection_if_needed_for_event(const GKeyEvent& event)
{ {
if (event.shift() && !m_selection.is_valid()) { if (event.shift() && !m_selection.is_valid()) {
m_selection.set(m_cursor, { }); m_selection.set(m_cursor, { });
did_update_selection();
update(); update();
return; return;
} }
if (!event.shift() && m_selection.is_valid()) { if (!event.shift() && m_selection.is_valid()) {
m_selection.clear(); m_selection.clear();
did_update_selection();
update(); update();
return; return;
} }
@ -243,8 +248,10 @@ void GTextEditor::keydown_event(GKeyEvent& event)
int new_column = min(m_cursor.column(), m_lines[new_line]->length()); int new_column = min(m_cursor.column(), m_lines[new_line]->length());
toggle_selection_if_needed_for_event(event); toggle_selection_if_needed_for_event(event);
set_cursor(new_line, new_column); set_cursor(new_line, new_column);
if (m_selection.start().is_valid()) if (m_selection.start().is_valid()) {
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
did_update_selection();
}
} }
return; return;
} }
@ -254,8 +261,10 @@ void GTextEditor::keydown_event(GKeyEvent& event)
int new_column = min(m_cursor.column(), m_lines[new_line]->length()); int new_column = min(m_cursor.column(), m_lines[new_line]->length());
toggle_selection_if_needed_for_event(event); toggle_selection_if_needed_for_event(event);
set_cursor(new_line, new_column); set_cursor(new_line, new_column);
if (m_selection.start().is_valid()) if (m_selection.start().is_valid()) {
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
did_update_selection();
}
} }
return; return;
} }
@ -265,8 +274,10 @@ void GTextEditor::keydown_event(GKeyEvent& event)
int new_column = min(m_cursor.column(), m_lines[new_line]->length()); int new_column = min(m_cursor.column(), m_lines[new_line]->length());
toggle_selection_if_needed_for_event(event); toggle_selection_if_needed_for_event(event);
set_cursor(new_line, new_column); set_cursor(new_line, new_column);
if (m_selection.start().is_valid()) if (m_selection.start().is_valid()) {
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
did_update_selection();
}
} }
return; return;
} }
@ -276,8 +287,10 @@ void GTextEditor::keydown_event(GKeyEvent& event)
int new_column = min(m_cursor.column(), m_lines[new_line]->length()); int new_column = min(m_cursor.column(), m_lines[new_line]->length());
toggle_selection_if_needed_for_event(event); toggle_selection_if_needed_for_event(event);
set_cursor(new_line, new_column); set_cursor(new_line, new_column);
if (m_selection.start().is_valid()) if (m_selection.start().is_valid()) {
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
did_update_selection();
}
} }
return; return;
} }
@ -286,15 +299,19 @@ void GTextEditor::keydown_event(GKeyEvent& event)
int new_column = m_cursor.column() - 1; int new_column = m_cursor.column() - 1;
toggle_selection_if_needed_for_event(event); toggle_selection_if_needed_for_event(event);
set_cursor(m_cursor.line(), new_column); set_cursor(m_cursor.line(), new_column);
if (m_selection.start().is_valid()) if (m_selection.start().is_valid()) {
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
did_update_selection();
}
} else if (m_cursor.line() > 0) { } else if (m_cursor.line() > 0) {
int new_line = m_cursor.line() - 1; int new_line = m_cursor.line() - 1;
int new_column = m_lines[new_line]->length(); int new_column = m_lines[new_line]->length();
toggle_selection_if_needed_for_event(event); toggle_selection_if_needed_for_event(event);
set_cursor(new_line, new_column); set_cursor(new_line, new_column);
if (m_selection.start().is_valid()) if (m_selection.start().is_valid()) {
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
did_update_selection();
}
} }
return; return;
} }
@ -303,50 +320,63 @@ void GTextEditor::keydown_event(GKeyEvent& event)
int new_column = m_cursor.column() + 1; int new_column = m_cursor.column() + 1;
toggle_selection_if_needed_for_event(event); toggle_selection_if_needed_for_event(event);
set_cursor(m_cursor.line(), new_column); set_cursor(m_cursor.line(), new_column);
if (m_selection.start().is_valid()) if (m_selection.start().is_valid()) {
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
did_update_selection();
}
} else if (m_cursor.line() != line_count() - 1) { } else if (m_cursor.line() != line_count() - 1) {
int new_line = m_cursor.line() + 1; int new_line = m_cursor.line() + 1;
int new_column = 0; int new_column = 0;
toggle_selection_if_needed_for_event(event); toggle_selection_if_needed_for_event(event);
set_cursor(new_line, new_column); set_cursor(new_line, new_column);
if (m_selection.start().is_valid()) if (m_selection.start().is_valid()) {
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
did_update_selection();
}
} }
return; return;
} }
if (!event.ctrl() && event.key() == KeyCode::Key_Home) { if (!event.ctrl() && event.key() == KeyCode::Key_Home) {
toggle_selection_if_needed_for_event(event); toggle_selection_if_needed_for_event(event);
set_cursor(m_cursor.line(), 0); set_cursor(m_cursor.line(), 0);
if (m_selection.start().is_valid()) if (m_selection.start().is_valid()) {
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
did_update_selection();
}
return; return;
} }
if (!event.ctrl() && event.key() == KeyCode::Key_End) { if (!event.ctrl() && event.key() == KeyCode::Key_End) {
toggle_selection_if_needed_for_event(event); toggle_selection_if_needed_for_event(event);
set_cursor(m_cursor.line(), current_line().length()); set_cursor(m_cursor.line(), current_line().length());
if (m_selection.start().is_valid()) if (m_selection.start().is_valid()) {
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
did_update_selection();
}
return; return;
} }
if (event.ctrl() && event.key() == KeyCode::Key_Home) { if (event.ctrl() && event.key() == KeyCode::Key_Home) {
toggle_selection_if_needed_for_event(event); toggle_selection_if_needed_for_event(event);
set_cursor(0, 0); set_cursor(0, 0);
if (m_selection.start().is_valid()) if (m_selection.start().is_valid()) {
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
did_update_selection();
}
return; return;
} }
if (event.ctrl() && event.key() == KeyCode::Key_End) { if (event.ctrl() && event.key() == KeyCode::Key_End) {
toggle_selection_if_needed_for_event(event); toggle_selection_if_needed_for_event(event);
set_cursor(line_count() - 1, m_lines[line_count() - 1]->length()); set_cursor(line_count() - 1, m_lines[line_count() - 1]->length());
if (m_selection.start().is_valid()) if (m_selection.start().is_valid()) {
m_selection.set_end(m_cursor); m_selection.set_end(m_cursor);
did_update_selection();
}
return; return;
} }
if (event.modifiers() == Mod_Ctrl && event.key() == KeyCode::Key_A) { if (event.modifiers() == Mod_Ctrl && event.key() == KeyCode::Key_A) {
GTextPosition start_of_document { 0, 0 }; GTextPosition start_of_document { 0, 0 };
GTextPosition end_of_document { line_count() - 1, m_lines[line_count() - 1]->length() }; GTextPosition end_of_document { line_count() - 1, m_lines[line_count() - 1]->length() };
m_selection.set(start_of_document, end_of_document); m_selection.set(start_of_document, end_of_document);
did_update_selection();
set_cursor(end_of_document); set_cursor(end_of_document);
update(); update();
return; return;
@ -355,6 +385,7 @@ void GTextEditor::keydown_event(GKeyEvent& event)
if (event.key() == KeyCode::Key_Backspace) { if (event.key() == KeyCode::Key_Backspace) {
if (has_selection()) { if (has_selection()) {
delete_selection(); delete_selection();
did_update_selection();
return; return;
} }
if (m_cursor.column() > 0) { if (m_cursor.column() > 0) {
@ -703,6 +734,7 @@ void GTextEditor::clear()
m_lines.clear(); m_lines.clear();
m_lines.append(make<Line>()); m_lines.append(make<Line>());
m_selection.clear(); m_selection.clear();
did_update_selection();
set_cursor(0, 0); set_cursor(0, 0);
update(); update();
} }
@ -771,6 +803,7 @@ void GTextEditor::delete_selection()
m_lines.append(make<Line>()); m_lines.append(make<Line>());
m_selection.clear(); m_selection.clear();
did_update_selection();
set_cursor(selection.start()); set_cursor(selection.start());
update(); update();
did_change(); did_change();
@ -829,3 +862,9 @@ void GTextEditor::did_change()
}); });
} }
} }
void GTextEditor::did_update_selection()
{
if (on_selection_change)
on_selection_change();
}

View file

@ -75,6 +75,7 @@ public:
void set_ruler_visible(bool b) { m_ruler_visible = b; } void set_ruler_visible(bool b) { m_ruler_visible = b; }
Function<void()> on_cursor_change; Function<void()> on_cursor_change;
Function<void()> on_selection_change;
void set_text(const String&); void set_text(const String&);
void scroll_cursor_into_view(); void scroll_cursor_into_view();
@ -160,6 +161,7 @@ private:
void toggle_selection_if_needed_for_event(const GKeyEvent&); void toggle_selection_if_needed_for_event(const GKeyEvent&);
void insert_at_cursor_or_replace_selection(const String&); void insert_at_cursor_or_replace_selection(const String&);
void delete_selection(); void delete_selection();
void did_update_selection();
Type m_type { MultiLine }; Type m_type { MultiLine };