diff --git a/core/src/avm2/globals/flash/display/simplebutton.rs b/core/src/avm2/globals/flash/display/simplebutton.rs index 3bcf6116f..1ddd2f55c 100644 --- a/core/src/avm2/globals/flash/display/simplebutton.rs +++ b/core/src/avm2/globals/flash/display/simplebutton.rs @@ -8,7 +8,7 @@ use crate::avm2::object::{Object, TObject}; use crate::avm2::traits::Trait; use crate::avm2::value::Value; use crate::avm2::Error; -use crate::display_object::{Avm2Button, TDisplayObject}; +use crate::display_object::{Avm2Button, ButtonTracking, TDisplayObject}; use crate::vminterface::Instantiator; use gc_arena::{GcCell, MutationContext}; use swf::ButtonState; @@ -257,6 +257,46 @@ pub fn set_up_state<'gc>( Ok(Value::Undefined) } +/// Implements `trackAsMenu`'s getter +pub fn track_as_menu<'gc>( + _activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + if let Some(btn) = this + .and_then(|this| this.as_display_object()) + .and_then(|this| this.as_avm2_button()) + { + return Ok((btn.button_tracking() == ButtonTracking::Menu).into()); + } + + Ok(Value::Undefined) +} + +/// Implements `trackAsMenu`'s setter +pub fn set_track_as_menu<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + args: &[Value<'gc>], +) -> Result, Error> { + if let Some(btn) = this + .and_then(|this| this.as_display_object()) + .and_then(|this| this.as_avm2_button()) + { + match args + .get(0) + .cloned() + .unwrap_or(Value::Undefined) + .coerce_to_boolean() + { + true => btn.set_button_tracking(&mut activation.context, ButtonTracking::Menu), + false => btn.set_button_tracking(&mut activation.context, ButtonTracking::Push), + } + } + + Ok(Value::Undefined) +} + /// Construct `SimpleButton`'s class. pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> { let class = Class::new( @@ -303,6 +343,14 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc> QName::new(Namespace::public(), "upState"), Method::from_builtin(set_up_state), )); + write.define_instance_trait(Trait::from_getter( + QName::new(Namespace::public(), "trackAsMenu"), + Method::from_builtin(track_as_menu), + )); + write.define_instance_trait(Trait::from_setter( + QName::new(Namespace::public(), "trackAsMenu"), + Method::from_builtin(set_track_as_menu), + )); class } diff --git a/core/src/display_object.rs b/core/src/display_object.rs index 5575336fd..2ec4ae296 100644 --- a/core/src/display_object.rs +++ b/core/src/display_object.rs @@ -39,7 +39,7 @@ pub use crate::display_object::container::{ }; use crate::events::{ClipEvent, ClipEventResult}; pub use avm1_button::Avm1Button; -pub use avm2_button::Avm2Button; +pub use avm2_button::{Avm2Button, ButtonTracking}; pub use bitmap::Bitmap; pub use edit_text::{AutoSizeMode, EditText, TextSelection}; pub use graphic::Graphic; diff --git a/core/src/display_object/avm2_button.rs b/core/src/display_object/avm2_button.rs index 9a988bb15..2a3fa2e43 100644 --- a/core/src/display_object/avm2_button.rs +++ b/core/src/display_object/avm2_button.rs @@ -356,6 +356,18 @@ impl<'gc> Avm2Button<'gc> { ) { self.0.write(context.gc_context).use_hand_cursor = use_hand_cursor; } + + pub fn button_tracking(self) -> ButtonTracking { + self.0.read().tracking + } + + pub fn set_button_tracking( + self, + context: &mut UpdateContext<'_, 'gc, '_>, + tracking: ButtonTracking, + ) { + self.0.write(context.gc_context).tracking = tracking; + } } impl<'gc> TDisplayObject<'gc> for Avm2Button<'gc> { @@ -847,7 +859,7 @@ struct ButtonAction { #[derive(Copy, Clone, Debug, PartialEq, Eq, Collect)] #[collect(require_static)] -enum ButtonTracking { +pub enum ButtonTracking { Push, Menu, }