Allow menu items to be configured with a callback function directly
(to which any args will be passed), instead of only dispatching controller commands. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4465 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -7,18 +7,23 @@ import flash.geom.Rectangle;
|
|||||||
|
|
||||||
import mx.controls.Menu;
|
import mx.controls.Menu;
|
||||||
import mx.core.mx_internal;
|
import mx.core.mx_internal;
|
||||||
|
import mx.core.ScrollPolicy;
|
||||||
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
|
* A pretty standard menu that can submit CommandEvents if menu items
|
||||||
* have "command" and possibly "arg" properties.
|
* have "command" and possibly "arg" properties. Commands are submitted to
|
||||||
|
* controllers for processing. Alternatively, you may specify
|
||||||
|
* "callback" properties that specify a function closure to call, with the
|
||||||
|
* "arg" property containing either a single arg or an array of args.
|
||||||
*
|
*
|
||||||
* Example dataProvider array:
|
* Example dataProvider array:
|
||||||
* [ { label: "Go home", icon: homeIconClass,
|
* [ { label: "Go home", icon: homeIconClass,
|
||||||
* command: Controller.GO_HOME, arg: homeId },
|
* command: Controller.GO_HOME, arg: homeId },
|
||||||
* { type: "separator"},
|
* { type: "separator"},
|
||||||
|
{ label: "Crazytown", callback: setCrazy, arg: [ true, false ] },
|
||||||
* { label: "Other places", children: subMenuArray }
|
* { label: "Other places", children: subMenuArray }
|
||||||
* ];
|
* ];
|
||||||
*
|
*
|
||||||
@@ -32,6 +37,7 @@ public class CommandMenu extends Menu
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
addEventListener(MenuEvent.ITEM_CLICK, itemClicked);
|
addEventListener(MenuEvent.ITEM_CLICK, itemClicked);
|
||||||
|
// addEventListener(MenuEvent.MENU_SHOW, handleMenuShown);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,14 +80,42 @@ public class CommandMenu extends Menu
|
|||||||
*/
|
*/
|
||||||
protected function itemClicked (event :MenuEvent) :void
|
protected function itemClicked (event :MenuEvent) :void
|
||||||
{
|
{
|
||||||
|
var arg :Object = getItemArgument(event.item);
|
||||||
var cmd :String = getItemCommand(event.item);
|
var cmd :String = getItemCommand(event.item);
|
||||||
if (cmd != null) {
|
var fn :Function;
|
||||||
|
if (cmd == null) {
|
||||||
|
fn = getItemCallback(event.item);
|
||||||
|
}
|
||||||
|
if (cmd != null || fn != null) {
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
var arg :Object = getItemArgument(event.item);
|
if (cmd != null) {
|
||||||
CommandEvent.dispatch(mx_internal::parentDisplayObject, cmd, arg);
|
CommandEvent.dispatch(mx_internal::parentDisplayObject, cmd, arg);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
var args :Array = (arg as Array);
|
||||||
|
if (args == null && arg != null) {
|
||||||
|
args = [ arg ];
|
||||||
|
}
|
||||||
|
fn.apply(null, args);
|
||||||
|
|
||||||
|
} catch (err :Error) {
|
||||||
|
Log.getLog(this).warning("Unable to call menu callback: " +
|
||||||
|
event.item);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Callback for MenuEvent.MENU_SHOW.
|
||||||
|
// */
|
||||||
|
// protected function handleMenuShown (event :MenuEvent) :void
|
||||||
|
// {
|
||||||
|
// // just ensure that every menu can scroll
|
||||||
|
// event.menu.verticalScrollPolicy = ScrollPolicy.ON;
|
||||||
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the command for the specified item, if any.
|
* Get the command for the specified item, if any.
|
||||||
* Somewhat similar to bits in the DefaultDataDescriptor.
|
* Somewhat similar to bits in the DefaultDataDescriptor.
|
||||||
@@ -90,10 +124,29 @@ public class CommandMenu extends Menu
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (item is XML) {
|
if (item is XML) {
|
||||||
return String(item.@command);
|
return (item.@command as String);
|
||||||
|
|
||||||
} else if (item is Object) {
|
} else if (item is Object) {
|
||||||
return String(item.command);
|
return (item.command as String);
|
||||||
|
}
|
||||||
|
} catch (e :Error) {
|
||||||
|
// fall through
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the callback function for the specified item, if any.
|
||||||
|
*/
|
||||||
|
protected function getItemCallback (item :Object) :Function
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (item is XML) {
|
||||||
|
return (item.@callback as Function);
|
||||||
|
|
||||||
|
} else if (item is Object) {
|
||||||
|
return (item.callback as Function);
|
||||||
}
|
}
|
||||||
} catch (e :Error) {
|
} catch (e :Error) {
|
||||||
// fall through
|
// fall through
|
||||||
|
|||||||
Reference in New Issue
Block a user