How to get ContextMenuItem x and y coordinates - actionscript-3

i build a contextmenu i want when user click any item then i get the x and y coordinate of the contextmenuitem............actully i want to dispaly a textbox infornt of contextmenuitem when user click on the item........ or any other solution that i will show inputtext control as submenuitem in contextmenuitem

The only way I can think of doing what you are asking for is:
disallow the right-click mouse in the
html container with javascript
capture right-click events and
forward them to flash via
ExternalInterface
In the method
triggered from ExternalInterface,
do/show what you want.
There are some open source solutions:
custom-context-menu
Article at ADM blog

Add an event listener to each menu item. In the listener function, the event's target object is the object you clicked on - all you need to do is cast it to DisplayObject, and you can access the x and y coordinates:
contextmenuItem.addEventListener (MouseEvent.CLICK, onItemClick);
function onItemClick (ev:MouseEvent) : void {
var item:DisplayObject = ev.target as DisplayObject;
// use item.x and item.y to get the object's position.
}

Related

using an array function for click events

I have created symbols which contain animations (mc1 - mc25). I would like to play these animations if I click on the symbols (click on mc1 -> play mc1, click on mc2 -> play mc2 etc.).
I created an array to address all my symbols in one go. It works ok.
var A:Array = [mc1, mc2, mc3, mc4,...mc25] // create array
car aClip:MovieClip;
for each (aClip in A) // stop all symbols
{aClip.stop();}
How can I get to the result below for all my symbols using an array function?
mc1.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler_4);
function fl_MouseClickHandler_4(event:MouseEvent):void
{
mc1.play();
}
I tried something like this but I couldn't get it work:
aClip.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event:MouseEvent):void {
aClip.play();
}
Thank you!
The simple way about it is to algorithmically figure which one was clicked. The script below is short and does not contain various checks, it assumes all the elements of A are really MovieClips.
// Assume, you filled the Array with these clips already.
var A:Array;
// Iterate all the clips.
for each (var aClip:MovieClip in A)
{
// Subscribe to each of the clips for the CLICK event.
aClip.addEventListener(MouseEvent.CLICK, clickPlay);
}
// Click event handler function. The point is, you can subscribe it
// to the multiple objects and use the function argument to figure out
// which one of them all is actually the source of the event.
// Furthermore, you can subscribe it to handle multiple events too,
// the argument also carries the id of the event. Sometimes it is
// really simpler to compose a single event-processing gate
// rather then process each one event in a separate handler.
function clickPlay(e:MouseEvent):void
{
// Use e.currentTarget because the initial e.target
// could be not the MovieClip itself, but some interactive
// element deep inside the MovieClip's hierarchy.
// Read about bubbling events (MouseEvent is bubbling)
// to get the whole picture of it.
// Typecasting, because e.target and e.currentTarget
// are of base Object type.
var aClip:MovieClip = e.currentTarget as MovieClip;
// Well, the only thing that is left.
aClip.play();
}

How does one get the localX, localY of container rather than the clicked object?

I have created an empty sprite to use as a container.
I then add several symbols as children to the container (container.addChild(symbol)).
I then add an event handler to the container (container.addEventListener(MouseEvent.CLICK, containerClick)).
In the event handler I trace the event.localX and event.localY.
When I click on a symbol it reports the localX and localY relative to the symbol's registration point.
What I would like is the localX and localY relative to the container's registration point.
Is that possible?
Yes, there's several ways of doing it.
The most naive approach is to simply add the clicked symbol's x and y position to the localX and localY to get the clicked coordinate in the container's coordinate space (assuming the clicked symbol is a child of the container). But this fails if any transformation such as scaling or rotation of the symbols are involved.
The best approach is to use localToGlobal() and globalToLocal() to convert between coordinate spaces:
private function onSymbolClicked(event : MouseEvent) : void {
// get the parent of the clicked symbol. We use currentTarget instead
// of target because we want to get the display object the listener was
// attached to (currentTarget) and not the clicked display object (target)
// which might not be the same as currentTarget if the clicked symbol
// contains children and mouseChildren is set to true. We store the parent
// in a variable using the most generic data type which is DisplayObjectContainer
var symbolParent : DisplayObjectContainer = DisplayObjectContainer(event.currentTarget.parent);
// get the clicked point in global coordinate space and create a Point instance
var point : Point = new Point(event.stageX, event.stageY);
// convert the point from global coordinates to the coordinate space
// of the clicked symbol's parent
point = symbolParent.globalToLocal(point);
trace(point);
}
I don't think there is a property in the event that will give you that, but some maths should give you what you need.
As you identified, the localX/Y is relative to the coordinates of the event target, if the target is a UIComponent its coordinates are relative to it's parent. So add one to another.
var containerX:Number;
var containerY:Number;
if(event.target !== container){
containerX = event.localX + event.target.x;
containerY = event.localY + event.target.y;
} else {
containerX = event.localX;
containerY = event.localY;
}
var rec:Rectangle = event.target.getBounds(event.target.parent);
var wantedX:Number = rec.x + event.localX;
var wantedY:Number = rec.y + event.localY;

Bubble click event in swf

