Skip to content

Commit

Permalink
avm1: Support MovieClip.tabChildren
Browse files Browse the repository at this point in the history
The property `MovieClip.tabChildren` allows changing the behavior of
tab ordering hierarchically. When set to `false`, it excludes the whole
subtree represented by the movie clip from tab ordering.
  • Loading branch information
kjarosh authored and adrian17 committed Mar 29, 2024
1 parent c3843d2 commit 1883daf
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 2 deletions.
1 change: 1 addition & 0 deletions core/src/avm1/globals/movie_clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ const PROTO_DECLS: &[Declaration] = declare_properties! {
// NOTE: `tabEnabled` is not a built-in property of MovieClip.
// NOTE: `tabIndex` is not enumerable in MovieClip, contrary to Button and TextField
"tabIndex" => property(mc_getter!(tab_index), mc_setter!(set_tab_index); DONT_ENUM | VERSION_6);
// NOTE: `tabChildren` is not a built-in property of MovieClip.
};

/// Implements `MovieClip`
Expand Down
9 changes: 8 additions & 1 deletion core/src/display_object/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,12 +475,19 @@ pub trait TDisplayObjectContainer<'gc>:
RenderIter::from_container(self.into())
}

fn is_tab_children(&self, _context: &mut UpdateContext<'_, 'gc>) -> bool {
true
}

fn fill_tab_order(
&self,
tab_order: &mut Vec<DisplayObject<'gc>>,
context: &mut UpdateContext<'_, 'gc>,
) {
// TODO Add support for `tabChildren`
if !self.is_tab_children(context) {
return;
}

for child in self.iter_render_list() {
if child.is_tab_enabled(context) {
tab_order.push(child);
Expand Down
12 changes: 12 additions & 0 deletions core/src/display_object/movie_clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3051,6 +3051,18 @@ impl<'gc> TDisplayObjectContainer<'gc> for MovieClip<'gc> {
fn raw_container_mut(&self, gc_context: &Mutation<'gc>) -> RefMut<'_, ChildContainer<'gc>> {
RefMut::map(self.0.write(gc_context), |this| &mut this.container)
}

/// The property `MovieClip.tabChildren` allows changing the behavior of
/// tab ordering hierarchically.
/// When set to `false`, it excludes the whole subtree represented by
/// the movie clip from tab ordering.
///
/// _NOTE:_
/// According to the AS2 documentation, it should affect only automatic tab ordering.
/// However, that does not seem to be the case, as it also affects custom ordering.
fn is_tab_children(&self, context: &mut UpdateContext<'_, 'gc>) -> bool {
self.get_avm1_boolean_property(context, "tabChildren", true)
}
}

impl<'gc> TInteractiveObject<'gc> for MovieClip<'gc> {
Expand Down
4 changes: 3 additions & 1 deletion core/src/focus_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ impl<'gc> FocusTracker<'gc> {
first
};

self.set(next.copied(), context);
if next.is_some() {
self.set(next.copied(), context);
}
}
}

0 comments on commit 1883daf

Please sign in to comment.