Skip to content

Commit

Permalink
tests: Add avm2/focus_events_focusable test
Browse files Browse the repository at this point in the history
This test verifies the behavior of focus-related events when
trying to focus various interactive objects.
  • Loading branch information
kjarosh committed Jul 13, 2024
1 parent 8f9af75 commit 3631050
Show file tree
Hide file tree
Showing 7 changed files with 526 additions and 0 deletions.
20 changes: 20 additions & 0 deletions tests/tests/swfs/avm2/focus_events_focusable/ButtonDisplayState.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package {
import flash.display.Shape;

internal class ButtonDisplayState extends Shape {
private var bgColor:uint;
private var size:uint;

public function ButtonDisplayState(bgColor:uint, size:uint) {
this.bgColor = bgColor;
this.size = size;
draw();
}

private function draw():void {
graphics.beginFill(bgColor);
graphics.drawRect(0, 0, size, size);
graphics.endFill();
}
}
}
200 changes: 200 additions & 0 deletions tests/tests/swfs/avm2/focus_events_focusable/Test.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
package {

import flash.display.InteractiveObject;
import flash.display.MovieClip;
import flash.display.SimpleButton;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.text.TextField;

[SWF(width="1100", height="200")]
public class Test extends MovieClip {
private var sprite: Sprite;
private var mc1: MovieClip;
private var mc2: MovieClip;
private var mc3: MovieClip;
private var mc4: MovieClip;
private var text1: TextField;
private var text2: TextField;
private var text3: TextField;
private var button1: SimpleButton;
private var button2: SimpleButton;
private var button3: SimpleButton;

private var lastFocusedObject: InteractiveObject = null;

public function Test() {
super();

sprite = newSprite();
sprite.name = "sprite";
sprite.x = 0;
sprite.y = 100;
sprite.tabEnabled = true;
sprite.tabIndex = 1;
mc1 = newMovieClip(false, true);
mc1.name = "mc1";
mc1.x = 100;
mc1.y = 100;
mc1.tabEnabled = true;
mc1.tabIndex = 2;
mc2 = newMovieClip(true, true);
mc2.name = "mc2";
mc2.x = 200;
mc2.y = 100;
mc2.tabEnabled = true;
mc2.tabIndex = 3;
mc3 = newMovieClip(true, false);
mc3.name = "mc3";
mc3.x = 300;
mc3.y = 100;
mc3.tabEnabled = true;
mc3.tabIndex = 4;
mc4 = newMovieClip(false, false);
mc4.name = "mc4";
mc4.x = 400;
mc4.y = 100;
mc3.tabIndex = 5;
text1 = newTextField();
text1.name = "text1";
text1.x = 500;
text1.y = 100;
text1.tabEnabled = true;
text1.tabIndex = 6;
text2 = newTextField();
text2.type = "dynamic";
text2.name = "text2";
text2.x = 600;
text2.y = 100;
text2.tabEnabled = true;
text2.tabIndex = 7;
text3 = newTextField();
text3.selectable = false;
text3.name = "text3";
text3.x = 700;
text3.y = 100;
text3.tabEnabled = true;
text3.tabIndex = 8;
button1 = newButton();
button1.name = "button1";
button1.x = 800;
button1.y = 100;
button1.tabEnabled = true;
button1.tabIndex = 9;
button2 = newButton();
button2.enabled = false;
button2.name = "button2";
button2.x = 900;
button2.y = 100;
button2.tabEnabled = true;
button2.tabIndex = 10;
button3 = newButton();
button3.useHandCursor = false;
button3.name = "button3";
button3.x = 1000;
button3.y = 100;
button3.tabEnabled = true;
button3.tabIndex = 11;

stage.addChild(sprite);
stage.addChild(mc1);
stage.addChild(mc2);
stage.addChild(mc3);
stage.addChild(mc4);
stage.addChild(text1);
stage.addChild(text2);
stage.addChild(text3);
stage.addChild(button1);
stage.addChild(button2);
stage.addChild(button3);

stage.addEventListener("keyDown", function(evt:KeyboardEvent):void {
if (evt.keyCode == 27 && stage.focus != lastFocusedObject) {
trace("Currently focused object: " + stage.focus + (stage.focus == null ? "" : ", " + stage.focus.name));
lastFocusedObject = stage.focus;
}
});

function eventListener(obj: InteractiveObject): Function {
return function(evt: Event): void {
var str;
if (evt is MouseEvent) {
str = evt.formatToString(
"MouseEvent", "type", "cancelable", "eventPhase",
"relatedObject", "ctrlKey", "altKey", "shiftKey");
} else {
str = evt.toString();
}
if (evt is FocusEvent && FocusEvent(evt).relatedObject) {
str += ", relatedObjectName=" + FocusEvent(evt).relatedObject.name;
}
trace(" " + obj.name + ", " + evt.target.name + ": " + str);
}
}

for each (var obj: InteractiveObject in [
sprite, mc1, mc2, mc3, mc4, text1, text2, text3, button1, button2, button3,
stage
]) {
obj.addEventListener("focusIn", eventListener(obj));
obj.addEventListener("focusOut", eventListener(obj));
obj.addEventListener("mouseDown", eventListener(obj));
obj.addEventListener("mouseUp", eventListener(obj));
obj.addEventListener("click", eventListener(obj));
obj.addEventListener("mouseFocusChange", eventListener(obj));
obj.addEventListener("keyFocusChange", eventListener(obj));
obj.addEventListener("rollOut", eventListener(obj));
obj.addEventListener("rollOver", eventListener(obj));
obj.addEventListener("mouseOver", eventListener(obj));
}
}

private function newSprite(): Sprite {
var s:Sprite = new Sprite();
s.graphics.beginFill(0x00FFFF);
s.graphics.drawRect(0, 0, 100, 100);
s.graphics.endFill();
return s;
}

private function newMovieClip(buttonMode: Boolean, handCursor: Boolean): MovieClip {
var mc:MovieClip = new MovieClip();
mc.buttonMode = buttonMode;
mc.useHandCursor = handCursor;
if (buttonMode) {
if (handCursor) {
mc.graphics.beginFill(0xFFCA00);
} else {
mc.graphics.beginFill(0xCAFF00);
}
} else {
mc.graphics.beginFill(0x00FF00);
}
mc.graphics.drawRect(0, 0, 100, 100);
mc.graphics.endFill();
return mc;
}

private function newTextField(): TextField {
var tf:TextField = new TextField();
tf.type = "input";
tf.border = true;
tf.width = 100;
tf.height = 100;
return tf;
}

private function newButton(): SimpleButton {
var b:SimpleButton = new SimpleButton();
b.downState = new ButtonDisplayState(0xFF0000, 100);
b.overState = new ButtonDisplayState(0x0000FF, 100);
b.upState = new ButtonDisplayState(0x000000, 100);
b.hitTestState = new ButtonDisplayState(0, 100);
b.useHandCursor = true;
return b;
}
}
}
68 changes: 68 additions & 0 deletions tests/tests/swfs/avm2/focus_events_focusable/input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
[
{ "type": "MouseMove", "pos": [1, 1] },
{ "type": "MouseDown", "pos": [1, 1], "btn": "Left" },
{ "type": "MouseUp", "pos": [1, 1], "btn": "Left" },
{ "type": "KeyDown", "key_code": 27 },
{ "type": "KeyUp", "key_code": 27 },
{ "type": "MouseMove", "pos": [1, 101] },
{ "type": "MouseDown", "pos": [1, 101], "btn": "Left" },
{ "type": "MouseUp", "pos": [1, 101], "btn": "Left" },
{ "type": "KeyDown", "key_code": 27 },
{ "type": "KeyUp", "key_code": 27 },
{ "type": "MouseMove", "pos": [101, 101] },
{ "type": "MouseDown", "pos": [101, 101], "btn": "Left" },
{ "type": "MouseUp", "pos": [101, 101], "btn": "Left" },
{ "type": "KeyDown", "key_code": 27 },
{ "type": "KeyUp", "key_code": 27 },
{ "type": "MouseMove", "pos": [201, 101] },
{ "type": "MouseDown", "pos": [201, 101], "btn": "Left" },
{ "type": "MouseUp", "pos": [201, 101], "btn": "Left" },
{ "type": "KeyDown", "key_code": 27 },
{ "type": "KeyUp", "key_code": 27 },
{ "type": "MouseMove", "pos": [301, 101] },
{ "type": "MouseDown", "pos": [301, 101], "btn": "Left" },
{ "type": "MouseUp", "pos": [301, 101], "btn": "Left" },
{ "type": "KeyDown", "key_code": 27 },
{ "type": "KeyUp", "key_code": 27 },
{ "type": "MouseMove", "pos": [401, 101] },
{ "type": "MouseDown", "pos": [401, 101], "btn": "Left" },
{ "type": "MouseUp", "pos": [401, 101], "btn": "Left" },
{ "type": "KeyDown", "key_code": 27 },
{ "type": "KeyUp", "key_code": 27 },
{ "type": "MouseMove", "pos": [501, 101] },
{ "type": "MouseDown", "pos": [501, 101], "btn": "Left" },
{ "type": "MouseUp", "pos": [501, 101], "btn": "Left" },
{ "type": "KeyDown", "key_code": 27 },
{ "type": "KeyUp", "key_code": 27 },
{ "type": "MouseMove", "pos": [601, 101] },
{ "type": "MouseDown", "pos": [601, 101], "btn": "Left" },
{ "type": "MouseUp", "pos": [601, 101], "btn": "Left" },
{ "type": "KeyDown", "key_code": 27 },
{ "type": "KeyUp", "key_code": 27 },
{ "type": "MouseMove", "pos": [701, 101] },
{ "type": "MouseDown", "pos": [701, 101], "btn": "Left" },
{ "type": "MouseUp", "pos": [701, 101], "btn": "Left" },
{ "type": "KeyDown", "key_code": 27 },
{ "type": "KeyUp", "key_code": 27 },
{ "type": "MouseMove", "pos": [801, 101] },
{ "type": "MouseDown", "pos": [801, 101], "btn": "Left" },
{ "type": "MouseUp", "pos": [801, 101], "btn": "Left" },
{ "type": "KeyDown", "key_code": 27 },
{ "type": "KeyUp", "key_code": 27 },
{ "type": "MouseMove", "pos": [901, 101] },
{ "type": "MouseDown", "pos": [901, 101], "btn": "Left" },
{ "type": "MouseUp", "pos": [901, 101], "btn": "Left" },
{ "type": "KeyDown", "key_code": 27 },
{ "type": "KeyUp", "key_code": 27 },
{ "type": "MouseMove", "pos": [1001, 101] },
{ "type": "MouseDown", "pos": [1001, 101], "btn": "Left" },
{ "type": "MouseUp", "pos": [1001, 101], "btn": "Left" },
{ "type": "KeyDown", "key_code": 27 },
{ "type": "KeyUp", "key_code": 27 },
{ "type": "MouseMove", "pos": [1, 1] },
{ "type": "MouseDown", "pos": [1, 1], "btn": "Left" },
{ "type": "MouseUp", "pos": [1, 1], "btn": "Left" },
{ "type": "KeyDown", "key_code": 27 },
{ "type": "KeyUp", "key_code": 27 },
{ "type": "Wait" }
]
47 changes: 47 additions & 0 deletions tests/tests/swfs/avm2/focus_events_focusable/input.json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env python3

