1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-30 21:48:11 +00:00

LibGUI: Add AbstractView::move_cursor() and share some movement logic

A view can now be told to move its cursor in one of multiple directions
as specified by the CursorMovement enum.

View subclasses can override move_cursor(CursorMovement) to implement
their own cursor behavior. By default, AbstractView::move_cursor() is
a no-op.

This patch improves code sharing between TableView and TreeView. :^)
This commit is contained in:
Andreas Kling 2020-08-27 17:47:19 +02:00
parent 1b3169f405
commit 0b9d765f6b
7 changed files with 154 additions and 55 deletions

View file

@ -418,43 +418,6 @@ void TreeView::keydown_event(KeyEvent& event)
return;
}
if (event.key() == KeyCode::Key_Up) {
ModelIndex previous_index;
ModelIndex found_index;
traverse_in_paint_order([&](const ModelIndex& index, const Gfx::IntRect&, const Gfx::IntRect&, int) {
if (index == cursor_index) {
found_index = previous_index;
return IterationDecision::Break;
}
previous_index = index;
return IterationDecision::Continue;
});
if (found_index.is_valid()) {
selection().set(found_index);
scroll_into_view(selection().first(), Orientation::Vertical);
update();
}
return;
}
if (event.key() == KeyCode::Key_Down) {
ModelIndex previous_index;
ModelIndex found_index;
traverse_in_paint_order([&](const ModelIndex& index, const Gfx::IntRect&, const Gfx::IntRect&, int) {
if (previous_index == cursor_index) {
found_index = index;
return IterationDecision::Break;
}
previous_index = index;
return IterationDecision::Continue;
});
if (found_index.is_valid()) {
selection().set(found_index);
scroll_into_view(selection().first(), Orientation::Vertical);
update();
}
return;
}
auto open_tree_node = [&](bool open, MetadataForIndex& metadata) {
if (on_toggle)
on_toggle(cursor_index, open);
@ -509,6 +472,73 @@ void TreeView::keydown_event(KeyEvent& event)
return;
}
}
AbstractTableView::keydown_event(event);
}
void TreeView::move_cursor(CursorMovement movement)
{
auto cursor_index = selection().first();
switch (movement) {
case CursorMovement::Up: {
ModelIndex previous_index;
ModelIndex found_index;
traverse_in_paint_order([&](const ModelIndex& index, const Gfx::IntRect&, const Gfx::IntRect&, int) {
if (index == cursor_index) {
found_index = previous_index;
return IterationDecision::Break;
}
previous_index = index;
return IterationDecision::Continue;
});
if (found_index.is_valid()) {
selection().set(found_index);
scroll_into_view(selection().first(), Orientation::Vertical);
update();
}
break;
}
case CursorMovement::Down: {
ModelIndex previous_index;
ModelIndex found_index;
traverse_in_paint_order([&](const ModelIndex& index, const Gfx::IntRect&, const Gfx::IntRect&, int) {
if (previous_index == cursor_index) {
found_index = index;
return IterationDecision::Break;
}
previous_index = index;
return IterationDecision::Continue;
});
if (found_index.is_valid()) {
selection().set(found_index);
scroll_into_view(selection().first(), Orientation::Vertical);
update();
}
return;
}
case CursorMovement::Home:
// FIXME: Implement.
break;
case CursorMovement::End:
// FIXME: Implement.
break;
case CursorMovement::PageUp:
// FIXME: Implement.
break;
case CursorMovement::PageDown:
// FIXME: Implement.
break;
case CursorMovement::Left:
case CursorMovement::Right:
// There is no left/right in a treeview, those keys expand/collapse items instead.
break;
}
}
int TreeView::item_count() const