[comp.sys.next] example menu code wanted

pbiron@weber.ucsd.edu (Paul Biron) (09/30/90)

Hi all,

I'm having a little trouble coding something, and need some
help.

Here's the situation:  I'm trying to add menu cells to a submenu
(of a submenu) on the fly.  From reading the Spec Sheets I can't
figure out how to do it.  The kind of thing I'm trying to do
is like the "Activate" menu in so many apps that are out there.

e.g.

------------
| Info     |
------------
| File    >|
------------  -----------------
| Submenu >|  | Add          a|
------------  -----------------
| Hide    h|  | Remove       r|
------------  -----------------
| Quit    q|  | Sub-Sub menu >|
------------  -----------------

and every time the user choses the "Add" cell, I do a little
processing and add another cell to "Sub-Sub menu" (and "Remove"
should be able to remove one such cell).

Could some kind soul please send me some example code which does
this? (Note, I can't get NeXT-mail at the address below).

Thanx,

Paul Biron      pbiron@ucsd.edu        (619) 534-5758
Central University Library, Mail Code C-075-R
Social Sciences DataBase Project
University of California, San Diego, La Jolla, Ca. 92093

wiml@milton.u.washington.edu (William Lewis) (10/02/90)

In article <3010@network.ucsd.edu> pbiron@weber.ucsd.edu (Paul Biron) writes:
>Here's the situation:  I'm trying to add menu cells to a submenu
>(of a submenu) on the fly.  From reading the Spec Sheets I can't
>figure out how to do it.  The kind of thing I'm trying to do
>is like the "Activate" menu in so many apps that are out there.
    ...
>and every time the user choses the "Add" cell, I do a little
>processing and add another cell to "Sub-Sub menu" (and "Remove"
>should be able to remove one such cell).


   I had this same problem a while ago, and this is how I solved it.
My main trouble was that IB wouldn't let me directly connect an
outlet to a submenu, only to the main window. So I ended up connecting
to the "Activate" menu cell (which IB thought was just a plain button, 
not a submenu) instead and creating and attaching the submenu in
the outlet initialization method. This may not be the correct/approved
way, but it works for me and seems reasonably clean.



- setActivateMenu:anObject
{  
    activateMenu = [Menu newTitle:[anObject title]];
    [[NXApp mainMenu] setSubmenu:activateMenu forItem:anObject];
    [activateMenu display];
    return self;
}

   
- addWindow:aWin title:(char *)title
{id amCell;
      amCell = [activateMenu addItem:title action:@selector(makeKeyAndOrderFront:)
      	keyEquivalent:-1];
      [amCell setTarget:aWin];
      [aWin setActivateCell:amCell];
      [activateMenu display];
      [aWin setDelegate:self];
      return amCell;
 }
 
- windowWillClose:sender
 {id matrix;
   int r,c,  i;
   
    [activateMenu disableDisplay];
    matrix = [activateMenu itemList];
    // now search for & remove a cell with a target of aWin
    [matrix getNumRows:&r numCols:&c];
    if(c != 1)  [self error:"Activate menu matrix has more than one column, in fact it has %d", c];
    for(i=0; i<r; i++)
       if([sender isEqual:[[matrix  cellAt:i:0] target]]) 
       {
          [matrix removeRowAt:i andFree:YES];
	  break;
       }
    [activateMenu sizeToFit];
    [activateMenu reenableDisplay];
    [activateMenu display];
    return sender;
}

  - setActivateMenu is, despite its name, connected to the activate *cell*,
but it ends up *setting* the activateMenu; hence the name.
  - addWin:title: adds a new window (actually my own subclass of
Window, which keeps track of (among other things) the menuCell
belonging to it (come to think of it, I don't actually use this any
more, but the window could use it to disable its cell or whatever
if it so desired). It creates a new menuCell, adds it to the Activate
menu, sets the new cell's action and target, and sets the window's
delegate to self so that the windowWillClose method is called.
  - windowWillClose is a little more complex because it has to run down
the list of menuCells and find the one with "sender" for its target. 
Other than that it's pretty simple.

  Oddly, the Window never seemed to call the windowWillClose: method
on its own ... I had to add an "if delegate responds, etc., then call,
etc." to the subclass's -close method. This could be a mistake on my part
though. It would be possible for the window to remove its own cell
if you apssed it the activateMenu rather than its cell id in the
-addWin:: method. 

   BTW, note that pop-up-lists (and pull-downs) are also quite convenient
for making a variable-size menu.

-- 
 wiml@milton.acs.washington.edu       Seattle, Washington   
     (William Lewis)   |  47 41' 15" N   122 42' 58" W  
"These 2 cents will cost the net thousands upon thousands of 
dollars to send everywhere. Are you sure you want to do this?"