More changes to attempt to make this whole new dialog scheme more

robust.  The new "fire" actions, while affording signficantly more
interactivity to libdialog, come at a cost - if the fire action trashes
the screen then you're not going to be in Kansas anymore when you
come back to the menu and there had better be considerable extra
smarts in place for coping with such a situation.  These changes are my
attempt to do just that.
This commit is contained in:
jkh 1996-04-16 12:17:27 +00:00
parent 8a2733c4b6
commit 1955cbd66c
13 changed files with 1391 additions and 1270 deletions

View File

@ -13,7 +13,7 @@
* the author assume any responsibility for damages incurred with
* its use.
*
* $Id: check1.c,v 1.1 1996/01/01 03:45:22 jkh Exp $
* $Id: check1.c,v 1.2 1996/04/07 03:20:50 jkh Exp $
*/
#include <stdio.h>
@ -28,19 +28,19 @@
static int
getBool(dialogMenuItem *self)
{
if (self->data && *((int *)self->data))
return TRUE;
return FALSE;
if (self->data && *((int *)self->data))
return TRUE;
return FALSE;
}
static int
setBool(dialogMenuItem *self)
{
if (self->data) {
*((int *)self->data) = !*((int *)self->data);
return DITEM_SUCCESS;
}
return DITEM_FAILURE;
if (self->data) {
*((int *)self->data) = !*((int *)self->data);
return DITEM_SUCCESS;
}
return DITEM_FAILURE;
}
static int german_book, italian_book, slang_book;
@ -48,17 +48,17 @@ static int german_book, italian_book, slang_book;
static int
clearBooks(dialogMenuItem *self)
{
german_book = italian_book = slang_book = FALSE;
return DITEM_REDRAW;
german_book = italian_book = slang_book = FALSE;
return DITEM_SUCCESS | DITEM_REDRAW;
}
/* menu2 - A more advanced way of using checked and fire hooks to manipulate the backing-variables directly */
/* prompt title checked fire sel data */
/* prompt title checked fire sel data */
static dialogMenuItem menu2[] = {
{ "German", "Buy book on learning German", getBool, setBool, NULL, &german_book},
{ "Italian", "Buy book on learning Italian", getBool, setBool, NULL, &italian_book },
{ "Slang", "Buy book on commonly used insults", getBool, setBool, NULL, &slang_book },
{ "Clear", "Clear book list", NULL, clearBooks, NULL, NULL, ' ', ' ', ' ' },
{ "German", "Buy book on learning German", getBool, setBool, NULL, &german_book},
{ "Italian", "Buy book on learning Italian", getBool, setBool, NULL, &italian_book },
{ "Slang", "Buy book on commonly used insults", getBool, setBool, NULL, &slang_book },
{ "Clear", "Clear book list", NULL, clearBooks, NULL, NULL, ' ', ' ', ' ' },
};
/* End of hook functions */
@ -67,16 +67,16 @@ static dialogMenuItem menu2[] = {
int
main(int argc, unsigned char *argv[])
{
int retval;
init_dialog();
retval = dialog_checklist("this is a dialog_checklist() in action, test #1",
"this checklist menu shows off some of the straight-forward features\n"
"of the new menu system's check & fire dispatch hooks", -1, -1, 4, -4, menu2, NULL);
dialog_clear();
fprintf(stderr, "returned value for dialog_checklist was %d (%d %d %d)\n", retval, german_book, italian_book, slang_book);
end_dialog();
return 0;
int retval;
init_dialog();
retval = dialog_checklist("this is a dialog_checklist() in action, test #1",
"this checklist menu shows off some of the straight-forward features\n"
"of the new menu system's check & fire dispatch hooks", -1, -1, 4, -4, menu2, NULL);
dialog_clear();
fprintf(stderr, "returned value for dialog_checklist was %d (%d %d %d)\n", retval, german_book, italian_book, slang_book);
end_dialog();
return 0;
}

View File

@ -13,7 +13,7 @@
* the author assume any responsibility for damages incurred with
* its use.
*
* $Id: test1.c,v 1.2 1995/12/23 14:53:07 jkh Exp $
* $Id: check2.c,v 1.1 1996/01/01 03:45:23 jkh Exp $
*/
#include <stdio.h>
@ -28,19 +28,19 @@
static int
getBool(dialogMenuItem *self)
{
if (self->data && *((int *)self->data))
return TRUE;
return FALSE;
if (self->data && *((int *)self->data))
return TRUE;
return FALSE;
}
static int
setBool(dialogMenuItem *self)
{
if (self->data) {
*((int *)self->data) = !*((int *)self->data);
return DITEM_SUCCESS;
}
return DITEM_FAILURE;
if (self->data) {
*((int *)self->data) = !*((int *)self->data);
return DITEM_SUCCESS;
}
return DITEM_FAILURE;
}
static int german_book, italian_book, slang_book;
@ -48,39 +48,39 @@ static int german_book, italian_book, slang_book;
static int
clearBooks(dialogMenuItem *self)
{
german_book = italian_book = slang_book = FALSE;
return DITEM_REDRAW;
german_book = italian_book = slang_book = FALSE;
return DITEM_SUCCESS | DITEM_REDRAW;
}
static int
buyBooks(dialogMenuItem *self)
{
char foo[256];
if (german_book || italian_book || slang_book) {
strcpy(foo, "Ok, you're buying books on");
if (german_book)
strcat(foo, " german");
if (italian_book)
strcat(foo, " italian");
if (slang_book)
strcat(foo, " slang");
}
else
strcpy(foo, "You're not buying any books?");
dialog_mesgbox("This is a direct callback for the `Buy' button", foo, -1, -1);
return DITEM_SUCCESS;
char foo[256];
if (german_book || italian_book || slang_book) {
strcpy(foo, "Ok, you're buying books on");
if (german_book)
strcat(foo, " german");
if (italian_book)
strcat(foo, " italian");
if (slang_book)
strcat(foo, " slang");
}
else
strcpy(foo, "You're not buying any books?");
dialog_mesgbox("This is a direct callback for the `Buy' button", foo, -1, -1);
return DITEM_SUCCESS;
}
/* menu3 - Look mom! We can finally use our own OK and Cancel buttons! */
/* prompt title checked fire sel data */
/* prompt title checked fire sel data */
static dialogMenuItem menu3[] = {
{ "Buy!", NULL, NULL, buyBooks }, /* New "OK" button */
{ "No Way!", NULL, NULL, NULL }, /* New "Cancel" button */
{ "German", "Buy books on learning German", getBool, setBool, NULL, &german_book },
{ "Italian", "Buy books on learning Italian", getBool, setBool, NULL, &italian_book },
{ "Slang", "Buy books on commonly used insults", getBool, setBool, NULL, &slang_book },
{ "Clear", "Clear book list", NULL, clearBooks, NULL, NULL, ' ', ' ', ' ' },
{ "Buy!", NULL, NULL, buyBooks }, /* New "OK" button */
{ "No Way!", NULL, NULL, NULL }, /* New "Cancel" button */
{ "German", "Buy books on learning German", getBool, setBool, NULL, &german_book },
{ "Italian", "Buy books on learning Italian", getBool, setBool, NULL, &italian_book },
{ "Slang", "Buy books on commonly used insults", getBool, setBool, NULL, &slang_book },
{ "Clear", "Clear book list", NULL, clearBooks, NULL, NULL, ' ', ' ', ' ' },
};
/* End of hook functions */
@ -89,16 +89,16 @@ static dialogMenuItem menu3[] = {
int
main(int argc, unsigned char *argv[])
{
int retval;
init_dialog();
retval = dialog_checklist("this is dialog_checklist() in action, test #2",
"Same as before, but now we relabel the buttons and override the OK action.",
-1, -1, 4, -4, menu3 + 2, (char *)TRUE);
dialog_clear();
fprintf(stderr, "returned value for dialog_checklist was %d\n", retval);
end_dialog();
return 0;
int retval;
init_dialog();
retval = dialog_checklist("this is dialog_checklist() in action, test #2",
"Same as before, but now we relabel the buttons and override the OK action.",
-1, -1, 4, -4, menu3 + 2, (char *)TRUE);
dialog_clear();
fprintf(stderr, "returned value for dialog_checklist was %d\n", retval);
end_dialog();
return 0;
}

View File

@ -13,7 +13,7 @@
* the author assume any responsibility for damages incurred with
* its use.
*
* $Id$
* $Id: check3.c,v 1.1 1996/01/01 03:45:23 jkh Exp $
*
*/
@ -25,19 +25,19 @@
static int
getBool(dialogMenuItem *self)
{
if (self->data && *((int *)self->data))
return TRUE;
return FALSE;
if (self->data && *((int *)self->data))
return TRUE;
return FALSE;
}
static int
setBool(dialogMenuItem *self)
{
if (self->data) {
*((int *)self->data) = !*((int *)self->data);
return DITEM_SUCCESS;
}
return DITEM_FAILURE;
if (self->data) {
*((int *)self->data) = !*((int *)self->data);
return DITEM_SUCCESS;
}
return DITEM_FAILURE;
}
static int german_book, italian_book, slang_book;
@ -46,26 +46,26 @@ static int spending;
static int
check(dialogMenuItem *self)
{
return ((int)self->data == spending);
return ((int)self->data == spending);
}
static int
spend(dialogMenuItem *self)
{
spending = (int)self->data;
return DITEM_REDRAW;
spending = (int)self->data;
return DITEM_SUCCESS | DITEM_REDRAW;
}
/* menu4 - Show off a simulated compound menu (group at top is checklist, group at bottom radio) */
/* prompt title checked fire sel, data lbra mark rbra */
/* prompt title checked fire sel, data lbra mark rbra */
static dialogMenuItem menu4[] = {
{ "German", "Buy books on learning German", getBool, setBool, NULL, &german_book },
{ "Italian", "Buy books on learning Italian", getBool, setBool, NULL, &italian_book },
{ "Slang", "Buy books on commonly used insults", getBool, setBool, NULL, &slang_book },
{ "-----", "----------------------------------", NULL, NULL, NULL, NULL, ' ', ' ', ' ' },
{ "1000", "Spend $1,000", check, spend, NULL, (void *)1000, '(', '*', ')' },
{ "500", "Spend $500", check, spend, NULL, (void *)500, '(', '*', ')' },
{ "100", "Spend $100", check, spend, NULL, (void *)100, '(', '*', ')' },
{ "German", "Buy books on learning German", getBool, setBool, NULL, &german_book },
{ "Italian","Buy books on learning Italian", getBool, setBool, NULL, &italian_book },
{ "Slang", "Buy books on commonly used insults", getBool, setBool, NULL, &slang_book },
{ "-----", "----------------------------------", NULL, NULL, NULL, NULL, ' ', ' ', ' ' },
{ "1000", "Spend $1,000", check, spend, NULL, (void *)1000, '(', '*', ')' },
{ "500", "Spend $500", check, spend, NULL, (void *)500, '(', '*', ')' },
{ "100", "Spend $100", check, spend, NULL, (void *)100, '(', '*', ')' },
};
/* End of hook functions */
@ -74,18 +74,18 @@ static dialogMenuItem menu4[] = {
int
main(int argc, unsigned char *argv[])
{
int retval;
init_dialog();
retval = dialog_checklist("this is dialog_checklist() in action, test #3",
"Now we show off some of the button 'styles' one can create.",
-1, -1, 7, -7, menu4, NULL);
dialog_clear();
fprintf(stderr, "spent $%d on %s%s%s books\n", spending, german_book ? " german" : "",
italian_book ? " italian" : "", slang_book ? " slang" : "");
end_dialog();
return 0;
int retval;
init_dialog();
retval = dialog_checklist("this is dialog_checklist() in action, test #3",
"Now we show off some of the button 'styles' one can create.",
-1, -1, 7, -7, menu4, NULL);
dialog_clear();
fprintf(stderr, "spent $%d on %s%s%s books\n", spending, german_book ? " german" : "",
italian_book ? " italian" : "", slang_book ? " slang" : "");
end_dialog();
return 0;
}

View File

@ -13,7 +13,7 @@
* the author assume any responsibility for damages incurred with
* its use.
*
* $Id: menu1.c,v 1.1 1996/01/01 03:45:26 jkh Exp $
* $Id: menu1.c,v 1.2 1996/04/07 03:20:52 jkh Exp $
*/
#include <stdio.h>
@ -29,69 +29,69 @@ static enum { nowhere, berlin, rome, ny } where;
static int
_menu1_berlin_action(dialogMenuItem *self)
{
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == berlin) {
dialog_mesgbox("excuse me?", "But you're already *in* Berlin!", -1, -1);
}
else {
where = berlin;
dialog_mesgbox("whoosh!", "Welcome to Berlin! Have a beer!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == berlin) {
dialog_mesgbox("excuse me?", "But you're already *in* Berlin!", -1, -1);
}
else {
where = berlin;
dialog_mesgbox("whoosh!", "Welcome to Berlin! Have a beer!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
}
static int
_menu1_rome_action(dialogMenuItem *self)
{
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == rome) {
dialog_mesgbox("The wine must be getting to you..", "You're already in Rome!", -1, -1);
}
else {
where = rome;
dialog_mesgbox("whoosh!", "Welcome to Rome! Have a coffee!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == rome) {
dialog_mesgbox("The wine must be getting to you..", "You're already in Rome!", -1, -1);
}
else {
where = rome;
dialog_mesgbox("whoosh!", "Welcome to Rome! Have a coffee!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
}
static int
_menu1_ny_action(dialogMenuItem *self)
{
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == ny) {
dialog_mesgbox("Say what?", "You're already there!", -1, -1);
}
else {
where = ny;
dialog_mesgbox("whoosh!", "Welcome to New York! Now go someplace else!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == ny) {
dialog_mesgbox("Say what?", "You're already there!", -1, -1);
}
else {
where = ny;
dialog_mesgbox("whoosh!", "Welcome to New York! Now go someplace else!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
}
/* menu1 - show off the "fire" action hook */
/* prompt title checked fire */
/* prompt title checked fire */
static dialogMenuItem menu1[] = {
{ "Berlin", "Go visit Germany's new capitol", NULL, _menu1_berlin_action },
{ "Rome", "Go visit the Roman ruins", NULL, _menu1_rome_action },
{ "New York", "Go visit the streets of New York", NULL, _menu1_ny_action },
{ "Berlin", "Go visit Germany's new capitol", NULL, _menu1_berlin_action },
{ "Rome", "Go visit the Roman ruins", NULL, _menu1_rome_action },
{ "New York", "Go visit the streets of New York", NULL, _menu1_ny_action },
};
/* End of hook functions */
@ -100,17 +100,17 @@ static dialogMenuItem menu1[] = {
int
main(int argc, unsigned char *argv[])
{
int retval;
init_dialog();
retval = dialog_menu("this is dialog_menu() in action, test #1",
"this simple menu shows off some of the straight-forward features\n"
"of the new menu system's action dispatch hooks. Select Cancel to leave",
-1, -1, 3, -3, menu1, NULL, NULL, NULL);
dialog_clear();
fprintf(stderr, "returned value for dialog_menu was %d\n", retval);
end_dialog();
return 0;
int retval;
init_dialog();
retval = dialog_menu("this is dialog_menu() in action, test #1",
"this simple menu shows off some of the straight-forward features\n"
"of the new menu system's action dispatch hooks. Select Cancel to leave",
-1, -1, 3, -3, menu1, NULL, NULL, NULL);
dialog_clear();
fprintf(stderr, "returned value for dialog_menu was %d\n", retval);
end_dialog();
return 0;
}

View File

@ -13,7 +13,7 @@
* the author assume any responsibility for damages incurred with
* its use.
*
* $Id: menu2.c,v 1.1 1996/01/01 03:45:26 jkh Exp $
* $Id: menu2.c,v 1.2 1996/04/07 03:20:54 jkh Exp $
*/
#include <stdio.h>
@ -29,69 +29,69 @@ static enum { nowhere, berlin, rome, ny } where;
static int
_menu1_berlin_action(dialogMenuItem *self)
{
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == berlin) {
dialog_mesgbox("excuse me?", "But you're already *in* Berlin!", -1, -1);
}
else {
where = berlin;
dialog_mesgbox("whoosh!", "Welcome to Berlin! Have a beer!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == berlin) {
dialog_mesgbox("excuse me?", "But you're already *in* Berlin!", -1, -1);
}
else {
where = berlin;
dialog_mesgbox("whoosh!", "Welcome to Berlin! Have a beer!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
}
static int
_menu1_rome_action(dialogMenuItem *self)
{
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == rome) {
dialog_mesgbox("The wine must be getting to you..", "You're already in Rome!", -1, -1);
}
else {
where = rome;
dialog_mesgbox("whoosh!", "Welcome to Rome! Have a coffee!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == rome) {
dialog_mesgbox("The wine must be getting to you..", "You're already in Rome!", -1, -1);
}
else {
where = rome;
dialog_mesgbox("whoosh!", "Welcome to Rome! Have a coffee!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
}
static int
_menu1_ny_action(dialogMenuItem *self)
{
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == ny) {
dialog_mesgbox("Say what?", "You're already there!", -1, -1);
}
else {
where = ny;
dialog_mesgbox("whoosh!", "Welcome to New York! Now go someplace else!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
WINDOW *w;
int st = DITEM_FAILURE;
w = dupwin(newscr);
if (where == ny) {
dialog_mesgbox("Say what?", "You're already there!", -1, -1);
}
else {
where = ny;
dialog_mesgbox("whoosh!", "Welcome to New York! Now go someplace else!", -1, -1);
}
touchwin(w);
wrefresh(w);
delwin(w);
return st;
}
/* menu1 - show off the "fire" action hook */
/* prompt title checked fire */
/* prompt title checked fire */
static dialogMenuItem menu1[] = {
{ "Berlin", "Go visit Germany's new capitol", NULL, _menu1_berlin_action },
{ "Rome", "Go visit the Roman ruins", NULL, _menu1_rome_action },
{ "New York", "Go visit the streets of New York", NULL, _menu1_ny_action },
{ "Berlin", "Go visit Germany's new capitol", NULL, _menu1_berlin_action },
{ "Rome", "Go visit the Roman ruins", NULL, _menu1_rome_action },
{ "New York", "Go visit the streets of New York", NULL, _menu1_ny_action },
};
/* End of hook functions */
@ -100,20 +100,20 @@ static dialogMenuItem menu1[] = {
int
main(int argc, unsigned char *argv[])
{
int retval;
init_dialog();
use_helpfile("menu2.c");
use_helpline("Type F1 to view the source for this demo");
retval = dialog_menu("this is dialog_menu() in action, test #2",
"this simple menu shows off some of the straight-forward features\n"
"of the new menu system's action dispatch hooks as well as a helpline\n"
"and a helpfile. Select Cancel to leave",
-1, -1, 3, -3, menu1, NULL, NULL, NULL);
dialog_clear();
fprintf(stderr, "returned value for dialog_menu was %d\n", retval);
end_dialog();
return 0;
int retval;
init_dialog();
use_helpfile("menu2.c");
use_helpline("Type F1 to view the source for this demo");
retval = dialog_menu("this is dialog_menu() in action, test #2",
"this simple menu shows off some of the straight-forward features\n"
"of the new menu system's action dispatch hooks as well as a helpline\n"
"and a helpfile. Select Cancel to leave",
-1, -1, 3, -3, menu1, NULL, NULL, NULL);
dialog_clear();
fprintf(stderr, "returned value for dialog_menu was %d\n", retval);
end_dialog();
return 0;
}

View File

@ -13,7 +13,7 @@
* the author assume any responsibility for damages incurred with
* its use.
*
* $Id: menu3.c,v 1.1 1996/01/01 03:45:27 jkh Exp $
* $Id: menu3.c,v 1.2 1996/04/07 03:20:55 jkh Exp $
*/
#include <stdio.h>
@ -28,61 +28,61 @@
static int
stop(dialogMenuItem *self)
{
dialog_mesgbox("!", "I'm no idiot!", -1, -1);
return DITEM_SUCCESS;
dialog_mesgbox("!", "I'm no idiot!", -1, -1);
return DITEM_SUCCESS;
}
static int
maybe(dialogMenuItem *self)
{
WINDOW *w;
w = dupwin(newscr);
dialog_mesgbox("!", "I said don't rush me! I'm THINKING!", -1, -1);
touchwin(w);
wrefresh(w);
delwin(w);
return DITEM_FAILURE;
WINDOW *w;
w = dupwin(newscr);
dialog_mesgbox("!", "I said don't rush me! I'm THINKING!", -1, -1);
touchwin(w);
wrefresh(w);
delwin(w);
return DITEM_FAILURE;
}
/* Dummy menu just to show of the ability */
static char *insurance[] = {
"1,000,000", "Mondo insurance policy", "Off",
"5,000,000", "Mega insurance policy", "Off",
"10,000,000", "Friend! Most Favored customer!"
"1,000,000", "Mondo insurance policy", "Off",
"5,000,000", "Mega insurance policy", "Off",
"10,000,000", "Friend! Most Favored customer!"
};
static void
preinsure(dialogMenuItem *self, int is_selected)
{
if (is_selected) {
static WINDOW *w;
/* This has to be here first if you want to see selection traverse properly in the invoking menu */
refresh();
w = dupwin(newscr);
DialogX = 1;
DialogY = 13;
dialog_radiolist("How much insurance would you like to take out?",
"If you're really going to do this, we recommend some insurance\n"
"first! What kind of life insurance policy would you like?",
-1, -1, 3, 3, insurance, NULL);
touchwin(w);
wrefresh(w);
delwin(w);
}
if (is_selected) {
static WINDOW *w;
/* This has to be here first if you want to see selection traverse properly in the invoking menu */
refresh();
w = dupwin(newscr);
DialogX = 1;
DialogY = 13;
dialog_radiolist("How much insurance would you like to take out?",
"If you're really going to do this, we recommend some insurance\n"
"first! What kind of life insurance policy would you like?",
-1, -1, 3, 3, insurance, NULL);
touchwin(w);
wrefresh(w);
delwin(w);
}
}
/*
* Show a simple menu that puts up a sub menu when a certain item is traversed to
*/
/* prompt title checked fire sel */
/* prompt title checked fire sel */
static dialogMenuItem doit[] = {
{ "Stop", "No, I'm not going to do that!", NULL, stop, NULL },
{ "Maybe", "I'm still thinking about it, don't rush me!", NULL, maybe, NULL, },
{ "Go", "Yes! Yes! I want to do it!", NULL, NULL, preinsure },
{ "Stop", "No, I'm not going to do that!", NULL, stop, NULL },
{ "Maybe", "I'm still thinking about it, don't rush me!", NULL, maybe, NULL, },
{ "Go", "Yes! Yes! I want to do it!", NULL, NULL, preinsure },
};
/* End of hook functions */
@ -91,20 +91,20 @@ static dialogMenuItem doit[] = {
int
main(int argc, unsigned char *argv[])
{
int retval;
init_dialog();
DialogX = 5;
DialogY = 1;
retval = dialog_menu("Do you have the GUTS?",
"C'mon, macho man! Do you have what it takes to do something REALLY\n"
"dangerous and stupid? WHAT ARE YOU WAITING FOR?!",
-1, -1, 3, -3, doit, NULL, NULL, NULL);
dialog_clear();
fprintf(stderr, "returned value for dialog_menu was %d\n", retval);
end_dialog();
return 0;
int retval;
init_dialog();
DialogX = 5;
DialogY = 1;
retval = dialog_menu("Do you have the GUTS?",
"C'mon, macho man! Do you have what it takes to do something REALLY\n"
"dangerous and stupid? WHAT ARE YOU WAITING FOR?!",
-1, -1, 3, -3, doit, NULL, NULL, NULL);
dialog_clear();
fprintf(stderr, "returned value for dialog_menu was %d\n", retval);
end_dialog();
return 0;
}

View File

@ -13,7 +13,7 @@
* the author assume any responsibility for damages incurred with
* its use.
*
* $Id: radio1.c,v 1.1 1996/01/01 03:45:29 jkh Exp $
* $Id: radio1.c,v 1.2 1996/04/07 03:20:57 jkh Exp $
*/
#include <stdio.h>
@ -30,22 +30,22 @@ static int spending;
static int
check(dialogMenuItem *self)
{
return ((int)self->data == spending);
return ((int)self->data == spending);
}
static int
spend(dialogMenuItem *self)
{
spending = (int)self->data;
return DITEM_REDRAW;
spending = (int)self->data;
return DITEM_SUCCESS | DITEM_REDRAW;
}
/* menu5 - Show a simple radiolist menu that inherits the radio appearance by default */
/* prompt title checked fire sel data */
/* prompt title checked fire sel data */
static dialogMenuItem menu5[] = {
{ "1000", "Spend $1,000", check, spend, NULL, (void *)1000 },
{ "500", "Spend $500", check, spend, NULL, (void *)500 },
{ "100", "Spend $100", check, spend, NULL, (void *)100 },
{ "1000", "Spend $1,000", check, spend, NULL, (void *)1000 },
{ "500", "Spend $500", check, spend, NULL, (void *)500 },
{ "100", "Spend $100", check, spend, NULL, (void *)100 },
};
/* End of hook functions */
@ -54,17 +54,17 @@ static dialogMenuItem menu5[] = {
int
main(int argc, unsigned char *argv[])
{
int retval;
init_dialog();
retval = dialog_radiolist("this is dialog_radiolist() in action, test #1",
"this radio menu shows off some of the straight-forward features\n"
"of the new menu system's check & fire dispatch hooks", -1, -1, 3, -3, menu5, NULL);
dialog_clear();
fprintf(stderr, "returned value for dialog_radiolist was %d (money set to %d)\n", retval, spending);
end_dialog();
return 0;
int retval;
init_dialog();
retval = dialog_radiolist("this is dialog_radiolist() in action, test #1",
"this radio menu shows off some of the straight-forward features\n"
"of the new menu system's check & fire dispatch hooks", -1, -1, 3, -3, menu5, NULL);
dialog_clear();
fprintf(stderr, "returned value for dialog_radiolist was %d (money set to %d)\n", retval, spending);
end_dialog();
return 0;
}

View File

@ -13,7 +13,7 @@
* the author assume any responsibility for damages incurred with
* its use.
*
* $Id: radio2.c,v 1.1 1996/01/01 03:45:29 jkh Exp $
* $Id: radio2.c,v 1.2 1996/04/07 03:20:59 jkh Exp $
*/
#include <stdio.h>
@ -30,39 +30,39 @@ static char bachelor[10], bachelette[10];
static int
getBachelor(dialogMenuItem *self)
{
return !strcmp(bachelor, self->prompt);
return !strcmp(bachelor, self->prompt);
}
static int
setBachelor(dialogMenuItem *self)
{
strcpy(bachelor, self->prompt);
return DITEM_REDRAW;
strcpy(bachelor, self->prompt);
return DITEM_SUCCESS | DITEM_REDRAW;
}
static int
getBachelette(dialogMenuItem *self)
{
return !strcmp(bachelette, self->prompt);
return !strcmp(bachelette, self->prompt);
}
static int
setBachelette(dialogMenuItem *self)
{
strcpy(bachelette, self->prompt);
return DITEM_REDRAW;
strcpy(bachelette, self->prompt);
return DITEM_SUCCESS | DITEM_REDRAW;
}
/* menu6- More complex radiolist menu that creates two groups in a single menu */
/* prompt title checked fire */
/* prompt title checked fire */
static dialogMenuItem menu6[] = {
{ "Tom", "Tom's a dynamic shoe salesman from Tulsa, OK!", getBachelor, setBachelor },
{ "Dick", "Dick's a retired engine inspector from McDonnell-Douglas!", getBachelor, setBachelor },
{ "Harry", "Harry's a professional female impersonator from Las Vegas!", getBachelor, setBachelor },
{ "-----", "----------------------------------", NULL, NULL, NULL, NULL, ' ', ' ', ' ' },
{ "Jane", "Jane's a twice-divorced housewife from Moose, Oregon!", getBachelette, setBachelette },
{ "Sally", "Sally's a shy Human Resources Manager for IBM!", getBachelette, setBachelette },
{ "Mary", "Mary's an energetic serial killer on the lam!", getBachelette, setBachelette },
{ "Tom", "Tom's a dynamic shoe salesman from Tulsa, OK!", getBachelor, setBachelor },
{ "Dick", "Dick's a retired engine inspector from McDonnell-Douglas!", getBachelor, setBachelor },
{ "Harry", "Harry's a professional female impersonator from Las Vegas!", getBachelor, setBachelor },
{ "-----", "----------------------------------", NULL, NULL, NULL, NULL, ' ', ' ', ' ' },
{ "Jane", "Jane's a twice-divorced housewife from Moose, Oregon!", getBachelette, setBachelette },
{ "Sally", "Sally's a shy Human Resources Manager for IBM!", getBachelette, setBachelette },
{ "Mary", "Mary's an energetic serial killer on the lam!", getBachelette, setBachelette },
};
/* End of hook functions */
@ -71,18 +71,18 @@ static dialogMenuItem menu6[] = {
int
main(int argc, unsigned char *argv[])
{
int retval;
init_dialog();
retval = dialog_radiolist("this is dialog_radiolist() in action, test #2",
"Welcome to \"The Love Blender!\" - America's favorite game show\n"
"where YOU, the contestant, get to choose which of these two\n"
"fine specimens of humanity will go home together, whether they\n"
"like it or not!", -1, -1, 7, -7, menu6, NULL);
dialog_clear();
fprintf(stderr, "I'm sure that %s and %s will be very happy together!\n", bachelor, bachelette);
end_dialog();
return 0;
int retval;
init_dialog();
retval = dialog_radiolist("this is dialog_radiolist() in action, test #2",
"Welcome to \"The Love Blender!\" - America's favorite game show\n"
"where YOU, the contestant, get to choose which of these two\n"
"fine specimens of humanity will go home together, whether they\n"
"like it or not!", -1, -1, 7, -7, menu6, NULL);
dialog_clear();
fprintf(stderr, "I'm sure that %s and %s will be very happy together!\n", bachelor, bachelette);
end_dialog();
return 0;
}

View File

@ -13,7 +13,7 @@
* the author assume any responsibility for damages incurred with
* its use.
*
* $Id: radio3.c,v 1.1 1996/01/01 03:45:30 jkh Exp $
* $Id: radio3.c,v 1.2 1996/04/07 03:21:01 jkh Exp $
*/
#include <stdio.h>
@ -30,32 +30,32 @@ static int spending;
static int
check(dialogMenuItem *self)
{
return ((int)self->data == spending);
return ((int)self->data == spending);
}
static int
spend(dialogMenuItem *self)
{
spending = (int)self->data;
return DITEM_REDRAW;
spending = (int)self->data;
return DITEM_SUCCESS | DITEM_REDRAW;
}
static void
ask(dialogMenuItem *self, int is_selected)
{
if (is_selected) {
char *str;
if (!strcmp(self->prompt, "1000"))
str = "You'd better ask both your parents first! ";
else if (!strcmp(self->prompt, "500"))
str = "You'd better at least ask your Dad! ";
else
str = "Yes, being frugal is probably a good idea!";
DialogX = 15;
DialogY = 17;
dialog_msgbox("Free Advice", str, -1, -1, 0);
}
if (is_selected) {
char *str;
if (!strcmp(self->prompt, "1000"))
str = "You'd better ask both your parents first! ";
else if (!strcmp(self->prompt, "500"))
str = "You'd better at least ask your Dad! ";
else
str = "Yes, being frugal is probably a good idea!";
DialogX = 15;
DialogY = 17;
dialog_msgbox("Free Advice", str, -1, -1, 0);
}
}
/*
@ -63,11 +63,11 @@ ask(dialogMenuItem *self, int is_selected)
* a different location, leaving room for a msg box below it. This shows off the DialogX/DialogY extensions.
*/
/* prompt title checked fire sel data */
/* prompt title checked fire sel data */
static dialogMenuItem menu5[] = {
{ "1000", "Spend $1,000", check, spend, ask, (void *)1000 },
{ "500", "Spend $500", check, spend, ask, (void *)500 },
{ "100", "Spend $100", check, spend, ask, (void *)100 },
{ "1000", "Spend $1,000", check, spend, ask, (void *)1000 },
{ "500", "Spend $500", check, spend, ask, (void *)500 },
{ "100", "Spend $100", check, spend, ask, (void *)100 },
};
/* End of hook functions */
@ -76,22 +76,22 @@ static dialogMenuItem menu5[] = {
int
main(int argc, unsigned char *argv[])
{
int retval;
init_dialog();
DialogX = 5;
DialogY = 1;
retval = dialog_radiolist("this is dialog_radiolist() in action, test #3",
"This radio menu shows off the ability to put dialog menus and other\n"
"controls at different locations, as well as the `selected' hook which\n"
"lets you follow the traversal of the selection bar as well as what's\n"
"selected.",
-1, -1, 3, -3, menu5, NULL);
dialog_clear();
fprintf(stderr, "returned value for dialog_radiolist was %d (money set to %d)\n", retval, spending);
end_dialog();
return 0;
int retval;
init_dialog();
DialogX = 5;
DialogY = 1;
retval = dialog_radiolist("this is dialog_radiolist() in action, test #3",
"This radio menu shows off the ability to put dialog menus and other\n"
"controls at different locations, as well as the `selected' hook which\n"
"lets you follow the traversal of the selection bar as well as what's\n"
"selected.",
-1, -1, 3, -3, menu5, NULL);
dialog_clear();
fprintf(stderr, "returned value for dialog_radiolist was %d (money set to %d)\n", retval, spending);
end_dialog();
return 0;
}

View File

@ -40,440 +40,469 @@ int
dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width,
int list_height, int item_no, void *it, unsigned char *result)
{
int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
l, k, scroll = 0, max_choice, *status;
int redraw_menu = FALSE;
char okButton, cancelButton;
WINDOW *dialog, *list;
unsigned char **items;
dialogMenuItem *ditems;
/* Allocate space for storing item on/off status */
if ((status = alloca(sizeof(int) * abs(item_no))) == NULL) {
endwin();
fprintf(stderr, "\nCan't allocate memory in dialog_checklist().\n");
exit(-1);
}
/* Previous calling syntax, e.g. just a list of strings? */
if (item_no >= 0) {
items = it;
ditems = NULL;
/* Initializes status */
for (i = 0; i < item_no; i++)
status[i] = !strcasecmp(items[i*3 + 2], "on");
}
/* It's the new specification format - fake the rest of the code out */
else {
item_no = abs(item_no);
ditems = it;
items = (unsigned char **)alloca((item_no * 3) * sizeof(unsigned char *));
/* Initializes status */
for (i = 0; i < item_no; i++) {
status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
items[i*3] = ditems[i].prompt;
items[i*3 + 1] = ditems[i].title;
items[i*3 + 2] = status[i] ? "on" : "off";
int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
l, k, scroll = 0, max_choice, *status;
int redraw_menu = FALSE;
char okButton, cancelButton;
WINDOW *dialog, *list, *save;
unsigned char **items;
dialogMenuItem *ditems;
/* Allocate space for storing item on/off status */
if ((status = alloca(sizeof(int) * abs(item_no))) == NULL) {
endwin();
fprintf(stderr, "\nCan't allocate memory in dialog_checklist().\n");
exit(-1);
}
}
max_choice = MIN(list_height, item_no);
check_x = 0;
item_x = 0;
/* Find length of longest item in order to center checklist */
for (i = 0; i < item_no; i++) {
l = strlen(items[i*3]);
for (j = 0; j < item_no; j++) {
k = strlen(items[j*3 + 1]);
check_x = MAX(check_x, l + k + 6);
/* Previous calling syntax, e.g. just a list of strings? */
if (item_no >= 0) {
items = it;
ditems = NULL;
/* Initializes status */
for (i = 0; i < item_no; i++)
status[i] = !strcasecmp(items[i*3 + 2], "on");
}
item_x = MAX(item_x, l);
}
if (height < 0)
height = strheight(prompt)+list_height+4+2;
if (width < 0) {
i = strwidth(prompt);
j = ((title != NULL) ? strwidth(title) : 0);
width = MAX(i,j);
width = MAX(width,check_x+4)+4;
}
width = MAX(width,24);
if (width > COLS)
width = COLS;
if (height > LINES)
height = LINES;
/* center dialog box on screen */
x = (COLS - width)/2;
y = (LINES - height)/2;
#ifdef HAVE_NCURSES
if (use_shadow)
draw_shadow(stdscr, y, x, height, width);
#endif
dialog = newwin(height, width, y, x);
if (dialog == NULL) {
endwin();
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width, y, x);
return -1;
}
keypad(dialog, TRUE);
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
wattrset(dialog, border_attr);
wmove(dialog, height-3, 0);
waddch(dialog, ACS_LTEE);
for (i = 0; i < width-2; i++)
waddch(dialog, ACS_HLINE);
wattrset(dialog, dialog_attr);
waddch(dialog, ACS_RTEE);
wmove(dialog, height-2, 1);
for (i = 0; i < width-2; i++)
waddch(dialog, ' ');
if (title != NULL) {
wattrset(dialog, title_attr);
wmove(dialog, 0, (width - strlen(title))/2 - 1);
waddch(dialog, ' ');
waddstr(dialog, title);
waddch(dialog, ' ');
}
wattrset(dialog, dialog_attr);
wmove(dialog, 1, 2);
print_autowrap(dialog, prompt, height - 1, width - 2, width, 1, 2, TRUE, FALSE);
list_width = width - 6;
getyx(dialog, cur_y, cur_x);
box_y = cur_y + 1;
box_x = (width - list_width) / 2 - 1;
/* create new window for the list */
list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
if (list == NULL) {
endwin();
fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", list_height, list_width,
y + box_y + 1, x + box_x + 1);
return -1;
}
keypad(list, TRUE);
/* draw a box around the list items */
draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, menubox_border_attr, menubox_attr);
check_x = (list_width - check_x) / 2;
item_x = check_x + item_x + 6;
/* Print the list */
for (i = 0; i < max_choice; i++)
print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice, DREF(ditems, i));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
display_helpline(dialog, height-1, width);
x = width/2-11;
y = height-2;
/* Is this a fancy new style argument string where we get to override
* the buttons, or an old style one where they're fixed?
*/
if (ditems && result) {
cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : FALSE);
okButton = toupper(ditems[OK_BUTTON].prompt[0]);
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : TRUE);
}
else {
cancelButton = 'C';
print_button(dialog, "Cancel", y, x + 14, FALSE);
okButton = 'O';
print_button(dialog, " OK ", y, x, TRUE);
}
wrefresh(dialog);
while (key != ESC) {
key = wgetch(dialog);
/* Shortcut to OK? */
if (toupper(key) == okButton) {
if (ditems && result && ditems[OK_BUTTON].fire) {
if (ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else
delwin(dialog);
}
else {
delwin(dialog);
*result = '\0';
/* It's the new specification format - fake the rest of the code out */
else {
item_no = abs(item_no);
ditems = it;
items = (unsigned char **)alloca((item_no * 3) * sizeof(unsigned char *));
/* Initializes status */
for (i = 0; i < item_no; i++) {
if (status[i]) {
strcat(result, items[i*3]);
strcat(result, "\n");
}
status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
items[i*3] = ditems[i].prompt;
items[i*3 + 1] = ditems[i].title;
items[i*3 + 2] = status[i] ? "on" : "off";
}
}
return 0;
}
/* Shortcut to cancel? */
else if (toupper(key) == cancelButton) {
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
if (ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
max_choice = MIN(list_height, item_no);
check_x = 0;
item_x = 0;
/* Find length of longest item in order to center checklist */
for (i = 0; i < item_no; i++) {
l = strlen(items[i*3]);
for (j = 0; j < item_no; j++) {
k = strlen(items[j*3 + 1]);
check_x = MAX(check_x, l + k + 6);
}
}
delwin(dialog);
return 1;
item_x = MAX(item_x, l);
}
if (height < 0)
height = strheight(prompt)+list_height+4+2;
if (width < 0) {
i = strwidth(prompt);
j = ((title != NULL) ? strwidth(title) : 0);
width = MAX(i,j);
width = MAX(width,check_x+4)+4;
}
width = MAX(width,24);
if (width > COLS)
width = COLS;
if (height > LINES)
height = LINES;
/* center dialog box on screen */
x = (COLS - width)/2;
y = (LINES - height)/2;
/* Check if key pressed matches first character of any item tag in list */
draw:
save = dupwin(newscr);
#ifdef HAVE_NCURSES
if (use_shadow)
draw_shadow(stdscr, y, x, height, width);
#endif
dialog = newwin(height, width, y, x);
if (dialog == NULL) {
delwin(save);
endwin();
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width, y, x);
return -1;
}
keypad(dialog, TRUE);
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
wattrset(dialog, border_attr);
wmove(dialog, height-3, 0);
waddch(dialog, ACS_LTEE);
for (i = 0; i < width-2; i++)
waddch(dialog, ACS_HLINE);
wattrset(dialog, dialog_attr);
waddch(dialog, ACS_RTEE);
wmove(dialog, height-2, 1);
for (i = 0; i < width-2; i++)
waddch(dialog, ' ');
if (title != NULL) {
wattrset(dialog, title_attr);
wmove(dialog, 0, (width - strlen(title))/2 - 1);
waddch(dialog, ' ');
waddstr(dialog, title);
waddch(dialog, ' ');
}
wattrset(dialog, dialog_attr);
wmove(dialog, 1, 2);
print_autowrap(dialog, prompt, height - 1, width - 2, width, 1, 2, TRUE, FALSE);
list_width = width - 6;
getyx(dialog, cur_y, cur_x);
box_y = cur_y + 1;
box_x = (width - list_width) / 2 - 1;
/* create new window for the list */
list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
if (list == NULL) {
delwin(dialog);
delwin(save);
endwin();
fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", list_height, list_width,
y + box_y + 1, x + box_x + 1);
return -1;
}
keypad(list, TRUE);
/* draw a box around the list items */
draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, menubox_border_attr, menubox_attr);
check_x = (list_width - check_x) / 2;
item_x = check_x + item_x + 6;
/* Print the list */
for (i = 0; i < max_choice; i++)
if (key < 0x100 && toupper(key) == toupper(items[(scroll+i)*3][0]))
break;
if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) || key == KEY_UP ||
key == KEY_DOWN || key == ' ' || key == '+' || key == '-' ) {
if (key >= '1' && key <= MIN('9', '0'+max_choice))
i = key - '1';
else if (key == KEY_UP || key == '-') {
if (!choice) {
if (scroll) {
/* Scroll list down */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
if (list_height > 1) {
/* De-highlight current first item before scrolling down */
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE, DREF(ditems, scroll));
scrollok(list, TRUE);
wscrl(list, -1);
scrollok(list, FALSE);
}
scroll--;
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE, DREF(ditems, scroll));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
}
continue; /* wait for another key press */
}
else
i = choice - 1;
}
else if (key == KEY_DOWN || key == '+') {
if (choice == max_choice - 1) {
if (scroll+choice < item_no-1) {
/* Scroll list up */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
if (list_height > 1) {
/* De-highlight current last item before scrolling up */
print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1],
status[scroll+max_choice-1], max_choice-1, FALSE, DREF(ditems, scroll + max_choice - 1));
scrollok(list, TRUE);
scroll(list);
scrollok(list, FALSE);
}
scroll++;
print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1],
status[scroll+max_choice-1], max_choice-1, TRUE, DREF(ditems, scroll + max_choice - 1));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
}
continue; /* wait for another key press */
}
else
i = choice + 1;
}
else if (key == ' ') { /* Toggle item status */
char lbra = 0, rbra = 0, mark = 0;
if (ditems) {
if (ditems[scroll+choice].fire) {
int st = ditems[scroll+choice].fire(&ditems[scroll+choice]);
if (st == DITEM_LEAVE_MENU) {
/* Allow a fire action to take us out of the menu */
key = ESC;
break;
print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice, DREF(ditems, i));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
display_helpline(dialog, height-1, width);
x = width/2-11;
y = height-2;
/* Is this a fancy new style argument string where we get to override
* the buttons, or an old style one where they're fixed?
*/
if (ditems && result) {
cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : FALSE);
okButton = toupper(ditems[OK_BUTTON].prompt[0]);
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : TRUE);
}
else {
cancelButton = 'C';
print_button(dialog, "Cancel", y, x + 14, FALSE);
okButton = 'O';
print_button(dialog, " OK ", y, x, TRUE);
}
wrefresh(dialog);
while (key != ESC) {
key = wgetch(dialog);
/* Shortcut to OK? */
if (toupper(key) == okButton) {
if (ditems && result && ditems[OK_BUTTON].fire) {
int st = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
if (DITEM_STATUS(st) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else {
delwin(dialog);
if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
}
}
else if (st == DITEM_FAILURE) {
wrefresh(dialog);
continue;
else {
delwin(dialog);
*result = '\0';
for (i = 0; i < item_no; i++) {
if (status[i]) {
strcat(result, items[i*3]);
strcat(result, "\n");
}
}
}
else if (st == DITEM_REDRAW) {
for (i = 0; i < max_choice; i++) {
status[scroll + i] = ditems[scroll + i].checked ?
ditems[scroll + i].checked(&ditems[scroll + i]) : FALSE;
delwin(save);
return 0;
}
/* Shortcut to cancel? */
else if (toupper(key) == cancelButton) {
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
int st;
st = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
if (DITEM_STATUS(st) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
}
delwin(dialog);
delwin(save);
return 1;
}
/* Check if key pressed matches first character of any item tag in list */
for (i = 0; i < max_choice; i++)
if (key < 0x100 && toupper(key) == toupper(items[(scroll+i)*3][0]))
break;
if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) || key == KEY_UP ||
key == KEY_DOWN || key == ' ' || key == '+' || key == '-' ) {
if (key >= '1' && key <= MIN('9', '0'+max_choice))
i = key - '1';
else if (key == KEY_UP || key == '-') {
if (!choice) {
if (scroll) {
/* Scroll list down */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
if (list_height > 1) {
/* De-highlight current first item before scrolling down */
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE, DREF(ditems, scroll));
scrollok(list, TRUE);
wscrl(list, -1);
scrollok(list, FALSE);
}
scroll--;
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE, DREF(ditems, scroll));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
}
continue; /* wait for another key press */
}
else
i = choice - 1;
}
else if (key == KEY_DOWN || key == '+') {
if (choice == max_choice - 1) {
if (scroll+choice < item_no-1) {
/* Scroll list up */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
if (list_height > 1) {
/* De-highlight current last item before scrolling up */
print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1],
status[scroll+max_choice-1], max_choice-1, FALSE, DREF(ditems, scroll + max_choice - 1));
scrollok(list, TRUE);
scroll(list);
scrollok(list, FALSE);
}
scroll++;
print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1],
status[scroll+max_choice-1], max_choice-1, TRUE, DREF(ditems, scroll + max_choice - 1));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
}
continue; /* wait for another key press */
}
else
i = choice + 1;
}
else if (key == ' ') { /* Toggle item status */
char lbra = 0, rbra = 0, mark = 0;
if (ditems) {
if (ditems[scroll+choice].fire) {
int st = ditems[scroll+choice].fire(&ditems[scroll+choice]);
if (st & DITEM_REDRAW) {
for (i = 0; i < max_choice; i++)
print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice,
DREF(ditems, scroll + i));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
}
if (DITEM_STATUS(st) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
if (st & DITEM_RECREATE) {
delwin(save);
delwin(dialog);
goto draw;
}
else if (st & DITEM_LEAVE_MENU) {
/* Allow a fire action to take us out of the menu */
key = ESC;
break;
}
}
status[scroll+choice] = ditems[scroll+choice].checked ?
ditems[scroll+choice].checked(&ditems[scroll+choice]) : FALSE;
lbra = ditems[scroll+choice].lbra;
rbra = ditems[scroll+choice].rbra;
mark = ditems[scroll+choice].mark;
}
else
status[scroll+choice] = !status[scroll+choice];
getyx(dialog, cur_y, cur_x); /* Save cursor position */
wmove(list, choice, check_x);
wattrset(list, check_selected_attr);
if (!lbra)
lbra = '[';
if (!rbra)
rbra = ']';
if (!mark)
mark = 'X';
wprintw(list, "%c%c%c", lbra, status[scroll+choice] ? mark : ' ', rbra);
wnoutrefresh(list);
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
wrefresh(dialog);
continue; /* wait for another key press */
}
if (i != choice) {
/* De-highlight current item */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, FALSE,
DREF(ditems, scroll + choice));
/* Highlight new item */
choice = i;
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, TRUE,
DREF(ditems, scroll + choice));
wnoutrefresh(list);
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
wrefresh(dialog);
}
continue; /* wait for another key press */
}
switch (key) {
case KEY_PPAGE: /* can we go up? */
if (scroll > height - 4)
scroll -= (height-4);
else
scroll = 0;
redraw_menu = TRUE;
break;
case KEY_NPAGE: /* can we go down a full page? */
if (scroll + list_height >= item_no-1 - list_height) {
scroll = item_no - list_height;
if (scroll < 0)
scroll = 0;
}
else
scroll += list_height;
redraw_menu = TRUE;
break;
case KEY_HOME: /* go to the top */
scroll = 0;
choice = 0;
redraw_menu = TRUE;
break;
case KEY_END: /* Go to the bottom */
scroll = item_no - list_height;
if (scroll < 0)
scroll = 0;
choice = max_choice - 1;
redraw_menu = TRUE;
break;
/* swap the selection of OK/Cancel buttons */
case TAB:
case KEY_BTAB:
case KEY_LEFT:
case KEY_RIGHT:
button = !button;
if (ditems && result) {
if (button) {
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
}
else {
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
}
}
else {
if (button) {
print_button(dialog, " OK ", y, x, !button);
print_button(dialog, "Cancel", y, x + 14, button);
}
else {
print_button(dialog, "Cancel", y, x + 14, button);
print_button(dialog, " OK ", y, x, !button);
}
}
wrefresh(dialog);
break;
/* Select either the OK or Cancel button */
case '\n':
case '\r':
if (!button && result) {
if (ditems && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) {
if (ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]) ==
DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
}
else {
*result = '\0';
for (i = 0; i < item_no; i++) {
if (status[i]) {
strcat(result, items[i*3]);
strcat(result, "\n");
}
}
}
}
delwin(dialog);
delwin(save);
return button;
break;
/* Let me outta here! */
case ESC:
break;
/* Help! */
case KEY_F(1):
case '?':
display_helpfile();
break;
}
if (redraw_menu) {
for (i = 0; i < max_choice; i++)
print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice,
DREF(ditems, scroll + i));
}
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
}
}
status[scroll+choice] = ditems[scroll+choice].checked ?
ditems[scroll+choice].checked(&ditems[scroll+choice]) : FALSE;
lbra = ditems[scroll+choice].lbra;
rbra = ditems[scroll+choice].rbra;
mark = ditems[scroll+choice].mark;
}
else
status[scroll+choice] = !status[scroll+choice];
getyx(dialog, cur_y, cur_x); /* Save cursor position */
wmove(list, choice, check_x);
wattrset(list, check_selected_attr);
if (!lbra)
lbra = '[';
if (!rbra)
rbra = ']';
if (!mark)
mark = 'X';
wprintw(list, "%c%c%c", lbra, status[scroll+choice] ? mark : ' ', rbra);
wnoutrefresh(list);
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
wrefresh(dialog);
continue; /* wait for another key press */
}
if (i != choice) {
/* De-highlight current item */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, FALSE,
DREF(ditems, scroll + choice));
/* Highlight new item */
choice = i;
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, TRUE,
DREF(ditems, scroll + choice));
wnoutrefresh(list);
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
wrefresh(dialog);
}
continue; /* wait for another key press */
}
switch (key) {
case KEY_PPAGE: /* can we go up? */
if (scroll > height - 4)
scroll -= (height-4);
else
scroll = 0;
redraw_menu = TRUE;
break;
case KEY_NPAGE: /* can we go down a full page? */
if (scroll + list_height >= item_no-1 - list_height) {
scroll = item_no - list_height;
if (scroll < 0)
scroll = 0;
}
else
scroll += list_height;
redraw_menu = TRUE;
break;
case KEY_HOME: /* go to the top */
scroll = 0;
choice = 0;
redraw_menu = TRUE;
break;
case KEY_END: /* Go to the bottom */
scroll = item_no - list_height;
if (scroll < 0)
scroll = 0;
choice = max_choice - 1;
redraw_menu = TRUE;
break;
/* swap the selection of OK/Cancel buttons */
case TAB:
case KEY_BTAB:
case KEY_LEFT:
case KEY_RIGHT:
button = !button;
if (ditems && result) {
if (button) {
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
}
else {
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
}
}
else {
if (button) {
print_button(dialog, " OK ", y, x, !button);
print_button(dialog, "Cancel", y, x + 14, button);
}
else {
print_button(dialog, "Cancel", y, x + 14, button);
print_button(dialog, " OK ", y, x, !button);
}
}
wrefresh(dialog);
break;
/* Select either the OK or Cancel button */
case '\n':
case '\r':
if (!button && result) {
if (ditems && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) {
if (ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]) ==
DITEM_FAILURE) {
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
continue;
}
redraw_menu = FALSE;
}
else {
*result = '\0';
for (i = 0; i < item_no; i++) {
if (status[i]) {
strcat(result, items[i*3]);
strcat(result, "\n");
}
}
}
}
delwin(dialog);
return button;
break;
/* Let me outta here! */
case ESC:
break;
/* Help! */
case KEY_F(1):
case '?':
display_helpfile();
break;
}
if (redraw_menu) {
for (i = 0; i < max_choice; i++)
print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice,
DREF(ditems, scroll + i));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
redraw_menu = FALSE;
}
}
delwin(dialog);
return -1; /* ESC pressed */
delwin(dialog);
delwin(save);
return -1; /* ESC pressed */
}
/* End of dialog_checklist() */
@ -485,31 +514,31 @@ static void
print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int status, int choice, int selected,
dialogMenuItem *me)
{
int i;
/* Clear 'residue' of last item */
wattrset(win, menubox_attr);
wmove(win, choice, 0);
for (i = 0; i < list_width; i++)
int i;
/* Clear 'residue' of last item */
wattrset(win, menubox_attr);
wmove(win, choice, 0);
for (i = 0; i < list_width; i++)
waddch(win, ' ');
wmove(win, choice, check_x);
wattrset(win, selected ? check_selected_attr : check_attr);
wprintw(win, "%c%c%c", me && me->lbra ? me->lbra : '[',
status ? me && me->mark ? me->mark : 'X' : ' ',
me && me->rbra ? me->rbra : ']');
wattrset(win, menubox_attr);
waddch(win, ' ');
wmove(win, choice, check_x);
wattrset(win, selected ? check_selected_attr : check_attr);
wprintw(win, "%c%c%c", me && me->lbra ? me->lbra : '[',
status ? me && me->mark ? me->mark : 'X' : ' ',
me && me->rbra ? me->rbra : ']');
wattrset(win, menubox_attr);
waddch(win, ' ');
wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
waddch(win, tag[0]);
wattrset(win, selected ? tag_selected_attr : tag_attr);
waddstr(win, tag + 1);
wmove(win, choice, item_x);
wattrset(win, selected ? item_selected_attr : item_attr);
waddstr(win, item);
/* If have a selection handler for this, call it */
if (me && me->selected) {
wrefresh(win);
me->selected(me, selected);
}
wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
waddch(win, tag[0]);
wattrset(win, selected ? tag_selected_attr : tag_attr);
waddstr(win, tag + 1);
wmove(win, choice, item_x);
wattrset(win, selected ? item_selected_attr : item_attr);
waddstr(win, item);
/* If have a selection handler for this, call it */
if (me && me->selected) {
wrefresh(win);
me->selected(me, selected);
}
}
/* End of print_item() */

