Creating a pop-up menu using simple menu protocol
A pop-up menu is independent of a menu bar. It is popped up in response to a mouse button-3 press, or release, depending on the platform. In order for the application to be notified of the mouse button event, an event handler must be added to the appropriate widget.
Tip:
Some platforms cause pop-up menus to appear on a mouse up event, and some on a mouse down event. The correct event for the platform must be used, or unpredictable behavior might result. To ensure that the correct event is used, specify ButtonMenuMask as the event mask when adding the event handler.
The open method of the class below opens a window containing a label widget. When a menu is requested over the label, a pop-up menu (shown at right) appears. The pop-up menu is created using a simple menu creation method. The menu is popped up by managing the row-column widget that represents the menu. It is automatically unmanaged when the menu is canceled by the user.
"This class illustrates the use of pop-up menus. Note that
the pop-up menu is kept in an instance variable so that it
can be referenced by the button event handler."
Object subclass: #PopupMenuExample
instanceVariableNames: 'menu '
classVariableNames: ''
poolDictionaries: 'CwConstants '
open
"Open the pop-up menu example."
| shell label |
shell := CwTopLevelShell
createApplicationShell: 'shell'
argBlock: [:w | w title: 'Popup Menu Example'].
label:= shell
createLabel: 'main'
argBlock: [:w | w labelString:
'Push the menu button over this message'].
label
"An event handler is added to the label widget. ButtonMenuMask label
indicates that the event handler should be activate when the menu
button on the mouse is pressed or released."
addEventHandler: ButtonMenuMask
receiver: self
selector: #button:clientData:event:
clientData: nil.
label manageChild.
"The pop-up menu is created. Note that the menu is not managed at this
stage. It will be managed when the event handler pops the menu up."
menu := label
createSimplePopupMenu: 'menu'
argBlock: [:w |
w
buttons: #('Add' 'Change' 'Delete')].
"Three menu items are specified. A callback is registered,
to be run when an item is selected."
menu
addCallback: XmNsimpleCallback
receiver: self
selector: #menuItem:clientData:callData:
clientData: nil.
"When the shell is realized, the shell and the label widgets
appear, but the menu does not, because it is not managed."
shell realizeWidget
Here is the activate callback used in the code:
button: widget clientData: clientData event: event
"Handle a menu button press event. The call data event structure is
checked for a mouse-button press. If it was not the menu button,
the menu is not popped up."
event button = 3 ifFalse: ^self].
"Position and pop up the menu by managing it."
menu
"The menu is positioned using the event object. It is popped up by
managing it."
menuPosition: event;
manageChild
Here is the Menu Button event handler used in the code:
menuItem: widget clientData: clientData callData: callData
"Display the index of the selected menu item in the transcript."
Transcript cr; show: 'Menu item ', clientData printString,
' was selected from the pop-up menu.'
Last modified date: 04/20/2020