coord_map = {
'void': [1, 1],
'sprite': [1, 101],
'mc1': [101, 101],
'mc2': [201, 101],
'mc3': [301, 101],
'mc4': [401, 101],
'text1': [501, 101],
'text2': [601, 101],
'text3': [701, 101],
'button1': [801, 101],
'button2': [901, 101],
'button3': [1001, 101],
}

click_seq = [
'void', 'esc',
'sprite', 'esc',
'mc1', 'esc',
'mc2', 'esc',
'mc3', 'esc',
'mc4', 'esc',
'text1', 'esc',
'text2', 'esc',
'text3', 'esc',
'button1', 'esc',
'button2', 'esc',
'button3', 'esc',
'void', 'esc',
]

print('[')

for obj in click_seq:
if obj == 'esc':
print(f' {{ "type": "KeyDown", "key_code": 27 }},')
print(f' {{ "type": "KeyUp", "key_code": 27 }},')
continue
pos = coord_map[obj]
print(f' {{ "type": "MouseMove", "pos": {pos} }},')
print(f' {{ "type": "MouseDown", "pos": {pos}, "btn": "Left" }},')
print(f' {{ "type": "MouseUp", "pos": {pos}, "btn": "Left" }},')

print(f' {{ "type": "Wait" }}')
print(']')
Loading

0 comments on commit 3631050

Please sign in to comment.