home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume17
/
menubar
/
part01
next >
Wrap
Internet Message Format
|
1991-03-21
|
9KB
From: jek5036@ultb.isc.rit.edu (J.E. King)
Newsgroups: comp.sources.misc
Subject: v17i062: menubar - C Menubar function, Part01/01
Message-ID: <1991Mar21.210826.12086@sparky.IMD.Sterling.COM>
Date: 21 Mar 91 21:08:26 GMT
Approved: kent@sparky.imd.sterling.com
X-Checksum-Snefru: 061bd438 cbe7e308 d69ed5dc 45037598
Submitted-by: J.E. King <jek5036@ultb.isc.rit.edu>
Posting-number: Volume 17, Issue 62
Archive-name: menubar/part01
Since I rely on curses heavily for my programs, I have began to write
some functions for my programs. I found this one so useful that I
decided to put it up on comp.sources.misc. It is a menu routine,
which will adjust to the size of a 2d char array and will draw a nice
box around the menu which is either numerically driven or arrow-key
driven. I hope someone finds it useful.
Jim King <jek5036@ultb.isc.rit.edu>
-- cut here -- cut here -- cut here -- cut here -- cut here -- cut here --
#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -s ./Makefile`
then
echo "writing ./Makefile"
cat > ./Makefile << '\End\Of\Shar\'
CFLAGS = -O
all: test
test: menubar.o test.o
cc test.o menubar.o -o test -g -lcurses -ltermcap
test.o: test.c
menubar.o: menubar.c
\End\Of\Shar\
else
echo "will not over write ./Makefile"
fi
if `test ! -s ./README`
then
echo "writing ./README"
cat > ./README << '\End\Of\Shar\'
Hi!
MenuBar is something I cooked up whilst bored at work. You can
use it for just about any program which prompts the user for menu choices.
I am planning on installing it in my next version of Chemtab, the
chemistry database released on comp.sources.unix not too long ago. Here's
how you would go about using menubar():
1) Set up a 2d array of char in your program, such as:
char *first_menu[] = {
"This is menu option number 1",
"This is menu option number 2",
"This will return a three",
"Exit the program",
0
};
2) Call the function like this:
menubar(y, x, first_menu, boxflag, title);
where:
y = the y position on the screen - upper left hand corner
x = the x position on the screen - upper left hand corner
first_menu = the char 2d array like above
boxflag = (1, 0) if 1, will put an ascii box around the menu
title = char string - centered in the first line of the menu
if you don't want a title, use NULL
3) The fuctions will return the number of the option, for example in the
above menu if I pressed return on "This will return a three" I would get
back a three because it was the third choice.. Have fun with it.
\End\Of\Shar\
else
echo "will not over write ./README"
fi
if `test ! -s ./menubar.c`
then
echo "writing ./menubar.c"
cat > ./menubar.c << '\End\Of\Shar\'
/*
* Menubar - curses driven menu bar display
* menubar will run a menu-bar display on screen for you.
* This type of package is useful for databases, etc..
*/
/* Menubar V1.0 by Jim King (jek5036@ultb.isc.rit.edu) */
#include <stdio.h>
#include <curses.h>
#include <signal.h>
#ifdef SYSV
# include <string.h>
#else
# include <strings.h>
#endif
#define MAXNAMELEN 70
#define UP 'A'
#define DN 'B'
#define LT 'C'
#define RT 'D'
#define ESC '\033'
#define RET '\015'
#define LF '\012'
struct mbar {
char menu_choice[MAXNAMELEN];
int menu_number;
struct mbar *next;
} *m;
WINDOW *MENU;
#define NEW(XXX) (struct XXX *)malloc(sizeof(struct XXX))
int Stopflag = 0; /* interrupt flag */
void (*oldsig)(); /* old signal catch */
/*
* signal calls this on an interrupt like ^C
*/
menuclean()
{
wclear(MENU); wrefresh(MENU); delwin(MENU); refresh();
printf("<<< Press return to continue >>>"); fflush(stdout);
signal(SIGINT, oldsig); /* reset signal handler */
++Stopflag;
return(-1); /* return to loop */
}
/*
* converts information in menu to a linked-list
*/
mkmenubar(num, menu)
int *num;
char *menu[];
{
int i = 0; /* counter for num */
struct mbar *tmp; /* tmp pointer to list */
m = NEW(mbar); /* initialize menubar */
tmp = m; /* set tmp to head */
do {
strcpy(tmp->menu_choice, menu[i]);
tmp->menu_number = i+1; /* move values into tmp */
tmp->next = NEW(mbar);
tmp = tmp->next; /* set up next link */
++i;
} while (menu[i] != NULL);
*num = i; /* 'return' the maxnum of choices */
tmp = NULL; /* lop off the end */
}
/*
* determine optimal size for menu bar.
*/
sizemenubar(len, wid, title)
int *len, *wid;
char *title;
{
int sz = 0, i = 0; /* tmp counter */
struct mbar *tmp; /* tmp placeholder */
*len = 0; *wid = 0;
tmp = m;
for (tmp = m; tmp != NULL; tmp = tmp->next) {
++i;
sz = strlen(tmp->menu_choice);
if (sz > *wid) /* as wide as longest line */
*wid = sz;
}
if (title != NULL)
if (strlen(title) > *wid)
*wid = strlen(title);
*wid += 8; /* extras like #] and . */
*len = i+1;
}
/*
* sets up the menu on MENU window
*/
dispmenu(boxflag, title, width, length)
int boxflag, width, length;
char *title;
{
struct mbar *tmp;
if (boxflag) {
box(MENU, '|', '-');
mvwaddch(MENU, 0, 0, '/');
mvwaddch(MENU, 0, width-1, '\\');
mvwaddch(MENU, length-1, 0, '\\');
mvwaddch(MENU, length-1, width-1, '/');
}
if (title != NULL) {
wstandout(MENU);
mvwaddstr(MENU, 0, (width / 2) - (strlen(title) / 2), title);
wstandend(MENU);
}
for (tmp = m; tmp != NULL; tmp = tmp->next) {
if (tmp->menu_number == 0) continue;
wmove(MENU, tmp->menu_number, 1);
wprintw(MENU, "%d] %s. ", tmp->menu_number, tmp->menu_choice);
}
wrefresh(MENU);
}
/*
* un-hilight old selection at num
*/
delight(num)
int num;
{
struct mbar *tmp;
for (tmp = m; tmp != NULL; tmp = tmp->next) {
if (num == tmp->menu_number) {
wmove(MENU, tmp->menu_number, 1);
wprintw(MENU, "%d] %s. ", tmp->menu_number, tmp->menu_choice);
}
}
wrefresh(MENU);
}
/*
* hilight selection at num
*/
hilight(num)
int num;
{
struct mbar *tmp;
for (tmp = m; tmp != NULL; tmp = tmp->next) {
if (num == tmp->menu_number) {
wstandout(MENU); /* highlight */
wmove(MENU, tmp->menu_number, 1);
wprintw(MENU, "%d> %s. ", tmp->menu_number, tmp->menu_choice);
wstandend(MENU);
}
}
wrefresh(MENU);
}
/*
* main function call
* menubar(y, x, menu) where
* y = starting line of menu
* x = starting column of menu
* menu is of type *menu[] in which are stored the items for be chosen
*/
menubar(y, x, menu, boxflag, title)
int y, x, boxflag;
char *menu[], *title;
{
int cur = 1, old = 1, l, w, num;
char c;
mkmenubar(&num, menu);
sizemenubar(&l, &w, title);
initscr();
MENU = newwin(l, w, y, x); /* start (x, y) to (x+w, y+l) */
dispmenu(boxflag, title, w, l);
oldsig = signal(SIGINT, menuclean);
noecho(); crmode();
for (;;) {
delight(old);
hilight(cur);
if (Stopflag) { cur = -1; goto end; }
c = wgetch(MENU);
switch(c) {
case ESC:
wgetch(MENU);
switch(wgetch(MENU)) {
case UP:
case RT: old = cur--;
if (Stopflag) { cur = -1; goto end; }
break;
case DN:
case LT: old = cur++;
if (Stopflag) { cur = -1; goto end; } break;
default:
if (Stopflag) { cur = -1; goto end; }
break;
}
break;
case LF:
case RET:
if (Stopflag) { cur = -1; goto end; }
end: wclear(MENU); wrefresh(MENU); delwin(MENU);
refresh(); echo(); crmode();
return(cur); break;
default:
if (Stopflag) { cur = -1; goto end; }
if (c > '0' || c <= '9') {
old = cur;
cur = c - '0';
if (cur > num) cur = num;
if (cur < 1) cur = 1;
}
break;
}
if (cur > num) cur = 1;
if (cur < 1) cur = num;
}
}
\End\Of\Shar\
else
echo "will not over write ./menubar.c"
fi
if `test ! -s ./test.c`
then
echo "writing ./test.c"
cat > ./test.c << '\End\Of\Shar\'
#include <stdio.h>
/*
* declare your menus like this:
*/
char *menu[40] = {
"This is menu option 1",
"This is menu option 2",
"This is menu option 3",
"This is menu option 4",
0
};
char title[80] = "THIS IS THE MenuBar";
/*
* don't forget this
*/
extern int menubar();
main()
{
/*
* call menubar like this
* it returns the number of choice (good to use as a switch statement)
* or a -1 if the person hit return
*/
printf("\n\nAnd the number is: %d\n", menubar(5, 20, menu, 1, title));
exit(1);
}
\End\Of\Shar\
else
echo "will not over write ./test.c"
fi
echo "Finished archive 1 of 1"
exit
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.