
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

David Roundy wrote:
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.
This sounds as if it might boil down to only allowing that which is
allowed on all platforms, which is too restrictive. While there may be
cases where such a facility might be practical, it would need to be an
alternative to a lower-level API, and not a replacement for it.
I suspect that this sort of issue really is best dealt with by having
platform-specific code.
--
Glynn Clements

Glynn Clements wrote:
David Roundy wrote:
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.
This sounds as if it might boil down to only allowing that which is allowed on all platforms, which is too restrictive. While there may be cases where such a facility might be practical, it would need to be an alternative to a lower-level API, and not a replacement for it.
What we have to discuss on this mailing list is the lowest level that works on all platforms. The lowest-level API that works on all platforms _will_ be a little restrictive. Nobody says there won't be platform-specific lower-level APIs, but that's not the point of this discussion. Allowing only what is "allowed" on all platforms is simple: define one menu bar for the application, and that's it. Very limiting. But that's not what David was proposing. We're talking about an abstraction here that tries to represent the logical structure of the menus and generate the appropriate platform-specific layout automatically. Very ambitious, it might or might not work. If it doesn't work out, then we will probably have to specify platform-specific menu bar layouts; but still, we have to do so at program initialization time, and we'll have to have some scheme for handling menu commands (as I said, simple callbacks attached to menu items don't do the trick). If we're unable to find any common abstraction for the menu bar issue that works for "normal" applications, then the CGA will be "incomplete" --- either it won't be cross-platform or the look&feel on some platforms will be just wrong... unless you write platform-specific code. Nobody has ever doubted that platform-specific code should be allowed; but please don't discount this scheme yet because it doesn't support some kinds of menu layouts that are not possible on all platforms, and perhaps not common on any platform.
I suspect that this sort of issue really is best dealt with by having platform-specific code.
Many X apps have document windows that all have the same menu bar, plus dialog windows that don't have any menu bar at all. At least this common situation can definitely be mapped to a common abstraction; at most we'd have to provide platform-specific layouts (i.e. where does the Preferences command go?), but no platform-specific code. We should think about how this can be done for more complex situations (e.g. more than one document type, non-document windows etc.). Cheers, Wolfgang

On Tue, 6 May 2003 21:59:59 +0100
Glynn Clements
This sounds as if it might boil down to only allowing that which is allowed on all platforms, which is too restrictive.
Why? I think, instead, that there needs to be a core, as restricted as it has to, that really works (in the sense that it respects the specification) on all platforms, (without emulation of features, of course). This will be the expected way for a programmer to create simple GUIs for haskell programs. These GUIs will be simple indeed, but they will surely feature menu bars, dialog boxes, text widgets and file open/save dialogs, wich is sufficient for many applications. The CGA should also provide simple means to create extensions wich work on a subset of the supported platforms. For example, xaw has no panel, while windows, gtk and kde (and macosx?) support applications in the panel or systray or whatever they call them. Windows allows for more than one menubar ecc. So if a programmer is going to work on a subset of the supported library, he will use the allowed extensions, like "more menubars". I think that this is the goal of the CGA, but since you seem to think differently, it's time to ask ourselves what are the goals, and to write them down, (BTW, the "mission statement" speaks about an intersection of features). V. -- Fedeli alla linea, anche quando non c'è Quando l'imperatore è malato, quando muore,o è dubbioso, o è perplesso. Fedeli alla linea la linea non c'è. [CCCP]

