[GUI] idea regarding mac menubar issue

David Roundy droundy@jdj5.mit.edu
Tue, 6 May 2003 15:37:54 -0400


Hello GUI people! (I figure a greeting is in order as I'm new to this
list...)  I had an idea a few days ago, and am not sure if it's workable,
but figured I'd better mention it before I forget it.  I understand (from
browsing the archives) that it's perhaps a bit early to be debating the
intricacies of menu events (or callbacks or whatever) for CGA, but didn't
want to forget the idea...

The idea is for a way to deal with the fact that on the Mac there is only
one menubar, and the UI guidelines stipulate that the contents of that
menubar must remain fixed, with inappropriate menus/menu items being
disabled but not removed, while on most other systems each window (or most
windows) will have its own menu bar, containing only menus and menu items
relating to that window.  This is functionally quite different, and makes
it hard to use the same code for both platforms.

I'm a wxWindows user, and with wxWindows you have to deal with this issue
manually using #ifdefs to check if you're on the mac, and adjust your main
menubar to contain the extra menus and menu items needed by the other
windows.  Yuck.  I'm a big fan of wxWindows, but this is ugly.  The problem
is that there is no way to map the information coded in the menubar of a
wxGTK version of an app into an appropriatly behaving mac menubar.

My understanding of the problem
===============================

As a concrete example, in my bridge game (the only cross-platform GUI app
I've written), there are two main window types (not counting little ones
like the score menu, which have no menu bar under wxGTK, and are thus
irrelevant), the lobby window and possibly several table windows.

There are several classes of menu commands:

1) Always relevant, handled by the lobby: e.g. New Table, Quit,
Preferences.

On GTK these commands are in the lobby menubar.
On Mac these commands should always be available (i.e. active), but, the
command event always needs to be sent to the lobby regardless of whether it
is the active window.

2) Only relevant to a table: e.g.  Close Table, Claim Tricks, Show Score,
Show Last Trick.

On GTK these commands are in each table menubar.
On Mac these commands should always be visible, but should only be active
when the currently selected window is a table window.

3) Relevant to either window: e.g. Copy, Paste (since they have chat boxes
you could copy into).  I don't have any other commands in this category,
but if I supported sending beeps to other players in a chat room, that
would be relevant to either window type.

On GTK these commands are in both table and lobby menubars.
On Mac these commands are always available, and get sent to the active
window, be it lobby or table.

Note that I've been only talking about menu items (or menu commands),
leaving out menus.  That is because the contents of each menu will be
different depending on whether you are running under Mac or GTK.

My Idea
=======

At the beginning of the program (whenever the menubar gets created) the
program needs to list every menu command it wants to recognize, each of
which will have an appropriate parent menu together with some information
to help order the contents of the parent menu.  On the mac, this will be
used to create the menubar.  Since the menu contents can't change
(according to the UI guidelines--at least not under normal circumstances),
we have to register everything early, rather than as each window is created
having it register what menu commands it needs.

Then each window, when it is created, will mention which menu commands it
responds to, and which these commands are also appropriate when the window
is in the background.  On GTK (and most other platforms) this information
will then be used to create a menubar for that window.  On the Mac, this
information will be used to determine which menu items are active and which
are inactive.

Of course, there is also a lot of other work that would need to be done.
For example, each window needs to be able to dynamically change its menu
command preferences.  The Save option should be disabled, for example,
unless there have been changes made.  Or in my bridge game, the "Claim
Tricks" command should be disabled while bidding is going on.

So to summarize, the idea is that by giving each menu command some kind of
unique identifier and at the beginning of the code giving enough
information to allow it to assemble those menu commands either into one
global menu bar or into individual menu bars for each wndow, I think it
should be possible to write portable menu code that obeys the user
interface guidelines on both platforms (probably also all platforms, but I
only really have experience with two) without writing extensive special
cases.  Another benefit is that this framework might significantly simplify
dealing with menus on the Mac, since it will take care of
disabling/enabling menu items and menus as the active window is changed.

One final issue is it seems that windows should have (perhaps optional)
parents, in order for the menu events to get appropriately routed on the
mac.  It would seem that if a window with no menu is in front (such as my
score window, which just displays the score for a specific table), the menu
commands of its parent should be active, and should get routed to the
parent.  It seems that the easiest way to implement this would be if each
window had a parent, although one could also require that these windows
specifically mention whose menubar they want to be displayed (or risk all
but global menu options being disabled).
-- 
David Roundy
http://www.abridgegame.org