avm2: Suppress events for selectable was_static TextFields
TextFields have a very unusual behavior - if they are selectable and have `was_static`, they *block* the dispatch of mouse events when they're targeted (not even the Stage will receive the event). This only occurs when the TextField is actually targeted (which requires mouseEnabled=true). With mouseEnabled=false, the event will be dispatched with an ancestor as the target, following the usual logic. Also, TextFields now properly propagate mouse picks to their parent if mouseEnabled=false. Previously, setting mouseEnabled=false for a TextField made all mouse picks cause a miss on it. This was the cause of the Turbo Kids regression. Fixes #10245
This commit is contained in:
parent
cc567c4e40
commit
c53a903d35
|
@ -1932,14 +1932,15 @@ impl<'gc> TInteractiveObject<'gc> for EditText<'gc> {
|
|||
_require_button_mode: bool,
|
||||
) -> Avm2MousePick<'gc> {
|
||||
// The text is hovered if the mouse is over any child nodes.
|
||||
if self.visible()
|
||||
&& self.mouse_enabled()
|
||||
&& self.hit_test_shape(context, point, HitTestOptions::MOUSE_PICK)
|
||||
{
|
||||
if self.was_static() {
|
||||
Avm2MousePick::PropagateToParent
|
||||
} else {
|
||||
if self.visible() && self.hit_test_shape(context, point, HitTestOptions::MOUSE_PICK) {
|
||||
// Note - for mouse-enabled selectable text, we consider this to be a hit (which
|
||||
// will cause us to show the proper cursor on mouse over).
|
||||
// However, in `Interactive::event_dispatch_to_avm2`, we will prevent mouse events
|
||||
// from being fired at all if the text is selectable and 'was_static()'.
|
||||
if self.mouse_enabled() && (self.is_selectable() || !self.was_static()) {
|
||||
Avm2MousePick::Hit((*self).into())
|
||||
} else {
|
||||
Avm2MousePick::PropagateToParent
|
||||
}
|
||||
} else {
|
||||
Avm2MousePick::Miss
|
||||
|
|
|
@ -222,6 +222,16 @@ pub trait TInteractiveObject<'gc>:
|
|||
context: &mut UpdateContext<'_, 'gc>,
|
||||
event: ClipEvent<'gc>,
|
||||
) -> ClipEventResult {
|
||||
// Flash appears to not fire events *at all* for a targeted EditText
|
||||
// that was originally created by the timeline. Normally, one of the ancestors
|
||||
// of the TextField would get targeted, but instead, the event isn't fired
|
||||
// (not even the Stage receives the event)
|
||||
if let Some(text) = self.as_displayobject().as_edit_text() {
|
||||
if text.is_selectable() && text.was_static() {
|
||||
return ClipEventResult::NotHandled;
|
||||
}
|
||||
}
|
||||
|
||||
let target = if let Avm2Value::Object(target) = self.as_displayobject().object2() {
|
||||
target
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
Clicked at 522, 27
|
||||
Clicked at 26, 373
|
||||
Clicked at 477, 343
|
||||
Clicked at 276, 197
|
||||
Clicked at 21, 24 target: [object MovieClip] instance2
|
||||
Clicked at 522, 27 target: [object MovieClip] click_mc
|
||||
Clicked at 26, 373 target: [object MovieClip] click_mc
|
||||
Clicked at 477, 343 target: [object MovieClip] click_mc
|
||||
Clicked at 276, 197 target: [object MovieClip] click_mc
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,50 @@
|
|||
package {
|
||||
|
||||
import flash.display.MovieClip;
|
||||
import flash.display.Sprite;
|
||||
import flash.events.MouseEvent;
|
||||
import flash.text.TextField;
|
||||
|
||||
|
||||
public class Main extends MovieClip {
|
||||
|
||||
|
||||
public function Main() {
|
||||
super();
|
||||
this.stage.addEventListener("mouseDown", function(e) {
|
||||
trace("mouseDown: " + e.target + " at: " + e.stageX + " " + e.stageY);
|
||||
});
|
||||
var childClip = Sprite(this.getChildAt(0));
|
||||
|
||||
var firstTimelineText = childClip.getChildAt(0);
|
||||
// Uncomment this line to verify that the coordinates in our input.json
|
||||
// are correct (a new event should get generated)
|
||||
//firstTimelineText.mouseEnabled = false;
|
||||
|
||||
var secondTimelineText = childClip.getChildAt(1);
|
||||
trace("Setting mouseEnabled=false for: " + secondTimelineText.text);
|
||||
trace("Before: secondTimelineText.selectable = " + secondTimelineText.selectable);
|
||||
secondTimelineText.mouseEnabled = false;
|
||||
trace("After: secondTimelineText.selectable = " + secondTimelineText.selectable);
|
||||
|
||||
// The timeline-add field remembers that it originally came from the timeline
|
||||
//childClip.removeChild(firstTimelineText)
|
||||
//childClip.addChildAt(firstTimelineText, 0)
|
||||
|
||||
|
||||
var avmText = new TextField();
|
||||
avmText.y = 100;
|
||||
avmText.text = "Hello from AS3";
|
||||
|
||||
var avmTextNonSelectable = new TextField();
|
||||
avmTextNonSelectable.selectable = false;
|
||||
avmTextNonSelectable.x = 140;
|
||||
avmTextNonSelectable.y = 100;
|
||||
avmTextNonSelectable.text = "AS3 non-selectable";
|
||||
|
||||
childClip.addChild(avmText);
|
||||
childClip.addChild(avmTextNonSelectable);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
[
|
||||
{
|
||||
"type": "MouseMove",
|
||||
"pos": [
|
||||
208.45,
|
||||
139.05
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "MouseDown",
|
||||
"pos": [
|
||||
208.45,
|
||||
139.05
|
||||
],
|
||||
"btn": "Left"
|
||||
},
|
||||
{
|
||||
"type": "MouseUp",
|
||||
"pos": [
|
||||
208.45,
|
||||
139.05
|
||||
],
|
||||
"btn": "Left"
|
||||
},
|
||||
{
|
||||
"type": "MouseMove",
|
||||
"pos": [
|
||||
202.45,
|
||||
171.05
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "MouseDown",
|
||||
"pos": [
|
||||
202.45,
|
||||
171.05
|
||||
],
|
||||
"btn": "Left"
|
||||
},
|
||||
{
|
||||
"type": "MouseUp",
|
||||
"pos": [
|
||||
202.45,
|
||||
171.05
|
||||
],
|
||||
"btn": "Left"
|
||||
},
|
||||
{
|
||||
"type": "MouseMove",
|
||||
"pos": [
|
||||
208.45,
|
||||
266.05
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "MouseDown",
|
||||
"pos": [
|
||||
208.45,
|
||||
266.05
|
||||
],
|
||||
"btn": "Left"
|
||||
},
|
||||
{
|
||||
"type": "MouseUp",
|
||||
"pos": [
|
||||
208.45,
|
||||
266.05
|
||||
],
|
||||
"btn": "Left"
|
||||
},
|
||||
{
|
||||
"type": "MouseMove",
|
||||
"pos": [
|
||||
211,
|
||||
373
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "MouseDown",
|
||||
"pos": [
|
||||
211,
|
||||
373
|
||||
],
|
||||
"btn": "Left"
|
||||
},
|
||||
{
|
||||
"type": "MouseUp",
|
||||
"pos": [
|
||||
211,
|
||||
373
|
||||
],
|
||||
"btn": "Left"
|
||||
},
|
||||
{
|
||||
"type": "MouseMove",
|
||||
"pos": [
|
||||
375.45,
|
||||
267.05
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "MouseDown",
|
||||
"pos": [
|
||||
375.45,
|
||||
267.05
|
||||
],
|
||||
"btn": "Left"
|
||||
},
|
||||
{
|
||||
"type": "MouseUp",
|
||||
"pos": [
|
||||
375.45,
|
||||
267.05
|
||||
],
|
||||
"btn": "Left"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
Setting mouseEnabled=false for: Second timeline text
|
||||
|
||||
Before: secondTimelineText.selectable = true
|
||||
After: secondTimelineText.selectable = true
|
||||
mouseDown: [object MovieClip] at: 202.45 171.05
|
||||
mouseDown: [object TextField] at: 208.45 266.05
|
||||
mouseDown: [object Stage] at: 211 373
|
||||
mouseDown: [object TextField] at: 375.45 267.05
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
num_frames = 1
|
Loading…
Reference in New Issue