pEdge = 2;
      m->LeftEdge = LastMenuItem->LeftEdge + LastMenuItem->Width + 12;
   } else {
      m->TopEdge = LastMenuItem->TopEdge + 12;
      m->LeftEdge = LastMenuItem->LeftEdge;
   }
   if (flags & CHECKIT)
      m->Width += CHECKWIDTH;
   if (flags & COMMSEQ)
      m->Width += COMMWIDTH + 20;
   m->Width += IntuiTextLength(m->ItemFill);
   m->Height = 10;
   /*
    *  Check last menu item's width to see if it is larger than this
    *  item's.  If new item is larger, then update width of all other
    *  items.
    */
   if (LastMenuItem) {
      if (LastMenuItem->Width > m->Width)
        m->Width = LastMenuItem->Width;
      else {
         register short delta = m->Width - LastMenuItem->Width;

	 for (n = LastMenu->FirstItem; n != m; n = n->NextItem) {
	    n->Width = m->Width;
	    if (n->LeftEdge > 0) n->LeftEdge += delta;
	 }
	 if (m->LeftEdge > 0) m->LeftEdge += delta;
      }
   }
   LastMenuItem = m;
   return MNUM(Cur_Menu, ++Cur_MenuItem, NOSUB);
}



char *
strsave(string) char *string; {
   char *out ;

   out = (char *) AllocRemember(&(Top->mn_Memory), strlen(string) + 1,
	MEMF_PUBLIC) ;
   if (out == NULL) return NULL ;
   (void) strcpy(out, string) ;
   return out ;
}
= 0)
      m->Flags |= HIGHCOMP;
   m->Command = ch;
   m->MutualExclude = mux;
   m->SubItem = NULL;
   m->ItemFill = (APTR) AllocRemember(&(Top->mn_Memory),
                      sizeof(struct IntuiText), MEMF_PUBLIC | MEMF_CLEAR);
   it = (struct IntArticle 1143 of net.micro.amiga:
Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site unisoft.UUCP
Path: unisoft!lll-lcc!lll-crg!caip!daemon
From: mwm%ucbopal@BERKELEY.EDU
Newsgroups: net.micro.amiga
Subject: browser posted to mod.sources
Message-ID: <1588@caip.RUTGERS.EDU>
Date: 22 Mar 86 15:42:43 GMT
Date-Received: 22 Mar 86 22:11:39 GMT
Sender: daemon@caip.RUTGERS.EDU
Organization: Rutgers Univ., New Brunswick, N.J.
Lines: 19

From: Mike (I'll be mellow when I'm dead) Meyer <mwm%ucbopal@BERKELEY.EDU>

Earlier today (late yesterday?) I posted a disk browser to
mod.sources. The program lets you wander around the file tree on a
disk, and shows the insides of files, all driven by the mouse.

The first menu entry has items for df0, df1 and ram. Selecting one of
those adds a new menu with the disk name as the menu name and the
files in the top-level directory as menu items. Selecting a directory
adds another menu level with etc.; selecting a file displays the file,
with up and down "page" gadgets. And yes, selecting things from older
menus does what you want it to. It runs about as fast as anything can
from the Amiga floppies (fixing that is my next project!).

This is also the program that caused the question "Why does my Amiga
crash when I pull down an empty menu?" Solution: an empty directory has
a single disabled entry, "EMPTY".

	<mike


LeftEdge += delta;
      }
   }
   LastMenuItem = m;
   return MNUM(Cur_Menu, ++Cur_MenuItem, NOSUThis program is a prerelease version for a future AMIGA product that
will someday emulate the major capabilities for the UNIX* C-Shell.

This program is NOT yet a Computerverse product!!
Computerverse will not assume any responsibility for its use.
This version is only for betasite testing and examination, and is
prone to stack crashes as most prereleases are.
This is not a "port" from anything at all, with no cross-testing.
Please be sure to examine the "known bugs" section at the e;
   Top->mn_Node.ln_Name = m->MenuName = strsave(name);
   m->Height = 0;
   m->Flags = enabled ? MENUENABLED : 0;
   m->FirstItem = NULL;
   LastMenu = m;

   AddHead(&Memory, Top);
   return MNUM(++Cur_Menu, NOITEM, NOSUB);
}

