From 9ba7bb86298132b116d3043fea8308d168667ad8 Mon Sep 17 00:00:00 2001 From: Kamil Jarosz Date: Tue, 26 Mar 2024 13:08:58 +0100 Subject: [PATCH] core: Reverse tab order on Shift+Tab When pressing Shift+Tab or Ctrl+Shift+Tab, elements are tabbed in reverse. --- core/src/focus_tracker.rs | 16 ++++++++++++---- core/src/player.rs | 3 ++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/core/src/focus_tracker.rs b/core/src/focus_tracker.rs index 020108368..50b5f0f79 100644 --- a/core/src/focus_tracker.rs +++ b/core/src/focus_tracker.rs @@ -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); diff --git a/core/src/player.rs b/core/src/player.rs index ea1772b4f..bd47e1005 100644 --- a/core/src/player.rs +++ b/core/src/player.rs @@ -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); }); } }