Apr 15 2009
Using uiMenu: Implementing “long press” contextual menu
The “long press” context menu is an alternative to the typical right-click context menu. In this example, we will allow end-users to bring up a contextual menu by “long pressing” (pressing the left-mouse button down on a spot and holding it down for a predefined time).
This example was implemented using uiMenu from the ActionScript 3.0 Aspire UI library.
Live demo:
- Pressing the mouse down anywhere on the dark area and holding it down, stationary, for half a second (500ms) will bring up a context menu.
- If the CTRL KEY check box is selected, pressing the mouse down anywhere on the dark area while holding down the CTRL-KEY will bring up the context menu (without waiting for 500ms).
- In this example, we have used 500ms for the delay – you can use another value in your own code, although 500ms is probably best for usability.
Here is the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | package { import com.ghostwire.ui.containers.*; import com.ghostwire.ui.controls.*; import com.ghostwire.ui.data.*; import com.ghostwire.ui.events.*; import com.ghostwire.ui.enums.*; import com.ghostwire.ui.managers.*; import flash.display.Sprite; import flash.display.DisplayObject; import flash.events.*; import flash.system.Capabilities; import flash.utils.Timer; public class ContextMenuDemo extends Sprite { // ** instances ** private var longPressTimer:Timer; private var popupMenu:uiMenu; private var menuModel:uiModel; private var ctrlKeyCheck:uiCheckBox; private var displayText:uiText; private var longPressDelay:int = 500; // ** delay of 500ms ** public function ContextMenuDemo() { addEventListener(Event.ADDED_TO_STAGE,init); } private function init(evt:Event):void { uiSkins.initialize("classic"); // ** using "classic" theme ** uiSkins.manager.addEventListener(Event.INIT,main); } private function main(evt:Event):void { // ** main application code ** // ** create a hotspot on the stage ** var hotspot:Sprite = new Sprite(); hotspot.graphics.beginFill(0,0.2); hotspot.graphics.drawRect(0,0,200,200); hotspot.graphics.endFill(); hotspot.x = 50; hotspot.y = 50; addChild(hotspot); hotspot.addEventListener(MouseEvent.MOUSE_DOWN,on_startTimer,false,0,true); hotspot.addEventListener(MouseEvent.MOUSE_MOVE,on_cancelTimer,false,0,true); hotspot.addEventListener(MouseEvent.MOUSE_UP,on_cancelTimer,false,0,true); // ** toggle CTRL key trigger ** ctrlKeyCheck = new uiCheckBox("CTRL KEY"); ctrlKeyCheck.move(50,250); addChild(ctrlKeyCheck); // ** display text for reporting menu choice ** displayText = new uiText(); addChild(displayText); // ** popup menu XML ** var menuXML:XML = <menu> <item label="View"> <item label="Large Icons" group="iconsize" /> <item label="Medium Icons" group="iconsize" /> <item label="Classic Icons" group="iconsize" checked="true" /> <item /> <item label="Auto Arrange" checked="false" /> <item label="Align to Grid" checked="true" /> </item> <item label="Sort By"> <item label="Name" /> <item label="Size" /> <item label="Type" /> <item label="Date Modified" /> </item> <item /> <item label="Refresh" /> <item /> <item label="Help" /> </menu> // ** menu model using the XML ** menuModel = new uiModel(menuXML); } private function showPopup():void { popupMenu = uiMenu.popup(menuModel,stage); popupMenu.addEventListener(uiMenuEvent.MENU_SELECT,on_menuSelect,false,0,true); } private function on_cancelTimer(evt:MouseEvent):void { if (longPressTimer) { displayText.text = "long press cancelled"; // ** cancel long press timer ** longPressTimer.removeEventListener(TimerEvent.TIMER,on_timer); longPressTimer.stop(); longPressTimer = null; } } private function on_startTimer(evt:MouseEvent):void { if (ctrlKeyCheck.selected && (evt.ctrlKey)) { showPopup(); } else { displayText.text = "pressing..."; // ** create a timer for detecting long press ** if (longPressTimer == null) { longPressTimer = new Timer(longPressDelay); } else { longPressTimer.reset(); } // ** start long press timer ** longPressTimer.addEventListener(TimerEvent.TIMER,on_timer,false,0,true); longPressTimer.start(); } } private function on_timer(evt:TimerEvent):void { displayText.text = "popup menu shown"; longPressTimer.removeEventListener(TimerEvent.TIMER,on_timer); longPressTimer.stop(); longPressTimer = null; showPopup(); } private function on_menuSelect(evt:uiMenuEvent):void { displayText.text = "Label: "+evt.item.label+" has been selected"; displayText.text += "\ngroup property value: "+evt.item.group; displayText.text += "\nchecked property value: "+evt.item.checked; } } } |
Notes:
- We start the timer when the mouse is pressed down on the hotspot, and cancel the timer if the mouse is moved or released.
50 51 52 | hotspot.addEventListener(MouseEvent.MOUSE_DOWN,on_startTimer,false,0,true); hotspot.addEventListener(MouseEvent.MOUSE_MOVE,on_cancelTimer,false,0,true); hotspot.addEventListener(MouseEvent.MOUSE_UP,on_cancelTimer,false,0,true); |
- If the CTRL KEY check box is selected, we want to show the popup menu immediately when the mouse is pressed down so the timer is not used:
108 109 110 111 112 113 114 115 116 | private function on_startTimer(evt:MouseEvent):void { if (ctrlKeyCheck.selected && (evt.ctrlKey)) { showPopup(); } else { ... |
- The static uiMenu.popup() method takes two parameters:
uiMenu.popup(model,context);
The “model” parameter is the uiModel object that will be used to populate the popup menu.
The “context” parameter can be any DisplayObject on the stage. The popup menu will be positioned below this “context” (or above if necessary). If this parameter is set to the stage (as is the case in this example), the current mouse position when the method is called will be used when deciding where to place the popup menu.
90 91 92 93 94 | private function showPopup():void { popupMenu = uiMenu.popup(menuModel,stage); popupMenu.addEventListener(uiMenuEvent.MENU_SELECT,on_menuSelect,false,0,true); } |
- The uiMenu.popup() method returns a reference to the uiMenu that is shown. The uiMenu dispatches the uiMenuEvent.MENU_SELECT event when the end-user selects a menu item.
141 142 143 144 145 146 | private function on_menuSelect(evt:uiMenuEvent):void { displayText.text = "Label: "+evt.item.label+" has been selected"; displayText.text += "\ngroup property value: "+evt.item.group; displayText.text += "\nchecked property value: "+evt.item.checked; } |
See also: uiMenu usage notes
Aspire UI Components
Aspire UI is a library of Actionscript 3.0 (AS3) classes for building flexible and lightweight UI elements in Adobe Flash applications. Key features include easy skinning using PNG image files, automatic tab focus ordering, CSS text styles, and layout management. This is a pure AS3 library with no dependency on the Flex framework. You may experiment with the various features by downloading a trial version at
http://ghostwire.com/aspireui/download/







