tags:

views:

51

answers:

1

Hi,

Basically, I have a button and on click it displays a menu. I want to click that menu a second time and the menu closes. Currently, every time you click the button, the menu reopens. I pasted the Flex livedoc example below. If you click the button, the menu keeps reopening.

Now, I rigged it up by setting a var to open and closed, so when clicking the button it does a check. However, if you click away from the screen, the HIDE event gets dispatched, and the menu closes. This messed up the open close var being set.

How could I make this Flex example below show the menu on button click, and then on a second button click, it closes the menu? Take into affect that if you click away from the menu, it closes it.

Also, I played around with the MOUSE_DOWN_OUTSIDE event for the button and set the preventDefault, and the FlexMouseEvent event.cancelable is set to false.

Changing to a PopUpMenuButton is not an option. I have to much skinning involved.

Here is the Flex example:

<mx:Script>
    <![CDATA[
        // Import the Menu control.
        import mx.controls.Menu;

        // Create and display the Menu control.
        private function createAndShow():void {
            var myMenu:Menu = Menu.createMenu(null, myMenuData, false);
            myMenu.labelField="@label";
            myMenu.show(10, 10);
        }
    ]]>
</mx:Script>

<!-- Define the menu data. -->
<mx:XML format="e4x" id="myMenuData">
    <root>
        <menuitem label="MenuItem A" >
            <menuitem label="SubMenuItem A-1" enabled="false"/>
            <menuitem label="SubMenuItem A-2"/>
        </menuitem>
        <menuitem label="MenuItem B" type="check" toggled="true"/>
        <menuitem label="MenuItem C" type="check" toggled="false"/>
        <menuitem type="separator"/>     
        <menuitem label="MenuItem D" >
            <menuitem label="SubMenuItem D-1" type="radio" 
                groupName="one"/>
            <menuitem label="SubMenuItem D-2" type="radio" 
                groupName="one" toggled="true"/>
            <menuitem label="SubMenuItem D-3" type="radio" 
                groupName="one"/>
        </menuitem>
    </root>
</mx:XML>

<mx:VBox>
    <!-- Define a Button control to open the menu -->
    <mx:Button id="myButton" 
        label="Open Menu" 
        click="createAndShow();"/>
</mx:VBox>

A: 
//Declare menu as an instance variable instead of a local var
private var myMenu:Menu;

//var to store menu status
private var isMenuVisible:Boolean

//Create the Menu control. call this from the creationComplete of the 
//application or the Component that it is part of.
private function createMenu():void 
{
    var myMenu:Menu = Menu.createMenu(null, myMenuData, false);
    myMenu.labelField="@label";
    //menu fires an event when it is hidden; listen to it.
    myMenu.addEventListener(MenuEvent.MENU_HIDE, onMenuHidden);
}
private function onMenuHidden(e:MenuEvent):void
{
    /*
    menuHide event fired whenever the menu or one of its submenus
    are hidden - makes sure it was indeed the main menu that was hidden
    I don't have compiler handy to test this, so if for 
    some reason comparing myMenu with e.menu doesn't work,
    try if(e.target == myMenu) instead; 
    And please let me know which one works via comment :)
    */

    if(e.menu == myMenu)
       isMenuVisible = false;
}
//call this from button's click 
private function toggleMenu():void
{
    if(isMenuVisible)
        myMenu.hide();
    else
        myMenu.show();
}
Amarghosh
I just ran your code and it isn't quite what I am looking for.When you click the button, the menu opens. If you click the button a second time, while the menu is still open, it closes the menu and reopens it. I want the menu to remain closed when you click the button while the menu is open. I am looking for a way to stop the menu from closing and reopening when clicking on the button while the menu is open.We also need to take into account that when you click away from the menu, it also hides the menu by dispatching the HIDE_MENU event.I need a way to do this. Any thoughts?
Dana
Here is why it doesn't work:When you initially click the button the toggleMenu gets called and the myMenu.show(); is called. The Menu class, adds a MENU_HIDE listener on a show.When the menu is open, and you click the button a second time, or click away from the menu, that MENU_HIDE gets dispatched. The Menu class listener happens before our onMenuHidden() gets called. So when our onMenuHidden() is called, the menu is already hidden, so it does myMenu.show().Is there a way to call our onMenuHidden() before the Menu class listener? Or any other idea on how to get this to work?
Dana
@Dana Clicking on the button counts as clicking outside the menu. Try adding `toggleMenu` as click event listener using `addEventListener()` (through actionscript instead of mxml's click attribute) and set a higher priority (4th parameter) and call `event.stopPropagation()` and `event.stopImmediatePropagation()` from `toggleMenu` - this should prevent the button's click event from being handled as clicking outside.
Amarghosh
Amarghosh, I really appreciate your help. Here is how I got it to work:I call toggleMenu in the MXML on mouseDown (instead of on click):mouseDown="toggleMenu(event)"Instead of event.stopImmediatePropagation, I used callLater. I was afraid to use the stopImmediatePropagation because my application is fairly large, and I didn't want to cause any odd sideaffects. Here is what I did when mouseDown:public function toggleMenu(e:Event):void{ if (myMenu.visible) { myMenu.hide(); } else { this.callLater(function():void { myMenu.show(); }); }}
Dana