avm2: Properly detect whether the event has been handled in event_dispatch_to_avm2

This commit is contained in:
Kamil Jarosz 2024-07-07 11:36:10 +02:00 committed by TÖRÖK Attila
parent 250bf64a92
commit 7621553a34
2 changed files with 45 additions and 26 deletions

View File

@ -294,9 +294,19 @@ pub trait TInteractiveObject<'gc>:
button, button,
); );
Avm2::dispatch_event(&mut activation.context, avm2_event, target); let handled = Avm2::dispatch_event(&mut activation.context, avm2_event, target);
if handled {
ClipEventResult::Handled ClipEventResult::Handled
} else {
// When there are any click handlers, the down event is considered handled.
let avm2_event = Avm2EventObject::mouse_event_click(
&mut activation,
self.as_displayobject(),
button,
);
Avm2::simulate_event_dispatch(&mut activation.context, avm2_event, target)
.into()
}
} }
ClipEvent::MouseUpInside ClipEvent::MouseUpInside
| ClipEvent::RightMouseUpInside | ClipEvent::RightMouseUpInside
@ -312,9 +322,7 @@ pub trait TInteractiveObject<'gc>:
}, },
); );
Avm2::dispatch_event(&mut activation.context, avm2_event, target); Avm2::dispatch_event(&mut activation.context, avm2_event, target).into()
ClipEventResult::Handled
} }
ClipEvent::Release => { ClipEvent::Release => {
let read = self.raw_interactive(); let read = self.raw_interactive();
@ -330,6 +338,7 @@ pub trait TInteractiveObject<'gc>:
drop(read); drop(read);
let handled;
if is_double_click { if is_double_click {
let avm2_event = Avm2EventObject::mouse_event( let avm2_event = Avm2EventObject::mouse_event(
&mut activation, &mut activation,
@ -341,7 +350,7 @@ pub trait TInteractiveObject<'gc>:
MouseButton::Left, MouseButton::Left,
); );
Avm2::dispatch_event(&mut activation.context, avm2_event, target); handled = Avm2::dispatch_event(&mut activation.context, avm2_event, target);
self.raw_interactive_mut(context.gc_context).last_click = None; self.raw_interactive_mut(context.gc_context).last_click = None;
} else { } else {
@ -351,12 +360,12 @@ pub trait TInteractiveObject<'gc>:
MouseButton::Left, MouseButton::Left,
); );
Avm2::dispatch_event(&mut activation.context, avm2_event, target); handled = Avm2::dispatch_event(&mut activation.context, avm2_event, target);
self.raw_interactive_mut(context.gc_context).last_click = Some(this_click); self.raw_interactive_mut(context.gc_context).last_click = Some(this_click);
} }
ClipEventResult::Handled handled.into()
} }
ClipEvent::RightRelease | ClipEvent::MiddleRelease => { ClipEvent::RightRelease | ClipEvent::MiddleRelease => {
let avm2_event = Avm2EventObject::mouse_event_click( let avm2_event = Avm2EventObject::mouse_event_click(
@ -369,9 +378,7 @@ pub trait TInteractiveObject<'gc>:
}, },
); );
Avm2::dispatch_event(&mut activation.context, avm2_event, target); Avm2::dispatch_event(&mut activation.context, avm2_event, target).into()
ClipEventResult::Handled
} }
ClipEvent::ReleaseOutside => { ClipEvent::ReleaseOutside => {
let avm2_event = Avm2EventObject::mouse_event( let avm2_event = Avm2EventObject::mouse_event(
@ -384,11 +391,11 @@ pub trait TInteractiveObject<'gc>:
MouseButton::Left, MouseButton::Left,
); );
Avm2::dispatch_event(&mut activation.context, avm2_event, target); let handled = Avm2::dispatch_event(&mut activation.context, avm2_event, target);
self.raw_interactive_mut(context.gc_context).last_click = None; self.raw_interactive_mut(context.gc_context).last_click = None;
ClipEventResult::Handled handled.into()
} }
ClipEvent::RollOut { to } | ClipEvent::DragOut { to } => { ClipEvent::RollOut { to } | ClipEvent::DragOut { to } => {
let avm2_event = Avm2EventObject::mouse_event( let avm2_event = Avm2EventObject::mouse_event(
@ -401,7 +408,7 @@ pub trait TInteractiveObject<'gc>:
MouseButton::Left, MouseButton::Left,
); );
Avm2::dispatch_event(&mut activation.context, avm2_event, target); let mut handled = Avm2::dispatch_event(&mut activation.context, avm2_event, target);
let lca = lowest_common_ancestor( let lca = lowest_common_ancestor(
self.as_displayobject(), self.as_displayobject(),
@ -426,7 +433,9 @@ pub trait TInteractiveObject<'gc>:
); );
if let Avm2Value::Object(avm2_target) = tgt.object2() { if let Avm2Value::Object(avm2_target) = tgt.object2() {
Avm2::dispatch_event(&mut activation.context, avm2_event, avm2_target); handled =
Avm2::dispatch_event(&mut activation.context, avm2_event, avm2_target)
|| handled;
} }
rollout_target = tgt.parent(); rollout_target = tgt.parent();
@ -434,7 +443,7 @@ pub trait TInteractiveObject<'gc>:
self.raw_interactive_mut(context.gc_context).last_click = None; self.raw_interactive_mut(context.gc_context).last_click = None;
ClipEventResult::Handled handled.into()
} }
ClipEvent::RollOver { from } | ClipEvent::DragOver { from } => { ClipEvent::RollOver { from } | ClipEvent::DragOver { from } => {
let lca = lowest_common_ancestor( let lca = lowest_common_ancestor(
@ -443,6 +452,7 @@ pub trait TInteractiveObject<'gc>:
.unwrap_or_else(|| activation.context.stage.into()), .unwrap_or_else(|| activation.context.stage.into()),
); );
let mut handled = false;
let mut rollover_target = Some(self.as_displayobject()); let mut rollover_target = Some(self.as_displayobject());
while let Some(tgt) = rollover_target { while let Some(tgt) = rollover_target {
if DisplayObject::option_ptr_eq(rollover_target, lca) { if DisplayObject::option_ptr_eq(rollover_target, lca) {
@ -460,7 +470,9 @@ pub trait TInteractiveObject<'gc>:
); );
if let Avm2Value::Object(avm2_target) = tgt.object2() { if let Avm2Value::Object(avm2_target) = tgt.object2() {
Avm2::dispatch_event(&mut activation.context, avm2_event, avm2_target); handled =
Avm2::dispatch_event(&mut activation.context, avm2_event, avm2_target)
|| handled;
} }
rollover_target = tgt.parent(); rollover_target = tgt.parent();
@ -476,9 +488,10 @@ pub trait TInteractiveObject<'gc>:
MouseButton::Left, MouseButton::Left,
); );
Avm2::dispatch_event(&mut activation.context, avm2_event, target); handled =
Avm2::dispatch_event(&mut activation.context, avm2_event, target) || handled;
ClipEventResult::Handled handled.into()
} }
ClipEvent::MouseWheel { delta } => { ClipEvent::MouseWheel { delta } => {
let avm2_event = Avm2EventObject::mouse_event( let avm2_event = Avm2EventObject::mouse_event(
@ -491,9 +504,7 @@ pub trait TInteractiveObject<'gc>:
MouseButton::Left, MouseButton::Left,
); );
Avm2::dispatch_event(&mut activation.context, avm2_event, target); Avm2::dispatch_event(&mut activation.context, avm2_event, target).into()
ClipEventResult::Handled
} }
ClipEvent::MouseMoveInside => { ClipEvent::MouseMoveInside => {
let avm2_event = Avm2EventObject::mouse_event( let avm2_event = Avm2EventObject::mouse_event(
@ -506,9 +517,7 @@ pub trait TInteractiveObject<'gc>:
MouseButton::Left, MouseButton::Left,
); );
Avm2::dispatch_event(&mut activation.context, avm2_event, target); Avm2::dispatch_event(&mut activation.context, avm2_event, target).into()
ClipEventResult::Handled
} }
_ => ClipEventResult::NotHandled, _ => ClipEventResult::NotHandled,
} }

View File

@ -94,6 +94,16 @@ pub enum ClipEventResult {
Handled, Handled,
} }
impl From<bool> for ClipEventResult {
fn from(value: bool) -> Self {
if value {
Self::Handled
} else {
Self::NotHandled
}
}
}
/// An event type that can be handled by a movie clip instance. /// An event type that can be handled by a movie clip instance.
/// ///
/// Clip events come in three flavors: broadcast, anycast and targeted. An /// Clip events come in three flavors: broadcast, anycast and targeted. An