From 1955cbd66c93128aba32e091142a474862329f24 Mon Sep 17 00:00:00 2001 From: jkh Date: Tue, 16 Apr 1996 12:17:27 +0000 Subject: [PATCH] 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. --- gnu/lib/libdialog/TESTS/check1.c | 56 +- gnu/lib/libdialog/TESTS/check2.c | 90 +-- gnu/lib/libdialog/TESTS/check3.c | 68 +-- gnu/lib/libdialog/TESTS/menu1.c | 126 ++--- gnu/lib/libdialog/TESTS/menu2.c | 132 ++--- gnu/lib/libdialog/TESTS/menu3.c | 102 ++-- gnu/lib/libdialog/TESTS/radio1.c | 42 +- gnu/lib/libdialog/TESTS/radio2.c | 58 +- gnu/lib/libdialog/TESTS/radio3.c | 78 +-- gnu/lib/libdialog/checklist.c | 915 +++++++++++++++--------------- gnu/lib/libdialog/dialog.h | 12 +- gnu/lib/libdialog/menubox.c | 50 +- gnu/lib/libdialog/radiolist.c | 932 ++++++++++++++++--------------- 13 files changed, 1391 insertions(+), 1270 deletions(-) diff --git a/gnu/lib/libdialog/TESTS/check1.c b/gnu/lib/libdialog/TESTS/check1.c index b66f48b9518a..e8a0751e2914 100644 --- a/gnu/lib/libdialog/TESTS/check1.c +++ b/gnu/lib/libdialog/TESTS/check1.c @@ -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 @@ -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; } diff --git a/gnu/lib/libdialog/TESTS/check2.c b/gnu/lib/libdialog/TESTS/check2.c index c28222a43be5..edad6cf5a115 100644 --- a/gnu/lib/libdialog/TESTS/check2.c +++ b/gnu/lib/libdialog/TESTS/check2.c @@ -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 @@ -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; } diff --git a/gnu/lib/libdialog/TESTS/check3.c b/gnu/lib/libdialog/TESTS/check3.c index ecd4275d58ee..6ba01ce11ace 100644 --- a/gnu/lib/libdialog/TESTS/check3.c +++ b/gnu/lib/libdialog/TESTS/check3.c @@ -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; } diff --git a/gnu/lib/libdialog/TESTS/menu1.c b/gnu/lib/libdialog/TESTS/menu1.c index bbab588f52f5..5e5a1add71cb 100644 --- a/gnu/lib/libdialog/TESTS/menu1.c +++ b/gnu/lib/libdialog/TESTS/menu1.c @@ -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 @@ -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; } diff --git a/gnu/lib/libdialog/TESTS/menu2.c b/gnu/lib/libdialog/TESTS/menu2.c index de0923812b8e..40f279e49b30 100644 --- a/gnu/lib/libdialog/TESTS/menu2.c +++ b/gnu/lib/libdialog/TESTS/menu2.c @@ -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 @@ -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; } diff --git a/gnu/lib/libdialog/TESTS/menu3.c b/gnu/lib/libdialog/TESTS/menu3.c index 5b291b00a6dc..f1acd3cd96de 100644 --- a/gnu/lib/libdialog/TESTS/menu3.c +++ b/gnu/lib/libdialog/TESTS/menu3.c @@ -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 @@ -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; } diff --git a/gnu/lib/libdialog/TESTS/radio1.c b/gnu/lib/libdialog/TESTS/radio1.c index bee0fb655a5e..19532073971c 100644 --- a/gnu/lib/libdialog/TESTS/radio1.c +++ b/gnu/lib/libdialog/TESTS/radio1.c @@ -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 @@ -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; } diff --git a/gnu/lib/libdialog/TESTS/radio2.c b/gnu/lib/libdialog/TESTS/radio2.c index 665f686974d8..3f97048a4c98 100644 --- a/gnu/lib/libdialog/TESTS/radio2.c +++ b/gnu/lib/libdialog/TESTS/radio2.c @@ -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 @@ -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; } diff --git a/gnu/lib/libdialog/TESTS/radio3.c b/gnu/lib/libdialog/TESTS/radio3.c index 7ec206188ac9..6a50287d1a6f 100644 --- a/gnu/lib/libdialog/TESTS/radio3.c +++ b/gnu/lib/libdialog/TESTS/radio3.c @@ -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 @@ -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; } diff --git a/gnu/lib/libdialog/checklist.c b/gnu/lib/libdialog/checklist.c index b93baf5e6826..a43b23c043c5 100644 --- a/gnu/lib/libdialog/checklist.c +++ b/gnu/lib/libdialog/checklist.c @@ -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() */ diff --git a/gnu/lib/libdialog/dialog.h b/gnu/lib/libdialog/dialog.h index 28c96f628a1a..9619adfbf966 100644 --- a/gnu/lib/libdialog/dialog.h +++ b/gnu/lib/libdialog/dialog.h @@ -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 diff --git a/gnu/lib/libdialog/menubox.c b/gnu/lib/libdialog/menubox.c index 572463a61121..9308aaa0a179 100644 --- a/gnu/lib/libdialog/menubox.c +++ b/gnu/lib/libdialog/menubox.c @@ -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() */ diff --git a/gnu/lib/libdialog/radiolist.c b/gnu/lib/libdialog/radiolist.c index 3443eceb10dc..fd0c25632ee1 100644 --- a/gnu/lib/libdialog/radiolist.c +++ b/gnu/lib/libdialog/radiolist.c @@ -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() */