Detect mouseUp on stage - actionscript-3

Is there a way to check the method that has been attached to the stage?
I have stage as global.. and need to fire some function in a object on mouseup...
Now it fires 2 or 3 depending how many objects i add..
I need something like..
if($.stage.hasEventListener(MouseEvent.MOUSE_UP, this.mouseUp) === false){
$.stage.addEventListener(MouseEvent.MOUSE_UP, this.mouseUp);
}
Or a better way to handle this?

I'm guessing you are adding the listener inside each object, no? That means every time you create an instance of your object you are adding yet another listener for stage mouse up events. If you really only want a single listener for this type of event, move it outside of the scope of the object and only add the listener once. Good luck!

Related

Global Event Listener

Is there any way by which I can make my button work, no matter in which scene or frame it is.
Is there any way by which i can call that Event Listener to another frame for that particular instance?
for example:
I have a button home_btn, I want this button to work in all scenes, without changing it's instance name. I already added an Event listener in first scene, but it doesn't work,
In another frame or scene.
Below is the code.
home_btn.addEventListener(MouseEvent.CLICK, process_it);
function process_it(event:MouseEvent):void
{
nextFrame();
}
I don't know how to use dispatch event function for my button.
// This only works for that particular frame.
Since you're doing this in the timeline, if you put the home_btn.addEventListener(MouseEvent.CLICK, process_it);
on the first frame of your main timeline, it will be registered even if you change to a different frame.
You can keep the function in its existing frame as that should still be called.
The reason why this works as opposed to the code being on a different frame is because frame 1 is where your timeline will start and process all the display items and code needed during this frame. That is any function, variable, or listener you want active will be running and/or stored into memory at the start of the application since it will always start on frame 1 until specified otherwise. If you have the listener on a different frame then you will have to gotoAndStop() to that frame to add the listener ( otherwise you are specifying that you don't want to add the listener until your application is at the frame ). Adding a listener to a display object on frame 1 is contingent upon the display object also being on that frame.

get inner component from flexGlobals.topLevelApplication

I feel the way inner components could be accessed be better than what I know.
I know we can access any inner component something like:
FlexGlobals.topLevelApplication.someChild1.someChild2.someChild3… and so on
I've a components which has number of parent components hierarchy. I wish to know if there could be anyway I could access the last child without referring all of its parent.
I need to trigger an event on that component.
FlexGlobals.topLevelApplication.child1.child2.child3.dispatchEvent(new Event('clearData', true));
Updated: I tried the way you suggested in point 1. I've added the event listener on child component and try to dispatch it from a action script file, but it went unheared.\
child3.addEventLisener('clearData', clearHandler);
And then I dispatched the event some thing like:
dispatchEvent(new Event(modelApp.CLEAR_PALETTE, true)
try to add
FlexGlobals.topLevelApplication.systemManger.addEventLisener('clearData', clearHandler);
in child3
and dispacthed it from any where you want,
for dispatching use the following
FlexGlobals.topLevelApplication.systemManager.dispatchEvent(new Event(modelApp.CLEAR_PALETTE, true)
How I understood from the question used no good principles of application design, but that's another question.
In your case, you can use stage as global currentTarget for bubbles events. Dispatch event from displayObject with bubbles = true; In target display object listen event with stage object with/out capture phase.
in any displayObject:
dispatchEvent(new Event("myEvent", true));
in target displayObject:
// add ADDED_TO_STAGE event listener in constructor or when component creation complete
protected function component_creationCompleteHandler(event:FlexEvent):void
{
addEventListener(Event.ADDED_TO_STAGE, onAddToStage);
}
..
protected function onAddToStage(event:Event):void
{
stage.addEventListener("myEvent", eventHandler, true);
}
protected function eventHandler(event:Event):void
{
trace("eventHandler");
}
It is better than use reference to FlexGlobals object. Code more flexible.
I think you should go down to the level of component and addEventListener on initialize.
and dispatch from where ever you want.
other way is to do that, you need to save component reference(ID) in object on creationComplete. save its refence in your model. now you can access it where ever you want. and do what ever you want.
i also did in this way, i saved my screen components refrence in an array and access it where i need to dynamically validate all components.
otherwise you need nested looping to got your required child.

Trigger mouse click on overlapping movieclips

I have two MovieClips (same parent) that overlap, both have a listener for mouse click.
But only the top most MC detects the click.
Is it possible to get both MCs detect the click using listeners ?
If not, is collisions a better way to do it, than using the getObjectsUnderPoint() ?
You can register the click event to a parent controller or class. When it receives the event callback it can then broadcast that back to all the other child MCs from that callback function. It's just a matter of managing the MCs - either keep a track of their names or add then all to an array so you can use a for loop to iterate through them.

Detecting MouseEvents for object below another object

So basically, I have a large movieclip, lets call it "hit" and a bunch of smaller "thumb" movieclips below it. I have ROLL_OVER and ROLL_OUT event listeners on the main "hit" movieclip that I use to position the thumbs correctly (the component is a kind of ticker).
I am having a problem with getting the ROLL_OVER, ROLL_OUT, and CLICK event listeners to fire on the "thumb" movieclips that are below "hit".
Right now I am using a hit test, which kind of works, but I'd like a simpler way. I am an actionscript-3 newbie so any help would be appreciated. Thanks!
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/MouseEvent.html#!flash/display/InteractiveObject.html#event:rollOver
Dispatched when the user moves a pointing device over an InteractiveObject instance. The event target is the object under the pointing device or a parent of that object. The relatedObject is the object that was previously under the pointing device. The rollOver events are dispatched consecutively down the parent chain of the object, starting with the highest parent that is neither the root nor an ancestor of the relatedObject and ending with the object.
Object under hit won't dispatch ROLL_OVER event if it's not a parent of hit. Only objects on top will dispatch it. Mouse cursor must literally touch the object. If there is something between cursor and object, event won't be dispatched.
This thread appears to be asking the same question. The solution including getObjectsUnderPoint seems to be the best choice.

ActionScript 3 Removing All RESIZE Event Listeners

I'm working on a Flash project which is separated into separate scenes.
In Scene 1 I have multiple MovieClips (which include event listeners for RESIZE (and others) inside them).
In Scene 2 I have a few common MovieClips and new ones (which also include event listeners for RESIZE (and others) inside them).
After clicking a button from Scene 1 to go to Scene 2, it's fine, except for if I resize the stage and then I get the following error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
I know it's related to the event listeners, but it would be unrealistic to remove them each individually as it's expected there will be many.
If I undertand your situation correctly, I think you will in the end need to remove each listener individually, or add the resize listener only once. Since you mentioned scenes, am I right to assume you are working on the timeline? I also am assuming the null object reference error comes from a scene that has been removed from the stage, making reference to a display object that is no more, a ref to the stage after the scene has been removed, or just calling a function (the resize handler) on an object that no longer exists.
Some way to deal with this are:
Add some checking in the listener handler functions
if (!this.stage) return
To avoid the errors, but will not help if the object the function is a method of has been removed.
To avoid needing remember to remove hundreds of listeners, create removeAllListeners and addCustomEventListener functions. Instead of the usual addEventListener, call you addCustomEventListener which in turn will call addEventListener. Have addCustomListener store the target, listener function and event string in a dictionary or array of objects. removeAllListeners can loop through the dictionary or array and remove all your listeners. It is a bit like setting up an event hub, but does not go quite that far.
Instead of adding the RESIZE event listener to each scene, add it only once. Then in the listener function call a function on whichever scene is the active scene or view.
This last one is the approach I have seen most often, and is the most bullet proof. It may be tricky to implement on the time line, I have always been a little hazy on timeline variable scope.
Yes, so far as I know there is no good automated way to do this, however it would be a good practice to create a registerAllListeners and a removeAllListeners methods that manually add and remove the appropriate listeners to your object.