home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Best Objectech Shareware Selections
/
UNTITLED.iso
/
boss
/
musi
/
misc
/
013
/
textwin.c
< prev
next >
Wrap
Text File
|
1993-04-10
|
14KB
|
603 lines
/*
* TEXTWIN.C - Text-windowing system
* Turbo C 2.0
*
* Description: Provides a simple text-menuing interface. Includes pop-down
* menus, and scrolling windows. To use, set up a main window
* with the MainWindow() function.
* eg. MainWindow("Title", 2, "Files", 'f', "Help", 'h');
*
* Then set the commands and command-numbers for each menu use
* the SetMenu function.
* eg. SetMenu(0, 3, "Open",'o',0, "Close",'c',1, "Quit",'q',2);
* SetMenu(1, 3, "Help",'h',3, "------------",-1,-1, "About",'a',4);
*
* Now just make a call to Choice() and the number it returns
* will be the command-number of the choice
* eg. If Help|About is chosen, 4 will be returned.
*
* If you want to get the user to select an option from a list
* of options, make an array of strings with the option
* descriptions in them (ensure final element is NULL). The
* element number chosen will be returned (first element = 0)
* after a call to ScrollChoice()
* eg. If the array is a, and the maximum string length is l, make the call
* ScrollChoice("BetterTitle", a, l);
*
* To display test inside a box, call DrawBox() with a NULL-
* terminated array of strings.
* eg. If the array is a, call
* DrawBox(a);
*
* To display text inside a box, and then wait for a key to be
* pressed, set up a NULL-terminated array of strings and call
* the InfoBox() function
* eg. If the array is a, make the call
* InfoBox(a);
*
* If you want to get input as well as print a box, make a call
* to DialogBox(), if nothing is entered, a default string is
* returned
* eg. DialogBox(a, "C:\") would return "C:\" if nothing was entered.
*
*
* Author: Andrew Scott (Adrenalin Software)
*
* Date: 14/3/1993 ver 0.1
*/
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
/* Maximum number of chars in a menu title */
#define MAXMENUWIDTH 9
/* Maximum number of chars in a menu command */
#define MAXCOMMWIDTH 12
/* Border graphics */
#define CRNRTL '┌'
#define CRNRTR '┐'
#define CRNRBL '└'
#define CRNRBR '┘'
#define HORIBAR '─'
#define VERTBAR '│'
typedef char *string;
struct MenuStruct {
char n[MAXCOMMWIDTH+1]; /* Item name ("" = no items) */
int k; /* Key-press selector (lower case) */
int x; /* Function reference number (-ve = no command) */
};
typedef struct MenuStruct *MenuItem;
struct MenuBar {
char n[MAXMENUWIDTH+1]; /* Menu name ("" = no menus) */
int k; /* Key-press selector (lower case) */
MenuItem m; /* Menu items */
} *Main;
#if 0
string parmlist(string bit, int n)
{
string s, t;
int l;
s = t = (string) malloc(1 + n * (l = strlen(bit)));
while (n--) {
strcpy(t, bit);
t += l;
}
return s;
}
#endif
void MainWindow(string title, int num, ...)
/* Post: Screen is set up with a nice title and num menus */
{
va_list args;
string t;
int i;
struct MenuBar *c;
c = Main = (struct MenuBar *) malloc(sizeof(struct MenuBar) * (num + 1));
va_start(args, &num);
textmode(C80);
textcolor(CYAN);
textbackground(BLACK);
clrscr();
textbackground(BLUE);
textcolor(WHITE);
i = 80 - strlen(title);
cprintf("%*c%s%*c", i/2, ' ', title, i/2 + i%2, ' ');
textcolor(YELLOW);
cprintf(" ");
for (i = num; i--; c++) {
t = (va_arg(args, string));
strcpy(c->n, t);
cprintf("%-*s", MAXMENUWIDTH, t);
c->k = (va_arg(args, int));
c->m = NULL;
}
c->n[0] = 0;
cprintf("%*c", 79 - MAXMENUWIDTH * num, ' ');
va_end(args);
}
void SetMenu(int menu, int n, ...)
/* Post: n commands has been set in menu #menu (0 = 1st) */
{
va_list args;
string t;
struct MenuBar *c1;
MenuItem c2;
int i;
for (i = menu, c1 = Main; i-- && c1->n[0] != 0; c1++);
if (! c1->n[0])
return; /* error */
c1->m = c2 = (MenuItem) malloc(sizeof(struct MenuStruct) * (n + 1));
va_start(args, &n);
for (; n--; c2++) {
t = va_arg(args, string);
strcpy(c2->n, t);
c2->k = va_arg(args, int);
c2->x = va_arg(args, int);
}
c2->n[0] = 0;
}
int _Menulength_; /* ignore this unstructured global variable ;) */
void PrintMenu(MenuItem m, int x)
/* Post: The menu which is pointed to by m is printed at column x */
{
int i;
char t[MAXCOMMWIDTH + 3];
i = MAXCOMMWIDTH+2;
t[i] = 0;
while (i--)
t[i] = HORIBAR;
textcolor(YELLOW);
textbackground(BLUE);
gotoxy(x, 3);
cprintf("%c%s%c", CRNRTL, t, CRNRTR);
_Menulength_ = 2;
i = 4;
while (m->n[0]) {
_Menulength_++;
gotoxy(x, i++);
cprintf("%c %-*s %c", VERTBAR, MAXCOMMWIDTH, (m++)->n, VERTBAR);
}
gotoxy(x, i);
cprintf("%c%s%c", CRNRBL, t, CRNRBR);
}
void ClearMenu(int x)
/* Post: The last menu printed at column x is now gone */
{
int i = 3;
textcolor(CYAN);
textbackground(BLACK);
while (_Menulength_--) {
gotoxy(x, i++);
cprintf("%*c", MAXCOMMWIDTH + 4, ' ');
}
}
void PrintComm(MenuItem m, int x, int y)
/* Post: Item *m is highlighted at column x, position y */
{
gotoxy(x+1, y+4);
textcolor(MAGENTA);
textbackground(BLACK);
cprintf(" %-*s ", MAXCOMMWIDTH, m->n);
}
void ClearComm(MenuItem m, int x, int y)
/* Post: Item *m is normalized at column x, position y */
{
gotoxy(x+1, y+4);
textcolor(YELLOW);
textbackground(BLUE);
cprintf(" %-*s ", MAXCOMMWIDTH, m->n);
}
void PrintBar(string s, int w, int y)
/* Post: String s (width w) is highlighted in the text window on line y */
{
gotoxy(1, y+1);
textcolor(WHITE);
textbackground(BLACK);
cprintf(" %-*s ", w, s);
}
void ClearBar(string s, int w, int y)
/* Post: String s (width w) is normalized in the text window on line y */
{
gotoxy(1, y+1);
textcolor(BLACK);
textbackground(CYAN);
cprintf(" %-*s ", w, s);
}
void Beep()
/* Post: Speaker has made a beep */
{
printf("%c", 7);
}
int Choice()
/*
* Returns: a function reference number corresponding to a chosen command,
* but returns -1 on an error.
*/
{
int ch;
struct MenuBar *c;
MenuItem p, q;
int i, fx = -1, y;
textcolor(CYAN);
textbackground(BLACK);
gotoxy(1, 25);
do {
cprintf("\rPress the letter of the menu you wish to select.");
ch = tolower(getch());
for (c = Main, i = 0; c->n[0] && c->k != ch; c++, i++);
i = 2 + MAXMENUWIDTH * i;
if (c->n[0] != 0)
do {
cprintf("\rPress a letter, or use cursor keys and <RETURN> to select a command.");
gotoxy(i, 2);
textbackground(BLUE);
textcolor(LIGHTRED);
cprintf("%-*s", MAXMENUWIDTH, c->n);
PrintMenu(p = c->m, i);
PrintComm(p, i, y = 0);
do {
ch = tolower(getch());
if (!ch) {
ch = -getch();
if (ch==-72) /* up-arrow */
if (!y)
Beep();
else {
ClearComm(p--, i, y--);
PrintComm(p, i, y);
}
else if (ch==-80) /* down-arrow */
if (! (p+1)->n[0])
Beep();
else {
ClearComm(p++, i, y++);
PrintComm(p, i, y);
}
} else {
for (q = c->m; q->n[0] && q->k != ch; q++);
if (q->n[0])
fx = q->x;
}
} while ((ch==-72 || ch==-80) && fx < 0);
if (ch==13 && fx < 0)
fx = p->x;
ClearMenu(i);
gotoxy(i, 2);
textbackground(BLUE);
textcolor(YELLOW);
cprintf("%-*s", MAXMENUWIDTH, c->n);
textcolor(CYAN);
textbackground(BLACK);
gotoxy(1, 25);
cprintf("%52c", ' ');
if (ch==-75)
if (i==2)
Beep();
else {
i -= MAXMENUWIDTH;
c--;
}
else if (ch==-77)
if (! (c+1)->n[0])
Beep();
else {
i += MAXMENUWIDTH;
c++;
}
} while (ch != 27 && fx < 0);
clreol();
} while (fx < 0);
return fx;
}
void ClearWin()
/* Post: Area below command and title bars is clear */
{