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.
This commit is contained in:
Glen Whitney 2019-08-02 20:31:48 -04:00
parent 341b12ba04
commit 2e0a3a480c
7 changed files with 1250 additions and 939 deletions

View File

@ -40,7 +40,7 @@ endif ()
find_package(FLTK) find_package(FLTK)
if (FLTK_FOUND) if (FLTK_FOUND)
fltk_wrap_ui(fteapot fteapot.fl) 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") set(fteapot_DEB_DEPENDS ", libstdc++6 (>= 4.1.1), libfltk1.3")
if (ENABLE_HELP) if (ENABLE_HELP)
set(fteapot_DEB_DEPENDS "${fteapot_DEB_DEPENDS}, libfltk-images1.3") set(fteapot_DEB_DEPENDS "${fteapot_DEB_DEPENDS}, libfltk-images1.3")

View File

@ -344,7 +344,13 @@ static void do_attribute(Sheet *cursheet, Key action)
case ADJUST_RIGHT: ++adj; case ADJUST_RIGHT: ++adj;
case ADJUST_LEFT: 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)) for (ALL_LOCS_IN_REGION(cursheet,w))
setadjust(cursheet, w, adj); setadjust(cursheet, w, adj);
break; break;
@ -355,8 +361,9 @@ static void do_attribute(Sheet *cursheet, Key action)
int n; int n;
if (onecell) n = !getscientific(fcell); if (onecell) n = !getscientific(fcell);
else n = line_ok(_("Make block notation scientific:"), else n = line_binary(_("Make block notation:"),
getscientific(fcell)); _("dD)ecimal"), _("sS)cientific"),
!getscientific(fcell));
if (n >= 0) if (n >= 0)
for (ALL_LOCS_IN_REGION(cursheet,w)) for (ALL_LOCS_IN_REGION(cursheet,w))
setscientific(cursheet, w, n); setscientific(cursheet, w, n);
@ -381,9 +388,12 @@ static void do_attribute(Sheet *cursheet, Key action)
case ADJUST_SHADOW: case ADJUST_SHADOW:
{ {
int n; int n;
Location r;
if (onecell) n = !SHADOWED(cursheet, cursheet->mark1); LOCATION_GETS(r, cursheet->mark1); ++r[X];
else n = line_ok(_("Shadow block:"), SHADOWED(cursheet, cursheet->mark1)); 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) { if (cursheet->mark1[X] == 0 && n == 1) {
line_msg(_("Shadow cell:"),_("You can not shadow cells in column 0")); line_msg(_("Shadow cell:"),_("You can not shadow cells in column 0"));
break; break;
@ -397,12 +407,14 @@ static void do_attribute(Sheet *cursheet, Key action)
if (n==0) if (n==0)
{ {
LOCATION_GETS(r, w); 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); shadow(cursheet, r, 0);
} }
else if (w[X]>0) shadow(cursheet, w, 1); else if (w[X]>0) shadow(cursheet, w, 1);
} }
} }
if (n>0) do_mark(cursheet, UNMARKED);
break; break;
} }
/*}}}*/ /*}}}*/
@ -412,8 +424,9 @@ static void do_attribute(Sheet *cursheet, Key action)
int n; int n;
if (onecell) n = !transparent(fcell); if (onecell) n = !transparent(fcell);
else n = line_ok(_("Make block transparent:"), else n = line_binary(_("Set block to:"),
transparent(fcell)); _("pP)rotected"), _("tT)ransparent:"),
!transparent(fcell));
if (n >= 0) if (n >= 0)
for (ALL_LOCS_IN_REGION(cursheet,w)) maketrans(cursheet, w, n); for (ALL_LOCS_IN_REGION(cursheet,w)) maketrans(cursheet, w, n);
break; break;
@ -425,7 +438,8 @@ static void do_attribute(Sheet *cursheet, Key action)
int n; int n;
if (onecell) n = !isbold(fcell); 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) if (n >= 0)
for (ALL_LOCS_IN_REGION(cursheet,w)) bold(cursheet, w, n); for (ALL_LOCS_IN_REGION(cursheet,w)) bold(cursheet, w, n);
break; break;
@ -437,7 +451,8 @@ static void do_attribute(Sheet *cursheet, Key action)
int n; int n;
if (onecell) n = !underlined(fcell); 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) if (n >= 0)
for (ALL_LOCS_IN_REGION(cursheet,w)) underline(cursheet, w, n); for (ALL_LOCS_IN_REGION(cursheet,w)) underline(cursheet, w, n);
break; break;
@ -456,7 +471,8 @@ static void do_attribute(Sheet *cursheet, Key action)
int n; int n;
if (onecell) n = !locked(fcell); 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) if (n >= 0)
for (ALL_LOCS_IN_REGION(cursheet,w)) lockcell(cursheet, w, n); for (ALL_LOCS_IN_REGION(cursheet,w)) lockcell(cursheet, w, n);
break; break;
@ -468,8 +484,8 @@ static void do_attribute(Sheet *cursheet, Key action)
int n; int n;
if (onecell) n = !ignored(fcell); if (onecell) n = !ignored(fcell);
else n = line_ok(_("Ignore contents of all cells in this block:"), else n = line_binary(_("Set block to:"), _("cC)omputed"), _("iI)gnored"),
ignored(fcell)); !ignored(fcell));
if (n >= 0) if (n >= 0)
for (ALL_LOCS_IN_REGION(cursheet,w)) igncell(cursheet, w, n); for (ALL_LOCS_IN_REGION(cursheet,w)) igncell(cursheet, w, n);
break; break;
@ -913,14 +929,11 @@ static int do_insert(Sheet *sheet)
{ {
MenuChoice menu[4]; MenuChoice menu[4];
menu[0].str=strdup(_("cC)olumn")); menu[0].c='\0'; menu[0].str = _("cC)olumn"); menu[0].c='\0';
menu[1].str=strdup(_("rR)ow")); menu[1].c='\0'; menu[1].str = _("rR)ow"); menu[1].c='\0';
menu[2].str=strdup(_("dD)epth")); menu[2].c='\0'; menu[2].str = _("dD)epth"); menu[2].c='\0';
menu[3].str=(char*)0; menu[3].str=(char*)0;
reply=line_menu(_("Insert:"),menu,0); reply=line_menu(_("Insert:"),menu,0);
free(menu[0].str);
free(menu[1].str);
free(menu[2].str);
if (reply<0) return reply; if (reply<0) return reply;
} }
/*}}}*/ /*}}}*/
@ -939,16 +952,14 @@ static int do_insert(Sheet *sheet)
/* show menu */ /*{{{*/ /* show menu */ /*{{{*/
switch (reply) switch (reply)
{ {
case 0: menu[0].str=strdup(_("wW)hole column")); break; case 0: menu[0].str = _("wW)hole column"); break;
case 1: menu[0].str=strdup(_("wW)hole line")); break; case 1: menu[0].str = _("wW)hole line"); break;
case 2: menu[0].str=strdup(_("wW)hole sheet")); break; case 2: menu[0].str = _("wW)hole sheet"); break;
default: assert(0); 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; menu[2].str = (char*)0;
r=line_menu(_("Insert:"),menu,0); r=line_menu(_("Insert:"),menu,0);
free(menu[0].str);
free(menu[1].str);
/*}}}*/ /*}}}*/
switch (r) switch (r)
{ {
@ -1030,14 +1041,11 @@ static int do_delete(Sheet *sheet)
{ {
MenuChoice menu[4]; MenuChoice menu[4];
menu[0].str=strdup(_("cC)olumn")); menu[0].c='\0'; menu[0].str = _("cC)olumn"); menu[0].c='\0';
menu[1].str=strdup(_("rR)ow")); menu[1].c='\0'; menu[1].str = _("rR)ow"); menu[1].c='\0';
menu[2].str=strdup(_("dD)epth")); menu[2].c='\0'; menu[2].str = _("dD)epth"); menu[2].c='\0';
menu[3].str = (char*)0; menu[3].str = (char*)0;
reply=line_menu(_("Delete:"),menu,0); reply=line_menu(_("Delete:"),menu,0);
free(menu[0].str);
free(menu[1].str);
free(menu[2].str);
if (reply<0) return reply; if (reply<0) return reply;
} }
/*}}}*/ /*}}}*/
@ -1057,16 +1065,14 @@ static int do_delete(Sheet *sheet)
/* show menu */ /*{{{*/ /* show menu */ /*{{{*/
switch (reply) switch (reply)
{ {
case 0: menu[0].str=strdup(_("wW)hole column")); break; case 0: menu[0].str = _("wW)hole column"); break;
case 1: menu[0].str=strdup(_("wW)hole line")); break; case 1: menu[0].str = _("wW)hole line"); break;
case 2: menu[0].str=strdup(_("wW)hole sheet")); break; case 2: menu[0].str = _("wW)hole sheet"); break;
default: assert(0); 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; menu[2].str=(char*)0;
r=line_menu(_("Delete:"),menu,0); r=line_menu(_("Delete:"),menu,0);
free(menu[0].str);
free(menu[1].str);
/*}}}*/ /*}}}*/
switch (r) switch (r)
{ {
@ -1454,14 +1460,11 @@ static int do_mirror(Sheet *sheet)
{ {
MenuChoice menu[4]; MenuChoice menu[4];
menu[0].str=strdup(_("lL)eft-right")); menu[0].c='\0'; menu[0].str = _("lL)eft-right"); menu[0].c='\0';
menu[1].str=strdup(_("uU)pside-down")); menu[1].c='\0'; menu[1].str = _("uU)pside-down"); menu[1].c='\0';
menu[2].str=strdup(_("fF)ront-back")); menu[2].c='\0'; menu[2].str = _("fF)ront-back"); menu[2].c='\0';
menu[3].str = (char*)0; menu[3].str = (char*)0;
reply=line_menu(_("Mirror block:"),menu,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; if (reply<0) return reply;
} }
/*}}}*/ /*}}}*/

View File

@ -67,21 +67,21 @@ static int do_attribute(Sheet *cursheet)
int c; int c;
/* create menus */ /* create menus */
adjmenu[0].str=strdup(_("lL)eft")); adjmenu[0].c='\0'; adjmenu[0].str = _("lL)eft"); adjmenu[0].c='\0';
adjmenu[1].str=strdup(_("rR)ight")); adjmenu[1].c='\0'; adjmenu[1].str = _("rR)ight"); adjmenu[1].c='\0';
adjmenu[2].str=strdup(_("cC)entered")); adjmenu[2].c='\0'; adjmenu[2].str = _("cC)entered"); adjmenu[2].c='\0';
adjmenu[3].str=strdup(_("11).23e1 <-> 12.3")); adjmenu[3].c='\0'; adjmenu[3].str = _("11).23e1 <-> 12.3"); adjmenu[3].c='\0';
adjmenu[4].str=strdup(_("pP)recision")); adjmenu[4].c='\0'; adjmenu[4].str = _("pP)recision"); adjmenu[4].c='\0';
adjmenu[5].str=strdup(_("sS)hadow")); adjmenu[5].c='\0'; adjmenu[5].str = _("sS)hadow"); adjmenu[5].c='\0';
adjmenu[6].str=strdup(_("bB)old")); adjmenu[6].c='\0'; adjmenu[6].str = _("bB)old"); adjmenu[6].c='\0';
adjmenu[7].str=strdup(_("uU)nderline")); adjmenu[7].c='\0'; adjmenu[7].str = _("uU)nderline"); adjmenu[7].c='\0';
adjmenu[8].str=strdup(_("oO)utput special characters")); adjmenu[8].c='\0'; adjmenu[8].str = _("oO)utput special characters"); adjmenu[8].c='\0';
adjmenu[9].str = (char*)0; adjmenu[9].str = (char*)0;
mainmenu[0].str=strdup(_("rR)epresentation")); mainmenu[0].c='\0'; mainmenu[0].str = _("rR)epresentation"); mainmenu[0].c='\0';
mainmenu[1].str=strdup(_("lL)abel")); mainmenu[1].c='\0'; mainmenu[1].str = _("lL)abel"); mainmenu[1].c='\0';
mainmenu[2].str=strdup(_("oLo)ck")); mainmenu[2].c='\0'; mainmenu[2].str = _("oLo)ck"); mainmenu[2].c='\0';
mainmenu[3].str=strdup(_("iI)gnore")); mainmenu[3].c='\0'; mainmenu[3].str = _("iI)gnore"); mainmenu[3].c='\0';
mainmenu[4].str = (char*)0; mainmenu[4].str = (char*)0;
do do
@ -130,21 +130,6 @@ static int do_attribute(Sheet *cursheet)
} while (c == K_INVALID); } while (c == K_INVALID);
if (c == KEY_CANCEL) 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; return c;
} }
@ -156,9 +141,9 @@ static int do_file(Sheet *cursheet)
int c; int c;
menu[0].str=strdup(_("lL)oad")); menu[0].c='\0'; menu[0].str = _("lL)oad"); menu[0].c='\0';
menu[1].str=strdup(_("sS)ave")); menu[1].c='\0'; menu[1].str = _("sS)ave"); menu[1].c='\0';
menu[2].str=strdup(_("nN)ame")); menu[2].c='\0'; menu[2].str = _("nN)ame"); menu[2].c='\0';
menu[3].str = (char*)0; menu[3].str = (char*)0;
c=0; c=0;
do do
@ -174,9 +159,6 @@ static int do_file(Sheet *cursheet)
} }
} while (c == K_INVALID); } while (c == K_INVALID);
if (c == KEY_CANCEL) c = K_INVALID; if (c == KEY_CANCEL) c = K_INVALID;
free(menu[0].str);
free(menu[1].str);
free(menu[2].str);
return c; return c;
} }
@ -258,14 +240,14 @@ static int do_block(Sheet *cursheet)
MenuChoice block[9]; MenuChoice block[9];
int c; int c;
block[0].str=strdup(_("ecle)ar")); block[0].c='\0'; block[0].str = _("ecle)ar"); block[0].c='\0';
block[1].str=strdup(_("iI)nsert")); block[1].c='\0'; block[1].str = _("iI)nsert"); block[1].c='\0';
block[2].str=strdup(_("dD)elete")); block[2].c='\0'; block[2].str = _("dD)elete"); block[2].c='\0';
block[3].str=strdup(_("mM)ove")); block[3].c='\0'; block[3].str = _("mM)ove"); block[3].c='\0';
block[4].str=strdup(_("cC)opy")); block[4].c='\0'; block[4].str = _("cC)opy"); block[4].c='\0';
block[5].str=strdup(_("fF)ill")); block[5].c='\0'; block[5].str = _("fF)ill"); block[5].c='\0';
block[6].str=strdup(_("sS)ort")); block[6].c='\0'; block[6].str = _("sS)ort"); block[6].c='\0';
block[7].str=strdup(_("rMir)ror")); block[7].c='\0'; block[7].str = _("rMir)ror"); block[7].c='\0';
block[8].str = (char*)0; block[8].str = (char*)0;
c=0; c=0;
do do
@ -285,14 +267,6 @@ static int do_block(Sheet *cursheet)
} }
} while (c == K_INVALID); } while (c == K_INVALID);
if (c == KEY_CANCEL) 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; return c;
} }
@ -304,14 +278,14 @@ int show_menu(Sheet *cursheet)
int c = K_INVALID; int c = K_INVALID;
menu[0].str=strdup(_("aA)ttributes")); menu[0].c='\0'; menu[0].str = _("aA)ttributes"); menu[0].c='\0';
menu[1].str=strdup(_("wW)idth")); menu[1].c='\0'; menu[1].str = _("wW)idth"); menu[1].c='\0';
menu[2].str=strdup(_("bB)lock")); menu[2].c='\0'; menu[2].str = _("bB)lock"); menu[2].c='\0';
menu[3].str=strdup(_("fF)ile")); menu[3].c='\0'; menu[3].str = _("fF)ile"); menu[3].c='\0';
menu[4].str=strdup(_("gG)oto")); menu[4].c='\0'; menu[4].str = _("gG)oto"); menu[4].c='\0';
menu[5].str=strdup(_("sS)hell")); menu[5].c='\0'; menu[5].str = _("sS)hell"); menu[5].c='\0';
menu[6].str=strdup(_("vV)ersion")); menu[6].c='\0'; menu[6].str = _("vV)ersion"); menu[6].c='\0';
menu[7].str=strdup(_("qQ)uit")); menu[7].c='\0'; menu[7].str = _("qQ)uit"); menu[7].c='\0';
menu[8].str = (char*)0; menu[8].str = (char*)0;
do do
@ -332,16 +306,6 @@ int show_menu(Sheet *cursheet)
} }
} while (c == K_INVALID); } while (c == K_INVALID);
if (c == KEY_CANCEL) 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; return c;
} }
@ -398,6 +362,7 @@ void display_main(Sheet *cursheet)
#define TEAPOT_WHITE 16 #define TEAPOT_WHITE 16
#define CHANNEL_MAX 1000 #define CHANNEL_MAX 1000
typedef short CursesColor[3];
void display_init(Sheet *cursheet, int always_redraw) void display_init(Sheet *cursheet, int always_redraw)
{ {
initscr(); initscr();
@ -417,6 +382,13 @@ void display_init(Sheet *cursheet, int always_redraw)
#ifdef HAVE_TYPEAHEAD #ifdef HAVE_TYPEAHEAD
if (always_redraw) typeahead(-1); if (always_redraw) typeahead(-1);
#endif #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) void display_end(Sheet* sheet)
@ -426,6 +398,7 @@ void display_end(Sheet* sheet)
noraw(); noraw();
refresh(); refresh();
endwin(); endwin();
free(sheet->palette);
} }
void redraw_cell(Sheet *sheet, const Location at ) void redraw_cell(Sheet *sheet, const Location at )
@ -833,19 +806,29 @@ int line_ok(const char *prompt, int curx)
{ {
MenuChoice menu[3]; MenuChoice menu[3];
int result;
assert(curx==0 || curx==1); assert(curx==0 || curx==1);
menu[0].str=strdup(_("nN)o")); menu[0].c='\0'; menu[0].str = _("nN)o"); menu[0].c='\0';
menu[1].str=strdup(_("yY)es")); menu[1].c='\0'; menu[1].str = _("yY)es"); menu[1].c='\0';
menu[2].str=(char*)0; menu[2].str=(char*)0;
result=line_menu(prompt,menu,curx); return line_menu(prompt, menu, curx);
free(menu[0].str); }
free(menu[1].str);
return (result); /* 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 */ /* line_menu -- one line menu */

View File

@ -11,7 +11,7 @@ extern "C" {
typedef struct typedef struct
{ {
Key c; Key c;
char *str; const char *str;
} MenuChoice; } MenuChoice;
void display_main(Sheet *cursheet); 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); 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_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_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); void line_msg(const char *prompt, const char *msg);
int keypressed(void); int keypressed(void);
void show_text(const char *text); void show_text(const char *text);

