core: Mouse picking for buttons uses shape hit tests

This commit is contained in:
Mike Welsh 2020-08-30 16:05:56 -07:00
parent d7a186b2cd
commit f2f70cc882
2 changed files with 26 additions and 26 deletions

View File

@ -280,13 +280,7 @@ impl<'gc> TDisplayObject<'gc> for Button<'gc> {
} }
fn hit_test_bounds(&self, point: (Twips, Twips)) -> bool { fn hit_test_bounds(&self, point: (Twips, Twips)) -> bool {
for child in self.0.read().hit_area.values().rev() { self.world_bounds().contains(point)
if child.world_bounds().contains(point) {
return true;
}
}
false
} }
fn hit_test_shape(&self, point: (Twips, Twips)) -> bool { fn hit_test_shape(&self, point: (Twips, Twips)) -> bool {
@ -306,12 +300,15 @@ impl<'gc> TDisplayObject<'gc> for Button<'gc> {
point: (Twips, Twips), point: (Twips, Twips),
) -> Option<DisplayObject<'gc>> { ) -> Option<DisplayObject<'gc>> {
// The button is hovered if the mouse is over any child nodes. // The button is hovered if the mouse is over any child nodes.
if self.hit_test_bounds(point) { if self.visible() {
Some(self_node) for child in self.0.read().hit_area.values() {
} else { if child.hit_test_shape(point) {
None return Some(self_node);
} }
} }
}
None
}
fn object(&self) -> Value<'gc> { fn object(&self) -> Value<'gc> {
self.0 self.0

View File

@ -1086,24 +1086,27 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
self_node: DisplayObject<'gc>, self_node: DisplayObject<'gc>,
point: (Twips, Twips), point: (Twips, Twips),
) -> Option<DisplayObject<'gc>> { ) -> Option<DisplayObject<'gc>> {
if self.visible() { if self.visible() && self.world_bounds().contains(point) {
if self.world_bounds().contains(point) { // This movieclip operates in "button mode" if it has a mouse handler,
// either via on(..) or via property mc.onRelease, etc.
let is_button_mode = {
if self.0.read().has_button_clip_event { if self.0.read().has_button_clip_event {
return Some(self_node); true
} } else {
let mut activation = Activation::from_stub( let mut activation = Activation::from_stub(
context.reborrow(), context.reborrow(),
ActivationIdentifier::root("[Mouse Pick]"), ActivationIdentifier::root("[Mouse Pick]"),
); );
let object = self.object().coerce_to_object(&mut activation); let object = self.object().coerce_to_object(&mut activation);
if ClipEvent::BUTTON_EVENT_METHODS ClipEvent::BUTTON_EVENT_METHODS
.iter() .iter()
.any(|handler| object.has_property(&mut activation, handler)) .any(|handler| object.has_property(&mut activation, handler))
{
return Some(self_node);
} }
};
if is_button_mode && self.hit_test_shape(point) {
return Some(self_node);
} }
// Maybe we could skip recursing down at all if !world_bounds.contains(point), // Maybe we could skip recursing down at all if !world_bounds.contains(point),