View File

@ -39,10 +39,16 @@
#endif
/* special return codes for `fire' actions */
#define DITEM_STATUS(flag) ((flag) & 0x0000FFFF)
#define DITEM_SUCCESS 0
#define DITEM_FAILURE -1
#define DITEM_LEAVE_MENU -2
#define DITEM_REDRAW -3
#define DITEM_FAILURE 1
/* Flags - returned in upper 16 bits of return status */
#define DITEM_LEAVE_MENU (1 << 16)
#define DITEM_REDRAW (1 << 17)
#define DITEM_RECREATE (1 << 18)
#define DITEM_RESTORE (1 << 19)
/* negative offsets for buttons in item lists, if specified */
#define OK_BUTTON -2

View File

@ -42,7 +42,7 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
l, k, scroll = 0, max_choice, redraw_menu = FALSE;
char okButton, cancelButton;
WINDOW *dialog, *menu;
WINDOW *dialog, *menu, *save;
unsigned char **items;
dialogMenuItem *ditems;
@ -99,12 +99,15 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
x = DialogX ? DialogX : (COLS - width)/2;
y = DialogY ? DialogY : (LINES - height)/2;
draw:
save = dupwin(newscr);
#ifdef HAVE_NCURSES
if (use_shadow)
draw_shadow(stdscr, y, x, height, width);
#endif
dialog = newwin(height, width, y, x);
if (dialog == NULL) {
delwin(save);
endwin();
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
return -1;
@ -142,6 +145,7 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
/* create new window for the menu */
menu = subwin(dialog, menu_height, menu_width, y + box_y + 1, x + box_x + 1);
if (menu == NULL) {
delwin(save);
endwin();
fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", menu_height,menu_width,y+box_y+1,x+box_x+1);
return -1;
@ -188,24 +192,42 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
/* Shortcut to OK? */
if (toupper(key) == okButton) {
if (ditems && result && ditems[OK_BUTTON].fire) {
if (ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]) == DITEM_FAILURE)
int status;
status = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
if (DITEM_STATUS(status) == DITEM_FAILURE)
continue;
else
else {
delwin(dialog);
if (status & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
}
}
else {
delwin(dialog);
strcpy(result, items[(scroll+choice)*2]);
strcpy(result, items[(scroll + choice) * 2]);
}
delwin(save);
return 0;
}
/* Shortcut to cancel? */
else if (toupper(key) == cancelButton) {
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
if (ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]) == DITEM_FAILURE)
int status;
status = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
if (DITEM_STATUS(status) == DITEM_FAILURE)
continue;
else if (status & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
}
delwin(dialog);
delwin(save);
return 1;
}
@ -358,14 +380,29 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
case '\r':
case '\n':
if (!button) {
/* A fire routine can do just about anything to the screen, so be prepared
to accept some hints as to what to do in the aftermath. */
if (ditems && ditems[scroll + choice].fire) {
if (ditems[scroll + choice].fire(&ditems[scroll + choice]) == DITEM_FAILURE)
int status;
status = ditems[scroll + choice].fire(&ditems[scroll + choice]);
if (DITEM_STATUS(status) == DITEM_FAILURE)
continue;
else if (status & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
else if (status & DITEM_RECREATE) {
delwin(save);
delwin(dialog);
goto draw;
}
}
else if (result)
strcpy(result, items[(scroll+choice)*2]);
}
delwin(dialog);
delwin(save);
return button;
case ESC:
@ -390,6 +427,7 @@ dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width,
}
delwin(dialog);
delwin(save);
return -1; /* ESC pressed */
}
/* End of dialog_menu() */

