Skip to content

Commit

Permalink
core: Reverse tab order on Shift+Tab
Browse files Browse the repository at this point in the history
When pressing Shift+Tab or Ctrl+Shift+Tab,
elements are tabbed in reverse.
  • Loading branch information
kjarosh committed Mar 26, 2024
1 parent 3fb2d04 commit 889a835
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 5 deletions.
16 changes: 12 additions & 4 deletions core/src/focus_tracker.rs
Expand Up @@ -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};

Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion core/src/player.rs
Expand Up @@ -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);
});
}
}
Expand Down
24 changes: 24 additions & 0 deletions tests/tests/swfs/avm1/tab_ordering_reverse/input.json
@@ -0,0 +1,24 @@
[
{ "type": "KeyDown", "key_code": 9 },
{ "type": "KeyDown", "key_code": 9 },
{ "type": "KeyDown", "key_code": 16 },
{ "type": "KeyDown", "key_code": 9 },
{ "type": "KeyUp", "key_code": 16 },
{ "type": "KeyDown", "key_code": 9 },
{ "type": "KeyDown", "key_code": 16 },
{ "type": "KeyDown", "key_code": 9 },
{ "type": "KeyDown", "key_code": 9 },
{ "type": "KeyDown", "key_code": 9 },
{ "type": "KeyUp", "key_code": 16 },
{ "type": "KeyDown", "key_code": 9 },
{ "type": "KeyDown", "key_code": 9 },
{ "type": "KeyDown", "key_code": 17 },
{ "type": "KeyDown", "key_code": 9 },
{ "type": "KeyUp", "key_code": 17 },
{ "type": "KeyDown", "key_code": 16 },
{ "type": "KeyDown", "key_code": 17 },
{ "type": "KeyDown", "key_code": 9 },
{ "type": "KeyUp", "key_code": 17 },
{ "type": "KeyUp", "key_code": 16 },
{ "type": "KeyDown", "key_code": 9 }
]
51 changes: 51 additions & 0 deletions tests/tests/swfs/avm1/tab_ordering_reverse/output.txt
@@ -0,0 +1,51 @@
Focus changed
old: null
new: _level0.text1
Tab pressed
Focus changed
old: _level0.text1
new: _level0.text2
Tab pressed
Focus changed
old: _level0.text2
new: _level0.text3
Tab pressed
Focus changed
old: _level0.text3
new: _level0.text2
Tab pressed
Focus changed
old: _level0.text2
new: _level0.text3
Tab pressed
Focus changed
old: _level0.text3
new: _level0.text2
Tab pressed
Focus changed
old: _level0.text2
new: _level0.text1
Tab pressed
Focus changed
old: _level0.text1
new: _level0.text4
Tab pressed
Focus changed
old: _level0.text4
new: _level0.text1
Tab pressed
Focus changed
old: _level0.text1
new: _level0.text2
Tab pressed
Focus changed
old: _level0.text2
new: _level0.text3
Tab pressed
Focus changed
old: _level0.text3
new: _level0.text2
Tab pressed
Focus changed
old: _level0.text2
new: _level0.text3
11 changes: 11 additions & 0 deletions tests/tests/swfs/avm1/tab_ordering_reverse/test.as
@@ -0,0 +1,11 @@
var listener = new Object();
listener.onSetFocus = function(oldFocus, newFocus) {
if (newFocus) {
trace("Focus changed");
trace(" old: " + oldFocus);
trace(" new: " + newFocus);
}
};
Selection.addListener(listener);

Selection.setFocus(text1);
Binary file not shown.
1 change: 1 addition & 0 deletions tests/tests/swfs/avm1/tab_ordering_reverse/test.toml
@@ -0,0 +1 @@
num_ticks = 1

0 comments on commit 889a835

Please sign in to comment.