How to get the ContextMenu Target in Flash - actionscript-3

in a flash application i have to build i would like to find out what the target of the context menu is, which gets displayed when i ctrl-click.
the reason for that: i created a custom context menu, which only displays over a certain area of the Sprite it belongs to. so there seems to be something "blocking the way".
any ideas? thanks!

Have a look here: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/ContextMenuEvent.html#ContextMenuEvent()
to get the target of a ContextMenuEvent you want to access the mouseTarget property of that event.

The best way to debug this is using a click handler at the stage level.
stage.addEventListener(MouseEvent.CLICK, stageClickHandler, true,
int.MAX_VALUE, true);
Set useCapture to true so no other object can "swallow" the event, and priority to int.MAX_VALUE for good measure.
In your stageClickHandler():
private function stageClickHandler(event:MouseEvent):void
{
var targetObject:DisplayObject = event.target;
trace("click target", targetObject);
}
Now click on the area that isn't displaying the context menu (when you expect it to), and see what is printed in the log file. You can do some inspection on targetObject by checking its name property, its parent, and so on.
Hope this helps.

take a look at at the contextMenuOwner property of the contextMenuEvent ;)

Related

How to make visible infinite movieclips with one button?

I'm working on an interactive map in Actionscript-3 (Adobe Flash CS6).
What I'm trying to do is, with a single button, to show multiple objects (movieclips) with each mouse click.
I'm currently working with this code, but I can't manage to find out how to show multiple movieclips, I can only show ONE:
btn_ally_unit.addEventListener(MouseEvent.CLICK, mostrar_ally_unit2);
function mostrar_ally_unit2(event:MouseEvent):void
{
map_editor.ally_unit.visible = true;
}
How do I extend this to apply to any number of movieclips?
I'm sure by infinite you mean indefinite.
Target the unit clicked by using the target property of the Event class. Looks something like this:
btn_ally_unit.addEventListener(MouseEvent.CLICK, mostrar_ally_unit2);
function mostrar_ally_unit2(event:MouseEvent):void
{
event.target.visible = true;
}
You see? (event:MouseEvent) is saying that this function expects one argument (a MouseEvent) which you are giving the variable name of event. That's a convention but I like to use me as an abbreviation for mouse event. Others just use the letter e. Ok. Now event has a property, target, which is the thing receiving the event. In this case it will be one of your units. Your units have a property of visible which you can toggle off like you have been doing but by using the relative mouse event target, you can use the same line of code for all units.
note
Of course you must add the event listener to each unit. You could make it part of the class or just add it when a new unit is instantiated.
note
Using the event flow in actionscript 3 can be tricky. Seek out a tutorial on this. Here is one link related to event flow from Adobe.

Having issues with event on click

