Custom Right Click or Context Menu in Flex/Flash AS3

Posted: May 31st, 2009 | Author: danny | Filed under: Flex | 9 Comments »

UPDATE: Please see comments for a bug, and a work around.

I've created a small little library for creating a right click menu in flash:

This works not only on the top level components, but also on nested components. In the example you can right click on each button and see a custom menu.

Demo:

Some Links:
AS3 Right Click Context Menu Right, Click To View Source

Context Menu Source In Zip File

MIT Licensed

package
{
	import flash.events.ContextMenuEvent;
	import flash.events.MouseEvent;
	import flash.ui.ContextMenuItem;
 
	import mx.core.Application;
	import mx.core.UIComponent;
 
	public class RightClickMenu
	{
		public var MenuContents:Array = new Array ();
 
		public  function RightClickMenu(){}
 
		public function AddItem (name:String, func:Function):void
		{
			MenuContents.push({Name:name, Func:func});
		}
 
		public function AssignRightClick (uiComponent:UIComponent):void
		{
			uiComponent.addEventListener(MouseEvent.MOUSE_OVER, genEnableMenu (uiComponent));
			uiComponent.addEventListener(MouseEvent.MOUSE_MOVE, disableMenu);
		}
 
		/* Assignment */
		private function ResetContextMenu (event:MouseEvent):void
		{	//remove menu
			Application.application.contextMenu.customItems = new Array ();
			//remove this function
			Application.application.removeEventListener(MouseEvent.MOUSE_MOVE, ResetContextMenu);
		}
 
		private function disableMenu(event:MouseEvent):void
		{
			//Stop the mouse move event from propagating to the application level, where we remove the menu
			event.stopImmediatePropagation();
		}
 
		private function genEnableMenu (uiComponent:UIComponent):Function
		{
			return function (event:MouseEvent):void
			{
				//add event listener to remove the menu on mouse move
				Application.application.addEventListener(MouseEvent.MOUSE_MOVE, ResetContextMenu);			
 
				//hide current menu
				Application.application.contextMenu.hideBuiltInItems();
 
				//remove menu (ifyou right click and then move, this may not be killed.
				Application.application.contextMenu.customItems = new Array ();				
 
				//create new menu
				for (var i:Number in MenuContents)
				{
					var menuItem:ContextMenuItem = new ContextMenuItem(MenuContents[i].Name);
					menuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, MenuContents[i].Func);
					Application.application.contextMenu.customItems.push(menuItem);
				}
			}
		}
 
		private function genClickCall (func:Function):Function
		{
			return function (event:ContextMenuEvent):void
			{
				func()
				ResetContextMenu(null);
			}
 
		}
 
	}
}

To use the class 1) Create an instance of it, 2) Populate it, 3) bind it to the component.

		<![CDATA[
			import mx.controls.Alert;
 
			private function appComplete ():void
			{
				var menu1:RightClickMenu = new RightClickMenu ();
				menu1.AddItem("B1", function ():void{Alert.show("B1");});
				menu1.AddItem("B1-A", function ():void{Alert.show("B1-A");});
				menu1.AssignRightClick(b1);
 
				var menu2:RightClickMenu = new RightClickMenu ();
				menu2.AddItem("B2", function ():void{Alert.show("B2");});
				menu2.AssignRightClick(b2);
 
				var menu3:RightClickMenu = new RightClickMenu ();
				menu3.AddItem("B3", function ():void{Alert.show("B3");});
				menu3.AssignRightClick(b3);		
 
			}
		]]>