Made more compatible with the base class, use object properties to

specify the command name and arg.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4352 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2006-08-31 00:12:48 +00:00
parent 0149aa3b1d
commit 9e1f81ceff
@@ -1,22 +1,36 @@
package com.threerings.mx.controls { package com.threerings.mx.controls {
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer; import flash.display.DisplayObjectContainer;
import flash.geom.Rectangle;
import mx.controls.Menu; import mx.controls.Menu;
import mx.core.mx_internal; import mx.core.mx_internal;
import mx.events.MenuEvent; import mx.events.MenuEvent;
import com.threerings.mx.events.CommandEvent; import com.threerings.mx.events.CommandEvent;
/**
* A pretty standard menu that can submit CommandEvents if menu items
* have "command" and possibly "arg" properties.
*
* Example dataProvider array:
* [ { label: "Go home", icon: homeIconClass,
* command: Controller.GO_HOME, arg: homeId },
* { type: "separator"},
* { label: "Other places", children: subMenuArray }
* ];
*
* See "Defining menu structure and data" in the Flex manual for the
* full list.
*/
public class CommandMenu extends Menu public class CommandMenu extends Menu
{ {
public function CommandMenu () public function CommandMenu ()
{ {
super(); super();
iconFunction = getIconFor;
labelFunction = getLabelFor;
addEventListener(MenuEvent.ITEM_CLICK, itemClicked); addEventListener(MenuEvent.ITEM_CLICK, itemClicked);
} }
@@ -24,12 +38,10 @@ public class CommandMenu extends Menu
* Factory method to create a command menu. * Factory method to create a command menu.
* *
* @param parent The parent of this menu. * @param parent The parent of this menu.
* @param items an array of menu items, where each item is another array * @param items an array of menu items.
* with the following format: [ text, iconClass, command, arg ]. Arg is
* optional.
*/ */
public static function createMenu ( public static function createMenu (
parent :DisplayObjectContainer, items :Array) :CommandMenu parent :DisplayObjectContainer, items :Array) :CommandMenu
{ {
var menu :CommandMenu = new CommandMenu(); var menu :CommandMenu = new CommandMenu();
menu.tabEnabled = false; menu.tabEnabled = false;
@@ -38,30 +50,76 @@ public class CommandMenu extends Menu
return menu; return menu;
} }
/**
* Actually pop up the menu. This can be used instead of show().
*/
public function popUp (
trigger :DisplayObject, popUpwards :Boolean = true) :void
{
var r :Rectangle = trigger.getBounds(trigger.stage);
if (popUpwards) {
show(r.x, 0);
// then, reposition the y once we know our size
y = r.y - getExplicitOrMeasuredHeight();
} else {
// simply position it below the trigger
show(r.x, r.y + r.height);
}
}
/** /**
* Callback for MenuEvent.ITEM_CLICK. * Callback for MenuEvent.ITEM_CLICK.
*/ */
protected function itemClicked (event :MenuEvent) :void protected function itemClicked (event :MenuEvent) :void
{ {
event.stopImmediatePropagation(); var cmd :String = getItemCommand(event.item);
var element :Array = (event.item as Array); if (cmd != null) {
event.stopImmediatePropagation();
CommandEvent.dispatch(mx_internal::parentDisplayObject, var arg :Object = getItemArgument(event.item);
String(element[2]), element[3]); CommandEvent.dispatch(mx_internal::parentDisplayObject, cmd, arg);
}
} }
// our function for retrieving a label for a menu entry /**
protected function getLabelFor (obj :Object) :String * Get the command for the specified item, if any.
* Somewhat similar to bits in the DefaultDataDescriptor.
*/
protected function getItemCommand (item :Object) :String
{ {
var element :Array = (obj as Array); try {
return String(element[0]); if (item is XML) {
return String(item.@command);
} else if (item is Object) {
return String(item.command);
}
} catch (e :Error) {
// fall through
}
return null;
} }
// our function for retrieving an icon for a menu entry /**
protected function getIconFor (obj :Object) :Class * Get the command for the specified item, if any.
* Somewhat similar to bits in the DefaultDataDescriptor.
*/
protected function getItemArgument (item :Object) :Object
{ {
var element :Array = (obj as Array); try {
return Class(element[1]); if (item is XML) {
return item.@arg;
} else if (item is Object) {
return item.arg;
}
} catch (e :Error) {
// fall through
}
return null;
} }
} }
} }