/*
 *  Add a menu item to the current MENU.  Note that Add_Menu *must* be
 *  called before this function.
 */
Menu_Item_Add(name, flags, mux, ch)
   char *name;       /* name of menu item */
   USHORT flags;
   LONG mux;         /* mutual exclusion mask */
   BYTE ch;        /* command sequence character, if COMMSEQ */
{
   register struct MenuItem *m, *n;
   register struct IntuiText *it;

   flags &= CHECKIT|CHECKED|COMMSEQ|MENUTOGGLE|ITEMENABLED|HIGHCOMP|HIGHBOX;
   if (LastMenu == NULL)
      return MNUM(NOMENU, NOITEM, NOSUB);

   if ((m = (struct MenuItem *) AllocRemember(&(Top->mn_Memory),
                 sizeof(struct MenuItem), MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
      return MNUM(NOMENU, NOITEM, NOSUB);

   if (LastMenuItem == NULL)
      LastMenu->FirstItem  = m;
   else
      LastMenuItem->NextItem = m;
   m->Flags = flags | ITEMTEXT;
   /*
    *  Check for highlight mode:  if none selected, use HIGHCOMP
    */
   if ((m->Flags & (HIGHCOMP | HIGHBOX)) == 0)
      m->Flags |= HIGHCOMP;
   m->Command = ch;
   m->MutualExclude = mux;
   m->SubItem = NULL;
   m->ItemFill = (APTR) AllocRemember(&(Top->mn_Memory),
                      sizeof(struct IntuiText), MEMF_PUBLIC | MEMF_CLEAR);
   it = (struct IntuiText *) m->ItemFill;
   it->FrontPen = AUTOFRONTPEN;
   it->BackPen = AUTOBACKPEN;
   it->DrawMode = JAM2;
   if (flags & CHECKIT)
      it->LeftEdge = CHECKWIDTH + 1;
   else
      it->LeftEdge = 1;
   it->TopEdge = 1;
   it->ITextFont = NULL;      /* default font */
   it->IText = strsave(name);
   it->NextText = NULL;
   m->Width = 0;
   if (LastMenuItem == NULL) {
      m->TopEdge = 2;
      m->LeftEdge = 0;
   } else if (LastMenuItem->TopEdge + 40 > SCREENHEIGHT) {
      m->TopEdge = 2;
      m->LeftEdge = LastMenuItem->LeftEdge + LastMenuItem->Width + 12;
   } else {
      m->TopEdge = LastMenuItem->TopEdge + 12;
      m->LeftEdge = LastMenuItem->LeftEdge;
   }
   if (flags & CHECKIT)
      m->Width += CHECKWIDTH;
   if (flags & COMMSEQ)
      m->Width += COMMWIDTH + 20;
   m->Width += IntuiTextLength(m->ItemFill);
   m->Height = 10;
   /*
    *  Check last menu item's width to see if it is larger than this
    *  item's.  If new item is larger, then update width of all other
    *  items.
    */
   if (LastMenuItem) {
      if (LastMenuItem->Width > m->Width)
        m->Width = LastMenuItem->Width;
      else {
         register short delta = m->Width - LastMenuItem->Width;

	 for (n = LastMenu->FirstItem; n != m; n = n->NextItem) {
	    n->Width = m->Width;
	    if (n->LeftEdge > 0) n->LeftEdge += delta;
	 }
	 if (m->LeftEdge > 0) m->LeftEdge += delta;
      }
   }
   LastMenuItem = m;
   return MNUM(Cur_Menu, ++Cur_MenuItem, NOSUB);
}



char *
strsave(string) char *string; {
   char *out ;

   out = (char *) AllocRemember(&(Top->mn_Memory), strlen(string) + 1,
	MEMF_PUBLIC) ;
   if (out == NULL) return NULL ;
   (void) strcpy(out, string) ;
   return out ;
}
