Reputation: 696
A previous question has gotten me thinking. Is it possible to simulate a MouseEvent.CLICK to get fired by just firing first a MOUSE_DOWN followed by a MOUSE_UP.
As per Adobe's doumentation. "... For a click event to occur, it must always follow this series of events in the order of occurrence: mouseDown event, then mouseUp. The target object must be identical for both of these events; otherwise the click event does not occur. Any number of other mouse events can occur at any time between the mouseDown or mouseUp events; the click event still occurs." http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/InteractiveObject.html#event:click
From my tests it shows that the CLICK event is NOT constructed from the ActionScript 3 event queue. Or is something wrong with the code?
See:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
[SWF(backgroundColor="0xFFFFFF", frameRate="30", width="800", height="600")]
public class Test extends Sprite
{
private var spr:Sprite = new Sprite();
public function Test()
{
trace("Test()");
this.addEventListener(Event.ADDED_TO_STAGE,init);
}
public function init(e:Event):void
{
trace("init()");
spr.graphics.beginFill(0xFF0000);
spr.graphics.drawRect(0,0,200,80);
spr.graphics.endFill();
addChild(spr);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
spr.addEventListener(MouseEvent.CLICK, onClick);
}
private var tick:int = 0;
private function onEnterFrame(e:Event):void
{
if (tick == 1) spr.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN,true,false));
if (tick == 2) spr.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP,true,false));
if (tick == 3) spr.dispatchEvent(new MouseEvent(MouseEvent.CLICK,true,false));
tick++;
}
private function onClick(e:MouseEvent):void
{
trace("onClick() MouseEvent.CLICK dispatched");
}
}
}
I should get TWO 'onClick()' events instead of one.
Upvotes: 5
Views: 6419
Reputation: 12527
The reason you cannot is that all three types are created by the plugin, and are not dependent upon each other.
MouseEvent.MOUSE_DOWN is fired as soon as you press on an interactive object. MouseEvent.MOUSE_UP is fired as soon as you release the mouse, it does not depend upon the mouse click having started a MOUSE_DOWN within the same InteractiveObject. MouseEvent.CLICK will only be fired when both events take place in the same object without the cursor leaving the object between the itnerval of mouse down and mouse up.
So you can see that there is a simple case, or two even, in which both MOUSE_DOWN and MOUSE_UP are fired, but CLICK is not called because the event is not a CLICK.
Furthermore, the ability to simply dispatch a MouseEvent.CLICK event makes it unnecesasry to create fake user interaction by firing multiple mouse events, when only one is called for. It would be awkward to have to track each object clicked in the mouse down listener, in order to check that the moue up should also trigger a click. You would also need to remove references when a ROLL_OUT event happened.
In short, the CLICK event is really a lot more than the MOUSE_DOWN and MOUSE_UP events. It is also managing that the events happened in succession and on the same display object without leaving the object. When that happens, and ONLY when that happens flash dispatches a CLICK event.
Upvotes: 3
Reputation: 4583
Not quite sure why everybody's making these complex spikes. Or maybe I'm just overseeing something.
Anyway, here's a very easy way to check it:
import flash.events.MouseEvent;
stage.addEventListener(MouseEvent.CLICK, function(){
trace( 'clicked' );
} );
stage.dispatchEvent( new MouseEvent( MouseEvent.MOUSE_DOWN ) );
stage.dispatchEvent( new MouseEvent( MouseEvent.MOUSE_UP ) );
And the answer would be, "no, it's not possible"...
...and probably should be followed by a counter-question: WHY would I want to simulate a click event using a sequence of mousedown and mouseup, when I can dispatch a click event just as well?
Am I a button, having an existential crisis?
Or is it a question out of mere curiosity? But you know what happened to the cat... Right, but maybe it's schrödinger's cat, which means that at the end of this completely irrelevant train of thought, curiosity REALLY did and did NOT kill the cat.
Except if the cat's out of a box.
Then it probably just got wasted.
See, thinking out of the box can get you killed.
Upvotes: 0
Reputation: 2375
If I understand what you're asking then the answer is YES.
I am curious if I have over simplified the solution here especially after reading your code attempt. It is very simple to "simulate" a mouse click. The code below outputs two "I have been clicked" statements when the object is clicked and none when you mouse down then move out of the objects boundaries.
This class extended a MovieClip I created on the stage so I didn't have to code a box.
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class clickMe extends MovieClip {
public function clickMe() {
// constructor code
this.addEventListener(MouseEvent.CLICK, clicked);
this.addEventListener(MouseEvent.MOUSE_DOWN, mDown);
}
private function clicked(e:MouseEvent):void{
trace("I have been clicked");
this.removeEventListener(MouseEvent.MOUSE_UP, clicked);
}
private function mDown(e:MouseEvent):void{
this.addEventListener(MouseEvent.MOUSE_UP, clicked);
}
}
}
In your code I believe the problem is that you are trying to run event listener dispatches through an "onEnterFrame" which will only ever fire one event per frame - never two. Also after testing your code I'm not sure what your were trying to accomplish with the "tick" variable because you never reset it. So the the MOUSE_UP event fires once (when tick = 2, unless your holding the mouse down) then none of the other dispatches will ever fire again.
Upvotes: 0
Reputation: 1490
not sure about this for flash. But when i was learning windows MFC and was clueless. What i did was that I sent WM_MOUSEDOWN followed by WM_MOUSEUP after a short delay. It did work and the button's visual states also changed - without any mouse click!
Upvotes: 0
Reputation: 4434
it's impossible, this code:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
/**
* ...
* @author www0z0k
*/
public class Main extends Sprite {
public function Main():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.addEventListener(MouseEvent.CLICK, onClick);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onStageKeyDown);
}
private function onStageKeyDown(e:KeyboardEvent):void {
trace('pressed');
stage.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_DOWN));
stage.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP));
stage.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
}
private function onClick(e:MouseEvent):void{
trace('clicked');
}
}
}
outputs just:
pressed
clicked
after a key is pressed on the keyboard
Upvotes: 2