mirror of
https://github.com/RGBCube/serenity
synced 2025-05-29 20:35:13 +00:00
LibGUI: Allow widget sibling navigation with arrow keys
There's no spatial navigation here, Left/Up moves to the previous sibling in the tab order, while Right/Down moves to the next. The arrow keys keep focus within the same parent widget, unlike the tab key which cycles through all focusable widgets in the window. This makes GUI::MessageBox feel a bit nicer since you can now arrow between the Yes/No/Cancel buttons. :^)
This commit is contained in:
parent
7d72168b14
commit
b4af4a4085
2 changed files with 27 additions and 11 deletions
|
@ -445,13 +445,25 @@ void Widget::hide_event(HideEvent&)
|
|||
|
||||
void Widget::keydown_event(KeyEvent& event)
|
||||
{
|
||||
if (!event.alt() && !event.ctrl() && !event.logo() && event.key() == KeyCode::Key_Tab) {
|
||||
if (event.shift())
|
||||
focus_previous_widget(FocusSource::Keyboard);
|
||||
else
|
||||
focus_next_widget(FocusSource::Keyboard);
|
||||
event.accept();
|
||||
return;
|
||||
if (!event.alt() && !event.ctrl() && !event.logo()) {
|
||||
if (event.key() == KeyCode::Key_Tab) {
|
||||
if (event.shift())
|
||||
focus_previous_widget(FocusSource::Keyboard, false);
|
||||
else
|
||||
focus_next_widget(FocusSource::Keyboard, false);
|
||||
event.accept();
|
||||
return;
|
||||
}
|
||||
if (!event.shift() && (event.key() == KeyCode::Key_Left || event.key() == KeyCode::Key_Up)) {
|
||||
focus_previous_widget(FocusSource::Keyboard, true);
|
||||
event.accept();
|
||||
return;
|
||||
}
|
||||
if (!event.shift() && (event.key() == KeyCode::Key_Right || event.key() == KeyCode::Key_Down)) {
|
||||
focus_next_widget(FocusSource::Keyboard, true);
|
||||
event.accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
event.ignore();
|
||||
}
|
||||
|
@ -822,9 +834,11 @@ void Widget::set_updates_enabled(bool enabled)
|
|||
update();
|
||||
}
|
||||
|
||||
void Widget::focus_previous_widget(FocusSource source)
|
||||
void Widget::focus_previous_widget(FocusSource source, bool siblings_only)
|
||||
{
|
||||
auto focusable_widgets = window()->focusable_widgets(source);
|
||||
if (siblings_only)
|
||||
focusable_widgets.remove_all_matching([this](auto& entry) { return entry->parent() != parent(); });
|
||||
for (int i = focusable_widgets.size() - 1; i >= 0; --i) {
|
||||
if (focusable_widgets[i] != this)
|
||||
continue;
|
||||
|
@ -835,9 +849,11 @@ void Widget::focus_previous_widget(FocusSource source)
|
|||
}
|
||||
}
|
||||
|
||||
void Widget::focus_next_widget(FocusSource source)
|
||||
void Widget::focus_next_widget(FocusSource source, bool siblings_only)
|
||||
{
|
||||
auto focusable_widgets = window()->focusable_widgets(source);
|
||||
if (siblings_only)
|
||||
focusable_widgets.remove_all_matching([this](auto& entry) { return entry->parent() != parent(); });
|
||||
for (size_t i = 0; i < focusable_widgets.size(); ++i) {
|
||||
if (focusable_widgets[i] != this)
|
||||
continue;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue