I was working on a custom menu component uses Menu. Turns out that Menu doesnt inherintly understand the stage height of the application. What I ended up doing was creating CustomMenu which extends Menu and adds in height bounds for the root and any sub menu.
package com.lejnieks.poc.ui.components.menu { import flash.display.DisplayObject; import flash.display.DisplayObjectContainer; import flash.geom.Point; import mx.controls.Menu; import mx.controls.listClasses.IListItemRenderer; import mx.controls.menuClasses.IMenuItemRenderer; import mx.core.Application; import mx.core.ScrollPolicy; import mx.core.mx_internal; import mx.managers.PopUpManager; use namespace mx_internal; public class CustomMenu extends Menu { private var xpos:Object = 0; private var ypos:Object = 0; private const END_OF_SCREEN_MENU_PADDING:Number = 5; public function CustomMenu() { super(); } public static function createMenu(parent:DisplayObjectContainer, mdp:Object, showRoot:Boolean=true):CustomMenu { var menu:CustomMenu = new CustomMenu(); menu.tabEnabled = false; menu.owner = DisplayObjectContainer(Application.application); menu.showRoot = showRoot; popUpMenu(menu, parent, mdp); return menu; } override mx_internal function openSubMenu(row:IListItemRenderer):void { supposedToLoseFocus = true; var r:Menu = getRootMenu(); var menu:Menu; if (!IMenuItemRenderer(row).menu) { menu = new TIPSMenu(); 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 (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); } else { menu = IMenuItemRenderer(row).menu; } super.openSubMenu(row); } override public function show(x:Object=null, y:Object=null):void { this.xpos = x; this.ypos = y; var absoluteHeightOfSubMenu:Number = this.height + this.ypos; var appHeight:Number = Application.application.height; if( absoluteHeightOfSubMenu > appHeight ) { this.ypos = Number(this.ypos) - (absoluteHeightOfSubMenu - appHeight) - END_OF_SCREEN_MENU_PADDING; } super.show(x, this.ypos); } } }
Im overriding show() so that when the menu displays, if the menus height + its absolute position is greater than the application height, then it will move the menus y position up by the difference of the menu height + menu y position, and then I add in just a bit of extra padding so the menu doesn’t butt up against the bottom of the application
best best best!!!