Can I create an overlay layer to disable all touches, even on menus? - cocos2d-x

I need to show a popup layer on a scene, creating a semi-transparent background layer that will also prevent touch events propagation. I am using the latest cocos2d-x v. 3.0-alpha-0.
What I want to achieve is a popup layer that fully handles touches (eg. buttons, menu items, scroll views, etc.), laying on a background layer (for design purposes), that covers the current scene. All items in the scene should not respond to touches any more.
Is this achievable using the new EventDispatcher class? I've been able to disable all touches to the main scene, but all instances of MenuItem that live in the scene are still touchable and active.
How can I achieve this? And, also, how can I create a touch listener that prevents all touches to the main scene but not to the popup?

You can disable menu items by setting setDisable property of menuitems to false.
Example
_menuItem->setEnabled(false);
For Layers use setTouchEnabled property
_backGroungLayer->setTouchEnabled(false);
Make sure that popup layer is not child of layer you want to disable.
To disable all items in menus do this
Suppose _menu contain various menuitems.
CCARRAY_FOREACH(_menu->getChildren(), item)
{
item.isEnabled=NO;
}
if you want to disable selected items just give them tags.There is no need to make any list.

I had the same problem and solved it with mm. It was dirty, but it worked:
Create a button using ccui.button.
Set the button size to your screen size.
Add this button as a background to your popup layer.
This will prevent any thing behind it being clicked.

By default, all CCMenu's have a set priority (kCCMenuHandlerPriority = -128) in cocos2d 2.1. So in a class (usually a CCNode descendant) that wants to swallow everything and preempt anything i do like in this dialog sequencer example below :
- (void)onEnter {
backdrop_.visible = self.isBackDropShown;
MPLOG(#"Adding self as a swallower touch delegate, above the rest of the planet.");
[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:_dialogTouchPriority swallowsTouches:YES];
for (CCMenu *mn in _menus) {
mn.touchPriotity = _dialogTouchPriority -1 ;
}
[super onEnter];
}
where _dialogTouchPriority is kCCMenuHandlerPriority-1 by default. It will be served before everything 'below'. It is a bad hack (cocos2d internals could be changed and break this), i know , but bullet proof. Use carefully, make certain you only ever have one of these in your scene.

Related

Which implementation of InteractiveObject that is lightweight should I use to keep track of mousefocus in flex?

I have a spark List control that shows a side-list on ListEvent.ITEM_ROLL_OVER event. Basicaly it shows the contents of the item you are hovering. I would be also using ListEvent.ITEM_ROLL_OUT to hide it again but I want the user to be able to click on it (the sidelist) too.
So, i use MouseEvent.ROLL_OUT and check the event.relatedObject's id to see where the cursor went. I added an invisible Rectangle overlaying the sidelist that's a bit larger so it gains focus 1st. But it doesn't.
Googling around, I think that the Spark Rectangle cant gain focus as it doesn't implement InteractiveObject. What should I use?
My logic:
protected function listOUT(event:MouseEvent):void
{
var obj:Object = event.relatedObject;
if (obj.id != "focusRect")
{
sidelist.visible = false;
}
}
My struggle is to keep the side-list visible if the user moves the cursor from the main list to the sidelist.
Any other suggestions outside my approach are also welcome.
Update
(image link)
Red are the invisible Buttons
On roll_over select the item in the mainlist, display the sidelist
based on the selecteditem in the mainlist.
Hide the sidelist when there is no item selected in the main list.
Deselect items inthe mainlist if the sidelist loses focus.
Furthermore mx.core.UIComponent is the lightest component that dispatches focus events.

AS3 Custom contextMenu to children

I have create a custom contextMenu using AS3 and can apply that to the stage. Any movie clip I place onto the stage does not inherit the contextMenu from the stage, i.e. they display the default contextMenu.
How do I apply my custom contextMenu to every child in my application?
[edit]
This is a simplified version of what I have in my main.as file:
var my_menu:ContextMenu = new ContextMenu();
my_menu.hideBuiltInItems();
var my_copyright = new ContextMenuItem("Copyright - 2012");
my_copyright.enabled = false;
my_copyright.separatorBefore = true;
my_menu.customItems.push(my_copyright);
stage.contextMenu = my_menu;
If I right-click on the stage then I get the copyright. If I add a movieclip (or anything else) to the stage then right-click on that, then I get the default context-menu.
[edit]
I have found the problem, and fixed it. I was adding a background image using stage.addChildAt(mc, 0);. For some reason this removes the context menu. Placing the child at 1 fixes this and allows everything to inherit the contextMenu.
Before: http://richard.parnaby-king.co.uk/examples/stackoverflow/stackoverflow.swf
After: http://richard.parnaby-king.co.uk/examples/stackoverflow/stackoverflow-after.swf
I am changing the purpose of the bounty - can someone explain WHY this happens!?
Ok, so after a bit of testing this is what I have. I can't say it's that definitively, as flash doesn't give the events for right-click, so it's only a guess, but it seems to hold up.
On a side note, you can't add a context menu to the stage, it won't allow it, so the lowest item you can add it to is the document class
When you right-click on a DisplayObject, it'll look for a ContextMenu on that object. It it doesn't find one, it'll continue on up the hierarchy for that object looking for one, stopping when it finds one. Something like this:
stage
- document (has context menu1)
- parent (has context menu2)
- child
- parent2
In this example, if you right click on child, there's no menu, so it looks to parent. Here it finds context menu2 so it shows that. However if you right-click on parent2, there's no menu, so it looks to document and here it finds context menu1.
There seems to be a bit of a hack though when you right-click somewhere else on the stage (i.e. somewhere with no graphics). In this case, as the stage can't have a ContextMenu (or at least you can't set one), it seems to decide to use the context menu of the child at depth 0 (normally the document class).
When you added your background image at depth 0, you were bumping up your document class to depth 1. Your hierarchy now looks something like this:
stage
- bg
- document (has context menu1)
- parent (has context menu2)
- child
- parent2
I'm assuming you're adding your context menu to the document class (in this example context menu1), so unless your document class has some graphics in it, your event would search up to the stage, find no context menu, then try to look for the context menu of child 0 - in this case bg which doesn't have one.
You can test this by drawing something in the graphics object of your document class (or clicking on one of the nested elements). If you right click on the graphics, you'll see your custom menu, even though bg is at depth 0. Alternatively, you can add another menu to bg to see what I mean.
The answer to your why really is subjective to what else you add into the stage & their order.
I could quote 2 points from the adobe live docs relating to the same :
An index of 0 represents the back (bottom) of the display list for
this DisplayObjectContainer object.
If you specify a currently occupied index position, the child object
that exists at that position and all higher positions are moved up one
position in the child list.
I think if you properly analyse all that is added onto the stage, you yourself might get the answer.
try changing stage.contextMenu = my_menu; to just contextMenu = my_menu;

