From 0479259fb922d8b11b780571abfcaa50448ac702 Mon Sep 17 00:00:00 2001 From: Kamil Jarosz Date: Fri, 19 Apr 2024 00:35:17 +0200 Subject: [PATCH] avm2: Implement DisplayObjectContainer.tabChildren --- core/src/avm2/globals/flash/display/Stage.as | 3 +- .../flash/display/display_object_container.rs | 35 ++++++++++--------- core/src/display_object/container.rs | 3 ++ 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/core/src/avm2/globals/flash/display/Stage.as b/core/src/avm2/globals/flash/display/Stage.as index a0d6647ba..21e9a0bac 100644 --- a/core/src/avm2/globals/flash/display/Stage.as +++ b/core/src/avm2/globals/flash/display/Stage.as @@ -149,7 +149,8 @@ package flash.display { } override public function set tabChildren(value:Boolean):void { - super.tabChildren = value; + // Docs say that this operation throws IllegalOperationError, + // but in reality this call is just ignored. } override public function set tabEnabled(value:Boolean):void { diff --git a/core/src/avm2/globals/flash/display/display_object_container.rs b/core/src/avm2/globals/flash/display/display_object_container.rs index 87171d1aa..546ac7817 100644 --- a/core/src/avm2/globals/flash/display/display_object_container.rs +++ b/core/src/avm2/globals/flash/display/display_object_container.rs @@ -9,10 +9,10 @@ use crate::avm2::object::{Object, TObject}; use crate::avm2::parameters::ParametersExt; use crate::avm2::value::Value; use crate::avm2::{ArrayObject, ArrayStorage, Error}; +use crate::avm2_stub_method; use crate::context::UpdateContext; use crate::display_object::HitTestOptions; use crate::display_object::{DisplayObject, TDisplayObject, TDisplayObjectContainer}; -use crate::{avm2_stub_getter, avm2_stub_method, avm2_stub_setter}; use std::cmp::min; /// Implements `flash.display.DisplayObjectContainer`'s native instance constructor. @@ -637,28 +637,31 @@ pub fn set_mouse_children<'gc>( pub fn get_tab_children<'gc>( activation: &mut Activation<'_, 'gc>, - _this: Object<'gc>, + this: Object<'gc>, _args: &[Value<'gc>], ) -> Result, Error<'gc>> { - avm2_stub_getter!( - activation, - "flash.display.DisplayObjectContainer", - "tabChildren" - ); - - Ok(true.into()) + if let Some(obj) = this + .as_display_object() + .and_then(|this| this.as_container()) + { + Ok(Value::Bool(obj.is_tab_children(&mut activation.context))) + } else { + Ok(Value::Undefined) + } } pub fn set_tab_children<'gc>( activation: &mut Activation<'_, 'gc>, - _this: Object<'gc>, - _args: &[Value<'gc>], + this: Object<'gc>, + args: &[Value<'gc>], ) -> Result, Error<'gc>> { - avm2_stub_setter!( - activation, - "flash.display.DisplayObjectContainer", - "tabChildren" - ); + if let Some(obj) = this + .as_display_object() + .and_then(|this| this.as_container()) + { + let value = args.get_bool(0); + obj.set_tab_children(&mut activation.context, value); + } Ok(Value::Undefined) } diff --git a/core/src/display_object/container.rs b/core/src/display_object/container.rs index 13c027f09..0e56aefa9 100644 --- a/core/src/display_object/container.rs +++ b/core/src/display_object/container.rs @@ -503,6 +503,9 @@ pub trait TDisplayObjectContainer<'gc>: context: &mut UpdateContext<'_, 'gc>, ) { if !self.is_tab_children(context) { + // AS3 docs say that objects with custom ordering (tabIndex set) + // are included even when tabChildren is false. + // Do not be fooled for that is untrue! return; }