Programmer's Reference

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 '


Figure SP007125 not displayed.

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
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
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.'


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]