On 29 Nov 2006, at 12:19, Christopher Armstrong wrote:

I have been looking at the code in NSMenu, and at the moment NSMenu is
reponsible for creating an NSMenuView and the NSPanel object that it is
housed in. As a result, this code makes the assumption that a menu is
always in a separate window, and that there is only one displayed
representation of a menu. It also assumes that the menu representation
is drawn in the same process with an NSMenuView object.

I have been assuming that we could support per-window menus by dynamically moving the menu view from window to window as the menu in each window needs to be drawn (since this is what is already done for transient menus), but having multiple menu views may be better.

In order to support different paridigms, such as the (addmittedly broken
but popular) one-menu-per-main-window on Win32/Gtk/Qt or Etoile's menu
server, I believe that programmers currently need to modify NSMenu
through means such as subclassing or overriding using categories. These
methods are prone to breakage as they often depend on internal
implementations.
I am proposing that we separate the visual representation of a menu
(which includes the window it is drawn in (NSMenuPanel), the view
(NSMenuView) and the item cells (NSMenuItemCell)) from the abstract
representation of a menu (NSMenu). I am suggesting we do this allowing
people to supply an object which will receive menu update notifications
(such as items being added, removed, etc.) and be responsible for
coordinating the drawing of the menus and handling events. It should be
different from the current use of the "NSMenuRepresentation" which
assumes that the menu representation is a subclass of NSView. This
"object" should implement some sort of protocol for communication
between itself and NSMenu, the protocol supplying methods which inform
the object of changes in the NSMenu, something like the interaction
between a Model and Controller in MVC.

I think the current separation, using notifications, is a pretty good start and could be extended if necessary ... but I'm not sure that it *is* necessary to go much further ... the assumption that the menu representation is a subclass of NSView appears to be OK for doing per-window menus, and in the etoile case of having a completely separate process handling the menu, it seems to me that the best solution is to replace the entire NSMenu with a proxy to that remote process.

For example, you may wish to place a menu on each of your document
windows, but this breaks the current assumption that there is only one
visual representation (view) of the menu.

Not necessarily ... the current implementation already uses the same view in two different windows (for transient menu support) ... but it's probably better to have multiple views (in the current implementation the rectangle the view is drawn in is the same in both windows, but that would not generally be the case). I would suggest carefully examining the option of extending the single-view-moved- between windows approach before deciding that multiple views are really necessary/best.

In this case, the intermediary
object would sit between NSMenu and the associated set of NSMenuViews
which reside in each document window. It would be responsible for
receiving update messages from the NSMenu object and forwarding them to
each of the NSMenuViews. These views in turn would somehow notify the
NSMenu when they are clicked/selected.

Alternatively, the menu can send a notification, and all views associated with it could watch for that notification and handle it. The notification mechanism is already used to inform menu representations of changes to the items in a menu, and implicitly has the feature that multiple views can observe the same notification. The notification center is acting as the intermediary object you suggest. The use of notifications has the additional advantage that it allows other objects outside the menu/representation mechanism to track the operation of menus. For having a menu in the current process with a representation in a separate process a proxy to forward notifications would be simple.

I think this may be a reasonably opportune time to play with the current
design, as Apple have deprecated the usage of NSMenuView and
NSMenuItemCell along with the -menuRepresentation property of NSMenu
(according to the Cocoa docs). Before I possibly attempted to implement
such a solution, I wanted to discuss it with the list as I fear this
solution may be too complex where simpler solutions exist, and I know it
has implications for some other areas in the AppKit (especially popup
buttons). I don't wish to engage anyone in debate about the merits or
disadvantages of stacked vs horizontal menus; I think this has been
discussed enough on these mailing lists before. I believe we should be
pragmatic and offer people a choice.

Hopefully the stacked vs horizontal thing is a dead issue now that GNUstep supports both.

I would like to see the same for the standalone-menu/menu-per- document-window issue, with the addition of per-menu windows as an NSInterfaceStyle option for the ms-windows interface style.

IMO the best way to proceed would be to implement the per-window menus using the minimum necessary changes to current code so as not to break anything. We have a long history of rewrites leaving menu support messed up for a long time as bugs are ironed out ... keeping menus working properly is tricky ... so minimising changes is a good thing. Implementing per-menu windows would provide the experience of what's needed and allow for better understanding and for progress to be made in the separation you talk about. It would also mean that you can see a concrete result (new menu style) earlier and have usable/ testable code throughout an incremental development process rather than doing one big coding change and then having to fix lots of bugs.

In conclusion, I like the idea of improving menu/representation separation, I think the approach should be to implement per-window menus while keeping all existing code working as a route to separation/cleanup, rather than attempting separation/cleanup on a theoretical basis and then trying to use the new setup to implement per-window menus.



_______________________________________________
Gnustep-dev mailing list
Gnustep-dev@gnu.org
http://lists.gnu.org/mailman/listinfo/gnustep-dev

Reply via email to