From 2e0a3a480c85046cf8b910e79741bfacfbaafd7c Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Fri, 2 Aug 2019 20:31:48 -0400 Subject: [PATCH] Improve dialogs Now in fteapot you can select any one of the buttons in a modal dialog with the cursor keys and hit enter and it will be selected. Fixes #17. In addition, I clarified that the block attribute options will either set every cell to bold (say), or unset every cell, or you can cancel to not actually go through with the block operation. These changes required adding a custom FLTK dialog, tpt_choose.{h,cxx}. Along the way, I reflowed fteapot.fl to make it more readable for further coding. Finally, there is a small amount of additional prep for color support that (unfortunately) got mixed in with these changes. --- src/CMakeLists.txt | 2 +- src/common/main.c | 99 +-- src/display.c | 147 ++-- src/display.h | 3 +- src/fteapot.fl | 1701 +++++++++++++++++++++++--------------------- src/tpt_choose.cxx | 230 ++++++ src/tpt_choose.h | 7 + 7 files changed, 1250 insertions(+), 939 deletions(-) create mode 100644 src/tpt_choose.cxx create mode 100644 src/tpt_choose.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a4441e9..fb6bb18 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,7 +40,7 @@ endif () find_package(FLTK) if (FLTK_FOUND) fltk_wrap_ui(fteapot fteapot.fl) - add_executable(fteapot WIN32 ${fteapot_FLTK_UI_SRCS}) + add_executable(fteapot WIN32 tpt_choose.cxx ${fteapot_FLTK_UI_SRCS}) set(fteapot_DEB_DEPENDS ", libstdc++6 (>= 4.1.1), libfltk1.3") if (ENABLE_HELP) set(fteapot_DEB_DEPENDS "${fteapot_DEB_DEPENDS}, libfltk-images1.3") diff --git a/src/common/main.c b/src/common/main.c index 25cd801..23f51d6 100644 --- a/src/common/main.c +++ b/src/common/main.c @@ -148,7 +148,7 @@ int doanyway(Sheet *sheet, const char *msg) int result; if (sheet->changed) { - result=line_ok(msg,0); + result = line_ok(msg,0); if (result < 0) return 0; return result; } @@ -344,7 +344,13 @@ static void do_attribute(Sheet *cursheet, Key action) case ADJUST_RIGHT: ++adj; case ADJUST_LEFT: { - if (!onecell && line_ok(_("Change adjustment of block:"), 0) <= 0) break; + const char *templ = _("Change adjustment of block to "); + char *prompt = malloc(strlen(templ) + 64); + const char *way = _("center?"); + if (action == ADJUST_RIGHT) way = _("right?"); + else if (action == ADJUST_LEFT) way = _("left?"); + strcpy(prompt, templ); strcat(prompt, way); + if (!onecell && line_ok(prompt, 0) <= 0) break; for (ALL_LOCS_IN_REGION(cursheet,w)) setadjust(cursheet, w, adj); break; @@ -355,8 +361,9 @@ static void do_attribute(Sheet *cursheet, Key action) int n; if (onecell) n = !getscientific(fcell); - else n = line_ok(_("Make block notation scientific:"), - getscientific(fcell)); + else n = line_binary(_("Make block notation:"), + _("dD)ecimal"), _("sS)cientific"), + !getscientific(fcell)); if (n >= 0) for (ALL_LOCS_IN_REGION(cursheet,w)) setscientific(cursheet, w, n); @@ -381,9 +388,12 @@ static void do_attribute(Sheet *cursheet, Key action) case ADJUST_SHADOW: { int n; - - if (onecell) n = !SHADOWED(cursheet, cursheet->mark1); - else n = line_ok(_("Shadow block:"), SHADOWED(cursheet, cursheet->mark1)); + Location r; + LOCATION_GETS(r, cursheet->mark1); ++r[X]; + if (onecell) n = !SHADOWED(cursheet, r); + else n = line_binary(_("Set block to:"), + _("uU)nshadowed"), _("sS)hadowed"), + !SHADOWED(cursheet, r)); if (cursheet->mark1[X] == 0 && n == 1) { line_msg(_("Shadow cell:"),_("You can not shadow cells in column 0")); break; @@ -397,12 +407,14 @@ static void do_attribute(Sheet *cursheet, Key action) if (n==0) { LOCATION_GETS(r, w); - for (++(r[X]); SHADOWED(cursheet, r); ++(r[X])) + if (!SHADOWED(cursheet, r)) ++(r[X]); + for (; SHADOWED(cursheet, r); ++(r[X])) shadow(cursheet, r, 0); } else if (w[X]>0) shadow(cursheet, w, 1); } } + if (n>0) do_mark(cursheet, UNMARKED); break; } /*}}}*/ @@ -412,8 +424,9 @@ static void do_attribute(Sheet *cursheet, Key action) int n; if (onecell) n = !transparent(fcell); - else n = line_ok(_("Make block transparent:"), - transparent(fcell)); + else n = line_binary(_("Set block to:"), + _("pP)rotected"), _("tT)ransparent:"), + !transparent(fcell)); if (n >= 0) for (ALL_LOCS_IN_REGION(cursheet,w)) maketrans(cursheet, w, n); break; @@ -425,7 +438,8 @@ static void do_attribute(Sheet *cursheet, Key action) int n; if (onecell) n = !isbold(fcell); - else n = line_ok(_("Make block bold:"), isbold(fcell)); + else n = line_binary(_("Set block weight to:"), + _("rR)egular"), _("bB)old"), !isbold(fcell)); if (n >= 0) for (ALL_LOCS_IN_REGION(cursheet,w)) bold(cursheet, w, n); break; @@ -437,7 +451,8 @@ static void do_attribute(Sheet *cursheet, Key action) int n; if (onecell) n = !underlined(fcell); - else n = line_ok(_("Underline block:"), underlined(fcell)); + else n = line_binary(_("Set block to:"), _("nN)ot underline"), + _("uU)nderline"), !underlined(fcell)); if (n >= 0) for (ALL_LOCS_IN_REGION(cursheet,w)) underline(cursheet, w, n); break; @@ -456,7 +471,8 @@ static void do_attribute(Sheet *cursheet, Key action) int n; if (onecell) n = !locked(fcell); - else n = line_ok(_("Lock block:"), locked(fcell)); + else n = line_binary(_("Set block to:"), _("uU)nlocked"), _("lL)ocked"), + !locked(fcell)); if (n >= 0) for (ALL_LOCS_IN_REGION(cursheet,w)) lockcell(cursheet, w, n); break; @@ -468,8 +484,8 @@ static void do_attribute(Sheet *cursheet, Key action) int n; if (onecell) n = !ignored(fcell); - else n = line_ok(_("Ignore contents of all cells in this block:"), - ignored(fcell)); + else n = line_binary(_("Set block to:"), _("cC)omputed"), _("iI)gnored"), + !ignored(fcell)); if (n >= 0) for (ALL_LOCS_IN_REGION(cursheet,w)) igncell(cursheet, w, n); break; @@ -913,14 +929,11 @@ static int do_insert(Sheet *sheet) { MenuChoice menu[4]; - menu[0].str=strdup(_("cC)olumn")); menu[0].c='\0'; - menu[1].str=strdup(_("rR)ow")); menu[1].c='\0'; - menu[2].str=strdup(_("dD)epth")); menu[2].c='\0'; + menu[0].str = _("cC)olumn"); menu[0].c='\0'; + menu[1].str = _("rR)ow"); menu[1].c='\0'; + menu[2].str = _("dD)epth"); menu[2].c='\0'; menu[3].str=(char*)0; reply=line_menu(_("Insert:"),menu,0); - free(menu[0].str); - free(menu[1].str); - free(menu[2].str); if (reply<0) return reply; } /*}}}*/ @@ -939,16 +952,14 @@ static int do_insert(Sheet *sheet) /* show menu */ /*{{{*/ switch (reply) { - case 0: menu[0].str=strdup(_("wW)hole column")); break; - case 1: menu[0].str=strdup(_("wW)hole line")); break; - case 2: menu[0].str=strdup(_("wW)hole sheet")); break; + case 0: menu[0].str = _("wW)hole column"); break; + case 1: menu[0].str = _("wW)hole line"); break; + case 2: menu[0].str = _("wW)hole sheet"); break; default: assert(0); } - menu[1].str=strdup(_("sS)ingle cell")); menu[1].c='\0'; - menu[2].str=(char*)0; + menu[1].str = _("sS)ingle cell"); menu[1].c='\0'; + menu[2].str = (char*)0; r=line_menu(_("Insert:"),menu,0); - free(menu[0].str); - free(menu[1].str); /*}}}*/ switch (r) { @@ -1030,14 +1041,11 @@ static int do_delete(Sheet *sheet) { MenuChoice menu[4]; - menu[0].str=strdup(_("cC)olumn")); menu[0].c='\0'; - menu[1].str=strdup(_("rR)ow")); menu[1].c='\0'; - menu[2].str=strdup(_("dD)epth")); menu[2].c='\0'; - menu[3].str=(char*)0; + menu[0].str = _("cC)olumn"); menu[0].c='\0'; + menu[1].str = _("rR)ow"); menu[1].c='\0'; + menu[2].str = _("dD)epth"); menu[2].c='\0'; + menu[3].str = (char*)0; reply=line_menu(_("Delete:"),menu,0); - free(menu[0].str); - free(menu[1].str); - free(menu[2].str); if (reply<0) return reply; } /*}}}*/ @@ -1057,16 +1065,14 @@ static int do_delete(Sheet *sheet) /* show menu */ /*{{{*/ switch (reply) { - case 0: menu[0].str=strdup(_("wW)hole column")); break; - case 1: menu[0].str=strdup(_("wW)hole line")); break; - case 2: menu[0].str=strdup(_("wW)hole sheet")); break; + case 0: menu[0].str = _("wW)hole column"); break; + case 1: menu[0].str = _("wW)hole line"); break; + case 2: menu[0].str = _("wW)hole sheet"); break; default: assert(0); } - menu[1].str=strdup(_("sS)ingle cell")); menu[1].c='\0'; + menu[1].str = _("sS)ingle cell"); menu[1].c='\0'; menu[2].str=(char*)0; r=line_menu(_("Delete:"),menu,0); - free(menu[0].str); - free(menu[1].str); /*}}}*/ switch (r) { @@ -1454,14 +1460,11 @@ static int do_mirror(Sheet *sheet) { MenuChoice menu[4]; - menu[0].str=strdup(_("lL)eft-right")); menu[0].c='\0'; - menu[1].str=strdup(_("uU)pside-down")); menu[1].c='\0'; - menu[2].str=strdup(_("fF)ront-back")); menu[2].c='\0'; - menu[3].str=(char*)0; + menu[0].str = _("lL)eft-right"); menu[0].c='\0'; + menu[1].str = _("uU)pside-down"); menu[1].c='\0'; + menu[2].str = _("fF)ront-back"); menu[2].c='\0'; + menu[3].str = (char*)0; reply=line_menu(_("Mirror block:"),menu,0); - free(menu[0].str); - free(menu[1].str); - free(menu[2].str); if (reply<0) return reply; } /*}}}*/ diff --git a/src/display.c b/src/display.c index 51b2a0c..5c17e8e 100644 --- a/src/display.c +++ b/src/display.c @@ -67,22 +67,22 @@ static int do_attribute(Sheet *cursheet) int c; /* create menus */ - adjmenu[0].str=strdup(_("lL)eft")); adjmenu[0].c='\0'; - adjmenu[1].str=strdup(_("rR)ight")); adjmenu[1].c='\0'; - adjmenu[2].str=strdup(_("cC)entered")); adjmenu[2].c='\0'; - adjmenu[3].str=strdup(_("11).23e1 <-> 12.3")); adjmenu[3].c='\0'; - adjmenu[4].str=strdup(_("pP)recision")); adjmenu[4].c='\0'; - adjmenu[5].str=strdup(_("sS)hadow")); adjmenu[5].c='\0'; - adjmenu[6].str=strdup(_("bB)old")); adjmenu[6].c='\0'; - adjmenu[7].str=strdup(_("uU)nderline")); adjmenu[7].c='\0'; - adjmenu[8].str=strdup(_("oO)utput special characters")); adjmenu[8].c='\0'; - adjmenu[9].str=(char*)0; + adjmenu[0].str = _("lL)eft"); adjmenu[0].c='\0'; + adjmenu[1].str = _("rR)ight"); adjmenu[1].c='\0'; + adjmenu[2].str = _("cC)entered"); adjmenu[2].c='\0'; + adjmenu[3].str = _("11).23e1 <-> 12.3"); adjmenu[3].c='\0'; + adjmenu[4].str = _("pP)recision"); adjmenu[4].c='\0'; + adjmenu[5].str = _("sS)hadow"); adjmenu[5].c='\0'; + adjmenu[6].str = _("bB)old"); adjmenu[6].c='\0'; + adjmenu[7].str = _("uU)nderline"); adjmenu[7].c='\0'; + adjmenu[8].str = _("oO)utput special characters"); adjmenu[8].c='\0'; + adjmenu[9].str = (char*)0; - mainmenu[0].str=strdup(_("rR)epresentation")); mainmenu[0].c='\0'; - mainmenu[1].str=strdup(_("lL)abel")); mainmenu[1].c='\0'; - mainmenu[2].str=strdup(_("oLo)ck")); mainmenu[2].c='\0'; - mainmenu[3].str=strdup(_("iI)gnore")); mainmenu[3].c='\0'; - mainmenu[4].str=(char*)0; + mainmenu[0].str = _("rR)epresentation"); mainmenu[0].c='\0'; + mainmenu[1].str = _("lL)abel"); mainmenu[1].c='\0'; + mainmenu[2].str = _("oLo)ck"); mainmenu[2].c='\0'; + mainmenu[3].str = _("iI)gnore"); mainmenu[3].c='\0'; + mainmenu[4].str = (char*)0; do { @@ -130,21 +130,6 @@ static int do_attribute(Sheet *cursheet) } while (c == K_INVALID); if (c == KEY_CANCEL) c = K_INVALID; - /* free menus */ - free(mainmenu[0].str); - free(mainmenu[1].str); - free(mainmenu[2].str); - free(mainmenu[3].str); - free(adjmenu[0].str); - free(adjmenu[1].str); - free(adjmenu[2].str); - free(adjmenu[3].str); - free(adjmenu[4].str); - free(adjmenu[5].str); - free(adjmenu[6].str); - free(adjmenu[7].str); - free(adjmenu[8].str); - return c; } @@ -156,10 +141,10 @@ static int do_file(Sheet *cursheet) int c; - menu[0].str=strdup(_("lL)oad")); menu[0].c='\0'; - menu[1].str=strdup(_("sS)ave")); menu[1].c='\0'; - menu[2].str=strdup(_("nN)ame")); menu[2].c='\0'; - menu[3].str=(char*)0; + menu[0].str = _("lL)oad"); menu[0].c='\0'; + menu[1].str = _("sS)ave"); menu[1].c='\0'; + menu[2].str = _("nN)ame"); menu[2].c='\0'; + menu[3].str = (char*)0; c=0; do { @@ -174,9 +159,6 @@ static int do_file(Sheet *cursheet) } } while (c == K_INVALID); if (c == KEY_CANCEL) c = K_INVALID; - free(menu[0].str); - free(menu[1].str); - free(menu[2].str); return c; } @@ -258,15 +240,15 @@ static int do_block(Sheet *cursheet) MenuChoice block[9]; int c; - block[0].str=strdup(_("ecle)ar")); block[0].c='\0'; - block[1].str=strdup(_("iI)nsert")); block[1].c='\0'; - block[2].str=strdup(_("dD)elete")); block[2].c='\0'; - block[3].str=strdup(_("mM)ove")); block[3].c='\0'; - block[4].str=strdup(_("cC)opy")); block[4].c='\0'; - block[5].str=strdup(_("fF)ill")); block[5].c='\0'; - block[6].str=strdup(_("sS)ort")); block[6].c='\0'; - block[7].str=strdup(_("rMir)ror")); block[7].c='\0'; - block[8].str=(char*)0; + block[0].str = _("ecle)ar"); block[0].c='\0'; + block[1].str = _("iI)nsert"); block[1].c='\0'; + block[2].str = _("dD)elete"); block[2].c='\0'; + block[3].str = _("mM)ove"); block[3].c='\0'; + block[4].str = _("cC)opy"); block[4].c='\0'; + block[5].str = _("fF)ill"); block[5].c='\0'; + block[6].str = _("sS)ort"); block[6].c='\0'; + block[7].str = _("rMir)ror"); block[7].c='\0'; + block[8].str = (char*)0; c=0; do { @@ -285,14 +267,6 @@ static int do_block(Sheet *cursheet) } } while (c == K_INVALID); if (c == KEY_CANCEL) c = K_INVALID; - free(block[0].str); - free(block[1].str); - free(block[2].str); - free(block[3].str); - free(block[4].str); - free(block[5].str); - free(block[6].str); - free(block[7].str); return c; } @@ -304,15 +278,15 @@ int show_menu(Sheet *cursheet) int c = K_INVALID; - menu[0].str=strdup(_("aA)ttributes")); menu[0].c='\0'; - menu[1].str=strdup(_("wW)idth")); menu[1].c='\0'; - menu[2].str=strdup(_("bB)lock")); menu[2].c='\0'; - menu[3].str=strdup(_("fF)ile")); menu[3].c='\0'; - menu[4].str=strdup(_("gG)oto")); menu[4].c='\0'; - menu[5].str=strdup(_("sS)hell")); menu[5].c='\0'; - menu[6].str=strdup(_("vV)ersion")); menu[6].c='\0'; - menu[7].str=strdup(_("qQ)uit")); menu[7].c='\0'; - menu[8].str=(char*)0; + menu[0].str = _("aA)ttributes"); menu[0].c='\0'; + menu[1].str = _("wW)idth"); menu[1].c='\0'; + menu[2].str = _("bB)lock"); menu[2].c='\0'; + menu[3].str = _("fF)ile"); menu[3].c='\0'; + menu[4].str = _("gG)oto"); menu[4].c='\0'; + menu[5].str = _("sS)hell"); menu[5].c='\0'; + menu[6].str = _("vV)ersion"); menu[6].c='\0'; + menu[7].str = _("qQ)uit"); menu[7].c='\0'; + menu[8].str = (char*)0; do { @@ -332,16 +306,6 @@ int show_menu(Sheet *cursheet) } } while (c == K_INVALID); if (c == KEY_CANCEL) c = K_INVALID; - - free(menu[0].str); - free(menu[1].str); - free(menu[2].str); - free(menu[3].str); - free(menu[4].str); - free(menu[5].str); - free(menu[6].str); - free(menu[7].str); - return c; } @@ -398,6 +362,7 @@ void display_main(Sheet *cursheet) #define TEAPOT_WHITE 16 #define CHANNEL_MAX 1000 +typedef short CursesColor[3]; void display_init(Sheet *cursheet, int always_redraw) { initscr(); @@ -417,6 +382,13 @@ void display_init(Sheet *cursheet, int always_redraw) #ifdef HAVE_TYPEAHEAD if (always_redraw) typeahead(-1); #endif + /* allocate and initialize the palette */ + cursheet->max_colors = COLORS; + cursheet->palette = (void *)malloc(COLORS*sizeof(CursesColor)); + memset(cursheet->palette, '\0', COLORS*sizeof(CursesColor)); + CursesColor *palt = (CursesColor *)(cursheet->palette); + for (size_t i = 0; i <= TEAPOT_WHITE; ++i) + (void)color_content(i, &(palt[i][0]), &(palt[i][1]), &(palt[i][2])); } void display_end(Sheet* sheet) @@ -426,6 +398,7 @@ void display_end(Sheet* sheet) noraw(); refresh(); endwin(); + free(sheet->palette); } void redraw_cell(Sheet *sheet, const Location at ) @@ -833,19 +806,29 @@ int line_ok(const char *prompt, int curx) { MenuChoice menu[3]; - int result; - - assert(curx==0 || curx==1); - menu[0].str=strdup(_("nN)o")); menu[0].c='\0'; - menu[1].str=strdup(_("yY)es")); menu[1].c='\0'; + menu[0].str = _("nN)o"); menu[0].c='\0'; + menu[1].str = _("yY)es"); menu[1].c='\0'; menu[2].str=(char*)0; - result=line_menu(prompt,menu,curx); - free(menu[0].str); - free(menu[1].str); - return (result); + return line_menu(prompt, menu, curx); +} + +/* line_binary -- two choices with cancel */ +int line_binary(const char *prompt, const char* op1, const char* op2, int curx) +{ + + MenuChoice menu[4]; + int result; + + assert(curx==0 || curx==1); + + menu[0].str = _("cC)ancel"); + menu[1].str = op1; menu[0].c='\0'; + menu[2].str = op2; menu[1].c='\0'; + menu[3].str = (char*)0; + return line_menu(prompt, menu, curx+1) - 1; } /* line_menu -- one line menu */ diff --git a/src/display.h b/src/display.h index d4964cf..48a9e21 100644 --- a/src/display.h +++ b/src/display.h @@ -11,7 +11,7 @@ extern "C" { typedef struct { Key c; - char *str; + const char *str; } MenuChoice; void display_main(Sheet *cursheet); @@ -22,6 +22,7 @@ void redraw_sheet(Sheet *sheet); const char *line_file(const char *file, const char *pattern, const char *title, int create); int line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt, size_t *x, size_t *offx); int line_ok(const char *prompt, int curx); +int line_binary(const char *prompt, const char* op1, const char* op2, int curx); void line_msg(const char *prompt, const char *msg); int keypressed(void); void show_text(const char *text); diff --git a/src/fteapot.fl b/src/fteapot.fl index f75ca6f..72340b7 100644 --- a/src/fteapot.fl +++ b/src/fteapot.fl @@ -2,875 +2,962 @@ version 1.0300 header_name {.h} code_name {.cxx} -decl {\#include } {private global -} -decl {\#include } {private global -} +decl {\#include } {public global} +decl {\#include } {public global} +decl {\#include } {public global} -decl {\#include } {private global -} +decl {\#include "display.h"} {public global} -decl {\#include } {private global -} +decl {\#include } {private global} +decl {\#include } {private global} +decl {\#include } {private global} +decl {\#include } {private global} -decl {\#define shadow _shadow} {private global -} +decl {\#define shadow _shadow} {private global} +decl {\#define transparent _transparent} {private global} +decl {\#define MenuChoice _MenuChoice} {private global} +decl {\#define Cell _Cell} {private global} -decl {\#define transparent _transparent} {private global -} +decl {\#include } {private local} +decl {\#include } {private global} +decl {\#include } {private global} +decl {\#include } {private global} +decl {\#include } {private global} -decl {\#define MenuChoice _MenuChoice} {private global -} +decl {\#undef shadow} {private global} +decl {\#undef transparent} {private global} +decl {\#undef MenuChoice} {private global} +decl {\#undef Cell} {private global} -decl {\#define Cell _Cell} {private global -} +decl {\#include "tpt_choose.h"} {private global} +decl {\#include "misc.h"} {private global} -decl {\#include } {private local -} +class TeapotTable {open : {public Fl_Table}} +{ + decl {Sheet *cursheet;} {protected local} + decl {bool cut, updating;} {protected local} + decl {static const TableContext ACTION = (TableContext)(1<<8);} + {public local} + decl {static const TableContext REFRESH = (TableContext)(1<<9);} + {public local} -decl {\#include } {private global -} + Function + {TeapotTable(int x, int y, int w, int h, const char *l=0) : + Fl_Table(x, y, w, h, l), cut(false), updating(false)} {open} {code + { + end(); + col_resize_min(10); + col_resize(true); + col_header(header); + row_resize(false); + row_header(header); + set_visible_focus(); + table_box(FL_THIN_UP_FRAME); + } {} } -decl {\#include } {private global -} + Function {~TeapotTable()} {} {code {} {} } -decl {\#include } {private global -} + Function + {sheet(Sheet *s)} {open return_type void} {code + { + cursheet = s; + s->display = (void *)this; + clear(); + update_table(); + do_callback(CONTEXT_NONE, 0, 0); + } {} } -decl {\#include } {private global -} + Function {sheet()} {return_type {Sheet *}} {code {return cursheet;} {} } -decl {\#include } {public global -} - -decl {\#include } {public global -} - -decl {\#include } {public global -} - -decl {\#undef shadow} {private global -} - -decl {\#undef transparent} {private global -} - -decl {\#undef MenuChoice} {private global -} - -decl {\#undef Cell} {private global -} - -decl {\#include "misc.h"} {private global -} - -decl {\#include "display.h"} {public global -} - -class TeapotTable {open : {public Fl_Table} -} { - decl {Sheet *cursheet;} {protected local - } - decl {bool cut, updating;} {protected local - } - decl {static const TableContext ACTION = (TableContext)(1<<8);} {public local - } - decl {static const TableContext REFRESH = (TableContext)(1<<9);} {public local - } - Function {TeapotTable(int x, int y, int w, int h, const char *l=0) : Fl_Table(x, y, w, h, l), cut(false), updating(false)} {open - } { - code {end(); -col_resize_min(10); -col_resize(true); -col_header(header); -row_resize(false); -row_header(header); -set_visible_focus(); -table_box(FL_THIN_UP_FRAME);} {} - } - Function {~TeapotTable()} {} { - code {} {} - } - Function {sheet(Sheet *s)} {open return_type void - } { - code {cursheet = s; -s->display = (void *)this; -clear(); -update_table(); -do_callback(CONTEXT_NONE, 0, 0);} {} - } - Function {sheet()} {return_type {Sheet *} - } { - code {return cursheet;} {} - } - Function {draw_cell(TableContext context, int R, int C, int xx, int yy, int W, int H)} {open return_type void - } { - code {char s[1024]; -//printf("DRAW: %i @%i,%i - (%i,%i) %ix%i\\n", context, C,R, xx,yy, W,H); -switch (context) { -case CONTEXT_ENDPAGE: - W = xx-x()-2; - H = yy-y()-2; - xx = x()+2; - yy = y()+2; - fl_font(FL_HELVETICA | FL_BOLD, 14); - fl_push_clip(xx, yy, W, H); - fl_draw_box(FL_DIAMOND_UP_BOX, xx, yy, W, H, col_header_color()); - fl_color(FL_INACTIVE_COLOR); - sprintf(s, "%d", cursheet->cur[Z]); - fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER); - fl_pop_clip(); - break; - -case CONTEXT_STARTPAGE: - adjust_outside(); - if (Fl::event_button1()) update_sheet(); - break; - -case CONTEXT_COL_HEADER: - fl_font(FL_HELVETICA | FL_BOLD, 14); - fl_push_clip(xx, yy, W, H); - fl_draw_box(FL_THIN_UP_BOX, xx, yy, W, H, col_header_color()); - fl_color(FL_FOREGROUND_COLOR); - sprintf(s, "%d", C); - fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER); - fl_pop_clip(); - return; - -case CONTEXT_ROW_HEADER: - fl_font(FL_HELVETICA | FL_BOLD, 14); - fl_push_clip(xx, yy, W, H); - fl_draw_box(FL_THIN_UP_BOX, xx, yy, W, H, row_header_color()); - fl_color(FL_FOREGROUND_COLOR); - sprintf(s, "%d", R); - fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER); - fl_pop_clip(); - return; - -case CONTEXT_CELL: { - while (SHADOWEDC(cursheet, C, R, cursheet->cur[Z])) xx -= W = col_width(--C); - int x = C+1; - while (SHADOWEDC(cursheet,x,R,cursheet->cur[Z])) W += col_width(x), x++; - - fl_push_clip(xx, yy, W, H); - bool selected = false; - MarkState ms = getmarkstate(cursheet); - Location test; - test[X] = C; test[Y] = R; test[Z] = cursheet->cur[Z]; - if (ms != UNMARKED) - selected = loc_in_box(test, cursheet->mark1, cursheet->mark2); - bool iscurrent = C == cursheet->cur[X] && R == cursheet->cur[Y]; - fl_draw_box(iscurrent ? FL_BORDER_BOX : FL_THIN_DOWN_BOX, xx, yy, W, H, - selected ? FL_SELECTION_COLOR : FL_BACKGROUND2_COLOR); - if (Fl::focus() == this && iscurrent) - draw_focus(FL_BORDER_BOX, xx, yy, W, H); - fl_pop_clip(); - - Cell *cell = safe_cell_at(cursheet, test); - - fl_push_clip(xx+3, yy+3, W-6, H-6); - fl_color(FL_FOREGROUND_COLOR); - fl_font(FL_HELVETICA | (isbold(cell) ? FL_BOLD : 0), 14); - - printvalue(s, sizeof(s), 0, 0, getscientific(cell), - getprecision(cell), cursheet, test); - - int ww = 0, hh = 0; - fl_measure(s, ww, hh, 0); - if (ww > W-6) for (int i = 0; s[i]; i++) s[i] = '\#'; - - int adj = getadjust(cell); - fl_draw(s, xx+3, yy+3, W-6, H-6, adj == RIGHT?FL_ALIGN_RIGHT:adj == LEFT?FL_ALIGN_LEFT:FL_ALIGN_CENTER); - if (underlined(cell)) fl_xyline(xx, yy+H-7, xx+W); - fl_pop_clip(); - - return; -} - -default: - return; -}} {selected - } - } - Function {update_table()} {open return_type void - } { - code {if (updating) return; - -updating = true; -//printf("update_table: %ix%i@%i,%i; %i[%i], %i[%i]\\n", cursheet->dimx, cursheet->dimy, cursheet->curx, cursheet->cury, cursheet->offx, cursheet->maxx, cursheet->offy, cursheet->maxy); - -if (cursheet->dimx > cols()) cols(cursheet->dimx); -if (cursheet->dimy > rows()) rows(cursheet->dimy); -adjust_outside(); - -for (int x = 0; x < cursheet->dimx; x++) { - int w = columnwidth(cursheet, x, cursheet->cur[Z])*10; - if (col_width(x) != w) col_width(x, w); -} -col_position(cursheet->offx); -row_position(cursheet->offy); -set_selection(cursheet->cur[Y], cursheet->cur[X], - cursheet->cur[Y], cursheet->cur[X]); -move_cursor(0,0); -updating = false;} {} - } - Function {update_sheet()} {return_type void - } { - code {int x1, x2, y1, y2; - -if (updating) return; -updating = true; - -get_selection(y1, x1, y2, x2); -if (x1 != x2 || y1 != y2) { - cursheet->mark1[X] = x1; - cursheet->mark1[Y] = y1; - cursheet->mark2[X] = x2; - cursheet->mark2[Y] = y2; - cursheet->mark1[Z] = cursheet->mark2[Z] = cursheet->cur[Z]; - cursheet->marking = MARKED; -} -moveto(cursheet, current_col, current_row, -1); -visible_cells(cursheet->offy, cursheet->maxy, cursheet->offx, cursheet->maxx); -cursheet->maxx -= cursheet->offx; -cursheet->maxy -= cursheet->offy; - -if (is_interactive_resize()) { - for (int C = 0; C < cursheet->dimx; C++) { - int w = (col_width(C) + 5)/10; - if (w != columnwidth(cursheet, C, cursheet->cur[Z])) - setwidth(cursheet, C, cursheet->cur[Z], w); - } -} - - -updating = false; -//printf("update_sheet: %ix%i@%i,%i; %i[%i], %i[%i] (%i,%i)-(%i,%i)\\n", cols(), rows(), cursheet->curx, cursheet->cury, cursheet->offx, cursheet->maxx, cursheet->offy, cursheet->maxy, x1, y1, x2, y2);} {} - } - Function {handle(int event)} {open return_type int - } { - code {if (event == FL_KEYDOWN) { - int ctrl = Fl::event_ctrl(); - int alt = Fl::event_alt(); - int shift = Fl::event_shift(); - Key k = (Key)Fl::event_key(); - - switch ((unsigned int)k) { - case FL_Escape: k = K_INVALID; break; - case FL_BackSpace: k = K_BACKSPACE; break; - case FL_F+1: k = ctrl?K_ABOUT:K_HELP; break; - case FL_F+8: k = ctrl?K_RECALC:K_CLOCK; break; - case FL_F+9: k = ctrl?K_RECALC:K_CLOCK; break; - case FL_F+10: k = (Key)'/'; break; - case FL_Tab: if (shift) { k = K_CLOCK; break; } - case FL_Enter: - case FL_KP_Enter: k = alt?K_MENTER:K_ENTER; break; - case 'c': if (ctrl) { do_mark(cursheet, GET_MARK_CUR); cut = false; k = K_NONE; } break; - case 'v': if (ctrl) { do_mark(cursheet, MARKED); - k = cut ? BLOCK_MOVE : BLOCK_COPY; - } + Function + {draw_cell(TableContext context, int R, int C, int xx, int yy, + int W, int H)} {open return_type void} {code + { + char s[1024]; + if (debug_level > 2) + printf("DRAW: %i @%i,%i - (%i,%i) %ix%i\\n", + context, C, R, xx, yy, W, H); + switch (context) { + case CONTEXT_ENDPAGE: + W = xx-x()-2; H = yy-y()-2; + xx = x()+2; yy = y()+2; + fl_font(FL_HELVETICA | FL_BOLD, 14); + fl_push_clip(xx, yy, W, H); + fl_draw_box(FL_DIAMOND_UP_BOX, xx, yy, W, H, col_header_color()); + fl_color(FL_INACTIVE_COLOR); + sprintf(s, "%d", cursheet->cur[Z]); + fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER); + fl_pop_clip(); break; - case 'x': if (ctrl) { do_mark(cursheet, GET_MARK_CUR); cut = true, k = K_NONE; } break; - case 'r': if (ctrl) k = K_RECALC; break; - case 'd': if (ctrl && shift && debug_level > 0) k = K_DUMPCELL; break; - case FL_Insert: if (ctrl) { do_mark(cursheet, GET_MARK_CUR); cut = false; } k = !shift?K_NONE:cut?BLOCK_MOVE:BLOCK_COPY; break; - case FL_Delete: if (shift) { do_mark(cursheet, GET_MARK_CUR); cut = true; } k = shift?K_NONE:BLOCK_CLEAR; break; - case FL_Home: k = ctrl?K_FIRSTL:shift?K_FSHEET:K_HOME; break; - case FL_End: k = ctrl?K_LASTL:shift?K_LSHEET:K_END; break; - case FL_Up: if (shift) do_mark(cursheet, MARKING); k = ctrl?K_PPAGE:K_UP; break; - case FL_Down: if (shift) do_mark(cursheet, MARKING); k = ctrl?K_NPAGE:K_DOWN; break; - case FL_Right: if (shift) do_mark(cursheet, MARKING); k = ctrl?K_FPAGE:K_RIGHT; break; - case FL_Left: if (shift) do_mark(cursheet, MARKING); k = ctrl?K_BPAGE:K_LEFT; break; - case FL_Page_Down: k = shift?K_NSHEET:ctrl?K_LASTL :K_NPAGE; break; - case FL_Page_Up: k = shift?K_PSHEET:ctrl?K_FIRSTL:K_PPAGE; break; - } - if (k > 0 && (ctrl || alt)) return 0; + case CONTEXT_STARTPAGE: + adjust_outside(); + if (Fl::event_button1()) update_sheet(); + break; - // Quick and dirty upper-case fix, fails for international chars on keyboards... - if (shift && !alt && !ctrl && k >= 'a' && k <= 'z') k = (Key)(k - 'a' + 'A'); + case CONTEXT_COL_HEADER: + fl_font(FL_HELVETICA | FL_BOLD, 14); + fl_push_clip(xx, yy, W, H); + fl_draw_box(FL_THIN_UP_BOX, xx, yy, W, H, col_header_color()); + fl_color(FL_FOREGROUND_COLOR); + sprintf(s, "%d", C); + fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER); + fl_pop_clip(); + return; - do_sheetcmd(cursheet, k, cursheet->moveonly); - do_callback(ACTION, 0, 0); - redraw(); -} else if (event == FL_FOCUS) { - do_callback(REFRESH, 0, 0); - return 1; -} else if (event == FL_PUSH) { - int ex = Fl::event_x() - x(), ey = Fl::event_y() - y(); - if (ex >= row_header_width() || ey >= col_header_height()) { + case CONTEXT_ROW_HEADER: + fl_font(FL_HELVETICA | FL_BOLD, 14); + fl_push_clip(xx, yy, W, H); + fl_draw_box(FL_THIN_UP_BOX, xx, yy, W, H, row_header_color()); + fl_color(FL_FOREGROUND_COLOR); + sprintf(s, "%d", R); + fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER); + fl_pop_clip(); + return; + + case CONTEXT_CELL: { + while (SHADOWEDC(cursheet, C, R, cursheet->cur[Z])) + xx -= W = col_width(--C); + int x = C+1; + while (SHADOWEDC(cursheet, x, R, cursheet->cur[Z])) + W += col_width(x), x++; + + fl_push_clip(xx, yy, W, H); + bool selected = false; + MarkState ms = getmarkstate(cursheet); + Location test; + test[X] = C; test[Y] = R; test[Z] = cursheet->cur[Z]; + if (ms != UNMARKED) + selected = loc_in_box(test, cursheet->mark1, cursheet->mark2); + bool iscurrent = C == cursheet->cur[X] && R == cursheet->cur[Y]; + fl_draw_box(iscurrent ? FL_BORDER_BOX : FL_THIN_DOWN_BOX, + xx, yy, W, H, + selected ? FL_SELECTION_COLOR : FL_BACKGROUND2_COLOR); + if (Fl::focus() == this && iscurrent) + draw_focus(FL_BORDER_BOX, xx, yy, W, H); + fl_pop_clip(); + + Cell *cell = safe_cell_at(cursheet, test); + + fl_push_clip(xx+3, yy+3, W-6, H-6); + fl_color(FL_FOREGROUND_COLOR); + fl_font(FL_HELVETICA | (isbold(cell) ? FL_BOLD : 0), 14); + + printvalue(s, sizeof(s), 0, 0, getscientific(cell), + getprecision(cell), cursheet, test); + + int ww = 0, hh = 0; + fl_measure(s, ww, hh, 0); + if (ww > W-6) for (int i = 0; s[i]; i++) s[i] = '\#'; + + int adj = getadjust(cell); + fl_draw(s, xx+3, yy+3, W-6, H-6, + adj == RIGHT ? FL_ALIGN_RIGHT : + adj == LEFT ? FL_ALIGN_LEFT : FL_ALIGN_CENTER); + if (underlined(cell)) fl_xyline(xx, yy+H-7, xx+W); + fl_pop_clip(); + + return; + } + + default: + return; + } + } {selected} } + + Function + {update_table()} {open return_type void} {code + { + if (updating) return; + updating = true; + if (debug_level > 2) + printf("update_table: %ix%i@%i,%i; %i[%i], %i[%i]\\n", + cursheet->dimx, cursheet->dimy, + cursheet->cur[X], cursheet->cur[Y], + cursheet->offx, cursheet->maxx, + cursheet->offy, cursheet->maxy); + + if (cursheet->dimx > cols()) cols(cursheet->dimx); + if (cursheet->dimy > rows()) rows(cursheet->dimy); + adjust_outside(); + + for (int x = 0; x < cursheet->dimx; x++) { + int w = columnwidth(cursheet, x, cursheet->cur[Z])*10; + if (col_width(x) != w) col_width(x, w); + } + col_position(cursheet->offx); + row_position(cursheet->offy); + set_selection(cursheet->cur[Y], cursheet->cur[X], + cursheet->cur[Y], cursheet->cur[X]); + move_cursor(0,0); + updating = false; + } {} } + + Function + {update_sheet()} {return_type void} {code + { + int x1, x2, y1, y2; + + if (updating) return; + updating = true; + + get_selection(y1, x1, y2, x2); + if (x1 != x2 || y1 != y2) { + cursheet->mark1[X] = x1; + cursheet->mark1[Y] = y1; + cursheet->mark2[X] = x2; + cursheet->mark2[Y] = y2; + cursheet->mark1[Z] = cursheet->mark2[Z] = cursheet->cur[Z]; + cursheet->marking = MARKED; + } + moveto(cursheet, current_col, current_row, -1); + visible_cells(cursheet->offy, cursheet->maxy, + cursheet->offx, cursheet->maxx); + cursheet->maxx -= cursheet->offx; + cursheet->maxy -= cursheet->offy; + + if (is_interactive_resize()) { + for (int C = 0; C < cursheet->dimx; C++) { + int w = (col_width(C) + 5)/10; + if (w != columnwidth(cursheet, C, cursheet->cur[Z])) + setwidth(cursheet, C, cursheet->cur[Z], w); + } + } + + updating = false; + if (debug_level > 2) + printf("upd_sheet: %ix%i@%i,%i; %i[%i], %i[%i] (%i,%i)-(%i,%i)\\n", + cols(), rows(), cursheet->cur[X], cursheet->cur[Y], + cursheet->offx, cursheet->maxx, + cursheet->offy, cursheet->maxy, x1, y1, x2, y2); + } {} } + + Function + {handle(int event)} {open return_type int} {code + { + if (event == FL_KEYDOWN) { + int ctrl = Fl::event_ctrl(); + int alt = Fl::event_alt(); + int shift = Fl::event_shift(); + Key k = (Key)Fl::event_key(); + + switch ((unsigned int)k) { + case FL_Escape: k = K_INVALID; break; + case FL_BackSpace: k = K_BACKSPACE; break; + case FL_F+1: k = ctrl?K_ABOUT:K_HELP; break; + case FL_F+8: k = ctrl?K_RECALC:K_CLOCK; break; + case FL_F+9: k = ctrl?K_RECALC:K_CLOCK; break; + case FL_F+10: k = (Key)'/'; break; + case FL_Tab: if (shift) { k = K_CLOCK; break; } + case FL_Enter: + case FL_KP_Enter: k = alt?K_MENTER:K_ENTER; break; + case 'c': + if (ctrl) { + do_mark(cursheet, GET_MARK_CUR); + cut = false; + k = K_NONE; + } + break; + case 'v': + if (ctrl) { + do_mark(cursheet, MARKED); + k = cut ? BLOCK_MOVE : BLOCK_COPY; + } + break; + case 'x': + if (ctrl) { + do_mark(cursheet, GET_MARK_CUR); + cut = true; + k = K_NONE; + } + break; + case 'r': if (ctrl) k = K_RECALC; break; + case 'd': + if (ctrl && shift && debug_level > 0) k = K_DUMPCELL; + break; + case FL_Insert: + if (ctrl) { + do_mark(cursheet, GET_MARK_CUR); + cut = false; + } + k = !shift ? K_NONE : cut ? BLOCK_MOVE : BLOCK_COPY; + break; + case FL_Delete: + if (shift) { + do_mark(cursheet, GET_MARK_CUR); + cut = true; + } + k = shift ? K_NONE : BLOCK_CLEAR; + break; + case FL_Home: k = ctrl ? K_FIRSTL : shift ? K_FSHEET: K_HOME; break; + case FL_End: k = ctrl ? K_LASTL : shift ? K_LSHEET : K_END; break; + case FL_Up: + if (shift) do_mark(cursheet, MARKING); + k = ctrl ? K_PPAGE : K_UP; + break; + case FL_Down: + if (shift) do_mark(cursheet, MARKING); + k = ctrl ? K_NPAGE : K_DOWN; + break; + case FL_Right: + if (shift) do_mark(cursheet, MARKING); + k = ctrl ? K_FPAGE : K_RIGHT; + break; + case FL_Left: + if (shift) do_mark(cursheet, MARKING); + k = ctrl ? K_BPAGE : K_LEFT; break; + case FL_Page_Down: + k = shift ? K_NSHEET : ctrl ? K_LASTL : K_NPAGE; + break; + case FL_Page_Up: + k = shift ? K_PSHEET : ctrl ? K_FIRSTL : K_PPAGE; + break; + } + + if (k > 0 && (ctrl || alt)) return 0; + + // Quick and dirty upper-case fix, fails for international chars on keyboards... + if (shift && !alt && !ctrl && k >= 'a' && k <= 'z') + k = (Key)(k - 'a' + 'A'); + + do_sheetcmd(cursheet, k, cursheet->moveonly); + do_callback(ACTION, 0, 0); + redraw(); + } else if (event == FL_FOCUS) { + do_callback(REFRESH, 0, 0); + return 1; + } else if (event == FL_PUSH) { + int ex = Fl::event_x() - x(), ey = Fl::event_y() - y(); + if (ex >= row_header_width() || ey >= col_header_height()) { int rc = Fl_Table::handle(event); do_callback(ACTION, 0, 0); return rc; + } + if (ex < row_header_width()/2) relmoveto(cursheet, 0, 0, -1); + else relmoveto(cursheet, 0, 0, 1); + return 1; + } else if (event != FL_KEYUP) { + return Fl_Table::handle(event); + } + + return 1; + } {} } + + Function + {adjust_outside()} {open protected return_type void} {code + { + int x1, x2, y1, y2; + + if (!cols() || !rows()) { cols(1); rows(1); } + + visible_cells(y1, y2, x1, x2); + if (debug_level > 2) + printf("adj: (%i,%i)-(%i,%i) %ix%i\\n", x1, y1, x2, y2, + cols(), rows()); + if (x2+2 < cols() && cols() > cursheet->dimx) + cols(x2+2 < cursheet->dimx?cursheet->dimx:x2+2); + else if (x2+1 == cols()) { + int xpos = col_scroll_position(cols()); + int w = col_width(cols()-1); + x2 += (tow + hscrollbar->value() - xpos) / w + 2; + //printf(" : t: %i, w: %i, p: %i, r: %i\\n", tow, w, xpos, x2+1); + cols(x2+1); + } + + if (y2+2 < rows() && rows() > cursheet->dimy) + rows(y2+2 < cursheet->dimy?cursheet->dimy:y2+2); + else if (y2+1 == rows()) { + int ypos = row_scroll_position(rows()); + int h = row_height(rows()-1); + y2 += (toh + vscrollbar->value() - ypos) / h + 2; + rows(y2+1); } - if (ex < row_header_width()/2) relmoveto(cursheet, 0, 0, -1); - else relmoveto(cursheet, 0, 0, 1); - return 1; -} else if (event != FL_KEYUP) { - return Fl_Table::handle(event); + } {} } + } +# End of class TeapotTable -return 1;} {} - } - Function {adjust_outside()} {open protected return_type void - } { - code {int x1, x2, y1, y2; +class MainWindow {open} +{ + decl {static MainWindow *current;} {protected local} + decl {int edit_rc;} {private local} -if (!cols() || !rows()) { - cols(1); - rows(1); -} - -visible_cells(y1, y2, x1, x2); -//printf("adj: (%i,%i)-(%i,%i) %ix%i\\n", x1, y1, x2, y2, cols(), rows()); -if (x2+2 < cols() && cols() > cursheet->dimx) cols(x2+2 < cursheet->dimx?cursheet->dimx:x2+2); -else if (x2+1 == cols()) { - int xpos = col_scroll_position(cols()); - int w = col_width(cols()-1); - x2 += (tow + hscrollbar->value() - xpos) / w + 2; - //printf(" : t: %i, w: %i, p: %i, r: %i\\n", tow, w, xpos, x2+1); - cols(x2+1); -} - -if (y2+2 < rows() && rows() > cursheet->dimy) rows(y2+2 < cursheet->dimy?cursheet->dimy:y2+2); -else if (y2+1 == rows()) { - int ypos = row_scroll_position(rows()); - int h = row_height(rows()-1); - y2 += (toh + vscrollbar->value() - ypos) / h + 2; - rows(y2+1); -}} {} - } -} - -class MainWindow {open -} { - decl {static MainWindow *current;} {protected local - } - decl {int edit_rc;} {private local - } - Function {MainWindow(Sheet *sheet)} {open - } { - Fl_Window window { - label teapot - callback {if (Fl::event_key(FL_Escape)) table->take_focus(); -else if (do_sheetcmd(table->sheet(), K_QUIT, 0) && doanyway(table->sheet(), _("Sheet modified, leave anyway?"))) { - line_label->deactivate(); - window->hide(); -}} open - protected xywh {866 342 800 600} type Double when 0 hide resizable - } { - Fl_Menu_Bar menu { - callback {Sheet *sheet = table->sheet(); -Key action = (Key)(intptr_t)o->mvalue()->user_data(); - -if (do_sheetcmd(sheet, action, sheet->moveonly) && doanyway(sheet, _("Sheet modified, leave anyway?"))) { - window->hide(); - return; -} - -table->update_table(); -table->redraw();} open - xywh {0 0 800 25} - class Fl_Sys_Menu_Bar - } { - Submenu {} { - label {&File} - xywh {25 25 67 24} - } { - MenuItem {} { - label {&Open...} - user_data K_LOADMENU - xywh {5 5 30 20} shortcut 0x4006f - } - MenuItem {} { - label {&Save} - user_data K_SAVE - xywh {0 0 30 20} shortcut 0x40073 - } - MenuItem {} { - label {Save &As...} - user_data K_NAME - xywh {0 0 30 20} shortcut 0x50053 divider - } - MenuItem {} { - label {&Quit} - user_data K_QUIT - xywh {0 0 30 20} shortcut 0x40071 - } - } - Submenu {} { - label {&Block} - xywh {25 25 67 24} - } { - MenuItem {} { - label {&Insert} - user_data BLOCK_INSERT - xywh {0 0 30 20} shortcut 0x90069 - } - MenuItem {} { - label {&Delete} - user_data BLOCK_DELETE - xywh {0 0 30 20} shortcut 0x90064 divider - } - MenuItem {} { - label {&Move} - user_data BLOCK_MOVE - xywh {0 0 30 20} shortcut 0x9006d - } - MenuItem {} { - label {&Copy} - user_data BLOCK_COPY - xywh {0 0 36 21} shortcut 0x90063 divider - } - MenuItem {} { - label {&Fill} - user_data BLOCK_FILL - xywh {0 0 36 21} shortcut 0x90066 - } - MenuItem {} { - label {FillWith} - user_data FILL_BLOCK - xywh {0 0 36 30} - } - MenuItem {} { - label {C&lear} - user_data BLOCK_CLEAR - xywh {0 0 36 21} shortcut 0x9006c divider - } - MenuItem {} { - label {&Sort} - user_data BLOCK_SORT - xywh {0 0 36 21} shortcut 0x90073 - } - MenuItem {} { - label {Mi&rror} - user_data BLOCK_MIRROR - xywh {0 0 36 21} shortcut 0x90072 - } - } - Submenu {} { - label {&View} - xywh {0 0 70 21} - } { - MenuItem {} { - label {Column &Width...} - user_data K_COLWIDTH - xywh {0 0 36 21} shortcut 0x80077 - } - MenuItem {} { - label {&Goto} - user_data K_GOTO - xywh {0 0 36 21} shortcut 0x40067 - } - } - Submenu {} { - label {F&ormat} open - xywh {5 5 70 21} - } { - MenuItem {} { - label {L&abel...} - user_data ADJUST_LABEL - xywh {0 0 36 21} shortcut 0x80061 divider - } - MenuItem bold { - label {&Bold} - user_data ADJUST_BOLD - protected xywh {0 0 34 21} shortcut 0x80062 - code0 {o->flags |= FL_MENU_TOGGLE;} - } - MenuItem underline { - label {&Underline} - user_data ADJUST_UNDERLINE - protected xywh {0 0 34 21} shortcut 0x80075 divider - code0 {o->flags |= FL_MENU_TOGGLE;} - } - MenuItem left { - label {&Left} - user_data ADJUST_LEFT - protected xywh {0 0 36 21} shortcut 0x8006c - code0 {o->flags |= FL_MENU_RADIO;} - } - MenuItem right { - label {&Right} - user_data ADJUST_RIGHT - protected xywh {0 0 36 21} shortcut 0x80072 - code0 {o->flags |= FL_MENU_RADIO;} - } - MenuItem center { - label {&Center} - user_data ADJUST_CENTER - protected xywh {0 0 36 21} shortcut 0x80063 divider - code0 {o->flags |= FL_MENU_RADIO;} - } - MenuItem {} { - label {&Precision...} - user_data ADJUST_PRECISION - xywh {0 0 36 21} shortcut 0x80070 divider - } - MenuItem sci { - label {&Scientific} - user_data ADJUST_SCIENTIFIC - protected xywh {0 0 36 21} shortcut 0x80073 - code0 {o->flags |= FL_MENU_TOGGLE;} - } - MenuItem shadow { - label {Shadow&ed} - user_data ADJUST_SHADOW - protected xywh {0 0 36 21} shortcut 0x80065 - code0 {o->flags |= FL_MENU_TOGGLE;} - } - MenuItem transparent { - label {&Transparent} - user_data ADJUST_TRANSPARENT - protected xywh {0 0 36 21} shortcut 0x80074 divider - code0 {o->flags |= FL_MENU_TOGGLE;} - } - MenuItem lock { - label {Lo&ck} - user_data ADJUST_LOCK - protected xywh {0 0 36 21} shortcut 0x80063 - code0 {o->flags |= FL_MENU_TOGGLE;} - } - MenuItem ignore { - label {&Ignore} - user_data ADJUST_IGNORE - protected xywh {0 0 36 21} shortcut 0x80069 - code0 {o->flags |= FL_MENU_TOGGLE;} - } - } - Submenu {} { - label {&Help} open - xywh {25 25 67 24} - } { - MenuItem {} { - label {&Manual} - user_data K_HELP - xywh {0 0 30 20} shortcut 0xffbe - } - MenuItem {} { - label {&About} - user_data K_ABOUT - xywh {0 0 30 20} - } - } - } - Fl_Group line_label { - label { Input:} open - protected xywh {0 25 800 25} box ROUND_UP_BOX align 20 deactivate - } { - Fl_Input line_input { - callback {bool enterkey = Fl::event_key(FL_Enter) || Fl::event_key(FL_KP_Enter); -if (Fl::focus() && (Fl::focus() != table || enterkey || Fl::event_key(FL_Escape))) { - if (enterkey) edit_rc = 0; - line_label->deactivate(); -}} - protected xywh {75 27 723 21} box ROUND_DOWN_BOX labeltype NO_LABEL align 20 when 6 deactivate - } - } - Fl_Box table { - callback {Sheet *sheet = table->sheet(); -table->update_sheet(); - -const char *label = getlabel(curcell(sheet)); -char moveonly=sheet->moveonly ? *_("V") : *_("E"); - -char buf[1024]; -if (*label == 0) - snprintf(buf, sizeof(buf), "%c @@(%d,%d,%d)=", moveonly, - sheet->cur[X], sheet->cur[Y], sheet->cur[Z]); -else snprintf(buf, sizeof(buf), "%c @@(%s)=", moveonly, label); - -if (moveonly && table->callback_context() == TeapotTable::ACTION) { - char valbuf[1024] = ""; - if (Fl::event_key() == 'p' || Fl::event_button1()) - sprintf(valbuf, "(%i,%i,%i)", - sheet->cur[X], sheet->cur[Y], sheet->cur[Z]); - else if (Fl::event_key() == 'v') - printvalue(valbuf, sizeof(valbuf), 0, 1, - getscientific(curcell(sheet)), -1, sheet, sheet->cur); - else if (Fl::event_key(FL_Tab)) line_input->take_focus(); - if (valbuf[0]) { - line_input->insert(valbuf); - line_input->take_focus(); + Function + {MainWindow(Sheet *sheet)} {open} + { + Fl_Window window { + label teapot + callback { + if (Fl::event_key(FL_Escape)) table->take_focus(); + else if (do_sheetcmd(table->sheet(), K_QUIT, 0) && + doanyway(table->sheet(), + _("Sheet modified, leave anyway?"))) { + line_label->deactivate(); + window->hide(); + } + } + open protected + xywh {866 342 800 600} type Double when 0 hide resizable } -} + { + Fl_Menu_Bar menu { + callback { + Sheet *sheet = table->sheet(); + Key action = (Key)(intptr_t)o->mvalue()->user_data(); + if (do_sheetcmd(sheet, action, sheet->moveonly) && + doanyway(sheet, _("Sheet modified, leave anyway?"))) + { + window->hide(); + return; + } -char *err; -char val[1024]; -if ((err = geterror(sheet, sheet->cur))) { - strncpy(val,err,sizeof(val)); - free(err); - val[sizeof(val)-1] = 0; -} else { - print(val, sizeof(val), 0, 1, getscientific(curcell(sheet)), -1, - getcont(curcell(sheet), BASE)); - Token **iter = getcont(curcell(sheet), ITERATIVE); - if (iter != EMPTY_TVEC) { - snprintf(val+strlen(val),sizeof(val)-strlen(val)," -> "); - print(val+strlen(val), sizeof(val)-strlen(val), 0, 1, - getscientific(curcell(sheet)), -1, iter); + table->update_table(); + table->redraw(); + } + open xywh {0 0 800 25} class Fl_Sys_Menu_Bar + } + { + Submenu {} {label {&File} xywh {25 25 67 24} } { + MenuItem {} { + label {&Open...} + user_data K_LOADMENU + xywh {5 5 30 20} shortcut 0x4006f + } + MenuItem {} { + label {&Save} + user_data K_SAVE + xywh {0 0 30 20} shortcut 0x40073 } -} + MenuItem {} { + label {Save &As...} + user_data K_NAME + xywh {0 0 30 20} shortcut 0x50053 divider + } + MenuItem {} { + label {&Quit} + user_data K_QUIT + xywh {0 0 30 20} shortcut 0x40071 + } + } + Submenu {} {label {&Block} xywh {25 25 67 24} } { + MenuItem {} { + label {&Insert} + user_data BLOCK_INSERT + xywh {0 0 30 20} shortcut 0x90069 + } + MenuItem {} { + label {&Delete} + user_data BLOCK_DELETE + xywh {0 0 30 20} shortcut 0x90064 divider + } + MenuItem {} { + label {&Move} + user_data BLOCK_MOVE + xywh {0 0 30 20} shortcut 0x9006d + } + MenuItem {} { + label {&Copy} + user_data BLOCK_COPY + xywh {0 0 36 21} shortcut 0x90063 divider + } + MenuItem {} { + label {&Fill} + user_data BLOCK_FILL + xywh {0 0 36 21} shortcut 0x90066 + } + MenuItem {} { + label {FillWith} + user_data FILL_BLOCK + xywh {0 0 36 30} + } + MenuItem {} { + label {C&lear} + user_data BLOCK_CLEAR + xywh {0 0 36 21} shortcut 0x9006c divider + } + MenuItem {} { + label {&Sort} + user_data BLOCK_SORT + xywh {0 0 36 21} shortcut 0x90073 + } + MenuItem {} { + label {Mi&rror} + user_data BLOCK_MIRROR + xywh {0 0 36 21} shortcut 0x90072 + } + } + Submenu {} {label {&View} xywh {0 0 70 21}} { + MenuItem {} { + label {Column &Width...} + user_data K_COLWIDTH + xywh {0 0 36 21} shortcut 0x80077 + } + MenuItem {} { + label {&Goto} + user_data K_GOTO + xywh {0 0 36 21} shortcut 0x40067 + } + } + Submenu {} {label {F&ormat} open xywh {5 5 70 21}} { + MenuItem {} { + label {L&abel...} + user_data ADJUST_LABEL + xywh {0 0 36 21} shortcut 0x80061 divider + } + MenuItem bold { + label {&Bold} + user_data ADJUST_BOLD + protected xywh {0 0 34 21} shortcut 0x80062 + code0 {o->flags |= FL_MENU_TOGGLE;} + } + MenuItem underline { + label {&Underline} + user_data ADJUST_UNDERLINE + protected xywh {0 0 34 21} shortcut 0x80075 divider + code0 {o->flags |= FL_MENU_TOGGLE;} + } + MenuItem left { + label {&Left} + user_data ADJUST_LEFT + protected xywh {0 0 36 21} shortcut 0x8006c + code0 {o->flags |= FL_MENU_RADIO;} + } + MenuItem right { + label {&Right} + user_data ADJUST_RIGHT + protected xywh {0 0 36 21} shortcut 0x80072 + code0 {o->flags |= FL_MENU_RADIO;} + } + MenuItem center { + label {&Center} + user_data ADJUST_CENTER + protected xywh {0 0 36 21} shortcut 0x80063 divider + code0 {o->flags |= FL_MENU_RADIO;} + } + MenuItem {} { + label {&Precision...} + user_data ADJUST_PRECISION + xywh {0 0 36 21} shortcut 0x80070 divider + } + MenuItem sci { + label {&Scientific} + user_data ADJUST_SCIENTIFIC + protected xywh {0 0 36 21} shortcut 0x80073 + code0 {o->flags |= FL_MENU_TOGGLE;} + } + MenuItem shadow { + label {Shadow&ed} + user_data ADJUST_SHADOW + protected xywh {0 0 36 21} shortcut 0x80065 + code0 {o->flags |= FL_MENU_TOGGLE;} + } + MenuItem transparent { + label {&Transparent} + user_data ADJUST_TRANSPARENT + protected xywh {0 0 36 21} shortcut 0x80074 divider + code0 {o->flags |= FL_MENU_TOGGLE;} + } + MenuItem lock { + label {Lo&ck} + user_data ADJUST_LOCK + protected xywh {0 0 36 21} shortcut 0x80063 + code0 {o->flags |= FL_MENU_TOGGLE;} + } + MenuItem ignore { + label {&Ignore} + user_data ADJUST_IGNORE + protected xywh {0 0 36 21} shortcut 0x80069 + code0 {o->flags |= FL_MENU_TOGGLE;} + } + } + Submenu {} {label {&Help} open xywh {25 25 67 24}} { + MenuItem {} { + label {&Manual} + user_data K_HELP + xywh {0 0 30 20} shortcut 0xffbe + } + MenuItem {} { + label {&About} + user_data K_ABOUT + xywh {0 0 30 20} + } + } + } + Fl_Group line_label { + label { Input:} open + protected xywh {0 25 800 25} box ROUND_UP_BOX align 20 deactivate + } + { + Fl_Input line_input { + callback { + bool enterkey = Fl::event_key(FL_Enter) || + Fl::event_key(FL_KP_Enter); + if (Fl::focus() && + (Fl::focus() != table || enterkey || + Fl::event_key(FL_Escape))) { + if (enterkey) edit_rc = 0; + line_label->deactivate(); + } + } + protected xywh {75 27 723 21} box ROUND_DOWN_BOX + labeltype NO_LABEL align 20 when 6 deactivate + } + } + Fl_Box table { + callback { + Sheet *sheet = table->sheet(); + table->update_sheet(); -line_edit(sheet, val, 0, buf, 0, 0); -Cell *cell = curcell(sheet); -int adj = getadjust(cell); -if (adj == LEFT) left->setonly(); -else if (adj == RIGHT) right->setonly(); -else if (adj == CENTER) center->setonly(); -if (SHADOWEDC(sheet, sheet->cur[X]+1, sheet->cur[Y], sheet->cur[Z])) - shadow->set(); -else shadow->clear(); -if (::transparent(cell)) transparent->set(); -else transparent->clear(); -if (locked(cell)) lock->set(); -else lock->clear(); -if (ignored(cell)) ignore->set(); -else ignore->clear(); -if (isbold(cell)) bold->set(); -else bold->clear(); -if (underlined(cell)) underline->set(); -else underline->clear(); -if (getscientific(cell)) sci->set(); -else sci->clear();} - protected xywh {0 50 800 525} box DOWN_FRAME labeltype NO_LABEL resizable + const char *label = getlabel(curcell(sheet)); + char moveonly=sheet->moveonly ? *_("V") : *_("E"); + + char buf[1024]; + if (*label == 0) + snprintf(buf, sizeof(buf), "%c @@(%d,%d,%d)=", moveonly, + sheet->cur[X], sheet->cur[Y], sheet->cur[Z]); + else snprintf(buf, sizeof(buf), "%c @@(%s)=", moveonly, label); + + if (moveonly && + table->callback_context() == TeapotTable::ACTION) + { + char valbuf[1024] = ""; + if (Fl::event_key() == 'p' || Fl::event_button1()) + sprintf(valbuf, "(%i,%i,%i)", + sheet->cur[X], sheet->cur[Y], sheet->cur[Z]); + else if (Fl::event_key() == 'v') + printvalue(valbuf, sizeof(valbuf), 0, 1, + getscientific(curcell(sheet)), + -1, sheet, sheet->cur); + else if (Fl::event_key(FL_Tab)) line_input->take_focus(); + if (valbuf[0]) { + line_input->insert(valbuf); + line_input->take_focus(); + } + } + + char *err; + char val[1024]; + if ((err = geterror(sheet, sheet->cur))) { + strncpy(val,err,sizeof(val)); + free(err); + val[sizeof(val)-1] = 0; + } else { + print(val, sizeof(val), 0, 1, getscientific(curcell(sheet)), + -1, getcont(curcell(sheet), BASE)); + Token **iter = getcont(curcell(sheet), ITERATIVE); + if (iter != EMPTY_TVEC) { + snprintf(val+strlen(val),sizeof(val)-strlen(val), + " -> "); + print(val+strlen(val), sizeof(val)-strlen(val), 0, 1, + getscientific(curcell(sheet)), -1, iter); + } + } + + line_edit(sheet, val, 0, buf, 0, 0); + Cell *cell = curcell(sheet); + int adj = getadjust(cell); + if (adj == LEFT) left->setonly(); + else if (adj == RIGHT) right->setonly(); + else if (adj == CENTER) center->setonly(); + if (SHADOWEDC(sheet, + sheet->cur[X]+1, sheet->cur[Y], sheet->cur[Z])) + shadow->set(); + else shadow->clear(); + if (::transparent(cell)) transparent->set(); + else transparent->clear(); + if (locked(cell)) lock->set(); + else lock->clear(); + if (ignored(cell)) ignore->set(); + else ignore->clear(); + if (isbold(cell)) bold->set(); + else bold->clear(); + if (underlined(cell)) underline->set(); + else underline->clear(); + if (getscientific(cell)) sci->set(); + else sci->clear();} + protected xywh {0 50 800 525} box DOWN_FRAME + labeltype NO_LABEL resizable code0 {table->sheet(sheet);} class TeapotTable - } - Fl_Box status { + } + Fl_Box status { label {teapot ready.} protected xywh {0 575 800 25} box GTK_ROUND_DOWN_BOX align 20 - } - } - code {current = this;} {} - } - Function {line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt, size_t *x, size_t *offx)} {open return_type int - } { - code {if (line_label->active()) { - if (x) line_msg(NULL, "Action not possible at this time."); - return -1; + } + } code { + current = this; + } {} + } + + Function + {line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt, + size_t *x, size_t *offx)} {open return_type int} {code + { + if (line_label->active()) { + if (x) line_msg(NULL, "Action not possible at this time."); + return -1; + } + + line_label->copy_label(prompt); + + int ww = 0, hh = 0; + line_label->measure_label(ww, hh); + line_input->resize(line_label->x()+ww+5, line_input->y(), + line_label->w()-ww-7, line_input->h()); + line_input->value(buf); + + if (!x) return 0; + + line_input->maximum_size(size); + line_input->position(*x, *x); + line_label->activate(); + line_input->activate(); + table->sheet()->moveonly = 1; + line_input->take_focus(); + + edit_rc = -1; + while (line_label->active()) Fl::wait(); + + memcpy(buf, line_input->value(), size); + line_input->deactivate(); + table->sheet()->moveonly = 0; + table->take_focus(); + return edit_rc; + } {} } + + Function + {line_msg(const char *prompt, const char *msg)} {return_type void} {code + { + char label[1024]; + snprintf(label, sizeof(label), "%s%s%s", + prompt ? prompt : "", prompt ? " " : "", msg); + status->copy_label(label); + } {} } + + decl {friend void line_msg(const char*, const char*);} {private local} } +# End of class MainWindow -line_label->copy_label(prompt); +Function +{line_file(const char *file, const char *pattern, const char *title, + int create)} {open C return_type {const char *}} {code +{ + static char buf[PATH_MAX]; + Fl_Native_File_Chooser chooser; -int ww = 0, hh = 0; -line_label->measure_label(ww, hh); -line_input->resize(line_label->x()+ww+5, line_input->y(), line_label->w()-ww-7, line_input->h()); -line_input->value(buf); + chooser.title(title); + chooser.type(create ? Fl_Native_File_Chooser::BROWSE_SAVE_FILE : + Fl_Native_File_Chooser::BROWSE_FILE); + chooser.filter(pattern); + chooser.options((create ? Fl_Native_File_Chooser::NEW_FOLDER : 0) | + Fl_Native_File_Chooser::SAVEAS_CONFIRM); -if (!x) return 0; - -line_input->maximum_size(size); -line_input->position(*x, *x); -line_label->activate(); -line_input->activate(); -table->sheet()->moveonly = 1; -line_input->take_focus(); - -edit_rc = -1; -while (line_label->active()) Fl::wait(); - -memcpy(buf, line_input->value(), size); -line_input->deactivate(); -table->sheet()->moveonly = 0; -table->take_focus(); -return edit_rc;} {} - } - Function {line_msg(const char *prompt, const char *msg)} {return_type void - } { - code {char label[1024]; -snprintf(label, sizeof(label), "%s%s%s", prompt?prompt:"", prompt?" ":"", msg); -status->copy_label(label);} {} - } - decl {friend void line_msg(const char*, const char*);} {private local - } -} - -Function {line_file(const char *file, const char *pattern, const char *title, int create)} {open C return_type {const char *} -} { - code {static char buf[PATH_MAX]; -Fl_Native_File_Chooser chooser; - -chooser.title(title); -chooser.type(create?Fl_Native_File_Chooser::BROWSE_SAVE_FILE:Fl_Native_File_Chooser::BROWSE_FILE); -chooser.filter(pattern); -chooser.options((create?Fl_Native_File_Chooser::NEW_FOLDER:0)|Fl_Native_File_Chooser::SAVEAS_CONFIRM); - -if (file) { + if (file) { fl_filename_absolute(buf, sizeof(buf), file); char *p = (char *)fl_filename_name(buf); *p = 0; chooser.directory(buf); -} -if (chooser.show()) return NULL; + } + if (chooser.show()) return NULL; -strncpy(buf, chooser.filename(), sizeof(buf)); -buf[sizeof(buf)-1] = 0; -return buf;} {} -} + strncpy(buf, chooser.filename(), sizeof(buf)); + buf[sizeof(buf)-1] = 0; + return buf; +} {} } -Function {line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt, size_t *x, size_t *offx)} {C return_type int -} { - code {if (sheet) return ((MainWindow*)((TeapotTable*)sheet->display)->parent()->user_data())->line_edit(sheet, buf, size, prompt, x, offx); +Function +{line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt, + size_t *x, size_t *offx)} {C return_type int} {code +{ + if (sheet) + return ((MainWindow*) + ((TeapotTable*)sheet->display)->parent()->user_data()) -> + line_edit(sheet, buf, size, prompt, x, offx); -const char *val = fl_input("%s", buf, prompt); -if (val) { + const char *val = fl_input("%s", buf, prompt); + if (val) { strncpy(buf, val, size); buf[size-1] = 0; -} + } -return !val;} {} -} + return !val; +} {} } -Function {line_ok(const char *prompt, int curx)} {C return_type int -} { - code {int rc = !!fl_choice("%s", "&No", NULL, "&Yes", prompt); -if (Fl::event_key(FL_Escape)) return -1; -return rc;} {} -} +Function +{line_ok(const char *prompt, int curx)} {C return_type int} {code +{ + return tpt_choose(prompt, "&No", "&Yes", NULL, curx); +} {} } -Function {line_msg(const char *prompt, const char *msg)} {C return_type void -} { - code {MainWindow::current->line_msg(prompt, msg);} {} -} - -Function {keypressed()} {open C return_type int -} { - code {while (Fl::wait(.01)) if (Fl::event_key(FL_Escape)) return 1; -return 0;} {} -} - -Function {line_menu(const char *prompt, const MenuChoice *choice, int curx)} {C return_type int -} { - Fl_Window line_menu_menu { - label {Please Choose} open - xywh {706 58 250 245} type Double hide resizable modal - } { - Fl_Group {} { - label {Please Choose:} open - xywh {0 0 250 200} box ENGRAVED_BOX align 21 - } { - Fl_Browser line_menu_browser { - callback {line_menu_menu->hide();} - xywh {5 25 240 170} - class Fl_Select_Browser - } +Function +{line_binary(const char *prompt, const char* op1, const char* op2, int curx)} +{C return_type int} {code +{ + char *top[2]; + top[0] = strdup(op1+1); top[1] = strdup(op2+1); + for (int i = 0; i < 2; ++i) { + char* foundparen = strchr(top[i], ')'); + if (foundparen) { + *foundparen = *(foundparen-1); + *(foundparen-1) = '&'; } - Fl_Button {} { - label Cancel - callback {line_menu_menu->hide();} - xywh {5 205 240 35} + } + int retval = tpt_choose(prompt, "&Cancel", top[0], top[1], curx+1) - 1; + free(top[0]); + free(top[1]); + return retval; +} {} } + +Function +{line_msg(const char *prompt, const char *msg)} {C return_type void} {code +{ + MainWindow::current->line_msg(prompt, msg); +} {} } + +Function {keypressed()} {open C return_type int} {code +{ + while (Fl::wait(.01)) if (Fl::event_key(FL_Escape)) return 1; + return 0; +} {} } + +Function +{line_menu(const char *prompt, const MenuChoice *choice, int curx)} +{C return_type int} +{ + Fl_Window line_menu_menu { + label {Please Choose} open + xywh {706 58 250 245} type Double hide resizable modal +} +{ + Fl_Group {} { + label {Please Choose:} open + xywh {0 0 250 200} box ENGRAVED_BOX align 21 + } + { + Fl_Browser line_menu_browser { + callback {line_menu_menu->hide();} + xywh {5 25 240 170} + class Fl_Select_Browser } - } - code {line_menu_browser->clear(); -while (choice->str) { + } + Fl_Button {} { + label Cancel + callback {line_menu_menu->hide();} + xywh {5 205 240 35} + } +} code +{ + line_menu_browser->clear(); + while (choice->str) { line_menu_browser->add(choice->str+1); choice++; + } + + line_menu_menu->show(); + while (line_menu_menu->shown()) Fl::wait(); + + return line_menu_browser->value()-1; +} {} } + +Function +{redraw_sheet(Sheet *sheet)} {C return_type void} {code +{ + TeapotTable *t = (TeapotTable*)sheet->display; + t->update_table(); + t->redraw();} {} } -line_menu_menu->show(); -while (line_menu_menu->shown()) Fl::wait(); +Function +{redraw_cell(Sheet *sheet, const Location /* at */)} {C return_type void} +{ code +{ + redraw_sheet(sheet); +} {} } -return line_menu_browser->value()-1;} {} -} - -Function {redraw_sheet(Sheet *sheet)} {C return_type void -} { - code {TeapotTable *t = (TeapotTable*)sheet->display; -t->update_table(); -t->redraw();} {} -} - -Function {redraw_cell(Sheet *sheet, const Location /* at */)} {C return_type void -} { - code {redraw_sheet(sheet);} {} -} - -Function {display_init(Sheet *sheet, int always_redraw)} {open C return_type void -} { - code {Fl::get_system_colors(); +Function +{display_init(Sheet *sheet, int always_redraw)} +{open C return_type void} {code +{ + Fl::get_system_colors(); \#ifdef ENABLE_HELP -Fl_File_Icon::load_system_icons(); + Fl_File_Icon::load_system_icons(); \#endif -Fl::scheme("gtk+"); -int ch = sheet->changed; -resize(sheet, 1, 1, 1); -sheet->changed = ch; -new MainWindow(sheet);} {} + Fl::scheme("gtk+"); + int ch = sheet->changed; + resize(sheet, 1, 1, 1); + sheet->changed = ch; + new MainWindow(sheet); +} {} } + +Function +{display_end(Sheet* sheet)} {C return_type void} {code +{ +} {} } + +Function +{display_main(Sheet *cursheet)} {C return_type void} {code +{ + ((TeapotTable *)cursheet->display)->parent()->show(); + Fl::run(); +} {} } + +Function {show_menu(Sheet *sheet)} {C return_type Key} {code +{ + return K_NONE; +} {}} + +decl {MainWindow *MainWindow::current;} {private global} + +declblock {\#ifdef ENABLE_HELP} {after {\#endif}} { + decl {\#include } {private global} + + Function + {show_text(const char *text)} {open C return_type void} {code + { + Fl_Help_Dialog *d = new Fl_Help_Dialog(); + if (strchr(text, '<')) d->value(text); + else d->load(text); + d->resize(d->x(), d->y(), d->w()*3/2, d->h()*3/2); + d->show(); + } {} } } -Function {display_end(Sheet* sheet)} {C return_type void -} { - code {} {} +declblock {\#ifndef ENABLE_HELP} {after {\#endif}} { + Function + {show_text(const char *text)} {open C return_type void} {code + { + char *txt = striphtml(text); + fl_message("%s", txt); + free(txt); + } {} } } -Function {display_main(Sheet *cursheet)} {C return_type void -} { - code {((TeapotTable *)cursheet->display)->parent()->show(); -Fl::run();} {} -} +Function +{find_helpfile(char *buf, int size, const char *argv0)} +{open C return_type void} {code +{ + fl_filename_absolute(buf, size, argv0); + char *p = (char *)fl_filename_name(buf); + strncpy(p, "../share/doc/teapot/html/index.html", buf+size-p); + buf[size-1] = 0; -Function {show_menu(Sheet *sheet)} {C return_type Key -} { - code {return K_NONE;} {} -} + // Check if help exists in default installed location, fallback value is valid for build directory + int test = open(buf, O_RDONLY); + if (test < 0) strncpy(p, "html/index.html", buf+size-p); + else close(test); + buf[size-1] = 0; -decl {MainWindow *MainWindow::current;} {private global -} + // Try the configure-time determined value + test = open(buf, O_RDONLY); + if (test < 0) strncpy(buf, HELPFILE, size); + else close(test); + buf[size-1] = 0; -declblock {\#ifdef ENABLE_HELP} {after {\#endif} -} { - decl {\#include } {private global - } - Function {show_text(const char *text)} {open C return_type void - } { - code {Fl_Help_Dialog *d = new Fl_Help_Dialog(); -if (strchr(text, '<')) { - d->value(text); -} else { - d->load(text); -} -d->resize(d->x(), d->y(), d->w()*3/2, d->h()*3/2); -d->show();} {} - } -} - -declblock {\#ifndef ENABLE_HELP} {after {\#endif} -} { - Function {show_text(const char *text)} {open C return_type void - } { - code {char *txt = striphtml(text); -fl_message("%s", txt); -free(txt);} {} - } -} - -Function {find_helpfile(char *buf, int size, const char *argv0)} {open C return_type void -} { - code {fl_filename_absolute(buf, size, argv0); -char *p = (char *)fl_filename_name(buf); -strncpy(p, "../share/doc/teapot/html/index.html", buf+size-p); -buf[size-1] = 0; - -// Check if help exists in default installed location, fallback value is valid for build directory -int test = open(buf, O_RDONLY); -if (test < 0) strncpy(p, "html/index.html", buf+size-p); -else close(test); -buf[size-1] = 0; - -// Try the configure-time determined value -test = open(buf, O_RDONLY); -if (test < 0) strncpy(buf, HELPFILE, size); -else close(test); -buf[size-1] = 0; - -// Fall back to a sane value for unixoid systems -test = open(buf, O_RDONLY); -if (test < 0) strncpy(buf, "/usr/share/doc/teapot/html/index.html", size); -else close(test); -buf[size-1] = 0; - -} {} -} + // Fall back to a sane value for unixoid systems + test = open(buf, O_RDONLY); + if (test < 0) strncpy(buf, "/usr/share/doc/teapot/html/index.html", size); + else close(test); + buf[size-1] = 0; +} {} } diff --git a/src/tpt_choose.cxx b/src/tpt_choose.cxx new file mode 100644 index 0000000..7792de8 --- /dev/null +++ b/src/tpt_choose.cxx @@ -0,0 +1,230 @@ +#include +#include +#include +#include + +#include + +#include +#include + +class Tpt_Return_Button : public Fl_Return_Button { +public: + int handle(int event) { + if (event == FL_KEYBOARD + && (Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter)) { + simulate_key_action(); + do_callback(); + return 1; + } else + return Fl_Button::handle(event); + } + Tpt_Return_Button(int x, int y, int w, int h) : Fl_Return_Button(x, y, w, h) + {} +}; + +static Fl_Window *message_form; +static Fl_Box *message; +static Fl_Box *icon; +static const int N_BUTTONS = 3; +static Fl_Button *button[N_BUTTONS]; +static int ret_val; +static const char *iconlabel = "?"; +static const char *message_title_default; +Fl_Font fl_message_font_ = FL_HELVETICA; +Fl_Fontsize fl_message_size_ = -1; +static int enableHotspot = 1; + +static char avoidRecursion = 0; + + +// Sets the global return value (ret_val) and closes the window. +static void button_cb(Fl_Widget *, long val) { + ret_val = (int) val; + if (Fl::event_key() == FL_Escape) ret_val = -1; + message_form->hide(); +} + +// If the window is simply closed, that's the same as hitting escape +static void form_cb(Fl_Widget *, long val) { + ret_val = -1; + message_form->hide(); +} + +static Fl_Window *makeform() { + if (message_form) { + return message_form; + } + // make sure that the dialog does not become the child of some + // current group + Fl_Group *previously_current_group = Fl_Group::current(); + Fl_Group::current(0); + // create a new top level window + Fl_Window *w = message_form = new Fl_Window(410,103); + message_form->callback(form_cb); + + (message = new Fl_Box(60, 25, 340, 20)) + ->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP); + {Fl_Box* o = icon = new Fl_Box(10, 10, 50, 50); + o->box(FL_THIN_UP_BOX); + o->labelfont(FL_TIMES_BOLD); + o->labelsize(34); + o->color(FL_WHITE); + o->labelcolor(FL_BLUE); + } + w->end(); // don't add the buttons automatically + // create the buttons (right to left) + for (int b=0, x=100*N_BUTTONS+10; balign(FL_ALIGN_INSIDE|FL_ALIGN_WRAP); + button[b]->callback(button_cb, b); + } + button[0]->shortcut(FL_Escape); + // add the buttons (left to right so arrow keys work) + for (int b = N_BUTTONS-1; b >= 0; --b) + w->add(button[b]); + + w->begin(); + w->resizable(new Fl_Box(60,10,110-60,27)); + w->end(); + w->set_modal(); + Fl_Group::current(previously_current_group); + return w; +} + +/* + * 'resizeform()' - Resize the form and widgets so that they hold everything + * that is asked of them... + */ + +static void resizeform() { + int i; + int message_w, message_h; + int text_height; + int button_w[N_BUTTONS], button_h[N_BUTTONS]; + int x, w, h, max_w, max_h; + const int icon_size = 50; + + message_form->size(410,103); + + fl_font(message->labelfont(), message->labelsize()); + message_w = message_h = 0; + fl_measure(message->label(), message_w, message_h); + + message_w += 10; + message_h += 10; + if (message_w < 340) + message_w = 340; + if (message_h < 30) + message_h = 30; + + fl_font(button[0]->labelfont(), button[0]->labelsize()); + + memset(button_w, 0, sizeof(button_w)); + memset(button_h, 0, sizeof(button_h)); + + for (max_h = 25, i = 0; i < N_BUTTONS; i ++) + if (button[i]->visible()) + { + fl_measure(button[i]->label(), button_w[i], button_h[i]); + + if (i == 1) + button_w[1] += 20; + + button_w[i] += 30; + button_h[i] += 10; + + if (button_h[i] > max_h) + max_h = button_h[i]; + } + + text_height = message_h; + + max_w = message_w + 10 + icon_size; + w = -10; + for (int i = 0; i < N_BUTTONS; ++i) w += button_w[i]; + + if (w > max_w) + max_w = w; + + message_w = max_w - 10 - icon_size; + + w = max_w + 20; + h = max_h + 30 + text_height; + + message_form->size(w, h); + message_form->size_range(w, h, w, h); + + message->resize(20 + icon_size, 10, message_w, message_h); + icon->resize(10, 10, icon_size, icon_size); + icon->labelsize(icon_size - 10); + + for (x = w, i = 0; i < N_BUTTONS; i ++) + if (button_w[i]) + { + x -= button_w[i]; + button[i]->resize(x, h - 10 - max_h, button_w[i] - 10, max_h); + } + message_form->init_sizes(); +} + +int tpt_choose(const char* prompt, const char* op0, const char *op1, + const char* op2, int curx) { + + if (avoidRecursion) return 0; + + Fl::pushed(0); // stop dragging + + avoidRecursion = 1; + + makeform(); + message_form->size(410,103); + message->label(prompt); + message->labelfont(fl_message_font_); + if (fl_message_size_ == -1) message->labelsize(FL_NORMAL_SIZE); + else message->labelsize(fl_message_size_); + if (op0) { + button[0]->show(); + button[0]->label(op0); + button[1]->position(210,70); + } + else { button[0]->hide(); button[1]->position(310,70); } + if (op1) { button[1]->show(); button[1]->label(op1);} + else button[1]->hide(); + if (op2) { button[2]->show(); button[2]->label(op2); } + else button[2]->hide(); + + button[curx]->take_focus(); + + const char* prev_icon_label = icon->label(); + if (!prev_icon_label) icon->label(iconlabel); + + resizeform(); + + if (enableHotspot) + message_form->hotspot(button[0]); + if (op0 && Fl_Widget::label_shortcut(op0)) + button[0]->shortcut(0); + else + button[0]->shortcut(FL_Escape); + + // set default window title, if defined and a specific title is not set + if (!message_form->label() && message_title_default) + message_form->label(message_title_default); + + // deactivate Fl::grab(), because it is incompatible with modal windows + Fl_Window* g = Fl::grab(); + if (g) Fl::grab(0); + Fl_Group *current_group = Fl_Group::current(); // make sure the dialog does not interfere with any active group + message_form->show(); + Fl_Group::current(current_group); + while (message_form->shown()) Fl::wait(); + if (g) // regrab the previous popup menu, if there was one + Fl::grab(g); + icon->label(prev_icon_label); + message_form->label(0); // reset window title + + avoidRecursion = 0; + + return ret_val; +} diff --git a/src/tpt_choose.h b/src/tpt_choose.h new file mode 100644 index 0000000..5b7842f --- /dev/null +++ b/src/tpt_choose.h @@ -0,0 +1,7 @@ +#ifndef TPT_CHOOSE_H +#define TPT_CHOOSE_H + +int tpt_choose(const char* prompt, const char* op0, const char *op1, + const char* op2, int deflt); + +#endif