Fresco Implementing Menus Using the Fresco Intrinsics


Introduction
Background
MenuKit
Issues
Status

Introduction

The task was to design a MenuKit interface for Fresco and provide a native Fresco implementation.

One of main goals was to simplify the life of programmers who use the MenuKit. This is done by defining a logical menu structure that can be instantiated into a physical menu on demand. The physical menus observe the logical menu structure and adjust as necessary.

One other goal was to allow for an implementation that uses platform native menus.

Background

Fresco uses a standard object model, resolution-independence, graphical embedding, dynamically loadable kits...

Why not use native (Windows, Mac, Motif) menus? We do want to have implementations that use platform native menus. We also want a Fresco native menu kit so that menus can be embeded if desired.

If you want to write portable code you may want to use the Fresco MenuKit interface. Then MenuKit implementations could be provided that use native menu systems for all of the supported platforms.

If you want to embed a menu within a Fresco object, such as a Fresco builder, then you need a Fresco implementation of the MenuKit so that all of Frescos features are supported (for example arbitrary transformations).

MenuKit

The basic idea is to create a logical hierarchy of menu items and then ask one of the menu kits to create a menu bar or popup menu for the top menu item in the hierarchy. You can then change any menu items in the hierarchy whenever you want and the physical menus will be automatically updated. This is just an application of subject/view separation, menu items are subjects and physical menus are views.

Using a logical menu structure allows an implementation of the MenuKit to create physical menus on demand and purge them when they are not in use. This can save a significant amount of memory. It also allows stay-up menus to be implemented completely by a MenuKit. One other bonus is that the same menu item can create a menu bar, or a popup menu. Separators turn into the proper visual elements: flexible space for the menu bar and a inset line for popup menus.

Rather than have a MenuItem base interface and derived interfaces for each specialization, there is a single imprecise interface. The implementation has a MenuItem base class with derived classes for each specialization. This seemed to be the best approach in that it reduces the amount of code that deals with menu items and the number of interfaces that users of the MenuKit must learn.

Selection paths are used to keep the menu protocol simple and efficient. To make sure that a specific item is selected you just construct a path to reach it and pass the path down to each menu starting at the menu bar. Each menu should do nothing when it is on the path otherwise it should close down the rest of the path. To change the selection you just create a new path or modify the current one and then tell the menu system to make that the current selection path. Since the menu items must form a tree you can discover the path for any given menu item. The menu manager interface takes advantage of this fact and just requires that a menu item be specified, not the complete path.

Issues

Laying out vertical menus is interesting because there is a basic three column grid that is broken up with elements that span all columns. Separators are one example of this. The final solution was to put all of the grid oriented elements into a single grid that determines the widths of the columns. Then each row of the grid is placed individually into a vertical box and interspersed with the other elements like separators. Grid layout elements are useful in many other places as well. One example is to use a two by two grid to layout a view, horizontal scroll bar, vertical scroll bar, and filler.

Event management is always fun. The menu system can be activated by a keyboard mnemonic or accelerators can be used to activate menu functions. Thus keyboard events destined for a window (or its auxiliary windows) must be examined in order to activate the menu system. Once the menu system is activated events must be grabbed until it is deactivated. While the menu system is activated popup windows are appearing and disappearing and events for these windows should be processed by the menu system as well. The solution was to add a filter to the display that watches for mnemonics and accelerators and activates the menu system as needed.

Status

The MenuKit interface and native Fresco implementation are in the current snapshot.
Comments or questions? Contact Stephen Juth ( juth@caip.rutgers.edu )

Last updated on Tue Jan 28 14:38:42 EST 1997.