bill@allegra.tempo.nj.att.com (Bill Schell) (10/04/90)
I'm having a small problem getting the menus for a view object I'm writing to look the way I want. My view is a subclass of aptv. On the front-most menu card, I'm getting "Save", "Switch File" and "Delete Window" menu selections from a parent view. I would like to move "Save" and "Switch File" to the "File" card and "Delete Window" to the "Window" card (the front menu card is getting too crowded). I would also like to remove selections like "Preview" from the "File" card as they don't make sense in my context. I'm using the "bind" interface to menus and I don't see any clear way to do it. I'm sure someone else out there has had this problem? Thanks very much, Bill Schell AT&T Bell Labs, Murray Hill, NJ bill@allegra.att.com [An Andrew ToolKit view (a raster image) was included here, but could not be displayed.]
nsb@THUMPER.BELLCORE.COM (Nathaniel Borenstein) (10/08/90)
I would think that you could do this using menulist_ChainAfterML to chain your menus together in the right order. You create your own bind structure entries with NULL values as appropriate to override the ones you're getting automatically. For an example of this -- albeit one that is embedded in a lot of other stuff -- look at how the sendmessage window gets rid of some of the extra style menus. The source is in atkams/messages/lib/sendaux.c, around line 541 you can see where things like "Enumerate" get overridden. Hope that helps. Good luck. -- Nathaniel
gk5g+@andrew.cmu.edu (Gary Keim) (10/11/90)
Excerpts from misc: 3-Oct-90 moving menu items Bill Schell@allegra.temp (743+1) > My view is a subclass of aptv. On the front-most menu card, I'm getting > "Save", "Switch File" and "Delete Window" menu selections from a parent > view. I would like to move "Save" and "Switch File" to the "File" card > and "Delete Window" to the "Window" card (the front menu card is getting > too crowded). Did you figure this out yet? There are two steps: (1) override those items that you want removed or moved-to-other-cards, (2) create bind entries for those items to be moved-to-other-cards. The First Part This is what Nathaniel was referring to in his message. Just create bind entries for those items to be moved or removed that have the same, exact menu-string as the bind entries that you want to override. Provide NULL values for the other bind entry fields. The Second Part To create bind entries for those items that you want to move to other cards, you have to provide a routine that will be called when that item is chosen. How do you do that when the item you're overriding is in another module. Well, first you have to load the class that you're overriding because to get a handle on the the original call-back routine you must make a proctable lookup. Let's have an example: You want to move 'Save' to the 'File' menu card. Let's call your aptv override foo. In foo__InitializeClass you make a call to class_Load("frame"); because the 'Save' menu item comes from the frame class. Here is the bind entry for 'Save' as it looks in andrew/atk/frame/framecmd.c: {"frame-save-file", "\030\023", 0, "Save~20", 0, frame_BufferMenus, (void (*)()) frame_SaveFile, "Saves buffer into its current file."}, You create a bind entry like this: {"foo-save-file", "\030\023", 0, "File, Save~20", 0, frame_BufferMenus , (void (*)()) foo_SaveFile, "Saves buffer into its current file."}, The only missing piece is foo_SaveFile. Where does that come from? Well, this is why you load frame in foo_InitializeClass. You must do a lookup of the proctable entry of the name frame-save-file. Here's how: static void foo_SaveFile(); boolean foo__InitializeClass( ClassID ) struct classheader *ClassID; { struct proctable_Entry *saveProcEnt = NULL; class_Load("frame"); if(saveProcEnt = proctable_Lookup("frame-save-file")) { foo_SaveFile = proctable_GetFunction(saveProcEnt); } else { printf("foo: couldn't lookup proctable entry frame-save-file.\n"); return(FALSE); } return(TRUE); } How does that sound? If you have any problems just send e-mail. Gary Keim ATK Group
gk5g+@andrew.cmu.edu (Gary Keim) (10/11/90)
There is a small problem with my solution to the problem of moving menu items to different cards. I directed that you get a handle on the original call-back routine via a proctable lookup, and then use that routine in the overriding bind entry. This is incorrect because then that routine (foo_SaveFile, really frame_SaveFile) will be called with (struct foo *) as the first argument when it expects a (struct frame *). So you must define your own routine to be used in the overriding bind entry, and in that routine you must get your frame pointer from self. Then make the original call-back that you looked-up in foo_InitializeClass, with the proper argument. So, here is the real code: static void frame_SaveFile(), foo_SaveFile(); static boolean FindMyFrame(); #define Parent(v) ((v)->header.view.parent) static void foo_SaveFile( self, rock ) struct foo *self; long rock; { struct frame *frame = NULL; if(frame = frame_Enumerate(FindMyFrame,foo_GetIM(self))) frame_SaveFile(frame,rock); else printf("foo: could not find frame.\n"); } static boolean FindMyFrame( frame, im ) struct frame *frame; long im; { return((struct view*) im == Parent(frame)); } static struct bind_Description fooBindings[]={ {"foo-save-file", "\030\023", 0, "File, Save~20", 0, frame_BufferMenus , (void (*)()) foo_SaveFile, "Saves buffer into its current file."}, } boolean foo__InitializeClass( ClassID ) struct classheader *ClassID; { struct proctable_Entry *saveProcEnt = NULL; class_Load("frame"); if(saveProcEnt = proctable_Lookup("frame-save-file")) { frame_SaveFile = proctable_GetFunction(saveProcEnt); } else { printf("foo: couldn't lookup proctable entry frame-save-file.\n"); return(FALSE); } return(TRUE); } Have Fun. Gary Keim ATK Group