diff --git a/src/as/com/threerings/flex/CommandMenu.as b/src/as/com/threerings/flex/CommandMenu.as index b44a9b5b..3e085e92 100644 --- a/src/as/com/threerings/flex/CommandMenu.as +++ b/src/as/com/threerings/flex/CommandMenu.as @@ -28,17 +28,29 @@ import flash.events.IEventDispatcher; import flash.geom.Rectangle; import mx.controls.Menu; +import mx.controls.listClasses.BaseListData; +import mx.controls.listClasses.IListItemRenderer; +import mx.controls.menuClasses.IMenuItemRenderer; + import mx.core.mx_internal; import mx.core.Application; +import mx.core.ClassFactory; +import mx.core.IFlexDisplayObject; import mx.core.ScrollPolicy; + import mx.events.MenuEvent; +import mx.managers.PopUpManager; + import mx.utils.ObjectUtil; import flexlib.controls.ScrollableArrowMenu; import com.threerings.util.CommandEvent; +import com.threerings.flex.menuClasses.CommandMenuItemRenderer; +import com.threerings.flex.menuClasses.CommandListData; + use namespace mx_internal; /** @@ -47,6 +59,10 @@ use namespace mx_internal; * specify "callback" properties that specify a function closure to call, with the "arg" property * containing either a single arg or an array of args. * + * Another property now supported is "iconObject", which is an already-instantiated + * IFlexDisplayObject to use as the icon. This will only be applied if the "icon" property + * (which specifies a Class) is not used. + * * Example dataProvider array: * [ { label: "Go home", icon: homeIconClass, * command: Controller.GO_HOME, arg: homeId }, @@ -77,6 +93,10 @@ public class CommandMenu extends ScrollableArrowMenu public function CommandMenu () { super(); + variableRowHeight = true; + + itemRenderer = new ClassFactory(CommandMenuItemRenderer); + verticalScrollPolicy = ScrollPolicy.OFF; addEventListener(MenuEvent.ITEM_CLICK, itemClicked); } @@ -147,6 +167,61 @@ public class CommandMenu extends ScrollableArrowMenu // else: no warning. There may be non-command menu items mixed in. } + // from ScrollableArrowMenu.. + override mx_internal function openSubMenu (row :IListItemRenderer) :void + { + supposedToLoseFocus = true; + + var r :Menu = getRootMenu(); + var menu :CommandMenu; + + // check to see if the menu exists, if not create it + if (!IMenuItemRenderer(row).menu) + { + /* The only differences between this method and the original method in mx.controls.Menu + * are these few lines. + */ + menu = new CommandMenu(); + menu.maxHeight = this.maxHeight; + menu.verticalScrollPolicy = this.verticalScrollPolicy; + menu.arrowScrollPolicy = this.arrowScrollPolicy; + + menu.parentMenu = this; + menu.owner = this; + menu.showRoot = showRoot; + menu.dataDescriptor = r.dataDescriptor; + menu.styleName = r; + menu.labelField = r.labelField; + menu.labelFunction = r.labelFunction; + menu.iconField = r.iconField; + menu.iconFunction = r.iconFunction; + menu.itemRenderer = r.itemRenderer; + menu.rowHeight = r.rowHeight; + menu.scaleY = r.scaleY; + menu.scaleX = r.scaleX; + + // if there's data and it has children then add the items + if (row.data && _dataDescriptor.isBranch(row.data) && + _dataDescriptor.hasChildren(row.data)) { + menu.dataProvider = _dataDescriptor.getChildren(row.data); + } + menu.sourceMenuBar = sourceMenuBar; + menu.sourceMenuBarItem = sourceMenuBarItem; + + IMenuItemRenderer(row).menu = menu; + PopUpManager.addPopUp(menu, r, false); + } + + super.openSubMenu(row); + } + + // from List + override protected function makeListData (data :Object, uid :String, rowNum :int) :BaseListData + { + return new CommandListData(itemToLabel(data), itemToIcon(data), + getItemProp(data, "iconObject") as IFlexDisplayObject, labelField, uid, this, rowNum); + } + /** * Get the specified property for the specified item, if any. Somewhat similar to bits in the * DefaultDataDescriptor. diff --git a/src/as/com/threerings/flex/menuClasses/CommandListData.as b/src/as/com/threerings/flex/menuClasses/CommandListData.as new file mode 100644 index 00000000..49d7c4e0 --- /dev/null +++ b/src/as/com/threerings/flex/menuClasses/CommandListData.as @@ -0,0 +1,43 @@ +// +// $Id$ +// +// Nenya library - tools for developing networked games +// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/nenya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +package com.threerings.flex.menuClasses { + +import mx.core.IFlexDisplayObject; +import mx.core.IUIComponent; + +import mx.controls.listClasses.ListData; + +public class CommandListData extends ListData +{ + /** An already-instantiated icon, to use if the icon property is null. */ + public var iconObject :IFlexDisplayObject; + + public function CommandListData (text :String, icon :Class, iconObject :IFlexDisplayObject, + labelField :String, uid :String, owner :IUIComponent, + rowIndex :int = 0, columnIndex :int = 0) + { + super(text, icon, labelField, uid, owner, rowIndex, columnIndex); + this.iconObject = iconObject; + } +} +} diff --git a/src/as/com/threerings/flex/menuClasses/CommandMenuItemRenderer.as b/src/as/com/threerings/flex/menuClasses/CommandMenuItemRenderer.as new file mode 100644 index 00000000..490e81ee --- /dev/null +++ b/src/as/com/threerings/flex/menuClasses/CommandMenuItemRenderer.as @@ -0,0 +1,48 @@ +// +// $Id$ +// +// Nenya library - tools for developing networked games +// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/nenya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +package com.threerings.flex.menuClasses { + +import flash.display.DisplayObject; + +import mx.controls.menuClasses.MenuItemRenderer; + +public class CommandMenuItemRenderer extends MenuItemRenderer +{ + public function CommandMenuItemRenderer () + { + super(); + } + + override protected function commitProperties () :void + { + super.commitProperties(); + + if ((icon == null) && (listData is CommandListData)) { + icon = CommandListData(listData).iconObject; + if (icon != null) { + addChild(DisplayObject(icon)); + } + } + } +} +}