I try to add a MovieClip to an existent SWF on the fly - inject an small code who do something like:
this.obj = new MovieClip(); // it is inside an object
obj.name = 'FLOOR';
obj.graphics.beginFill(0xFFFFFF, 0);
obj.graphics.drawRect(0,0,self.width, self.height);
obj.graphics.endFill();
obj.buttonMode = true;
self.addChildAt( floorLayerMC , 0); /* self is an reference for the this keyword, reference for the entire swf */
My question is: this SWF has many elements like images and textfields, and some of this elements has no event handler for click. I Need to find a way to "redirect" all of the events to my "FLOOR" element, using something like bubbling the event.
Of course, I can add the FLOOR in top of any elements BUT I have some elements with click handler. I can't ignore all of the elements. So my problem is:
if I click over an MovieClip with click handler, perform the original action.
if I click over an MovieClip without click handler, perform the FLOOR action.
I can't add a event handler in all of the elements.
Any Idea?
Listen for a click on the container movieclip's own stage (the movieclip that contains the FLOOR). In the handler method for the click event, do a hit test using hitTestPoint with the mouseX and MouseY of the container movieclip, and if the mouse is over any clickable objects, ignore the stage click. Store all the objects that are clickable in an array to do that test.
This code is untested but it would go something like this:
var exemptArray:Array = [ btn_mc1, btn_mc2, btn_mc3 ];
containerMC.stage.addEventListener(MouseEvent.CLICK, onClickMyMC);
function onClickMyMC( event:Event ):void
{
for(var i:int = 0; i < exemptArray.length; i++)
{
if( exemptArray[i].hitTestPoint(containerMC.mouseX, containerMC.mouseY) )
{
// do nothing, ignore the stage click ( and let the object with the click respond )
break;
}
else
{
// respond to the stage click
}
}
}
To build the exemptArray without knowing what objects are clickable ahead of time:
( untested but should be close enough to give you an idea ).
var exemptArray:Array = buildExemptArray();
function buildExemptArray():Array
{
var arr:Array = [];
for(var j:int = 0; j < containerMC.numChildren; j++)
{
if( containerMC.getChildAt(i).hasEventListener(MouseEvent.CLICK) )
{
arr.push( containerMC.getChildAt(i) );
}
}
return arr:
}
EDIT TO ANSWER QUESTION IN COMMENTS:
this.addEventListener(MouseEvent.CLICK, onClick) will add a click event to the whole object, children included.
this.stage.addEventListener(MouseEvent.CLICK, onClick) will add a click only to the movieclip's stage, not its children as well.
In as3 all movieclips have a stage property. If you wrote on the main timeline this.stage.addEventListener(MouseEvent.CLICK, onClick); that would be adding a stage click to the whole swf. But, if you wrote something like myMC.stage.addEventListener(MouseEvent.CLICK, onClick); it would only add a click to that movieclip's stage (myMC's stage). Since stage is below the display list, you can capture a click there in any movieclip. If you don't have access to all the objects that have mouse events ahead of time, you could loop through all the container's children and check if they have a mouseEvent with .hasEventListener(MouseEvent.CLICK);, create your exemptArray from that, then use the same logic above to ignore items in the exemptArray.

how to simulate a click event for android using ActionScript 3

i have an object called sniper scope and a fire button.
when i point the crosshair of my sniper scope on the target and press the fire button i want it to simulate a mouseevent.click or a touchevent.TAP to play the movieclip of the target object.
how can i do this?
you can use this example, I'm using this in my accessibility implementation for the button in accDoDefaultAction method, it will work for you, you may wish to just use the click event (in my case I had to use all to properly update button with states), and feed with some details like mouseX. The master is the button in my case.
//this is to update buttons state (BaseButton children)
//we need to simulate user interaction in order to have button working
var e:MouseEvent = new MouseEvent(MouseEvent.MOUSE_OVER);
master.dispatchEvent(e);
e = new MouseEvent(MouseEvent.MOUSE_DOWN);
master.dispatchEvent(e);
e = new MouseEvent(MouseEvent.MOUSE_UP);
master.dispatchEvent(e);
e = new MouseEvent(MouseEvent.MOUSE_OUT);
master.dispatchEvent(e);
//this is to trigger actions associated with button (BaseButton children)
e = new MouseEvent(MouseEvent.CLICK);
master.dispatchEvent(e);
However after reading your query second time, I think you r problem may be that the sniper scope is hijacking the event if that is the case try:
myCrosshairInstance.mouseEnabled = false;
myCrosshairInstance.mouseChildren = false;
best regards

Making simple paint in html 5 canvas

I have simple code to "draw" in canvas element:
function doFirst(){
var x = document.getElementById('canvas');
canvas = x.getContext('2d');
window.addEventListener("mousemove", rys, false);
}
function rys(e){
var xPos = e.clientX;
var yPos = e.clientY;
canvas.fillStyle="#000";
canvas.beginPath();
canvas.arc(xPos-7,yPos-7,10,0,Math.PI*2,true);
canvas.closePath();
canvas.fill();
}
window.addEventListener("load", doFirst, false);
As you can see, the function is working only when the mouse is over the canvas element. Now i want to make it "draw" when the mouse is clicked (just like in paint). Can someone tell me how to do it (with code)?
Thx for help
You need to keep track of the current mouse button state (pressed or not pressed) independently of the mouse movements.
You can do this by attaching event handlers to the "mousedown" and "mouseup" events, similar to how you attached to the "mousemove" event.
In these event handlers, you could keep track of the current state of the first mouse button by updating a global variable indicating whether or not the button is currently pressed. Then, in your "mousemove" handler, you can check this global variable and determine whether or not to paint when the mouse is moved.
When using the "mouseup" and "mousedown" events, you may want to limit your handling to only when the first mouse button is pressed. You can do this by checking that the event property "button" is 0. Note, that you can check for other buttons and keep track of them, also.
You can see a working example of this here: http://jsfiddle.net/mQtKz/