mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 14:38:11 +00:00
GTextEditor: Allow GTextDocumentSpans to be "skippable"
Setting the is_skippable flag on a GTextDocumentSpan will now cause the cursor to skip over that span when moving with Ctrl+Left/Right.
This commit is contained in:
parent
27a30fdc2a
commit
57f7009b9e
3 changed files with 56 additions and 26 deletions
|
@ -298,3 +298,37 @@ Vector<GTextRange> GTextDocument::find_all(const StringView& needle) const
|
|||
}
|
||||
return ranges;
|
||||
}
|
||||
|
||||
Optional<GTextDocumentSpan> GTextDocument::first_non_skippable_span_before(const GTextPosition& position) const
|
||||
{
|
||||
for (int i = m_spans.size() - 1; i >= 0; --i) {
|
||||
if (!m_spans[i].range.contains(position))
|
||||
continue;
|
||||
while ((i - 1) >= 0 && m_spans[i - 1].is_skippable)
|
||||
--i;
|
||||
if (i <= 0)
|
||||
return {};
|
||||
return m_spans[i - 1];
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<GTextDocumentSpan> GTextDocument::first_non_skippable_span_after(const GTextPosition& position) const
|
||||
{
|
||||
for (int i = 0; i < m_spans.size(); ++i) {
|
||||
if (!m_spans[i].range.contains(position))
|
||||
continue;
|
||||
while ((i + 1) < m_spans.size() && m_spans[i + 1].is_skippable)
|
||||
++i;
|
||||
if (i >= (m_spans.size() - 1))
|
||||
return {};
|
||||
return m_spans[i + 1];
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ class GTextDocumentLine;
|
|||
struct GTextDocumentSpan {
|
||||
GTextRange range;
|
||||
Color color;
|
||||
bool is_skippable { false };
|
||||
const Font* font { nullptr };
|
||||
};
|
||||
|
||||
|
@ -76,6 +77,9 @@ public:
|
|||
|
||||
char character_at(const GTextPosition&) const;
|
||||
|
||||
Optional<GTextDocumentSpan> first_non_skippable_span_before(const GTextPosition&) const;
|
||||
Optional<GTextDocumentSpan> first_non_skippable_span_after(const GTextPosition&) const;
|
||||
|
||||
private:
|
||||
explicit GTextDocument(Client* client);
|
||||
|
||||
|
|
|
@ -678,19 +678,15 @@ void GTextEditor::keydown_event(GKeyEvent& event)
|
|||
if (event.key() == KeyCode::Key_Left) {
|
||||
if (event.ctrl() && document().has_spans()) {
|
||||
// FIXME: Do something nice when the document has no spans.
|
||||
for (int i = 0; i < document().spans().size(); ++i) {
|
||||
if (!document().spans()[i].range.contains(m_cursor))
|
||||
continue;
|
||||
GTextPosition new_cursor = i == 0
|
||||
? GTextPosition(0, 0)
|
||||
: document().spans()[i - 1].range.start();
|
||||
toggle_selection_if_needed_for_event(event);
|
||||
set_cursor(new_cursor);
|
||||
if (event.shift() && m_selection.start().is_valid()) {
|
||||
m_selection.set_end(m_cursor);
|
||||
did_update_selection();
|
||||
}
|
||||
break;
|
||||
auto span = document().first_non_skippable_span_before(m_cursor);
|
||||
GTextPosition new_cursor = !span.has_value()
|
||||
? GTextPosition(0, 0)
|
||||
: span.value().range.start();
|
||||
toggle_selection_if_needed_for_event(event);
|
||||
set_cursor(new_cursor);
|
||||
if (event.shift() && m_selection.start().is_valid()) {
|
||||
m_selection.set_end(m_cursor);
|
||||
did_update_selection();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -717,19 +713,15 @@ void GTextEditor::keydown_event(GKeyEvent& event)
|
|||
if (event.key() == KeyCode::Key_Right) {
|
||||
if (event.ctrl() && document().has_spans()) {
|
||||
// FIXME: Do something nice when the document has no spans.
|
||||
for (int i = 0; i < document().spans().size(); ++i) {
|
||||
if (!document().spans()[i].range.contains(m_cursor))
|
||||
continue;
|
||||
GTextPosition new_cursor = i == (document().spans().size() - 1)
|
||||
? document().spans().last().range.end()
|
||||
: document().spans()[i + 1].range.start();
|
||||
toggle_selection_if_needed_for_event(event);
|
||||
set_cursor(new_cursor);
|
||||
if (event.shift() && m_selection.start().is_valid()) {
|
||||
m_selection.set_end(m_cursor);
|
||||
did_update_selection();
|
||||
}
|
||||
break;
|
||||
auto span = document().first_non_skippable_span_after(m_cursor);
|
||||
GTextPosition new_cursor = !span.has_value()
|
||||
? document().spans().last().range.end()
|
||||
: span.value().range.start();
|
||||
toggle_selection_if_needed_for_event(event);
|
||||
set_cursor(new_cursor);
|
||||
if (event.shift() && m_selection.start().is_valid()) {
|
||||
m_selection.set_end(m_cursor);
|
||||
did_update_selection();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue