/* Checkbook - a demo of GIL scrolling list functions Version 1: This version supports editing checks in the popup window. The scrolling list of checks is not implemented in this version. */ #include "geosim.h" #include/* Application parameters */ #define NAME "Checkbook" #define IFILE "sclist1.inf" #define USE_BSTORE 1 #define MIN_NUMBER 100 #define MAX_NUMBER 500 #define MIN_AMOUNT 1 #define MAX_AMOUNT 1000 #define MAX_PAYEE_LEN 30 /* */ /* Interface element names */ #define LIST_WINDOW "ListWindow" #define UP_BTN "list_up" #define DOWN_BTN "list_down" #define LIST_DA "list" #define SCROLLBAR_DA "scroll_bar" #define CHECK_WINDOW "CheckWindow" #define NUMBER_FLD "number" #define PAYEE_FLD "payee" #define AMOUNT_FLD "amount" #define NUMBER_INC_BTN "number_inc" #define NUMBER_DEC_BTN "number_dec" #define AMOUNT_INC_BTN "amount_inc" #define AMOUNT_DEC_BTN "amount_dec" #define CHAR_FUNC "char_func" /* */ /* Typedefs */ typedef struct { int number, amount; BigString payee; } CheckType; typedef enum { NOT_SHOWN, ADD_STATE, EDIT_STATE } CheckWindState; /* */ /* Interface function prototypes */ bool redraw_func(); bool quit(); bool null_func(); bool add(); bool edit(); bool check_ok(); bool check_cancel(); bool char_func(int, int, char); bool number_inc(); bool number_dec(); bool amount_inc(); bool amount_dec(); /* */ /* Other prototypes */ void initialize(); void init_data_window(); void display_checkwind(); void display_amount(); void display_payee(); void display_number(); /* */ /* Globals */ CheckWindState wind_state = NOT_SHOWN; CheckType edit_check; int next_number; int payee_len, ins_point; /* */ void main(int argc, char *argv[]) { GSinterfaceinit(NAME, IFILE, USE_BSTORE, "wc", G640x480x256, argc, argv); initialize(); GSinterface(); } /* initialize() */ void initialize() { GScharfunc(CHAR_FUNC); next_number=MIN_NUMBER; } /* redraw_func() : called when the GIL window needs to be redrawn */ bool redraw_func() { GSredrawnamedwindow("root"); GSredrawnamedwindow(LIST_WINDOW); if (wind_state != NOT_SHOWN) { GSredrawnamedwindow(CHECK_WINDOW); display_checkwind(); } } /* quit() : called when the "Quit" button is pressed */ bool quit() { GSquit(NULL); return TRUE; } /* add() : called when the "add" button is pressed Displays check entry window. */ bool add() { edit_check.number = next_number++; edit_check.amount = 100; sprintf(edit_check.payee, "Payee"); wind_state = ADD_STATE; init_data_window(); return TRUE; } /* edit() : called when the "edit" button is pressed Displays check entry window. */ bool edit() { wind_state = EDIT_STATE; init_data_window(); return TRUE; } /* init_data_window() : called from add() and edit() Initializes "+" and "-" buttons in check entry window, sets text entry variables (ins_point and payee_len), displays check window and draws contents. */ void init_data_window() { if (edit_check.number <= MIN_NUMBER) GSdisablebutton(CHECK_WINDOW, NUMBER_DEC_BTN, FALSE); else GSenablebutton(CHECK_WINDOW, NUMBER_DEC_BTN, FALSE); if (edit_check.amount <= MIN_AMOUNT) GSdisablebutton(CHECK_WINDOW, AMOUNT_DEC_BTN, FALSE); else GSenablebutton(CHECK_WINDOW, AMOUNT_DEC_BTN, FALSE); if (edit_check.number >= MAX_NUMBER) GSdisablebutton(CHECK_WINDOW, NUMBER_INC_BTN, FALSE); else GSenablebutton(CHECK_WINDOW, NUMBER_INC_BTN, FALSE); if (edit_check.amount >= MAX_AMOUNT) GSdisablebutton(CHECK_WINDOW, AMOUNT_INC_BTN, FALSE); else GSenablebutton(CHECK_WINDOW, AMOUNT_INC_BTN, FALSE); payee_len = strlen(edit_check.payee); ins_point = payee_len; GSdrawnamedwindow(CHECK_WINDOW, POPUP, BSTORE); display_checkwind(); } /* check_ok() : called when the "OK" button in the check entry window is pressed Removes check entry window. */ bool check_ok() { GSremovenamedwindow(CHECK_WINDOW); wind_state = NOT_SHOWN; } /* check_cancel() : called when the "Cancel" button in the check entry window is pressed Removes check entry window. */ bool check_cancel() { GSremovenamedwindow(CHECK_WINDOW); wind_state = NOT_SHOWN; } /* null_func() : "do-nothing" function; fill-in for missing interface functions */ bool null_func() { return TRUE; } /* number_inc() : called when "+" button for check number is pressed */ bool number_inc() { if (edit_check.number == MIN_NUMBER) GSenablebutton(CHECK_WINDOW, NUMBER_DEC_BTN, TRUE); edit_check.number++; if (edit_check.number == MAX_NUMBER) GSdisablebutton(CHECK_WINDOW, NUMBER_INC_BTN, TRUE); display_number(); return TRUE; } /* number_decc() : called when "-" button for check number is pressed */ bool number_dec() { if (edit_check.number == MAX_NUMBER) GSenablebutton(CHECK_WINDOW, NUMBER_INC_BTN, TRUE); edit_check.number--; if (edit_check.number == MIN_NUMBER) GSdisablebutton(CHECK_WINDOW, NUMBER_DEC_BTN, TRUE); display_number(); return TRUE; } /* amount_inc() : called when "+" button for check amount is pressed */ bool amount_inc() { if (edit_check.amount == MIN_AMOUNT) GSenablebutton(CHECK_WINDOW, NUMBER_DEC_BTN, TRUE); edit_check.amount++; if (edit_check.amount == MAX_AMOUNT) GSdisablebutton(CHECK_WINDOW, NUMBER_INC_BTN, TRUE); display_amount(); return TRUE; } /* number_dec() : called when "-" button for check amount is pressed */ bool amount_dec() { if (edit_check.amount == MAX_AMOUNT) GSenablebutton(CHECK_WINDOW, AMOUNT_INC_BTN, TRUE); edit_check.amount--; if (edit_check.amount == MIN_AMOUNT) GSdisablebutton(CHECK_WINDOW, AMOUNT_DEC_BTN, TRUE); display_amount(); return TRUE; } /* display_amount() : called when check amount needs to be displayed */ void display_amount() { int x, y, wd, ht; GSColor col; BigString str; GSsetcurrentnamedwindow(CHECK_WINDOW); GSsetfont(SMALL); GSgetfieldrect(AMOUNT_FLD, &x, &y, &wd, &ht, &col); GSsetcolor(col); GSwfillrect(x, y, wd, ht); GSframefield(CHECK_WINDOW, AMOUNT_FLD, GSconvertcolor("black"), GSconvertcolor("dgray")); GSsetcolor(GSconvertcolor("black")); sprintf(str, "$%d.%02d", edit_check.amount/100, /*(float)*/ (edit_check.amount%100)); GSwwritemsg(x+1, y+SMALL+1, str); } /* display_payee() : called when check payee needs to be displayed */ void display_payee() { int x, y, wd, ht; int curs_start, curs_len; char curs_char; GSColor col; BigString str; GSsetcurrentnamedwindow(CHECK_WINDOW); GSsetfont(SMALL); GSgetfieldrect(PAYEE_FLD, &x, &y, &wd, &ht, &col); GSsetcolor(col); GSwfillrect(x, y, wd, ht); GSframefield(CHECK_WINDOW, PAYEE_FLD, GSconvertcolor("black"), GSconvertcolor("dgray")); GSsetcolor(GSconvertcolor("black")); GSwwritemsg(x+1, y+SMALL+1, edit_check.payee); /* underline current position */ sprintf(str, "%s", edit_check.payee); if (ins_point >= payee_len) curs_char = ' '; else curs_char = str[ins_point]; str[ins_point] = '\0'; curs_start = GStextwidth(str); str[0] = curs_char; str[1] = '\0'; curs_len = GStextwidth(str); GSwdrawline(x+1+curs_start, y+SMALL+2, x+1+curs_start+curs_len, y+SMALL+2); } /* display_number() : called when check number needs to be displayed */ void display_number() { int x, y, wd, ht; GSColor col; BigString str; GSsetcurrentnamedwindow(CHECK_WINDOW); GSsetfont(SMALL); GSgetfieldrect(NUMBER_FLD, &x, &y, &wd, &ht, &col); GSsetcolor(col); GSwfillrect(x, y, wd, ht); GSframefield(CHECK_WINDOW, NUMBER_FLD, GSconvertcolor("black"), GSconvertcolor("dgray")); GSsetcolor(GSconvertcolor("black")); sprintf(str, "%d", edit_check.number); GSwwritemsg(x+1, y+SMALL+1, str); } /* display_checkwind() : called when entire check window contents need to be displayed */ void display_checkwind() { display_number(); display_payee(); display_amount(); } /* char_func() : called by GIL when a key is pressed Processes key presses; handles typing chars, backspace, and arrow keys. */ bool char_func(int x, int y, char ch) { int i; /* if check entry window is not displayed, don't do anything */ if (wind_state == NOT_SHOWN) return; /* update payee string and redraw payee field */ switch (ch) { case KeyLeft: if (ins_point > 0) ins_point--; break; case KeyRight: if (ins_point < payee_len) ins_point++; break; case '\b': if (ins_point > 0) { /* delete character before ins_point */ for (i=ins_point-1; i < payee_len; i++) edit_check.payee[i] = edit_check.payee[i+1]; payee_len--; ins_point--; } break; default: if ((ch >= ' ') && (ch <= '~') && (payee_len < MAX_PAYEE_LEN)) { /* insert ch at ins_point */ for (i=payee_len; i >= ins_point; i--) edit_check.payee[i+1] = edit_check.payee[i]; edit_check.payee[ins_point] = ch; payee_len++; ins_point++; } break; } display_payee(); return TRUE; } IntrFunction FuncNames[] = { {"redraw_func", redraw_func}, {"quit", quit}, {"add", add}, {"edit", edit}, {"delete", null_func}, {"OK", check_ok}, {"Cancel", check_cancel}, {"number_inc", number_inc}, {"number_dec", number_dec}, {"amount_inc", amount_inc}, {"amount_dec", amount_dec}, {"char_func", (bool(*)())char_func}, }; int NumFuncs = GSnumifuncs(FuncNames);