View File

@ -2,118 +2,86 @@
version 1.0300 version 1.0300
header_name {.h} header_name {.h}
code_name {.cxx} code_name {.cxx}
decl {\#include <unistd.h>} {private global
}
decl {\#include <stdint.h>} {private global decl {\#include <FL/Fl_Table.H>} {public global}
} decl {\#include <FL/Fl_Select_Browser.H>} {public global}
decl {\#include <FL/Fl_Sys_Menu_Bar.H>} {public global}
decl {\#include <limits.h>} {private global decl {\#include "display.h"} {public global}
}
decl {\#include <fcntl.h>} {private global decl {\#include <unistd.h>} {private global}
} decl {\#include <stdint.h>} {private global}
decl {\#include <limits.h>} {private global}
decl {\#include <fcntl.h>} {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 <FL/fl_message.H>} {private local}
} decl {\#include <FL/fl_draw.H>} {private global}
decl {\#include <FL/Fl_Native_File_Chooser.H>} {private global}
decl {\#include <FL/Fl_File_Icon.H>} {private global}
decl {\#include <FL/filename.H>} {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 <FL/fl_message.H>} {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 <FL/fl_draw.H>} {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
decl {\#include <FL/Fl_Native_File_Chooser.H>} {private global {
} end();
decl {\#include <FL/Fl_File_Icon.H>} {private global
}
decl {\#include <FL/filename.H>} {private global
}
decl {\#include <FL/Fl_Table.H>} {public global
}
decl {\#include <FL/Fl_Select_Browser.H>} {public global
}
decl {\#include <FL/Fl_Sys_Menu_Bar.H>} {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_min(10);
col_resize(true); col_resize(true);
col_header(header); col_header(header);
row_resize(false); row_resize(false);
row_header(header); row_header(header);
set_visible_focus(); set_visible_focus();
table_box(FL_THIN_UP_FRAME);} {} table_box(FL_THIN_UP_FRAME);
} } {} }
Function {~TeapotTable()} {} {
code {} {} Function {~TeapotTable()} {} {code {} {} }
}
Function {sheet(Sheet *s)} {open return_type void Function
} { {sheet(Sheet *s)} {open return_type void} {code
code {cursheet = s; {
cursheet = s;
s->display = (void *)this; s->display = (void *)this;
clear(); clear();
update_table(); update_table();
do_callback(CONTEXT_NONE, 0, 0);} {} do_callback(CONTEXT_NONE, 0, 0);
} } {} }
Function {sheet()} {return_type {Sheet *}
} { Function {sheet()} {return_type {Sheet *}} {code {return cursheet;} {} }
code {return cursheet;} {}
} Function
Function {draw_cell(TableContext context, int R, int C, int xx, int yy, int W, int H)} {open return_type void {draw_cell(TableContext context, int R, int C, int xx, int yy,
} { int W, int H)} {open return_type void} {code
code {char s[1024]; {
//printf("DRAW: %i @%i,%i - (%i,%i) %ix%i\\n", context, C,R, xx,yy, W,H); 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) { switch (context) {
case CONTEXT_ENDPAGE: case CONTEXT_ENDPAGE:
W = xx-x()-2; W = xx-x()-2; H = yy-y()-2;
H = yy-y()-2; xx = x()+2; yy = y()+2;
xx = x()+2;
yy = y()+2;
fl_font(FL_HELVETICA | FL_BOLD, 14); fl_font(FL_HELVETICA | FL_BOLD, 14);
fl_push_clip(xx, yy, W, H); fl_push_clip(xx, yy, W, H);
fl_draw_box(FL_DIAMOND_UP_BOX, xx, yy, W, H, col_header_color()); fl_draw_box(FL_DIAMOND_UP_BOX, xx, yy, W, H, col_header_color());
@ -149,9 +117,11 @@ case CONTEXT_ROW_HEADER:
return; return;
case CONTEXT_CELL: { case CONTEXT_CELL: {
while (SHADOWEDC(cursheet, C, R, cursheet->cur[Z])) xx -= W = col_width(--C); while (SHADOWEDC(cursheet, C, R, cursheet->cur[Z]))
xx -= W = col_width(--C);
int x = C+1; int x = C+1;
while (SHADOWEDC(cursheet,x,R,cursheet->cur[Z])) W += col_width(x), x++; while (SHADOWEDC(cursheet, x, R, cursheet->cur[Z]))
W += col_width(x), x++;
fl_push_clip(xx, yy, W, H); fl_push_clip(xx, yy, W, H);
bool selected = false; bool selected = false;
@ -161,7 +131,8 @@ case CONTEXT_CELL: {
if (ms != UNMARKED) if (ms != UNMARKED)
selected = loc_in_box(test, cursheet->mark1, cursheet->mark2); selected = loc_in_box(test, cursheet->mark1, cursheet->mark2);
bool iscurrent = C == cursheet->cur[X] && R == cursheet->cur[Y]; 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, fl_draw_box(iscurrent ? FL_BORDER_BOX : FL_THIN_DOWN_BOX,
xx, yy, W, H,
selected ? FL_SELECTION_COLOR : FL_BACKGROUND2_COLOR); selected ? FL_SELECTION_COLOR : FL_BACKGROUND2_COLOR);
if (Fl::focus() == this && iscurrent) if (Fl::focus() == this && iscurrent)
draw_focus(FL_BORDER_BOX, xx, yy, W, H); draw_focus(FL_BORDER_BOX, xx, yy, W, H);
@ -181,7 +152,9 @@ case CONTEXT_CELL: {
if (ww > W-6) for (int i = 0; s[i]; i++) s[i] = '\#'; if (ww > W-6) for (int i = 0; s[i]; i++) s[i] = '\#';
int adj = getadjust(cell); 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); 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); if (underlined(cell)) fl_xyline(xx, yy+H-7, xx+W);
fl_pop_clip(); fl_pop_clip();
@ -190,15 +163,20 @@ case CONTEXT_CELL: {
default: default:
return; return;
}} {selected
} }
} } {selected} }
Function {update_table()} {open return_type void
} {
code {if (updating) return;
Function
{update_table()} {open return_type void} {code
{
if (updating) return;
updating = true; 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 (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->dimx > cols()) cols(cursheet->dimx);
if (cursheet->dimy > rows()) rows(cursheet->dimy); if (cursheet->dimy > rows()) rows(cursheet->dimy);
@ -213,11 +191,13 @@ row_position(cursheet->offy);
set_selection(cursheet->cur[Y], cursheet->cur[X], set_selection(cursheet->cur[Y], cursheet->cur[X],
cursheet->cur[Y], cursheet->cur[X]); cursheet->cur[Y], cursheet->cur[X]);
move_cursor(0,0); move_cursor(0,0);
updating = false;} {} updating = false;
} } {} }
Function {update_sheet()} {return_type void
} { Function
code {int x1, x2, y1, y2; {update_sheet()} {return_type void} {code
{
int x1, x2, y1, y2;
if (updating) return; if (updating) return;
updating = true; updating = true;
@ -232,7 +212,8 @@ if (x1 != x2 || y1 != y2) {
cursheet->marking = MARKED; cursheet->marking = MARKED;
} }
moveto(cursheet, current_col, current_row, -1); moveto(cursheet, current_col, current_row, -1);
visible_cells(cursheet->offy, cursheet->maxy, cursheet->offx, cursheet->maxx); visible_cells(cursheet->offy, cursheet->maxy,
cursheet->offx, cursheet->maxx);
cursheet->maxx -= cursheet->offx; cursheet->maxx -= cursheet->offx;
cursheet->maxy -= cursheet->offy; cursheet->maxy -= cursheet->offy;
@ -244,13 +225,18 @@ if (is_interactive_resize()) {
} }
} }
updating = false; 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);} {} if (debug_level > 2)
} printf("upd_sheet: %ix%i@%i,%i; %i[%i], %i[%i] (%i,%i)-(%i,%i)\\n",
Function {handle(int event)} {open return_type int cols(), rows(), cursheet->cur[X], cursheet->cur[Y],
} { cursheet->offx, cursheet->maxx,
code {if (event == FL_KEYDOWN) { 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 ctrl = Fl::event_ctrl();
int alt = Fl::event_alt(); int alt = Fl::event_alt();
int shift = Fl::event_shift(); int shift = Fl::event_shift();
@ -266,30 +252,74 @@ updating = false;
case FL_Tab: if (shift) { k = K_CLOCK; break; } case FL_Tab: if (shift) { k = K_CLOCK; break; }
case FL_Enter: case FL_Enter:
case FL_KP_Enter: k = alt?K_MENTER:K_ENTER; break; 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 'c':
case 'v': if (ctrl) { do_mark(cursheet, MARKED); 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; k = cut ? BLOCK_MOVE : BLOCK_COPY;
} }
break; break;
case 'x': if (ctrl) { do_mark(cursheet, GET_MARK_CUR); cut = true, k = K_NONE; } 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 'r': if (ctrl) k = K_RECALC; break;
case 'd': if (ctrl && shift && debug_level > 0) k = K_DUMPCELL; break; case 'd':
case FL_Insert: if (ctrl) { do_mark(cursheet, GET_MARK_CUR); cut = false; } k = !shift?K_NONE:cut?BLOCK_MOVE:BLOCK_COPY; break; if (ctrl && shift && debug_level > 0) k = K_DUMPCELL;
case FL_Delete: if (shift) { do_mark(cursheet, GET_MARK_CUR); cut = true; } k = shift?K_NONE:BLOCK_CLEAR; break; 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_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_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_Up:
case FL_Down: if (shift) do_mark(cursheet, MARKING); k = ctrl?K_NPAGE:K_DOWN; break; if (shift) do_mark(cursheet, MARKING);
case FL_Right: if (shift) do_mark(cursheet, MARKING); k = ctrl?K_FPAGE:K_RIGHT; break; k = ctrl ? K_PPAGE : K_UP;
case FL_Left: if (shift) do_mark(cursheet, MARKING); k = ctrl?K_BPAGE:K_LEFT; break; break;
case FL_Page_Down: k = shift?K_NSHEET:ctrl?K_LASTL :K_NPAGE; break; case FL_Down:
case FL_Page_Up: k = shift?K_PSHEET:ctrl?K_FIRSTL:K_PPAGE; break; 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; if (k > 0 && (ctrl || alt)) return 0;
// Quick and dirty upper-case fix, fails for international chars on keyboards... // 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'); if (shift && !alt && !ctrl && k >= 'a' && k <= 'z')
k = (Key)(k - 'a' + 'A');
do_sheetcmd(cursheet, k, cursheet->moveonly); do_sheetcmd(cursheet, k, cursheet->moveonly);
do_callback(ACTION, 0, 0); do_callback(ACTION, 0, 0);
@ -311,20 +341,22 @@ updating = false;
return Fl_Table::handle(event); return Fl_Table::handle(event);
} }
return 1;} {} return 1;
} } {} }
Function {adjust_outside()} {open protected return_type void
} {
code {int x1, x2, y1, y2;
if (!cols() || !rows()) { Function
cols(1); {adjust_outside()} {open protected return_type void} {code
rows(1); {
} int x1, x2, y1, y2;
if (!cols() || !rows()) { cols(1); rows(1); }
visible_cells(y1, y2, x1, x2); visible_cells(y1, y2, x1, x2);
//printf("adj: (%i,%i)-(%i,%i) %ix%i\\n", x1, y1, x2, y2, cols(), rows()); if (debug_level > 2)
if (x2+2 < cols() && cols() > cursheet->dimx) cols(x2+2 < cursheet->dimx?cursheet->dimx:x2+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()) { else if (x2+1 == cols()) {
int xpos = col_scroll_position(cols()); int xpos = col_scroll_position(cols());
int w = col_width(cols()-1); int w = col_width(cols()-1);
@ -333,51 +365,61 @@ else if (x2+1 == cols()) {
cols(x2+1); cols(x2+1);
} }
if (y2+2 < rows() && rows() > cursheet->dimy) rows(y2+2 < cursheet->dimy?cursheet->dimy:y2+2); if (y2+2 < rows() && rows() > cursheet->dimy)
rows(y2+2 < cursheet->dimy?cursheet->dimy:y2+2);
else if (y2+1 == rows()) { else if (y2+1 == rows()) {
int ypos = row_scroll_position(rows()); int ypos = row_scroll_position(rows());
int h = row_height(rows()-1); int h = row_height(rows()-1);
y2 += (toh + vscrollbar->value() - ypos) / h + 2; y2 += (toh + vscrollbar->value() - ypos) / h + 2;
rows(y2+1); rows(y2+1);
}} {}
}
} }
} {} }
class MainWindow {open
} {
decl {static MainWindow *current;} {protected local
} }
decl {int edit_rc;} {private local # End of class TeapotTable
}
Function {MainWindow(Sheet *sheet)} {open class MainWindow {open}
} { {
decl {static MainWindow *current;} {protected local}
decl {int edit_rc;} {private local}
Function
{MainWindow(Sheet *sheet)} {open}
{
Fl_Window window { Fl_Window window {
label teapot label teapot
callback {if (Fl::event_key(FL_Escape)) table->take_focus(); callback {
else if (do_sheetcmd(table->sheet(), K_QUIT, 0) && doanyway(table->sheet(), _("Sheet modified, leave anyway?"))) { 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(); line_label->deactivate();
window->hide(); window->hide();
}} open }
protected xywh {866 342 800 600} type Double when 0 hide resizable }
} { open protected
xywh {866 342 800 600} type Double when 0 hide resizable
}
{
Fl_Menu_Bar menu { Fl_Menu_Bar menu {
callback {Sheet *sheet = table->sheet(); callback {
Sheet *sheet = table->sheet();
Key action = (Key)(intptr_t)o->mvalue()->user_data(); Key action = (Key)(intptr_t)o->mvalue()->user_data();
if (do_sheetcmd(sheet, action, sheet->moveonly) && doanyway(sheet, _("Sheet modified, leave anyway?"))) { if (do_sheetcmd(sheet, action, sheet->moveonly) &&
doanyway(sheet, _("Sheet modified, leave anyway?")))
{
window->hide(); window->hide();
return; return;
} }
table->update_table(); table->update_table();
table->redraw();} open table->redraw();
xywh {0 0 800 25} }
class Fl_Sys_Menu_Bar open xywh {0 0 800 25} class Fl_Sys_Menu_Bar
} { }
Submenu {} { {
label {&File} Submenu {} {label {&File} xywh {25 25 67 24} } {
xywh {25 25 67 24}
} {
MenuItem {} { MenuItem {} {
label {&Open...} label {&Open...}
user_data K_LOADMENU user_data K_LOADMENU
@ -399,10 +441,7 @@ table->redraw();} open
xywh {0 0 30 20} shortcut 0x40071 xywh {0 0 30 20} shortcut 0x40071
} }
} }
Submenu {} { Submenu {} {label {&Block} xywh {25 25 67 24} } {
label {&Block}
xywh {25 25 67 24}
} {
MenuItem {} { MenuItem {} {
label {&Insert} label {&Insert}
user_data BLOCK_INSERT user_data BLOCK_INSERT
@ -449,10 +488,7 @@ table->redraw();} open
xywh {0 0 36 21} shortcut 0x90072 xywh {0 0 36 21} shortcut 0x90072
} }
} }
Submenu {} { Submenu {} {label {&View} xywh {0 0 70 21}} {
label {&View}
xywh {0 0 70 21}
} {
MenuItem {} { MenuItem {} {
label {Column &Width...} label {Column &Width...}
user_data K_COLWIDTH user_data K_COLWIDTH
@ -464,10 +500,7 @@ table->redraw();} open
xywh {0 0 36 21} shortcut 0x40067 xywh {0 0 36 21} shortcut 0x40067
} }
} }
Submenu {} { Submenu {} {label {F&ormat} open xywh {5 5 70 21}} {
label {F&ormat} open
xywh {5 5 70 21}
} {
MenuItem {} { MenuItem {} {
label {L&abel...} label {L&abel...}
user_data ADJUST_LABEL user_data ADJUST_LABEL
@ -539,10 +572,7 @@ table->redraw();} open
code0 {o->flags |= FL_MENU_TOGGLE;} code0 {o->flags |= FL_MENU_TOGGLE;}
} }
} }
Submenu {} { Submenu {} {label {&Help} open xywh {25 25 67 24}} {
label {&Help} open
xywh {25 25 67 24}
} {
MenuItem {} { MenuItem {} {
label {&Manual} label {&Manual}
user_data K_HELP user_data K_HELP
@ -558,18 +588,26 @@ table->redraw();} open
Fl_Group line_label { Fl_Group line_label {
label { Input:} open label { Input:} open
protected xywh {0 25 800 25} box ROUND_UP_BOX align 20 deactivate protected xywh {0 25 800 25} box ROUND_UP_BOX align 20 deactivate
} { }
{
Fl_Input line_input { Fl_Input line_input {
callback {bool enterkey = Fl::event_key(FL_Enter) || Fl::event_key(FL_KP_Enter); callback {
if (Fl::focus() && (Fl::focus() != table || enterkey || Fl::event_key(FL_Escape))) { 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; if (enterkey) edit_rc = 0;
line_label->deactivate(); line_label->deactivate();
}} }
protected xywh {75 27 723 21} box ROUND_DOWN_BOX labeltype NO_LABEL align 20 when 6 deactivate }
protected xywh {75 27 723 21} box ROUND_DOWN_BOX
labeltype NO_LABEL align 20 when 6 deactivate
} }
} }
Fl_Box table { Fl_Box table {
callback {Sheet *sheet = table->sheet(); callback {
Sheet *sheet = table->sheet();
table->update_sheet(); table->update_sheet();
const char *label = getlabel(curcell(sheet)); const char *label = getlabel(curcell(sheet));
@ -581,14 +619,17 @@ if (*label == 0)
sheet->cur[X], sheet->cur[Y], sheet->cur[Z]); sheet->cur[X], sheet->cur[Y], sheet->cur[Z]);
else snprintf(buf, sizeof(buf), "%c @@(%s)=", moveonly, label); else snprintf(buf, sizeof(buf), "%c @@(%s)=", moveonly, label);
if (moveonly && table->callback_context() == TeapotTable::ACTION) { if (moveonly &&
table->callback_context() == TeapotTable::ACTION)
{
char valbuf[1024] = ""; char valbuf[1024] = "";
if (Fl::event_key() == 'p' || Fl::event_button1()) if (Fl::event_key() == 'p' || Fl::event_button1())
sprintf(valbuf, "(%i,%i,%i)", sprintf(valbuf, "(%i,%i,%i)",
sheet->cur[X], sheet->cur[Y], sheet->cur[Z]); sheet->cur[X], sheet->cur[Y], sheet->cur[Z]);
else if (Fl::event_key() == 'v') else if (Fl::event_key() == 'v')
printvalue(valbuf, sizeof(valbuf), 0, 1, printvalue(valbuf, sizeof(valbuf), 0, 1,
getscientific(curcell(sheet)), -1, sheet, sheet->cur); getscientific(curcell(sheet)),
-1, sheet, sheet->cur);
else if (Fl::event_key(FL_Tab)) line_input->take_focus(); else if (Fl::event_key(FL_Tab)) line_input->take_focus();
if (valbuf[0]) { if (valbuf[0]) {
line_input->insert(valbuf); line_input->insert(valbuf);
@ -596,7 +637,6 @@ if (moveonly && table->callback_context() == TeapotTable::ACTION) {
} }
} }
char *err; char *err;
char val[1024]; char val[1024];
if ((err = geterror(sheet, sheet->cur))) { if ((err = geterror(sheet, sheet->cur))) {
@ -604,11 +644,12 @@ if ((err = geterror(sheet, sheet->cur))) {
free(err); free(err);
val[sizeof(val)-1] = 0; val[sizeof(val)-1] = 0;
} else { } else {
print(val, sizeof(val), 0, 1, getscientific(curcell(sheet)), -1, print(val, sizeof(val), 0, 1, getscientific(curcell(sheet)),
getcont(curcell(sheet), BASE)); -1, getcont(curcell(sheet), BASE));
Token **iter = getcont(curcell(sheet), ITERATIVE); Token **iter = getcont(curcell(sheet), ITERATIVE);
if (iter != EMPTY_TVEC) { if (iter != EMPTY_TVEC) {
snprintf(val+strlen(val),sizeof(val)-strlen(val)," -> "); snprintf(val+strlen(val),sizeof(val)-strlen(val),
" -> ");
print(val+strlen(val), sizeof(val)-strlen(val), 0, 1, print(val+strlen(val), sizeof(val)-strlen(val), 0, 1,
getscientific(curcell(sheet)), -1, iter); getscientific(curcell(sheet)), -1, iter);
} }
@ -620,7 +661,8 @@ int adj = getadjust(cell);
if (adj == LEFT) left->setonly(); if (adj == LEFT) left->setonly();
else if (adj == RIGHT) right->setonly(); else if (adj == RIGHT) right->setonly();
else if (adj == CENTER) center->setonly(); else if (adj == CENTER) center->setonly();
if (SHADOWEDC(sheet, sheet->cur[X]+1, sheet->cur[Y], sheet->cur[Z])) if (SHADOWEDC(sheet,
sheet->cur[X]+1, sheet->cur[Y], sheet->cur[Z]))
shadow->set(); shadow->set();
else shadow->clear(); else shadow->clear();
if (::transparent(cell)) transparent->set(); if (::transparent(cell)) transparent->set();
@ -635,7 +677,8 @@ if (underlined(cell)) underline->set();
else underline->clear(); else underline->clear();
if (getscientific(cell)) sci->set(); if (getscientific(cell)) sci->set();
else sci->clear();} else sci->clear();}
protected xywh {0 50 800 525} box DOWN_FRAME labeltype NO_LABEL resizable protected xywh {0 50 800 525} box DOWN_FRAME
labeltype NO_LABEL resizable
code0 {table->sheet(sheet);} code0 {table->sheet(sheet);}
class TeapotTable class TeapotTable
} }
@ -643,12 +686,16 @@ else sci->clear();}
label {teapot ready.} label {teapot ready.}
protected xywh {0 575 800 25} box GTK_ROUND_DOWN_BOX align 20 protected xywh {0 575 800 25} box GTK_ROUND_DOWN_BOX align 20
} }
} code {
current = this;
} {}
} }
code {current = this;} {}
} Function
Function {line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt, size_t *x, size_t *offx)} {open return_type int {line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt,
} { size_t *x, size_t *offx)} {open return_type int} {code
code {if (line_label->active()) { {
if (line_label->active()) {
if (x) line_msg(NULL, "Action not possible at this time."); if (x) line_msg(NULL, "Action not possible at this time.");
return -1; return -1;
} }
@ -657,7 +704,8 @@ line_label->copy_label(prompt);
int ww = 0, hh = 0; int ww = 0, hh = 0;
line_label->measure_label(ww, hh); 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->resize(line_label->x()+ww+5, line_input->y(),
line_label->w()-ww-7, line_input->h());
line_input->value(buf); line_input->value(buf);
if (!x) return 0; if (!x) return 0;
@ -676,27 +724,35 @@ memcpy(buf, line_input->value(), size);
line_input->deactivate(); line_input->deactivate();
table->sheet()->moveonly = 0; table->sheet()->moveonly = 0;
table->take_focus(); table->take_focus();
return edit_rc;} {} 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 *} Function
} { {line_msg(const char *prompt, const char *msg)} {return_type void} {code
code {static char buf[PATH_MAX]; {
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
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; Fl_Native_File_Chooser chooser;
chooser.title(title); chooser.title(title);
chooser.type(create?Fl_Native_File_Chooser::BROWSE_SAVE_FILE:Fl_Native_File_Chooser::BROWSE_FILE); chooser.type(create ? Fl_Native_File_Chooser::BROWSE_SAVE_FILE :
Fl_Native_File_Chooser::BROWSE_FILE);
chooser.filter(pattern); chooser.filter(pattern);
chooser.options((create?Fl_Native_File_Chooser::NEW_FOLDER:0)|Fl_Native_File_Chooser::SAVEAS_CONFIRM); 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); fl_filename_absolute(buf, sizeof(buf), file);
@ -708,12 +764,17 @@ if (chooser.show()) return NULL;
strncpy(buf, chooser.filename(), sizeof(buf)); strncpy(buf, chooser.filename(), sizeof(buf));
buf[sizeof(buf)-1] = 0; buf[sizeof(buf)-1] = 0;
return buf;} {} 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 Function
} { {line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt,
code {if (sheet) return ((MainWindow*)((TeapotTable*)sheet->display)->parent()->user_data())->line_edit(sheet, buf, size, prompt, x, offx); 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); const char *val = fl_input("%s", buf, prompt);
if (val) { if (val) {
@ -721,37 +782,60 @@ if (val) {
buf[size-1] = 0; buf[size-1] = 0;
} }
return !val;} {} return !val;
} } {} }
Function {line_ok(const char *prompt, int curx)} {C return_type int Function
} { {line_ok(const char *prompt, int curx)} {C return_type int} {code
code {int rc = !!fl_choice("%s", "&No", NULL, "&Yes", prompt); {
if (Fl::event_key(FL_Escape)) return -1; return tpt_choose(prompt, "&No", "&Yes", NULL, curx);
return rc;} {} } {} }
}
Function {line_msg(const char *prompt, const char *msg)} {C return_type void Function
} { {line_binary(const char *prompt, const char* op1, const char* op2, int curx)}
code {MainWindow::current->line_msg(prompt, msg);} {} {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) = '&';
} }
Function {keypressed()} {open C return_type int
} {
code {while (Fl::wait(.01)) if (Fl::event_key(FL_Escape)) return 1;
return 0;} {}
} }
int retval = tpt_choose(prompt, "&Cancel", top[0], top[1], curx+1) - 1;
free(top[0]);
free(top[1]);
return retval;
} {} }
Function {line_menu(const char *prompt, const MenuChoice *choice, int curx)} {C return_type int 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 { Fl_Window line_menu_menu {
label {Please Choose} open label {Please Choose} open
xywh {706 58 250 245} type Double hide resizable modal xywh {706 58 250 245} type Double hide resizable modal
} { }
{
Fl_Group {} { Fl_Group {} {
label {Please Choose:} open label {Please Choose:} open
xywh {0 0 250 200} box ENGRAVED_BOX align 21 xywh {0 0 250 200} box ENGRAVED_BOX align 21
} { }
{
Fl_Browser line_menu_browser { Fl_Browser line_menu_browser {
callback {line_menu_menu->hide();} callback {line_menu_menu->hide();}
xywh {5 25 240 170} xywh {5 25 240 170}
@ -763,8 +847,9 @@ Function {line_menu(const char *prompt, const MenuChoice *choice, int curx)} {C
callback {line_menu_menu->hide();} callback {line_menu_menu->hide();}
xywh {5 205 240 35} xywh {5 205 240 35}
} }
} } code
code {line_menu_browser->clear(); {
line_menu_browser->clear();
while (choice->str) { while (choice->str) {
line_menu_browser->add(choice->str+1); line_menu_browser->add(choice->str+1);
choice++; choice++;
@ -773,24 +858,29 @@ while (choice->str) {
line_menu_menu->show(); line_menu_menu->show();
while (line_menu_menu->shown()) Fl::wait(); while (line_menu_menu->shown()) Fl::wait();
return line_menu_browser->value()-1;} {} return line_menu_browser->value()-1;
} } {} }
Function {redraw_sheet(Sheet *sheet)} {C return_type void Function
} { {redraw_sheet(Sheet *sheet)} {C return_type void} {code
code {TeapotTable *t = (TeapotTable*)sheet->display; {
TeapotTable *t = (TeapotTable*)sheet->display;
t->update_table(); t->update_table();
t->redraw();} {} t->redraw();} {}
} }
Function {redraw_cell(Sheet *sheet, const Location /* at */)} {C return_type void Function
} { {redraw_cell(Sheet *sheet, const Location /* at */)} {C return_type void}
code {redraw_sheet(sheet);} {} { code
} {
redraw_sheet(sheet);
} {} }
Function {display_init(Sheet *sheet, int always_redraw)} {open C return_type void Function
} { {display_init(Sheet *sheet, int always_redraw)}
code {Fl::get_system_colors(); {open C return_type void} {code
{
Fl::get_system_colors();
\#ifdef ENABLE_HELP \#ifdef ENABLE_HELP
Fl_File_Icon::load_system_icons(); Fl_File_Icon::load_system_icons();
\#endif \#endif
@ -798,58 +888,57 @@ Fl::scheme("gtk+");
int ch = sheet->changed; int ch = sheet->changed;
resize(sheet, 1, 1, 1); resize(sheet, 1, 1, 1);
sheet->changed = ch; sheet->changed = ch;
new MainWindow(sheet);} {} new MainWindow(sheet);
} } {} }
Function {display_end(Sheet* sheet)} {C return_type void Function
} { {display_end(Sheet* sheet)} {C return_type void} {code
code {} {} {
} } {} }
Function {display_main(Sheet *cursheet)} {C return_type void Function
} { {display_main(Sheet *cursheet)} {C return_type void} {code
code {((TeapotTable *)cursheet->display)->parent()->show(); {
Fl::run();} {} ((TeapotTable *)cursheet->display)->parent()->show();
} Fl::run();
} {} }
Function {show_menu(Sheet *sheet)} {C return_type Key Function {show_menu(Sheet *sheet)} {C return_type Key} {code
} { {
code {return K_NONE;} {} return K_NONE;
} } {}}
decl {MainWindow *MainWindow::current;} {private global decl {MainWindow *MainWindow::current;} {private global}
}
declblock {\#ifdef ENABLE_HELP} {after {\#endif} declblock {\#ifdef ENABLE_HELP} {after {\#endif}} {
} { decl {\#include <FL/Fl_Help_Dialog.H>} {private global}
decl {\#include <FL/Fl_Help_Dialog.H>} {private global
} Function
Function {show_text(const char *text)} {open C return_type void {show_text(const char *text)} {open C return_type void} {code
} { {
code {Fl_Help_Dialog *d = new Fl_Help_Dialog(); Fl_Help_Dialog *d = new Fl_Help_Dialog();
if (strchr(text, '<')) { if (strchr(text, '<')) d->value(text);
d->value(text); else d->load(text);
} else {
d->load(text);
}
d->resize(d->x(), d->y(), d->w()*3/2, d->h()*3/2); d->resize(d->x(), d->y(), d->w()*3/2, d->h()*3/2);
d->show();} {} d->show();
} } {} }
} }
declblock {\#ifndef ENABLE_HELP} {after {\#endif} declblock {\#ifndef ENABLE_HELP} {after {\#endif}} {
} { Function
Function {show_text(const char *text)} {open C return_type void {show_text(const char *text)} {open C return_type void} {code
} { {
code {char *txt = striphtml(text); char *txt = striphtml(text);
fl_message("%s", txt); fl_message("%s", txt);
free(txt);} {} free(txt);
} } {} }
} }
Function {find_helpfile(char *buf, int size, const char *argv0)} {open C return_type void Function
} { {find_helpfile(char *buf, int size, const char *argv0)}
code {fl_filename_absolute(buf, size, argv0); {open C return_type void} {code
{
fl_filename_absolute(buf, size, argv0);
char *p = (char *)fl_filename_name(buf); char *p = (char *)fl_filename_name(buf);
strncpy(p, "../share/doc/teapot/html/index.html", buf+size-p); strncpy(p, "../share/doc/teapot/html/index.html", buf+size-p);
buf[size-1] = 0; buf[size-1] = 0;
@ -871,6 +960,4 @@ test = open(buf, O_RDONLY);
if (test < 0) strncpy(buf, "/usr/share/doc/teapot/html/index.html", size); if (test < 0) strncpy(buf, "/usr/share/doc/teapot/html/index.html", size);
else close(test); else close(test);
buf[size-1] = 0; buf[size-1] = 0;
} {} }
} {}
}

230
src/tpt_choose.cxx Normal file
View File

@ -0,0 +1,230 @@
#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Return_Button.H>
#include <FL/Fl_Window.H>
#include <FL/fl_draw.H>
#include <stdarg.h>
#include <string.h>
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; b<N_BUTTONS; b++, x -= 100) {
button[b] = new Tpt_Return_Button(x, 70, 90, 23);
button[b]->align(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;
}

7
src/tpt_choose.h Normal file
View File

@ -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