core: Fix stageX and stageY getters for MouseEvent

These getters were previously calling `local_to_global`
with the unused localX/localY coordinate set to 0. Howver,
`local_to_global` does a matrix multiplication, which in general
will depend on both the x and y values. This was causing the getters
to return incorrect results when any of the `transform.matrix` values
included a non-diagonal matrix.

We now call `local_to_transform` with the real `localX` and `localY`
values.
This commit is contained in:
Aaron Hill 2023-02-13 12:28:40 -06:00 committed by Adrian Wielgosik
parent 081387e047
commit a52a41de97
4 changed files with 70 additions and 27 deletions

View File

@ -17,11 +17,18 @@ pub fn get_stage_x<'gc>(
.get_public_property("localX", activation)?
.coerce_to_number(activation)?;
if local_x.is_nan() {
let local_y = this
.get_public_property("localY", activation)?
.coerce_to_number(activation)?;
if local_x.is_nan() || local_y.is_nan() {
return Ok(Value::Number(local_x));
} else if let Some(target) = evt.target().and_then(|t| t.as_display_object()) {
let as_twips = Twips::from_pixels(local_x);
let xformed = target.local_to_global((as_twips, Twips::ZERO)).0;
let x_as_twips = Twips::from_pixels(local_x);
let y_as_twips = Twips::from_pixels(local_y);
// `local_to_global` does a matrix multiplication, which in general
// depends on both the x and y coordinates.
let xformed = target.local_to_global((x_as_twips, y_as_twips)).0;
return Ok(Value::Number(xformed.to_pixels()));
} else {
@ -41,15 +48,22 @@ pub fn get_stage_y<'gc>(
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(this) = this {
if let Some(evt) = this.as_event() {
let local_x = this
.get_public_property("localX", activation)?
.coerce_to_number(activation)?;
let local_y = this
.get_public_property("localY", activation)?
.coerce_to_number(activation)?;
if local_y.is_nan() {
if local_x.is_nan() || local_y.is_nan() {
return Ok(Value::Number(local_y));
} else if let Some(target) = evt.target().and_then(|t| t.as_display_object()) {
let as_twips = Twips::from_pixels(local_y);
let xformed = target.local_to_global((Twips::ZERO, as_twips)).1;
let x_as_twips = Twips::from_pixels(local_x);
let y_as_twips = Twips::from_pixels(local_y);
// `local_to_global` does a matrix multiplication, which in general
// depends on both the x and y coordinates.
let xformed = target.local_to_global((x_as_twips, y_as_twips)).1;
return Ok(Value::Number(xformed.to_pixels()));
} else {

View File

@ -26,11 +26,28 @@
}
import flash.events.MouseEvent;
import flash.geom.Matrix;
function assert_event(evt: MouseEvent) {
trace("/// evt.stageX");
trace(evt.stageX);
trace("/// evt.stageY");
trace(evt.stageY);
trace("/// evt.localX = " + evt.localX + " evt.localY = " + evt.localY + " evt.stageX = " + evt.stageX + " evt.stageY = " + evt.stageY);
evt.localX = 1;
evt.localY = 2;
trace("/// set localX=1 localY=2")
trace("/// evt.localX = " + evt.localX + " evt.localY = " + evt.localY + " evt.stageX = " + evt.stageX + " evt.stageY = " + evt.stageY);
trace("/// modified target.x and target.y")
evt.target.x = 100;
evt.target.y = 100;
trace("/// evt.localX = " + evt.localX + " evt.localY = " + evt.localY + " evt.stageX = " + evt.stageX + " evt.stageY = " + evt.stageY);
trace("/// modified target.transform.matrix")
evt.target.transform.matrix = new Matrix(1, 2, 3, 4, 5, 6);
trace("/// evt.localX = " + evt.localX + " evt.localY = " + evt.localY + " evt.stageX = " + evt.stageX + " evt.stageY = " + evt.stageY);
}

View File

@ -1,23 +1,35 @@
/// (dispatching MouseEvent at 5.0, 1.5...)
/// evt.stageX
5
/// evt.stageY
1.5
/// evt.localX = 5 evt.localY = 1.5 evt.stageX = 5 evt.stageY = 1.5
/// set localX=1 localY=2
/// evt.localX = 1 evt.localY = 2 evt.stageX = 1 evt.stageY = 2
/// modified target.x and target.y
/// evt.localX = 1 evt.localY = 2 evt.stageX = 101 evt.stageY = 102
/// modified target.transform.matrix
/// evt.localX = 1 evt.localY = 2 evt.stageX = 12 evt.stageY = 16
/// (dispatching MouseEvent at 5.0, 1.5...)
/// evt.stageX
37
/// evt.stageY
17.5
/// evt.localX = 5 evt.localY = 1.5 evt.stageX = 41.5 evt.stageY = 32
/// set localX=1 localY=2
/// evt.localX = 1 evt.localY = 2 evt.stageX = 39 evt.stageY = 26
/// modified target.x and target.y
/// evt.localX = 1 evt.localY = 2 evt.stageX = 107 evt.stageY = 110
/// modified target.transform.matrix
/// evt.localX = 1 evt.localY = 2 evt.stageX = 12 evt.stageY = 16
///this.addChild(this.te);
/// (dispatching MouseEvent at 5.0, 1.5...)
/// evt.stageX
37
/// evt.stageY
17.5
/// evt.localX = 5 evt.localY = 1.5 evt.stageX = 14.5 evt.stageY = 22
/// set localX=1 localY=2
/// evt.localX = 1 evt.localY = 2 evt.stageX = 12 evt.stageY = 16
/// modified target.x and target.y
/// evt.localX = 1 evt.localY = 2 evt.stageX = 107 evt.stageY = 110
/// modified target.transform.matrix
/// evt.localX = 1 evt.localY = 2 evt.stageX = 12 evt.stageY = 16
///this.scaleX = 0.5
///this.scaleY = 0.25
/// (dispatching MouseEvent at 5.0, 1.5...)
/// evt.stageX
18.5
/// evt.stageY
4.4
/// evt.localX = 5 evt.localY = 1.5 evt.stageX = 7.25 evt.stageY = 5.5
/// set localX=1 localY=2
/// evt.localX = 1 evt.localY = 2 evt.stageX = 6 evt.stageY = 4
/// modified target.x and target.y
/// evt.localX = 1 evt.localY = 2 evt.stageX = 53.5 evt.stageY = 27.5
/// modified target.transform.matrix
/// evt.localX = 1 evt.localY = 2 evt.stageX = 6 evt.stageY = 4