Zoom in Zoom out loop on action script 3

I have this code for my effect to zoom in and zoom out in certains buttons
canada.addEventListener(MouseEvent.MOUSE_OVER, canadaover);
function canadaover(event:MouseEvent):void
{
gotoAndPlay("canadaS");
trace("in");
}
canada.addEventListener(MouseEvent.MOUSE_OUT, canadaout);
function canadaout(event:MouseEvent):void
{
gotoAndPlay("canadaF");
trace("out");
}
canada.addEventListener(MouseEvent.CLICK, clickcanada);
function clickcanada(event:MouseEvent):void
{
trace("Mouse clicked");
}
the problem is when u reach certain corner of the button it kinda gets into a loop, any ideas how can i fix this?
here its the link of the swf i'm trying to do:
http://viajescupatitzio.com/america%20map.swf
If your buttons are MovieClips you can add inside a layer with a mask (for example rectangle) on top. Mask width and height should be your mouseover region and give it alpha = 0. It will be invisible, but it will work with MOUSE_OVER and MOUSE_OUT Events.
You should move your buttons into a different hierarchy level than the graphics you are changing - even if the buttons disappear, or are covered with graphics for just a very short moment, both mouseOver and mouseOut events will be fired (the mouse has left and reentered the button) - and that probably causes your "loop".
It is generally a good idea to have animations and graphical objects within nested MovieClips, and place control elements on a higher level of the display list - that way you can make sure the elements don't overlap and/or interfere.

ActionScript Effects using Tweener?

HI,
I want to implement tweener effects in my application, but I have a rectangle,
shape = new Shape();
shape.graphics.beginFill(0xF9F9F9);
shape.graphics.drawRect(200,80,700,450);
shape.graphics.endFill();
account_label.label ="Accounts";
account_label.setPosition(200,530);
account_label.width =140;
personal_details_label.label ="Personal Details";
personal_details_label.setPosition(340,530);
personal_details_label.width=180;
the above code shows my rectangle and two buttons,
Intially Accounts Form was selected by default, when i click PersonalDetails button i have to show the screen change effect (From Right to Left that means Personal DetailsForm is moving from right to left ) within that rectangle. Is this possible ?
I'm a fan of tweensy, but you can do this with most tweening engines easily
Tweensy.to(shape, {x:-100}, 2.0);
Tweensy.onComplete = animationComplete; //optional
The important part to consider when working with animations is timing. Either disable buttons or setup a proper fallbacks. The animations can take a few seconds and if the user can restart the animation, or if objects aren't cleared or initialized properly you can run into some issues.

How to popup a transparent Panel that is dismissed when clicked outside of it in Flex 4

I need to popup some buttons in Flex 4. Users should be able to see the background (ideally a little faded, but not important) around and in between the buttons. And clicking anywhere except the buttons should dismiss them all.
So I created a spark Panel and added a spark VGroup with some buttons. Then I call
PopupManager.addPopUp(myNewPanel, background, true);
My 2 main problems are the panel is not transparent and clicking outside the buttons doesn't dismiss them... How do I implement that?
UPDATE: Figured out how to dismiss the popup when clicking outside the panel with:
addEventListener("mouseDownOutside", close);
private function close(event:FlexMouseEvent):void {
PopUpManager.removePopUp(this);
}
Now I just need to figure out how to make the Panel transparent so you can see the background around and in between the buttons.
You should use FlexMouseEvent.MOUSE_DOWN_OUTSIDE instead of the string "mouseDownOutside". Code completion, compile-time checking and makes it easier for others to read your code.
For the background, you can use css to style it. Heres a list of all the css properties for a spark panel - http://docs.huihoo.com/flex/4/spark/components/Panel.html#styleSummary