Book HomeMastering Perl/TkSearch this book

Chapter 12. The Menu System

Contents:

Menu System Components
Menubars and Pulldown Menus
The Win32 System Menu Item
Classical Menubars
Popup Menus
Option Menus
Menu Virtual Events
Pie Menus

This chapter describes the menu system: its components, how to use them, and how they behave in a Unix and Win32 environment. Of primary interest are menubars and conventional linear menus (pulldown, option, and popup), although at chapter's end, we do visit a new kind of menu, the pie menu.

Typically, a menu contains commands that aren't used frequently, such as configuration options, File Open, File Close, Help, and so on. Commands that are used frequently may not be appropriate for menus and should be placed directly in the window to provide easier access for the user. Some examples of how menus might be used are for:

You can build each of these different types of menus with the basic Menu widget.

12.1. Menu System Components

First, let's take a quick tour of the components of a menu.

12.1.1. Menus and Menu Items

The foundation of the menu system is the Menu widget, a rectangular window that, as a result of some event, appears out of the ether and displays one or more columns of menu items. The event that causes the menu to appear is often the press of a Menubutton or keyboard character, but could just as well be a mouseclick or even a callback. The action of making a menu appear is called posting; making a menu disappear is called unposting. There are six flavors of menu item, shown in Figure 12-1: cascade, checkbutton, command, radiobutton, separator, and tearoff.

Figure 12-1

Figure 12-1. Important components of the menu system

With the exception of a separator, clicking a menu item initiates item-specific behavior, such as executing a callback, posting a menu, or perhaps setting a Perl variable. We'll examine the various menu items in detail shortly. Briefly:

12.1.2. Menu Indexes

Many Menu methods expect a menu item index that specifies which menu item to operate upon. The following are valid menu indexes:

12.1.3. Manipulating Menus

Configure a Menu widget using the configure and cget methods, just like any other widget. If you're unfamiliar with these methods, see Chapter 13, "Miscellaneous Perl/Tk Methods".

Here are some other Menu methods:

$menu->clone(parent_menu, clone_type)
Clones a Menu, but you never call it yourself. Tk makes clones of menubar and tearoff Menus. Enter perldoc Tk::Menu for details.

$menu->post(x, y)
Posts a Menu at root window coordinates (x, y). This method is most often superseded by the Post or Popup methods.

$menu->unpost
Unmaps a Menu so it's no longer displayed.

12.1.4. Manipulating Menu Items

Configuring menu items is analogous to configuring widgets, except that we want to limit our activities to one menu item; that's what the entryconfigure and entrycget methods are for. The format is:

$menu->entryconfigure(index, -option => value);

The index, which can be in any of the previously described forms, specifies which menu item to configure. To fetch the value of a particular menu item option, use:

$menu->entrycget(index, -option);

Of course, there are other things you can do with menu items:

$menu->activate(index)
Makes the menu item at index the sole active menu item.

$menu->delete(index [, index_end])
Deletes menu item index or the range index through index_end

$menu->index(index)
Returns the integer ordinal of the menu item at index, where index can be any of the previously described forms

$menu->insert(index, type [, options])
Inserts a new menu item of type before index, where type may be cascade, checkbutton, command, radiobutton, or separator

$menu->invoke(index)
Executes the callback associated with menu item index

$menu->postcascade(index)
Posts the menu associated with the cascade menu item index

$menu->type(index)
Returns a string indicating the type of menu item at index

$menu->yposition(index)
Returns the y coordinate of the top-left pixel of the menu item at index

12.1.5. Menubars

Most nontrivial applications have menubars arrayed across the tops of their MainWindows (or any Toplevels for that matter). Arranged within a menubar is a series of menubuttons, which, when pressed, post menus. Unfortunately, these days the term menubutton is somewhat of a misnomer, because in modern Tks, the menubutton is not an actual Menubutton widget but a cascade menu item. This came about because of menu system support for multiple operating systems.

Prior to Perl/Tk Version 8, menubars were Frames filled with Menubutton widgets, and programmers were responsible for managing the geometry and appearance of the entire apparatus. Perl/Tk Versions 8 and above support a native look and feel for Unix and Win32,[24] so to keep menubar management simple and consistent from the user and application developer points of view, a new menubar management scheme was devised. The basic idea is that the menubar is just a standard Menu widget associated with a MainWindow or Toplevel widget, and cascade menu items fill the role of Menubuttons. In fact, these statements created the menubar portion of Figure 12-1:

[24] Tcl/Tk also supports MacOS Classic. We'll mention menubar support code for this operating system even though it's not currently supported by Perl/Tk. But Apple's next generation operating system, Mac OS X, is BSD Unix-based, so it's possible to run Perl/Tk with a Unix look and feel on a Mac today. Work is in progress to convert the Tcl/Tk widgets to native Aqua, so we may see Perl/Tk with a Mac OS X look in the future.

$mw->configure(-menu => my $menubar = $mw->Menu);

my $file = $menubar->cascade(-label => '~File');
my $edit = $menubar->cascade(-label => '~Edit');
my $help = $menubar->cascade(-label => '~Help');

To keep things simple, we'll call menubar buttons that post menus "menubuttons," whether they're real Menubuttons or just cascade menu items. Menubutton widgets are discussed in a later section.

The menu system is also aware of special operating system-dependent menubuttons, which is why the Help menubutton in Figure 12-1 is right justified (a custom in the Unix world). Under Mac OS, which always has a Help menubutton at the top of the display, Help menu items are appended to the existing Help items. Similarly, Apple menu items are prepended to the existing Apple menu items. Later on, we'll see how to augment the System menubutton on Win32 systems.

In summary, Tk 8 menubars have these benefits over the classical Frame/Menubutton approach:

Figure 12-2 shows how the code that produced Figure 12-1 is rendered on a Win32 machine. In particular, note how the Help menubutton is not treated specially and not right justified.

Figure 12-2

Figure 12-2. Compare this picture produced on Win32 with Figure 12-1, produced on Unix

12.1.6. Menu Options

As with any widget, there are options that affect how the Menu looks and behaves. The following is a list of the options available for the Menu widget:

-activebackground => color
Sets the background color behind the active menu item.

-activeborderwidth => amount
Sets the edge width of the active menu item's border.

-activeforeground => color
Sets the text color of the active menu item.

-background => color
Sets the background color of the entire menu.

-borderwidth => amount
Sets the width of the menu's edge.

-cursor => cursorname
Sets the cursor displayed when the mouse cursor is over the menu.

-disabledforeground => color
Sets the text color of any disabled menu items.

-font => font
Sets the font of the menu text.

-foreground => color
Sets the color of the text in the menu.

-menuitems => list
Defines a list of items to create in the menu.

-postcommand => callback
Sets the callback that is invoked before the menu is posted to the screen.

-relief => 'flat' | 'groove' | 'raised' | 'ridge' | 'sunken'
Sets the relief of the menu's edges.

-selectcolor => color
Sets the color of the selection box in checkbutton or radiobutton items.

-takefocus => 0 | 1| undef
Controls the ability to use the keyboard to traverse the menu.

-tearoff => 0 | 1
Determines whether or not the menu will contain the tearoff item as the first item.

-tearoffcommand => callback | 1
Invokes the callback when a Menu is torn off. The callback is passed references to the Menu and new Toplevel widgets.

-title => string
Title of the torn-off Toplevel.



Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.