diff --git a/core/src/avm2/globals/flash/display/interactiveobject.rs b/core/src/avm2/globals/flash/display/interactiveobject.rs index 1dd644d13..2e71d69c3 100644 --- a/core/src/avm2/globals/flash/display/interactiveobject.rs +++ b/core/src/avm2/globals/flash/display/interactiveobject.rs @@ -2,11 +2,12 @@ use crate::avm2::activation::Activation; use crate::avm2::class::Class; -use crate::avm2::method::Method; +use crate::avm2::method::{Method, NativeMethodImpl}; use crate::avm2::names::{Namespace, QName}; -use crate::avm2::object::Object; +use crate::avm2::object::{Object, TObject}; use crate::avm2::value::Value; use crate::avm2::Error; +use crate::display_object::{TDisplayObject, TInteractiveObject}; use gc_arena::{GcCell, MutationContext}; /// Implements `flash.display.InteractiveObject`'s instance constructor. @@ -40,6 +41,80 @@ pub fn class_init<'gc>( Ok(Value::Undefined) } +/// Implements `InteractiveObject.mouseEnabled`'s getter. +pub fn mouse_enabled<'gc>( + _activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + if let Some(int) = this + .and_then(|t| t.as_display_object()) + .and_then(|dobj| dobj.as_interactive()) + { + return Ok(int.mouse_enabled().into()); + } + + Ok(Value::Undefined) +} + +/// Implements `InteractiveObject.mouseEnabled`'s setter. +pub fn set_mouse_enabled<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + args: &[Value<'gc>], +) -> Result, Error> { + if let Some(int) = this + .and_then(|t| t.as_display_object()) + .and_then(|dobj| dobj.as_interactive()) + { + let value = args + .get(0) + .cloned() + .unwrap_or(Value::Undefined) + .coerce_to_boolean(); + int.set_mouse_enabled(activation.context.gc_context, value); + } + + Ok(Value::Undefined) +} + +/// Implements `InteractiveObject.doubleClickEnabled`'s getter. +pub fn double_click_enabled<'gc>( + _activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + if let Some(int) = this + .and_then(|t| t.as_display_object()) + .and_then(|dobj| dobj.as_interactive()) + { + return Ok(int.double_click_enabled().into()); + } + + Ok(Value::Undefined) +} + +/// Implements `InteractiveObject.doubleClickEnabled`'s setter. +pub fn set_double_click_enabled<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + args: &[Value<'gc>], +) -> Result, Error> { + if let Some(int) = this + .and_then(|t| t.as_display_object()) + .and_then(|dobj| dobj.as_interactive()) + { + let value = args + .get(0) + .cloned() + .unwrap_or(Value::Undefined) + .coerce_to_boolean(); + int.set_double_click_enabled(activation.context.gc_context, value); + } + + Ok(Value::Undefined) +} + /// Construct `InteractiveObject`'s class. pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> { let class = Class::new( @@ -62,5 +137,19 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc> mc, )); + const PUBLIC_INSTANCE_PROPERTIES: &[( + &str, + Option, + Option, + )] = &[ + ("mouseEnabled", Some(mouse_enabled), Some(set_mouse_enabled)), + ( + "doubleClickEnabled", + Some(double_click_enabled), + Some(set_double_click_enabled), + ), + ]; + write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES); + class } diff --git a/tests/tests/regression_tests.rs b/tests/tests/regression_tests.rs index 0826bf046..1363eabad 100644 --- a/tests/tests/regression_tests.rs +++ b/tests/tests/regression_tests.rs @@ -711,6 +711,7 @@ swf_tests! { (as3_hasownproperty_namespaces, "avm2/hasownproperty_namespaces", 1), (as3_propertyisenumerable_namespaces, "avm2/propertyisenumerable_namespaces", 1), (as3_interface_namespaces, "avm2/interface_namespaces", 1), + (as3_interactiveobject_enabled, "avm2/interactiveobject_enabled", 1), } // TODO: These tests have some inaccuracies currently, so we use approx_eq to test that numeric values are close enough. diff --git a/tests/tests/swfs/avm2/interactiveobject_enabled/output.txt b/tests/tests/swfs/avm2/interactiveobject_enabled/output.txt new file mode 100644 index 000000000..1abe3e341 --- /dev/null +++ b/tests/tests/swfs/avm2/interactiveobject_enabled/output.txt @@ -0,0 +1,25 @@ +///(Initial state of event enabled flags...) +///this.mouseEnabled +true +///this.doubleClickEnabled +false +///this.doubleClickEnabled = true +///this.mouseEnabled +true +///this.doubleClickEnabled +true +///this.mouseEnabled = false +///this.mouseEnabled +false +///this.doubleClickEnabled +true +///this.doubleClickEnabled = false +///this.mouseEnabled +false +///this.doubleClickEnabled +false +///this.mouseEnabled = true +///this.mouseEnabled +true +///this.doubleClickEnabled +false diff --git a/tests/tests/swfs/avm2/interactiveobject_enabled/test.fla b/tests/tests/swfs/avm2/interactiveobject_enabled/test.fla new file mode 100644 index 000000000..f2fd6a7b9 Binary files /dev/null and b/tests/tests/swfs/avm2/interactiveobject_enabled/test.fla differ diff --git a/tests/tests/swfs/avm2/interactiveobject_enabled/test.swf b/tests/tests/swfs/avm2/interactiveobject_enabled/test.swf new file mode 100644 index 000000000..cc37cd68d Binary files /dev/null and b/tests/tests/swfs/avm2/interactiveobject_enabled/test.swf differ