home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_GEN
/
FACETV.ZIP
/
MENUBARS.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-04
|
7KB
|
246 lines
/************************************************************************
**
** @(#)menubars.cpp 04/01/93 Chris Ahlstrom
**
** ------------------------
** 73340.26!compuserve.com
** ------------------------
**
** Routines for handling generic menu-bars and drop-down menus
** that are specified not by code, but by a set of data structures
** suitable for use by Borland's Turbo Vision.
**
** Also handles the status line.
**
*************************************************************************/
#define MENUBARS_cpp // just in case
#if defined(__BORLANDC__)
#pragma warn -amp // ignore superfluous "&" warning
#endif
#include "menubars.h" // class definition
#if defined(__BORLANDC__)
#pragma warn .amp // restore superfluous "&" warning
#endif
/************************************************************************
** MenuBarApp constructor
*************************************************************************/
MenuBarApp::MenuBarApp ()
:
TProgInit // initialize the desktop
(
MenuBarApp::initStatusLine,
MenuBarApp::initMenuBar,
MenuBarApp::initDeskTop
)
{
}
/************************************************************************
** MenuBarApp destructor unnecessary
*************************************************************************/
/************************************************************************
** Overloading "+" for TMenuItems
**
** Menu items are always in a linked list. Since the "+" operator
** is processed from left-to-right, we define it as appending item 2
** to the end of item 1, and returning item 1.
**
*************************************************************************/
TMenuItem& operator +
(
TMenuItem& item1,
TMenuItem& item2
)
{
TMenuItem *p = &item1; // start at the first item
while (p->next != NULL) // traverse to the end of the item
{
p = p->next;
}
p->next = &item2; // insert item 2
return item1; // return original first item
}
/************************************************************************
** MenuBarApp::menuBox()
**
** This global function knows how to recursively handle a nested
** list of menus as defined in tvmenus.h.
**
** It returns a null pointer if a problem occurred.
**
** See mt32app.men for examples of the NestItems structures used.
**
*************************************************************************/
TMenuItem *
MenuBarApp::menuBox
(
NestPtr n
)
{
TMenuItem *anchor, *tmi;
int ncount = 0;
if (n->item != MENU_TERMINATE) // bogus empty menu?
{
if (*n->item == NEWLINE) // bogus, new-line at start
{
anchor = (TMenuItem *) 0; // return an error code
}
else
{
while (n->item != MENU_TERMINATE) // handle every menu item
{
if (n->nest == MENU_END_NEST) // menu item is a leaf
{
if (*n->item == NEWLINE) // menu item is just a line
tmi = &newLine();
else
tmi = new TMenuItem // add the leaf item
(
n->item, n->cmcode, n->key, n->help, n->label
);
}
else if (*n->item == NEWLINE) // menu item is just a line
{
tmi = &newLine();
}
else // menu item not a leaf
{
tmi = new TMenuItem
(
n->item,
n->key,
new TMenu // create a sub-menu
(
*menuBox(n->nest) // recursive call
),
n->help
);
}
if (ncount == 0) // first case
anchor = tmi; // start the linked list
else
*anchor = *anchor + *tmi; // append to linked list
ncount++; // count the case
n++; // finished first one
}
}
}
else
{
anchor = (TMenuItem *) 0; // return an error code
}
return anchor;
}
/************************************************************************
** MenuBarApp::initMenuBar
**
** Rather than hard-wiring the menubar and it's entries, we leave
** an opening for the usage of resources. Right now, it's still very
** primitive... the resource is essentially part of a C++ header file
** (*.men) that sets up the menu.
**
** Basically, we take two linear lists of entries (one for the
** menubar, and one for each set of entries in the menubar), and
** dynamically use the lists to build the menu tree.
**
** We create the first entry (TSubMenu) in the menubar tree;
** this entry anchors the whole tree. We then add its menu-items.
** The rest of the main entries are added, and, for each, we add
** the menu-items.
**
** Note that any menu-item with a newline for a label is simply
** inserted as a straightline (see MENU_NEWLINE in midi_ex.men, and
** NEWLINE here, below).
**
** New parameters:
**
** menubar
** menubarsize
**
** These parameters get copied to their global versions (menuBar
** and menuBarSize).
**
*************************************************************************/
TMenuBar *
MenuBarApp::initMenuBar
(
TRect r
)
{
TSubMenu *mb; // to be an alias for menu bar
const NestBar *bar; // pointer to main list
const Nests *men; // pointer to current sub-menu
TMenuItem *m; // pointer to current menu-item
bar = menuBar; // point to first sub-menu
men = bar->items; // point to first item in menu
for (int i = 0; i < bar->barCount; i++, men++)
{
if (i == 0) // first item is the anchor
{
mb = new TSubMenu(men->submenu, men->submenukey);
}
else // append another node
{
*mb = *mb + *new TSubMenu(men->submenu, men->submenukey);
}
m = menuBox(men->items); // process first item in TSubMenu
if (m)
*mb = *mb + *m;
}
r.b.y = r.a.y + 1; // set bottom 1 line below top line
return new TMenuBar(r, *mb);
}
/************************************************************************
** MenuBarApp::initStatusLine
*************************************************************************/
TStatusLine *
MenuBarApp::initStatusLine
(
TRect r
)
{
TStatusDef *sb; // to be an alias for menu bar
const StatusBar *stat; // pointer to current sub-menu
const StatusItems *s; // pointer to current menu-item
stat = statusBar; // point to status-bar
s = stat->items; // point to first item in status-bar
for (int i = 0; i < stat->barCount; i++, s++)
{
if (i == 0) // first item is the anchor
{
sb = new TStatusDef(0, 0xFFFF); // range of help contexts
}
*sb = *sb + *new TStatusItem(s->item, s->key, s->cmcode);
}
r.a.y = r.b.y - 1; // move top to 1 line above bottom
return new TStatusLine(r, *sb);
}