Allow a trigger button to be set.

- When the menu hides, if the trigger is a toggle, it will be de-selected.
- If the menu is up and you mouseDown on the trigger, it will supress the menu
  from re-popping by blocking the CLICK that comes on the trigger.

Jesus this was complicated to get right. For a while I was trying stuff
with MethodQueue, but we react to the MOUSE_DOWN and the CLICK doesn't
get generated until some time later.


git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@813 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Ray Greenwell
2009-05-04 00:33:59 +00:00
parent 86e9c39a2f
commit 34153b66aa
+57
View File
@@ -26,10 +26,12 @@ import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.events.IEventDispatcher;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import mx.controls.Button;
import mx.controls.Menu;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IListItemRenderer;
@@ -178,6 +180,7 @@ public class CommandMenu extends Menu
verticalScrollPolicy = ScrollPolicy.OFF;
variableRowHeight = true;
addEventListener(MenuEvent.ITEM_CLICK, itemClicked);
addEventListener(MenuEvent.MENU_HIDE, menuHidden);
}
/**
@@ -189,6 +192,17 @@ public class CommandMenu extends Menu
return CommandMenuItemRenderer;
}
/**
* Configure the button that popped-up this menu, which enables two features:
* 1) If the button is clicked again while the menu is up, it won't re-trigger, the menu will
* just close.
* 2) However the menu closes, if the button is a toggle, it will be de-selected.
*/
public function setTriggerButton (trigger :Button) :void
{
_trigger = trigger;
}
/**
* Configures the event dispatcher to be used when dispatching this menu's command events.
* Normally they will be dispatched on our parent (usually the SystemManager or something).
@@ -276,6 +290,17 @@ public class CommandMenu extends Menu
maxHeight = fitting.height;
y = fitting.y;
}
// set up some stuff to clean up and behave
systemManager.topLevelSystemManager.getSandboxRoot().addEventListener(
MouseEvent.MOUSE_DOWN, handleMouseDownOutside, false, 1, true);
}
override public function hide () :void
{
super.hide();
systemManager.topLevelSystemManager.getSandboxRoot().removeEventListener(
MouseEvent.MOUSE_DOWN, handleMouseDownOutside);
}
/**
@@ -342,6 +367,37 @@ public class CommandMenu extends Menu
// else: no warning. There may be non-command menu items mixed in.
}
/**
* Handles MenuEvent.MENU_HIDE.
*/
protected function menuHidden (event :MenuEvent) :void
{
// don't react to submenu hides
if ((event.menu == this) && (_trigger != null) && _trigger.toggle) {
_trigger.selected = false;
}
}
/**
* Handle a down-popping click outside the menu.
*/
protected function handleMouseDownOutside (event :MouseEvent) :void
{
if (event.target == _trigger) {
_trigger.addEventListener(
MouseEvent.CLICK, handleTriggerClick, false, int.MAX_VALUE, true);
}
}
/**
* Suppress the click that wants to land on the trigger button.
*/
protected function handleTriggerClick (event :MouseEvent) :void
{
event.stopImmediatePropagation();
_trigger.removeEventListener(MouseEvent.CLICK, handleTriggerClick);
}
// from ScrollableArrowMenu..
override mx_internal function openSubMenu (row :IListItemRenderer) :void
{
@@ -473,6 +529,7 @@ public class CommandMenu extends Menu
}
protected var _dispatcher :IEventDispatcher;
protected var _trigger :Button;
protected var _lefting :Boolean = false;
protected var _upping :Boolean = false;
protected var _fitting :Rectangle = null;