core: Reverse tab order on Shift+Tab

When pressing Shift+Tab or Ctrl+Shift+Tab,
elements are tabbed in reverse.
This commit is contained in:
Kamil Jarosz 2024-03-26 13:08:58 +01:00 committed by Adrian Wielgosik
parent 208aae78ee
commit 9ba7bb8629
2 changed files with 14 additions and 5 deletions

View File

@ -4,6 +4,7 @@ use crate::context::UpdateContext;
pub use crate::display_object::{
DisplayObject, TDisplayObject, TDisplayObjectContainer, TextSelection,
};
use either::Either;
use gc_arena::lock::GcLock;
use gc_arena::{Collect, Mutation};
@ -67,7 +68,7 @@ impl<'gc> FocusTracker<'gc> {
}
}
pub fn cycle(&self, context: &mut UpdateContext<'_, 'gc>) {
pub fn cycle(&self, context: &mut UpdateContext<'_, 'gc>, reverse: bool) {
let stage = context.stage;
let mut tab_order = vec![];
stage.fill_tab_order(&mut tab_order, context);
@ -88,16 +89,23 @@ impl<'gc> FocusTracker<'gc> {
tab_order.sort_by_key(|o| o.tab_index());
}
let mut tab_order = if reverse {
Either::Left(tab_order.iter().rev())
} else {
Either::Right(tab_order.iter())
}
.peekable();
let first = tab_order.peek().copied();
let next = if let Some(current_focus) = self.0.get() {
// Find the next object which should take the focus.
tab_order
.iter()
.skip_while(|o| o.as_ptr() != current_focus.as_ptr())
.nth(1)
.or(tab_order.first())
.or(first)
} else {
// If no focus is present, we start from the beginning.
tab_order.first()
first
};
self.set(next.copied(), context);

View File

@ -1186,8 +1186,9 @@ impl Player {
} = event
{
self.mutate_with_update_context(|context| {
let reversed = context.input.is_key_down(KeyCode::Shift);
let tracker = context.focus_tracker;
tracker.cycle(context);
tracker.cycle(context, reversed);
});
}
}