View File

@ -40,427 +40,475 @@ int
dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height,
int item_no, void *it, unsigned char *result)
{
int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
l, k, scroll = 0, max_choice, *status, was_on = 0;
int redraw_menu = FALSE;
char okButton, cancelButton;
WINDOW *dialog, *list;
unsigned char **items;
dialogMenuItem *ditems;
/* Allocate space for storing item on/off status */
if ((status = alloca(sizeof(int) * abs(item_no))) == NULL) {
endwin();
fprintf(stderr, "\nCan't allocate memory in dialog_radiolist().\n");
exit(-1);
}
/* Previous calling syntax, e.g. just a list of strings? */
if (item_no >= 0) {
items = it;
ditems = NULL;
/* Initializes status */
for (i = 0; i < item_no; i++) {
status[i] = !strcasecmp(items[i*3 + 2], "on");
if (status[i]) {
if (was_on)
status[i] = FALSE;
else
was_on = 1;
}
}
}
/* It's the new specification format - fake the rest of the code out */
else {
item_no = abs(item_no);
ditems = it;
items = (unsigned char **)alloca((item_no * 3) * sizeof(unsigned char *));
/* Initializes status */
for (i = 0; i < item_no; i++) {
status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
if (status[i]) {
if (was_on)
status[i] = FALSE;
else
was_on = 1;
}
items[i*3] = ditems[i].prompt;
items[i*3 + 1] = ditems[i].title;
items[i*3 + 2] = status[i] ? "on" : "off";
}
}
max_choice = MIN(list_height, item_no);
check_x = 0;
item_x = 0;
/* Find length of longest item in order to center radiolist */
for (i = 0; i < item_no; i++) {
l = strlen(items[i*3]);
for (j = 0; j < item_no; j++) {
k = strlen(items[j*3 + 1]);
check_x = MAX(check_x, l + k + 6);
}
item_x = MAX(item_x, l);
}
if (height < 0)
height = strheight(prompt)+list_height+4+2;
if (width < 0) {
i = strwidth(prompt);
j = ((title != NULL) ? strwidth(title) : 0);
width = MAX(i,j);
width = MAX(width,check_x+4)+4;
}
width = MAX(width,24);
if (width > COLS)
width = COLS;
if (height > LINES)
height = LINES;
/* center dialog box on screen */
x = DialogX ? DialogX : (COLS - width)/2;
y = DialogY ? DialogY : (LINES - height)/2;
#ifdef HAVE_NCURSES
if (use_shadow)
draw_shadow(stdscr, y, x, height, width);
#endif
dialog = newwin(height, width, y, x);
if (dialog == NULL) {
endwin();
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
return -1;
}
keypad(dialog, TRUE);
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
wattrset(dialog, border_attr);
wmove(dialog, height-3, 0);
waddch(dialog, ACS_LTEE);
for (i = 0; i < width-2; i++)
waddch(dialog, ACS_HLINE);
wattrset(dialog, dialog_attr);
waddch(dialog, ACS_RTEE);
wmove(dialog, height-2, 1);
for (i = 0; i < width-2; i++)
waddch(dialog, ' ');
if (title != NULL) {
wattrset(dialog, title_attr);
wmove(dialog, 0, (width - strlen(title))/2 - 1);
waddch(dialog, ' ');
waddstr(dialog, title);
waddch(dialog, ' ');
}
wattrset(dialog, dialog_attr);
wmove(dialog, 1, 2);
print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
list_width = width-6;
getyx(dialog, cur_y, cur_x);
box_y = cur_y + 1;
box_x = (width - list_width)/2 - 1;
/* create new window for the list */
list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
if (list == NULL) {
endwin();
fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", list_height,list_width,y+box_y+1,x+box_x+1);
return -1;
}
keypad(list, TRUE);
/* draw a box around the list items */
draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);
check_x = (list_width - check_x) / 2;
item_x = check_x + item_x + 6;
/* Print the list */
for (i = 0; i < max_choice; i++)
print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice, DREF(ditems, i));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
display_helpline(dialog, height-1, width);
x = width/2-11;
y = height-2;
if (ditems && result) {
cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : FALSE);
okButton = toupper(ditems[OK_BUTTON].prompt[0]);
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : TRUE);
}
else {
cancelButton = 'C';
print_button(dialog, "Cancel", y, x + 14, FALSE);
okButton = 'O';
print_button(dialog, " OK ", y, x, TRUE);
}
wrefresh(dialog);
while (key != ESC) {
key = wgetch(dialog);
/* See if its the short-cut to "OK" */
if (toupper(key) == okButton) {
if (ditems && result && ditems[OK_BUTTON].fire) {
if (ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else
delwin(dialog);
}
else {
delwin(dialog);
*result = '\0';
for (i = 0; i < item_no; i++) {
if (status[i]) {
strcat(result, items[i*3]);
break;
}
}
}
return 0;
}
/* Shortcut to cancel */
else if (toupper(key) == cancelButton) {
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
if (ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
}
delwin(dialog);
return 1;
}
/* Check if key pressed matches first character of any item tag in list */
for (i = 0; i < max_choice; i++)
if (toupper(key) == toupper(items[(scroll+i)*3][0]))
break;
if (i < max_choice || (key >= '1' && key <= MIN('9', '0' + max_choice)) ||
key == KEY_UP || key == KEY_DOWN || key == ' ' || key == '+' || key == '-' ) {
if (key >= '1' && key <= MIN('9', '0' + max_choice))
i = key - '1';
else if (key == KEY_UP || key == '-') {
if (!choice) {
if (scroll) {
/* Scroll list down */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
if (list_height > 1) {
/* De-highlight current first item before scrolling down */
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE, DREF(ditems, scroll));
scrollok(list, TRUE);
wscrl(list, -1);
scrollok(list, FALSE);
}
scroll--;
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE, DREF(ditems, scroll));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
}
continue; /* wait for another key press */
}
else
i = choice - 1;
}
else if (key == KEY_DOWN || key == '+') {
if (choice == max_choice - 1) {
if (scroll+choice < item_no-1) {
/* Scroll list up */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
if (list_height > 1) {
/* De-highlight current last item before scrolling up */
print_item(list, items[(scroll + max_choice - 1) * 3], items[(scroll + max_choice - 1) * 3 + 1],
status[scroll + max_choice - 1], max_choice - 1, FALSE, DREF(ditems, scroll + max_choice - 1));
scrollok(list, TRUE);
scroll(list);
scrollok(list, FALSE);
}
scroll++;
print_item(list, items[(scroll + max_choice - 1) * 3], items[(scroll + max_choice - 1) * 3 + 1],
status[scroll + max_choice - 1], max_choice - 1, TRUE, DREF(ditems, scroll + max_choice - 1));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
}
continue; /* wait for another key press */
}
else
i = choice + 1;
}
else if (key == ' ') { /* Toggle item status */
if (status[scroll + choice])
continue;
else if (ditems) {
if (ditems[scroll + choice].fire) {
int st = ditems[scroll + choice].fire(&ditems[scroll + choice]);
if (st == DITEM_LEAVE_MENU) {
/* Allow a fire action to take us out of the menu */
key = ESC;
break;
}
else if (st == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
}
for (i = 0; i < item_no; i++)
status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
}
else {
for (i = 0; i < item_no; i++)
status[i] = 0;
status[scroll + choice] = TRUE;
}
getyx(dialog, cur_y, cur_x); /* Save cursor position */
for (i = 0; i < max_choice; i++)
print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1], status[scroll + i], i, i == choice,
DREF(ditems, scroll + i));
wnoutrefresh(list);
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
wrefresh(dialog);
continue; /* wait for another key press */
}
if (i != choice) {
/* De-highlight current item */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 +1], status[scroll+choice], choice, FALSE,
DREF(ditems, scroll + choice));
/* Highlight new item */
choice = i;
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, TRUE,
DREF(ditems, scroll + choice));
wnoutrefresh(list);
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
wrefresh(dialog);
}
continue; /* wait for another key press */
}
switch (key) {
case KEY_PPAGE:
if (scroll > height-4) /* can we go up? */
scroll -= (height-4);
else
scroll = 0;
redraw_menu = TRUE;
break;
case KEY_NPAGE:
if (scroll + list_height >= item_no-1 - list_height) { /* can we go down a full page? */
scroll = item_no - list_height;
if (scroll < 0)
scroll = 0;
}
else
scroll += list_height;
redraw_menu = TRUE;
break;
case KEY_HOME:
scroll = 0;
choice = 0;
redraw_menu = TRUE;
break;
case KEY_END:
scroll = item_no - list_height;
if (scroll < 0)
scroll = 0;
choice = max_choice - 1;
redraw_menu = TRUE;
break;
case KEY_BTAB:
case TAB:
case KEY_LEFT:
case KEY_RIGHT:
button = !button;
if (ditems && result) {
if (button) {
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
}
else {
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
}
}
else {
if (button) {
print_button(dialog, " OK ", y, x, !button);
print_button(dialog, "Cancel", y, x + 14, button);
}
else {
print_button(dialog, "Cancel", y, x + 14, button);
print_button(dialog, " OK ", y, x, !button);
}
}
wrefresh(dialog);
break;
case ' ':
case '\r':
case '\n':
if (!button && result) {
if (ditems && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) {
if (ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]) ==
DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
}
else {
*result = '\0';
for (i = 0; i < item_no; i++) {
if (status[i]) {
strcpy(result, items[i*3]);
break;
}
}
}
}
delwin(dialog);
return button;
break;
case ESC:
break;
case KEY_F(1):
case '?':
display_helpfile();
break;
int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
l, k, scroll = 0, max_choice, *status, was_on = 0;
int redraw_menu = FALSE;
char okButton, cancelButton;
WINDOW *dialog, *list, *save;
unsigned char **items;
dialogMenuItem *ditems;
/* Allocate space for storing item on/off status */
if ((status = alloca(sizeof(int) * abs(item_no))) == NULL) {
endwin();
fprintf(stderr, "\nCan't allocate memory in dialog_radiolist().\n");
exit(-1);
}
if (redraw_menu) {
for (i = 0; i < max_choice; i++)
print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1], status[scroll + i], i, i == choice,
DREF(ditems, scroll + i));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
redraw_menu = FALSE;
/* Previous calling syntax, e.g. just a list of strings? */
if (item_no >= 0) {
items = it;
ditems = NULL;
/* Initializes status */
for (i = 0; i < item_no; i++) {
status[i] = !strcasecmp(items[i*3 + 2], "on");
if (status[i]) {
if (was_on)
status[i] = FALSE;
else
was_on = 1;
}
}
}
}
/* It's the new specification format - fake the rest of the code out */
else {
item_no = abs(item_no);
ditems = it;
items = (unsigned char **)alloca((item_no * 3) * sizeof(unsigned char *));
/* Initializes status */
for (i = 0; i < item_no; i++) {
status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
if (status[i]) {
if (was_on)
status[i] = FALSE;
else
was_on = 1;
}
items[i*3] = ditems[i].prompt;
items[i*3 + 1] = ditems[i].title;
items[i*3 + 2] = status[i] ? "on" : "off";
}
}
max_choice = MIN(list_height, item_no);
check_x = 0;
item_x = 0;
/* Find length of longest item in order to center radiolist */
for (i = 0; i < item_no; i++) {
l = strlen(items[i*3]);
for (j = 0; j < item_no; j++) {
k = strlen(items[j*3 + 1]);
check_x = MAX(check_x, l + k + 6);
}
item_x = MAX(item_x, l);
}
if (height < 0)
height = strheight(prompt)+list_height+4+2;
if (width < 0) {
i = strwidth(prompt);
j = ((title != NULL) ? strwidth(title) : 0);
width = MAX(i,j);
width = MAX(width,check_x+4)+4;
}
width = MAX(width,24);
if (width > COLS)
width = COLS;
if (height > LINES)
height = LINES;
/* center dialog box on screen */
x = DialogX ? DialogX : (COLS - width)/2;
y = DialogY ? DialogY : (LINES - height)/2;
delwin(dialog);
free(status);
return -1; /* ESC pressed */
draw:
save = dupwin(newscr);
#ifdef HAVE_NCURSES
if (use_shadow)
draw_shadow(stdscr, y, x, height, width);
#endif
dialog = newwin(height, width, y, x);
if (dialog == NULL) {
delwin(save);
endwin();
fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
return -1;
}
keypad(dialog, TRUE);
draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
wattrset(dialog, border_attr);
wmove(dialog, height-3, 0);
waddch(dialog, ACS_LTEE);
for (i = 0; i < width-2; i++)
waddch(dialog, ACS_HLINE);
wattrset(dialog, dialog_attr);
waddch(dialog, ACS_RTEE);
wmove(dialog, height-2, 1);
for (i = 0; i < width-2; i++)
waddch(dialog, ' ');
if (title != NULL) {
wattrset(dialog, title_attr);
wmove(dialog, 0, (width - strlen(title))/2 - 1);
waddch(dialog, ' ');
waddstr(dialog, title);
waddch(dialog, ' ');
}
wattrset(dialog, dialog_attr);
wmove(dialog, 1, 2);
print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
list_width = width-6;
getyx(dialog, cur_y, cur_x);
box_y = cur_y + 1;
box_x = (width - list_width)/2 - 1;
/* create new window for the list */
list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
if (list == NULL) {
delwin(save);
delwin(dialog);
endwin();
fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", list_height,list_width,y+box_y+1,x+box_x+1);
return -1;
}
keypad(list, TRUE);
/* draw a box around the list items */
draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);
check_x = (list_width - check_x) / 2;
item_x = check_x + item_x + 6;
/* Print the list */
for (i = 0; i < max_choice; i++)
print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice, DREF(ditems, i));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
display_helpline(dialog, height-1, width);
x = width/2-11;
y = height-2;
if (ditems && result) {
cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : FALSE);
okButton = toupper(ditems[OK_BUTTON].prompt[0]);
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : TRUE);
}
else {
cancelButton = 'C';
print_button(dialog, "Cancel", y, x + 14, FALSE);
okButton = 'O';
print_button(dialog, " OK ", y, x, TRUE);
}
wrefresh(dialog);
while (key != ESC) {
key = wgetch(dialog);
/* See if its the short-cut to "OK" */
if (toupper(key) == okButton) {
if (ditems && result && ditems[OK_BUTTON].fire) {
int st;
st = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
if (DITEM_STATUS(st) == DITEM_FAILURE)
continue;
else {
delwin(dialog);
if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
}
}
else {
delwin(dialog);
*result = '\0';
for (i = 0; i < item_no; i++) {
if (status[i]) {
strcat(result, items[i*3]);
break;
}
}
}
delwin(save);
return 0;
}
/* Shortcut to cancel */
else if (toupper(key) == cancelButton) {
if (ditems && result && ditems[CANCEL_BUTTON].fire) {
int st;
st = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
if (DITEM_STATUS(st) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
}
delwin(dialog);
delwin(save);
return 1;
}
/* Check if key pressed matches first character of any item tag in list */
for (i = 0; i < max_choice; i++)
if (toupper(key) == toupper(items[(scroll+i)*3][0]))
break;
if (i < max_choice || (key >= '1' && key <= MIN('9', '0' + max_choice)) ||
key == KEY_UP || key == KEY_DOWN || key == ' ' || key == '+' || key == '-' ) {
if (key >= '1' && key <= MIN('9', '0' + max_choice))
i = key - '1';
else if (key == KEY_UP || key == '-') {
if (!choice) {
if (scroll) {
/* Scroll list down */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
if (list_height > 1) {
/* De-highlight current first item before scrolling down */
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE, DREF(ditems, scroll));
scrollok(list, TRUE);
wscrl(list, -1);
scrollok(list, FALSE);
}
scroll--;
print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE, DREF(ditems, scroll));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
}
continue; /* wait for another key press */
}
else
i = choice - 1;
}
else if (key == KEY_DOWN || key == '+') {
if (choice == max_choice - 1) {
if (scroll+choice < item_no-1) {
/* Scroll list up */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
if (list_height > 1) {
/* De-highlight current last item before scrolling up */
print_item(list, items[(scroll + max_choice - 1) * 3], items[(scroll + max_choice - 1) * 3 + 1],
status[scroll + max_choice - 1], max_choice - 1, FALSE, DREF(ditems, scroll + max_choice - 1));
scrollok(list, TRUE);
scroll(list);
scrollok(list, FALSE);
}
scroll++;
print_item(list, items[(scroll + max_choice - 1) * 3], items[(scroll + max_choice - 1) * 3 + 1],
status[scroll + max_choice - 1], max_choice - 1, TRUE, DREF(ditems, scroll + max_choice - 1));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
}
continue; /* wait for another key press */
}
else
i = choice + 1;
}
else if (key == ' ') { /* Toggle item status */
if (status[scroll + choice])
continue;
else if (ditems) {
if (ditems[scroll + choice].fire) {
int st = ditems[scroll + choice].fire(&ditems[scroll + choice]);
if (st & DITEM_REDRAW) {
for (i = 0; i < max_choice; i++)
print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1],
status[scroll + i], i, i == choice,
DREF(ditems, scroll + i));
wnoutrefresh(list);
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
wrefresh(dialog);
}
if (DITEM_STATUS(st) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
if (st & DITEM_RECREATE) {
delwin(save);
delwin(dialog);
goto draw;
}
else if (st & DITEM_LEAVE_MENU) {
/* Allow a fire action to take us out of the menu */
key = ESC;
break;
}
}
for (i = 0; i < item_no; i++)
status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
}
else {
for (i = 0; i < item_no; i++)
status[i] = 0;
status[scroll + choice] = TRUE;
}
getyx(dialog, cur_y, cur_x); /* Save cursor position */
for (i = 0; i < max_choice; i++)
print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1], status[scroll + i], i, i == choice,
DREF(ditems, scroll + i));
wnoutrefresh(list);
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
wrefresh(dialog);
continue; /* wait for another key press */
}
if (i != choice) {
/* De-highlight current item */
getyx(dialog, cur_y, cur_x); /* Save cursor position */
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 +1], status[scroll+choice], choice, FALSE,
DREF(ditems, scroll + choice));
/* Highlight new item */
choice = i;
print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, TRUE,
DREF(ditems, scroll + choice));
wnoutrefresh(list);
wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
wrefresh(dialog);
}
continue; /* wait for another key press */
}
switch (key) {
case KEY_PPAGE:
if (scroll > height-4) /* can we go up? */
scroll -= (height-4);
else
scroll = 0;
redraw_menu = TRUE;
break;
case KEY_NPAGE:
if (scroll + list_height >= item_no-1 - list_height) { /* can we go down a full page? */
scroll = item_no - list_height;
if (scroll < 0)
scroll = 0;
}
else
scroll += list_height;
redraw_menu = TRUE;
break;
case KEY_HOME:
scroll = 0;
choice = 0;
redraw_menu = TRUE;
break;
case KEY_END:
scroll = item_no - list_height;
if (scroll < 0)
scroll = 0;
choice = max_choice - 1;
redraw_menu = TRUE;
break;
case KEY_BTAB:
case TAB:
case KEY_LEFT:
case KEY_RIGHT:
button = !button;
if (ditems && result) {
if (button) {
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
}
else {
print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
}
}
else {
if (button) {
print_button(dialog, " OK ", y, x, !button);
print_button(dialog, "Cancel", y, x + 14, button);
}
else {
print_button(dialog, "Cancel", y, x + 14, button);
print_button(dialog, " OK ", y, x, !button);
}
}
wrefresh(dialog);
break;
case '\r':
case '\n':
if (!button && result) {
if (ditems && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) {
int st = ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]);
if (DITEM_STATUS(st) == DITEM_FAILURE) {
wrefresh(dialog);
continue;
}
else if (st & DITEM_RESTORE) {
touchwin(save);
wrefresh(save);
}
else if (st & DITEM_RECREATE) {
delwin(save);
delwin(dialog);
goto draw;
}
}
else {
*result = '\0';
for (i = 0; i < item_no; i++) {
if (status[i]) {
strcpy(result, items[i*3]);
break;
}
}
}
}
delwin(dialog);
delwin(save);
return button;
break;
case ESC:
break;
case KEY_F(1):
case '?':
display_helpfile();
break;
}
if (redraw_menu) {
for (i = 0; i < max_choice; i++)
print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1], status[scroll + i], i, i == choice,
DREF(ditems, scroll + i));
wnoutrefresh(list);
print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
wrefresh(dialog);
redraw_menu = FALSE;
}
}
delwin(dialog);
delwin(save);
free(status);
return -1; /* ESC pressed */
}
/* End of dialog_radiolist() */
@ -471,31 +519,31 @@ dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int wi
static void
print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected, dialogMenuItem *me)
{
int i;
/* Clear 'residue' of last item */
wattrset(win, menubox_attr);
wmove(win, choice, 0);
for (i = 0; i < list_width; i++)
int i;
/* Clear 'residue' of last item */
wattrset(win, menubox_attr);
wmove(win, choice, 0);
for (i = 0; i < list_width; i++)
waddch(win, ' ');
wmove(win, choice, check_x);
wattrset(win, selected ? check_selected_attr : check_attr);
wprintw(win, "%c%c%c", me && me->lbra ? me->lbra : '(',
status ? me && me->mark ? me->mark : '*' : ' ',
me && me->rbra ? me->rbra : ')');
wattrset(win, menubox_attr);
waddch(win, ' ');
wmove(win, choice, check_x);
wattrset(win, selected ? check_selected_attr : check_attr);
wprintw(win, "%c%c%c", me && me->lbra ? me->lbra : '(',
status ? me && me->mark ? me->mark : '*' : ' ',
me && me->rbra ? me->rbra : ')');
wattrset(win, menubox_attr);
waddch(win, ' ');
wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
waddch(win, tag[0]);
wattrset(win, selected ? tag_selected_attr : tag_attr);
waddstr(win, tag + 1);
wmove(win, choice, item_x);
wattrset(win, selected ? item_selected_attr : item_attr);
waddstr(win, item);
/* If have a selection handler for this, call it */
if (me && me->selected) {
wrefresh(win);
me->selected(me, selected);
}
wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
waddch(win, tag[0]);
wattrset(win, selected ? tag_selected_attr : tag_attr);
waddstr(win, tag + 1);
wmove(win, choice, item_x);
wattrset(win, selected ? item_selected_attr : item_attr);
waddstr(win, item);
/* If have a selection handler for this, call it */
if (me && me->selected) {
wrefresh(win);
me->selected(me, selected);
}
}
/* End of print_item() */