home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1992 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1992.iso
/
msdos
/
cpluspls
/
menus.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-15
|
18KB
|
677 lines
_C Programming_
by Al Stevens
[LISTING ONE]
// ------------ menus.h
#ifndef MENUS
#define MENUS
#include "window.h"
#define MAXSELECTIONS 12
#define CHECK '\xfb' // IBM Graphics character set check mark
#define MENUFG CYAN
#define MENUBG BLUE
#define SELECTFG BLACK
#define SELECTBG WHITE
#define DISABLEFG LIGHTGRAY
#define DISABLEBG BLUE
//
// SLIDING BAR MENUS
//
class SlideBar {
int row; // menu screen row
void (**mfunc)(SlideBar&); // selection functions
char **mtext; // selection titles
int selections; // number of selections
int quitflag; // flag for appl to say quit
unsigned *msave; // save area for menu bar
int selection; // selection position
int dispatch(int sel, int titlewidth);
public:
SlideBar(int line, char **text, int sel,
void (**func)(SlideBar&));
~SlideBar();
void terminate(void)
{ quitflag = 1; }
int current_selection(void)
{ return selection; }
};
//
// POPDOWN MENUS
//
class PopdownMenu : Window {
int selections; // number of selections
void (**mfunc)(PopdownMenu&); // selection functions
char **text; // address of menu text
int quitflag; // flag for appl to say quit
int selection; // current selection position
// --- private methods
int get_selection(int sel);
int dispatch(int sel);
int menuheight(char **text);
int menuwidth(char **text);
void operator<<(char **text);
public:
PopdownMenu(unsigned left, unsigned top,
char **text, int sel, void (**func)(PopdownMenu&));
~PopdownMenu(){};
void terminate(void)
{ quitflag = 1; }
void disable_selection(int sel)
{ *text[sel-1] = '-'; }
void enable_selection(int sel)
{ *text[sel-1] = ' '; }
int test_toggle(int selection);
int current_selection(void)
{ return selection; }
};
#endif
[LISTING TWO]
// ----------- menus.c
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include "menus.h"
#include "console.h"
static void select(int row,int sel, char *ttl,int set,int wd);
#define ON 1
#define OFF 0
//
// SLIDING BAR MENUS
//
// ----------- constructor for a sliding menu bar
SlideBar::SlideBar(int line, char **text, int sel,
void (**func)(SlideBar&))
{
savecursor();
hidecursor();
initconsole();
// ------ menu variables
quitflag = 0;
mfunc = func;
mtext = text;
// -------- save video memory
msave = new unsigned[SCREENWIDTH];
row = min(line-1, 24);
savevideo(msave, row, 0, row, SCREENWIDTH-1);
// --------- display the menu bar
colors(MENUFG, MENUBG);
setcursor(0, row);
int cols = SCREENWIDTH;
while (cols--)
window_putc(' ');
// ---- compute the width of the selection texts
int titlewidth = 0;
for (int i = 0; mtext[i] && i < MAXSELECTIONS; i++)
titlewidth = max(titlewidth, strlen(mtext[i]));
// ----- save the selection count
selections = i;
// ------ display the selection texts
for (i = 0; i < selections; i++)
select(row, i+1, mtext[i], OFF, titlewidth);
// ------- dispatch the menu's selections
dispatch(sel, titlewidth);
}
// ----------- destructor for a menu bar
SlideBar::~SlideBar(void)
{
restorevideo(msave, row, 0, row, SCREENWIDTH-1);
delete msave;
restorecursor();
unhidecursor();
}
// ------ navigate the menu and dispatch a chosen function
int SlideBar::dispatch(int sel, int titlewidth)
{
savecursor();
int sliding = 1;
if (sel)
selection = sel;
while (sliding) {
// ---- highlight the menu bar selection
select(row, selection, mtext[selection-1],
ON,titlewidth);
// ----- read a selection key
int c = getkey();
switch (c) {
case ESC:
// ----- ESC key quits
sliding = 0;
break;
case FWD:
// ------ right-arrow cursor key
select(row, selection, mtext[selection-1],OFF,
titlewidth);
if (selection++ == selections)
selection = 1;
break;
case BS:
// ------ left-arrow cursor key
select(row, selection, mtext[selection-1],OFF,
titlewidth);
if (--selection == 0)
selection = selections;
break;
default:
// ---- test for 1st letter match
for (int i = 0; i < selections; i++)
if (tolower(c) == tolower(mtext[i][1])) {
// -- match, turn off current selection
select(row, selection,
mtext[selection-1],
OFF,titlewidth);
// --- turn on new selection
selection = i+1;
select(row, selection,
mtext[selection-1],
ON,titlewidth);
break;
}
if (i == selections)
break;
case '\r':
// ------- ENTER key = user selection
if (mfunc[selection-1])
(*mfunc[selection-1])(*this);
sliding = !(quitflag == 1);
break;
}
}
restorecursor();
select(row,selection,mtext[selection-1],OFF,titlewidth);
return quitflag ? 0 : selection;
}
// --- set or clear the highlight on a menu bar selection
static void select(int row,int sel,char *ttl,int set,int wd)
{
setcursor(5+(sel-1)*wd, row);
if (set == OFF)
colors(MENUFG, MENUBG);
else
colors(SELECTFG, SELECTBG);
window_printf(ttl);
}
//
// POPDOWN MENUS
//
// -------- constructor for the PopdownMenu
PopdownMenu::PopdownMenu(unsigned left, unsigned top,
char **mtext, int sel, void (**func)(PopdownMenu&))
: (left, top, left+1+menuwidth(mtext),
top+1+menuheight(mtext), MENUFG, MENUBG)
{
*this << mtext;
mfunc = func;
text = mtext;
selection = sel;
selections = menuheight(text);
// ------ dispatch the menu selection
dispatch(sel);
}
// ------- write text selections into the popdown menu
void PopdownMenu::operator<<(char **mtext)
{
hidecursor();
int y = 0;
// ----- a NULL-terminated array of character pointers
text = mtext;
while (*mtext != NULL) {
cursor(0, y++);
char hold = **mtext;
if (**mtext == '-') {
set_colors(DISABLEFG, DISABLEBG);
**mtext = ' ';
}
*this << *mtext;
**mtext++ = hold;
set_colors(MENUFG, MENUBG);
}
unhidecursor();
}
// ------------ get a popdown menu selection
int PopdownMenu::get_selection(int sel)
{
// ---- set the initial selection
if (sel)
selection = sel;
int selecting = 1;
int c;
while (selecting) {
// ------- display the menu's selection texts
*this << text;
// ------ watch for disabled selections
if (**(text+selection-1)=='-')
c = DN; // force a key to
// bypass a disabled selection
else {
// ---- highlight the current selection
cursor(0, selection-1);
set_colors(SELECTFG, SELECTBG);
*this << *(text + selection - 1);
set_colors(MENUFG, MENUBG);
hidecursor();
c = getkey(); // --- read the next keystroke
}
switch (c) {
case ESC:
case FWD:
case BS:
// ---- ESC,FWD, or BS will terminate selection
selecting = 0;
break;
case UP:
// ------- up-arrow cursor key
do
if (--selection == 0)
selection = selections;
while (**(text+selection-1) == '-');
break;
case DN:
// ------- down-arrow cursor key
do
if (selection++ == selections)
selection = 1;
while (**(text+selection-1) == '-');
break;
default:
// ----- other key, test first letter match
for (int i = 0; i < selections; i++) {
if (tolower(c) == tolower(text[i][1]) &&
*(text[i]) != '-') {
selection = i+1;
selecting = 0;
}
}
break;
case '\r':
// ---- ENTER key is a selection
selecting = 0;
break;
}
}
return c == '\r' ? selection : c;
}
// ------------ get and dispatch a popdown menu selection
int PopdownMenu::dispatch(int sel)
{
int upanddown = 1;
while (upanddown) {
// ---------- read a user selection
sel = get_selection(sel);
switch (sel) {
// -------- these keys exit the menu
case FWD:
case BS:
case ESC:
upanddown = 0;
break;
default:
// -------- user has made a menu selection
if (mfunc[selection-1]) {
// ----- execute a menu selection function
hidewindow();
(*mfunc[selection-1])(*this);
upanddown = !(quitflag == 1);
restorewindow();
}
else {
// ----- no function, must be a toggle
char *cp = text[selection-1];
cp += strlen(cp)-1;
if (*cp == ' ')
*cp = CHECK;
else if ((*cp & 255) == CHECK)
*cp = ' ';
}
break;
}
}
return sel == ESC ? ESC : 0;
}
// --------- compute the height of a popdown menu
int PopdownMenu::menuheight(char **text)
{
int height = 0;
while (text[height])
height++;
return height;
}
// --------- compute the width of a popdown menu
int PopdownMenu::menuwidth(char **text)
{
int width = 0;
while (*text) {
width = max(width, strlen(*text));
text++;
}
return width;
}
// ----- test the setting of a toggle selection
int PopdownMenu::test_toggle(int sel)
{
char *cp = text[sel-1];
cp += strlen(cp)-1;
return (*cp & 255) == CHECK;
}
[LISTING THREE]
// ---------- demoslid.c
#include <stddef.h>
#include <conio.h>
#include <stdio.h>
#include "menus.h"
#include "console.h"
// ----------- File menu
static char *fmenu[] = {
" Load ",
" Save ",
" New ",
" Quit ",
NULL
};
static void load(SlideBar&);
static void save(SlideBar&);
static void newfile(SlideBar&);
static void quit(SlideBar&);
static void (*ffuncs[])(SlideBar&)={load,save,newfile,quit};
void main(void)
{
SlideBar menu(1, fmenu, 1, ffuncs);
}
static void load(SlideBar& menu)
{
Window wnd(20,10,40,20,BLACK,CYAN);
wnd.title("(Stub Function)");
wnd << "\n\n\n\n LOAD A FILE";
getkey();
}
static void save(SlideBar &menu)
{
Window wnd(20,10,40,20,YELLOW,RED);
wnd.title("(Stub Function)");
wnd << "\n\n\n\n SAVE A FILE";
getkey();
}
static void newfile(SlideBar &menu)
{
Window wnd(20,10,40,20,YELLOW,RED);
wnd.title("(Stub Function)");
wnd << "\n\n\n\n NEW FILE";
getkey();
}
static void quit(SlideBar& menu)
{
YesNo yn("Quit");
if (yn.answer)
menu.terminate();
}
[LISTING FOUR]
// ---------- demopop.c
#include <stddef.h>
#include <conio.h>
#include <stdio.h>
#include "menus.h"
#include "console.h"
// ----------- File menu
static char *fmenu[] = {
" Load ",
"-Save ",
" New ",
" Option ",
" Quit ",
NULL
};
static void load(PopdownMenu&);
static void save(PopdownMenu&);
static void newfile(PopdownMenu&);
static void quit(PopdownMenu&);
static void (*ffuncs[])(PopdownMenu&) =
{ load, save, newfile, NULL, quit };
void main(void)
{
PopdownMenu menu(20, 10, fmenu, 1, ffuncs);
}
static void load(PopdownMenu& menu)
{
Window wnd(20,10,40,20,BLACK,CYAN);
wnd.title("(Stub Function)");
wnd << "\n\n\n\n LOAD A FILE";
menu.enable_selection(2); // enable the save command
getkey();
}
static void save(PopdownMenu &menu)
{
Window wnd(20,10,40,20,YELLOW,RED);
wnd.title("(Stub Function)");
wnd << "\n\n\n\n SAVE A FILE";
menu.disable_selection(2); // disable the save command
getkey();
}
static void newfile(PopdownMenu &menu)
{
Window wnd(20,10,40,20,YELLOW,RED);
wnd.title("(Stub Function)");
wnd << "\n\n\n\n NEW FILE";
menu.enable_selection(2); // enable the save command
getkey();
}
static void quit(PopdownMenu& menu)
{
if (menu.test_toggle(4))
menu.terminate();
else {
YesNo yn("Quit");
if (yn.answer)
menu.terminate();
}
}
[LISTING FIVE]
// -------- strings.h
#ifndef STRINGS
#define STRINGS
#include <string.h>
class string {
char *sptr;
public:
// CONSTRUCTORS
// -------- construct a null string
string(void);
// ------- construct with a char * initializer
string(char *s);
// ------- construct with another string as initializer
string(string& s);
// -------- construct with just a size
string(int len);
// DESTRUCTOR
~string(void) { delete sptr; }
// MEMBER FUNCTIONS
// ------ return the address of the string
const char *stradr(void) { return sptr; }
// SUBSTRINGS
// ------ substring: right len chars
string right(int len);
// ------ substring: left len chars
string left(int len);
// ------ substring: middle len chars starting from where
string mid(int len, int where);
// ASSIGNMENTS
// -------- assign a char array to a string
void operator=(char *s);
// ---------- assign a string to a string
void operator=(string& s) { *this = s.sptr; }
// CONCATENATORS
// ------- 1st concatenation operator (str1 += char *)
void operator+=(char *s);
// ------- 2nd concatenation operator (str1 += str2;)
void operator+=(string& s) { *this += s.sptr; }
// ------- 3rd concatenation operator (str1 = str2+char*;)
string operator+(char *s);
// ------- 4th concatenation operator (str1 = str2 + str3;)
string operator+(string& s) { return *this + s.sptr; }
// RELATIONAL OPERATORS
int operator==(string& s) { return strcmp(sptr,s.sptr)==0;}
int operator!=(string& s) { return strcmp(sptr,s.sptr)!=0;}
int operator<(string& s) { return strcmp(sptr,s.sptr)< 0;}
int operator>(string& s) { return strcmp(sptr,s.sptr)> 0;}
int operator<=(string& s) { return strcmp(sptr,s.sptr)<=0;}
int operator>=(string& s) { return strcmp(sptr,s.sptr)>=0;}
int operator==(char *s) { return strcmp(sptr,s)==0; }
int operator!=(char *s) { return strcmp(sptr,s)!=0; }
int operator<(char *s) { return strcmp(sptr,s)< 0; }
int operator>(char *s) { return strcmp(sptr,s)> 0; }
int operator<=(char *s) { return strcmp(sptr,s)<=0; }
int operator>=(char *s) { return strcmp(sptr,s)>=0; }
// SUBSCRIPTORS
char operator[](int n) { return *(sptr + n); }
char* operator+(int n) { return sptr + n; }
};
#endif
[LISTING SIX]
// -------- strings.c
#include <stddef.h>
#include <stream.hpp>
#include "strings.h"
// -------- construct a null string
string::string(void)
{
sptr = new char;
*sptr = '\0';
}
// ------- construct with a char * initializer
string::string(char *s)
{
sptr = new char[strlen(s)+1];
strcpy(sptr, s);
}
// ------- construct with another string as initializer
string::string(string& s)
{
sptr = new char[strlen(s.sptr)+1];
strcpy(sptr, s.sptr);
}
// -------- construct with just a size
string::string(int len)
{
sptr = new char[len+1];
memset(sptr, 0, len+1);
}
// -------- assign a char array to a string
void string::operator=(char *s)
{
delete sptr;
sptr = new char[strlen(s)+1];
strcpy(sptr, s);
}
// ------- 1st concatenation operator (str1 += char *;)
void string::operator+=(char *s)
{
char *sp = new char[strlen(sptr) + strlen(s) + 1];
strcpy(sp, sptr);
strcat(sp, s);
delete sptr;
sptr = sp;
}
// ------- 3rd concatenation operator (str1 = str2 + char*;)
string string::operator+(char *s)
{
string tmp(*this);
tmp += s;
return tmp;
}
// ------ substring: right len chars
string string::right(int len)
{
string tmp(sptr + strlen(sptr) - len);
return tmp;
}
// ------ substring: left len chars
string string::left(int len)
{
string tmp(len+1);
strncpy(tmp.stradr(), sptr, len);
return tmp;
}
// ------ substring: middle len chars starting from where
string string::mid(int len, int where)
{
string tmp(len+1);
strncpy(tmp.stradr(),sptr+where-1,len);
return tmp;
}