David Roundy wrote:
Hello GUI people! (I figure a greeting is in order as I'm new to this list...)
Welcome!
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...
We probably shouldn't decide anything yet, but tossing around a few ideas can't hurt...
There are several classes of menu commands:
1) Always relevant, handled by the lobby: e.g. New Table, Quit, Preferences. [...]
2) Only relevant to a table: e.g. Close Table, Claim Tricks, Show Score, Show Last Trick. [...]
3) Relevant to either window: e.g. Copy, Paste (since they have chat boxes you could copy into).
Copy and Paste (and a few other commands, mostly from the "Edit" menu) are relevant whenever a widget that supports copy & paste is in focus; this is even the case when an application-modal dialog is active. An application-modal dialog disables all menu commands except copy, paste & co. In most applications (perhaps not in your example), there is also a fourth class: 4) Relevant to the entire application, even if there is no open window at all (this is a situation that's not even possible on other platforms). Examples include "New", "Open" and "About..". All MacOS-specific toolkits and OO frameworks handle menu commands about like this: A "menu command" event is first passed to the widget that has the keyboard focus; If that widget doesn't handle the menu command, it is passed on to the widget's container, and so on. If the window doesn't handle it, it is usually passed to the "application object"; if the application has multi-window documents, it might be passed to a "document controller" object before that. So the "Copy" and "Paste" commands would be handled by a text entry widget; the "Close" command would be handled by the window; the "Save" and "Save As" commands would be handled by the window or by the document controller; and the "New", "Open", "About" and "Preferences" commands would be handled by the application object. Can such a scheme be adapted for cross-platform use? I doubt that simple callbacks attached to the menu items would do the trick for MacOS style menu bars.
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. [...]
Sounds nice... if it can be made to work. It's not trivial to come up with a scheme for this "automatic menu bar composition"; but if it worked that would be great, as I don't like special cases either. That "information to help order the contents" should probably be predefined in the CGA backend for standard commands; so that if I say "I want a preferences command", it would automatically be in the right place; if I say, I want a "Do Some Other Stuff" command, I would have to say where it has to go (and it's unlikely that different platforms' standards on where to put those extra commands differ too much).
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).
Perhaps ... but commands that are specific to a certain window _should not_ be enabled when another window is in the foreground, even if that other window handles no commands of it's own. In some cases, both windows may belong to the same logical group of windows --- for example, both windows might belong to the same "document" or to the same "game" --- in that case, commands that apply to the "document" in general should remain enabled, but not commands that relate specifically to the main document window. There might be cases where it's more confusing to the user to enable inappropriate commands than to disable some commands that _could_ be enabled. Anyway, I wouldn't call this a "parent window"; so far, I know of one case where we will most definitely have the notion of a parent window, and that case is window-modal dialogs. However, a window-modal dialog won't use it's parent window's menu bar; rather, it would disable all but the application-wide commands (About, New, Open,...). So the name "parent window" is already taken by something with different semantics... Cheers, Wolfgang

On Tue, May 06, 2003 at 11:54:59PM +0200, Wolfgang Thaller wrote:
Sounds nice... if it can be made to work. It's not trivial to come up with a scheme for this "automatic menu bar composition"; but if it worked that would be great, as I don't like special cases either.
I agree, which is why I didn't want to go into too much detail (which would obscure the main idea). My current idea (for the "normal" cases) is something like this: Each menu command would specify its parent menu name and an ordering index. When a menubar is composed of a set of commands, it gets all the menus that are needed, and then the commands are placed in these menus according to the order of their indices. This method will only work if the relative ordering of two commands is the same in all cases, which seems reasonable to me, but may be considered too limiting.
That "information to help order the contents" should probably be predefined in the CGA backend for standard commands; so that if I say "I want a preferences command", it would automatically be in the right place; if I say, I want a "Do Some Other Stuff" command, I would have to say where it has to go (and it's unlikely that different platforms' standards on where to put those extra commands differ too much).
Absolutely, I think there should be the ability to deal with special cases, and some standard special cases (e.g. Preferences) should be predefined.
Perhaps ... but commands that are specific to a certain window _should not_ be enabled when another window is in the foreground, even if that other window handles no commands of it's own. In some cases, both windows may belong to the same logical group of windows --- for example, both windows might belong to the same "document" or to the same "game" --- in that case, commands that apply to the "document" in general should remain enabled, but not commands that relate specifically to the main document window. There might be cases where it's more confusing to the user to enable inappropriate commands than to disable some commands that _could_ be enabled.
Anyway, I wouldn't call this a "parent window"; so far, I know of one case where we will most definitely have the notion of a parent window, and that case is window-modal dialogs. However, a window-modal dialog won't use it's parent window's menu bar; rather, it would disable all but the application-wide commands (About, New, Open,...). So the name "parent window" is already taken by something with different semantics...
Good points. I am convinced that the idea of using the window-parent (if it exists) to inherit menu-bars was ill-conceived. -- David Roundy http://www.abridgegame.org
participants (4)
-
David Roundy
-
Glynn Clements
-
Vincenzo Ciancia
-
Wolfgang Thaller