I have a button instance named "instructionButton" and I'm trying to trace "Clicked." to the output when it is clicked as a test but I haven' been successful thus far. Is there something I'm missing?
I'm using code in Flash Pro 6
import flash.events.MouseEvent;
var clickedVar:String = "Clicked.";
var runVar:String = "mice running...";
trace(runVar);
function instructionOpen(event:MouseEvent):void
{
trace(clickedVar);
gotoAndPlay(255);
}
instructionsButton.addEventListener (MouseEvent.CLICK, instructionOpen);
And of course if there's a more simple way to approach this, all knowledge will be helpful.
Check instance name is provided or not in the property window for the button (click the button and go to menu 'Window->Properties' to open property window)
What name is mentioned in the property window for the button, should use the same instance name in action script coding. Ensure the spelling from both script(code) and property window instance name.
I don't really see anything wrong with your button code, but here's how i do mine in AS3, it may help :) Creating a simple function within the event listener, I use stopPropgation to prevent my button from clicking anything that may be below it in the flash file. ( say you have two buttons on top of one another, you'll click both instead of one)
instructionsButton.addEventListener(MouseEvent.CLICK, function(e){
e.stopPropagation();
trace("Clicked.");
gotoAndPlay(255);
});
This is one button, if you need say fifteen, let me know as I have a code sample I'll give you that i use to create a limitless amount of buttons and eventlistners using switch/case which has been a huge help to me :)
The only way this will not work is if you are not reaching this frame.
Try add this code on your first frame and tell me if this helping.

How to handle mouseEvent transparently in AS3?

I have a DisplayObject docked at the top of my interface that displays debug information (frames per second, etc.) and is translucent with an alpha of 60%.
I would like to interact with items under this surface, such that when the mouse rolls over it, it dims to 10% alpha, and mouse events pass through it to the underlying objects.
Normally, I have this debug info panel's mouseEnabled and mouseChildren properties set to false, so objects under it receive mouse events.
The problem is that in order to hide it when the mouse rolls over it, it needs to have mouseEnabled set to true. However, if mouseEnabled is true, the mouse events are not picked up by objects underneath it.
As far as I know, I can't selectively enable mouseEvents, so it's either going to receive them all or none of them. That means that I'd have to handle and forward ALL events, if I took that approach.
I really wish the mouseEnabled property had a "peek" mode or something, so that it could receive the events if it is on top, but also allow them to pass through to objects underneath.
If a DisplayObject has mouseEnabled=true it means that its events will be sent to its container not to whateve is underneath the object. So this solution will not work. The best solution would be to reroute events from it manually using getObjectsUnderPoint as described here.
I've been using this approach for years in multi-touch apps. With multiple touch points I don't see any processor overhead. And you got only one cursor.
I feel your pain. Unfortunately, I don't know of a way to enable/disable specific mouse events. You could get creative with the solution though. For instance, maybe try adding a MOUSE_MOVE listener to your stage and track the coordinates of the mouse. Then, if the stageX,stageY of the mouse is in the area of your panel, set the visibility. You might also be able to use getObjectsUnderPoint() to determine which objects are under the mouse. But, my guess is that it would get a little intense on the processor to run that on each frame iteration.
I believe you are looking for mouseEnabled = false
But another last ditch attempt you can do is on mouse over move it to the other side of the screen.
One approach you can take, although not ideal, is to add an enter frame listener and check the mouse position every frame. something along the lines of:
stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
private function onEnterFrame(e:Event):void {
if(mouseX > width || mouseY > height){
//hide stats
}
}
I'm assuming you have this display hierarchy:
Debug Window
Debug Control 1
Debug Control 2
...
Overlay
Why not make the overlay a mask on DebugWindow and have your mouseEvents attached to DebugWindow itself? See this page for some inspiration: http://blog.shaperstudio.com/2010/11/as3-inverse-mask/
I had this same problem.. i made function to check is mouse over certain object:
public function isMouseOverObject(mPos: Point, pObject:DisplayObject, pContainer:DisplayObjectContainer) {
var under_objects:Array = pContainer.getObjectsUnderPoint(mPos);
var is_under:Boolean = false;
for (var i:int = 0; i < under_objects.length; i++) {
if (under_objects[i] == pObject) {
is_under = true;
break;
}
}
return is_under;
}

AS3: Making a SimpleButton from library sprites: Possible?

I'm working on a small project in AS3, and I need to make some interface buttons. I had them as separate classes at first, but then realized that it was probably overkill, and on top of that, figured out a way to simplify the event calls by making them buttons and assigning the event dispatches to their parent.
ANYWAY,
I tried remaking them using the SimpleButton class, but I can't figure out how to give the buttons any sort of design. Every tutorial on the web uses SimpleButton to make only the most bare-bones Actionscript graphics by actually drawing them with the code (why anybody would want to do that is beyond me), and my attempt at assigning a library item to the upState:
_deletebutton = new SimpleButton();
_deletebutton.upState = mc_deleteButtonUp; <--- exists in my library
doesn't do anything.
The Adobe docs say that the various states take DisplayObjects, which mean they take Sprites and MovieClips, so you should be able to do this. Does anyone know how?
THANK YOU
+1 weltraumpirat
the example in the doc generates the states by code but you can assign whatever displayObject to the different states of the button.
var btn:SimpleButton = new SimpleButton();
btn.downState = new clipFromLibDown();
btn.overState = new clipFromLibOver();
btn.upState = new clipFromLibUp();
btn.hitTestState = new clipFromLibHit();
btn.useHandCursor = true;
addChild( btn );
assuming you have 4 states called : clipFromLibDown, clipFromLibOver ... in your library, this works
You have to instantiate an item from your library in order to use it with ActionScript. To do this, click "Export for ActionScript" and assign a class or base class to mc_deleteButtonUp in the properties panel. Then use the new operator with the assigned class to instantiate it. You can start your button by using the example from Adobe's documentation, then change things to fit your own program.
You're probably not setting the hitTestState property of your SimpleButton instances. This property is a DisplayObject that defines where the user has to move the mouse to get mouse events on the SimpleButton. You will never see the DisplayObject that you set this to. I would suggest just using one of the DisplayObjects you are already using for another state.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/SimpleButton.html#hitTestState
Also you will need to use the new operator as weltraumpirat and nicoptere have already said.

How do I force or lock focus in actionscript 3?

I want to create a dialog or alert box, where a DisplayObject would take and force the focus, until an okay button or something releases the lock. thanks.
The easy way to do this is to make your "dialog" as big as the stage, with a whacking great transparent area around the dialog itself.
The transparent area can listen for any mouse clicks, and just swallow them (which will prevent them being picked up by stuff further back in the display list).
To show the alert, just stick it on top of everything else, When the user closes it, take it away again.
If you are using flex and actionscript, simply use a SkinnablePopUpContainer
var alt:CustomPopUp = new CustomPopUp();
alt.open(this,true) //the second variable is for modal, which will disable view
this.enabled = false; //this will grey out the parent view and provide visual focus to your popup.
To do this, you will need to disable access to all objects under your 'alert' DisplayObject. There are multiple ways of doing this, here 2 I can think off:
Loop through the display list and disable any display objects under your alert depth wise.
Cheat it with a blocker. When you display your alert, display another clip (could have alpha set to 0 ) that blocks the user from hovering/clicking objects. The blocker might need a bit of setup( buttonMode = true, useHandCursor = false, etc. )
This 'modal' behavior has been around for some so there might be no need to reinvent the wheel, depending of your current setup.
If you're using the Flex framework, you've got the functionality in, for Flash you can use the Alert Manager from the Yahoo! Flash Astra Components:
Goodluck,