2019-07-22 20:32:33 +00:00
|
|
|
# data file for the Fltk User Interface Designer (fluid)
|
2023-04-09 05:41:50 +00:00
|
|
|
# Code replacements for dummy numerical constants:
|
|
|
|
# 9999100/*fontsize*/
|
|
|
|
# 9999112/*fontsize + 12*/
|
|
|
|
# 9999114/*fontsize + 14*/
|
|
|
|
# 9999110/*fontsize + 10*/
|
|
|
|
# 9999224/*2*fontsize + 24*/
|
|
|
|
# 99990336/*600 - 3*fontsize - 36*/
|
|
|
|
# 99990112/*600 - fontsize - 12*/
|
2019-07-22 20:32:33 +00:00
|
|
|
version 1.0300
|
|
|
|
header_name {.h}
|
|
|
|
code_name {.cxx}
|
|
|
|
|
2019-08-03 00:31:48 +00:00
|
|
|
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 "display.h"} {public global}
|
2019-09-03 08:41:37 +00:00
|
|
|
decl {\#include "utf8.h"} {public global}
|
2019-08-03 00:31:48 +00:00
|
|
|
|
|
|
|
decl {\#include <unistd.h>} {private global}
|
|
|
|
decl {\#include <stdint.h>} {private global}
|
|
|
|
decl {\#include <limits.h>} {private global}
|
|
|
|
decl {\#include <fcntl.h>} {private global}
|
|
|
|
|
2019-08-03 16:42:32 +00:00
|
|
|
decl {\#define SKIPDEFCOLS(c) while (c == DefaultCN[FOREGROUND] || c == DefaultCN[BACKGROUND]) ++c}
|
2019-08-03 03:21:58 +00:00
|
|
|
{private global}
|
2019-08-03 00:31:48 +00:00
|
|
|
decl {\#define shadow _shadow} {private global}
|
|
|
|
decl {\#define transparent _transparent} {private global}
|
|
|
|
decl {\#define Cell _Cell} {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 {\#undef shadow} {private global}
|
|
|
|
decl {\#undef transparent} {private global}
|
|
|
|
decl {\#undef Cell} {private global}
|
|
|
|
|
|
|
|
decl {\#include "tpt_choose.h"} {private global}
|
2019-08-03 03:21:58 +00:00
|
|
|
decl {\#include "default.h"} {private global}
|
2019-08-03 00:31:48 +00:00
|
|
|
decl {\#include "misc.h"} {private global}
|
|
|
|
|
2019-08-03 03:21:58 +00:00
|
|
|
decl {Fl_Color tpt_selection_version(Fl_Color base);} {private global}
|
|
|
|
|
2019-08-03 00:31:48 +00:00
|
|
|
class TeapotTable {open : {public Fl_Table}}
|
|
|
|
{
|
|
|
|
decl {Sheet *cursheet;} {protected local}
|
|
|
|
decl {bool cut, updating;} {protected local}
|
2023-04-09 05:41:50 +00:00
|
|
|
decl {int unit_width, unit_height;} {protected local}
|
2019-08-03 00:31:48 +00:00
|
|
|
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) :
|
2023-04-09 05:41:50 +00:00
|
|
|
Fl_Table(x, y, w, h, l), cut(false), updating(false),
|
|
|
|
unit_width(10), unit_height(0)} {open} {code
|
2019-08-03 00:31:48 +00:00
|
|
|
{
|
|
|
|
end();
|
2023-04-09 05:41:50 +00:00
|
|
|
col_resize_min(unit_width);
|
2019-08-03 00:31:48 +00:00
|
|
|
col_resize(true);
|
|
|
|
col_header(header);
|
2023-04-09 05:41:50 +00:00
|
|
|
unit_height = fl_height(FL_HELVETICA, fontsize);
|
|
|
|
col_header_height(unit_height);
|
|
|
|
fl_font(FL_HELVETICA, fontsize);
|
|
|
|
int ww = 0, hh = 0;
|
|
|
|
fl_measure("8888", ww, hh, 0);
|
|
|
|
int min_row_height = (unit_height + ROWHEIGHT_DENOMINATOR/2 - 1)
|
|
|
|
/ ROWHEIGHT_DENOMINATOR;
|
|
|
|
if (min_row_height < 1) min_row_height = 1;
|
|
|
|
row_resize_min(min_row_height);
|
|
|
|
row_resize(true);
|
2019-08-03 00:31:48 +00:00
|
|
|
row_header(header);
|
2023-04-09 05:41:50 +00:00
|
|
|
row_header_width(ww + unit_width);
|
2019-08-03 00:31:48 +00:00
|
|
|
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
|
|
|
|
{
|
2023-04-08 01:34:37 +00:00
|
|
|
// Fl_Table calls this function to draw each visible cell in the table.
|
|
|
|
// context specifies what part of the table is being drawn;
|
|
|
|
// R and C give the row and column of the cell in the table;
|
|
|
|
// xx and yy give the screen coordinates where the cell is to be drawn;
|
|
|
|
// and W and H give the width and height of the rectangle into which to
|
|
|
|
// draw.
|
2019-08-03 00:31:48 +00:00
|
|
|
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;
|
2023-04-09 05:41:50 +00:00
|
|
|
fl_font(FL_HELVETICA | FL_BOLD, fontsize);
|
2019-08-03 00:31:48 +00:00
|
|
|
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();
|
2019-07-27 04:14:26 +00:00
|
|
|
break;
|
2019-07-22 20:32:33 +00:00
|
|
|
|
2019-08-03 00:31:48 +00:00
|
|
|
case CONTEXT_STARTPAGE:
|
|
|
|
adjust_outside();
|
|
|
|
if (Fl::event_button1()) update_sheet();
|
|
|
|
break;
|
2019-07-22 20:32:33 +00:00
|
|
|
|
2019-08-03 03:21:58 +00:00
|
|
|
case CONTEXT_COL_HEADER: {
|
2023-04-09 05:41:50 +00:00
|
|
|
fl_font(FL_HELVETICA | FL_BOLD, fontsize);
|
2019-08-03 00:31:48 +00:00
|
|
|
fl_push_clip(xx, yy, W, H);
|
2019-08-03 03:21:58 +00:00
|
|
|
Fl_Color hd_clr = col_header_color();
|
|
|
|
if (C == cursheet->cur[X]) hd_clr = tpt_selection_version(hd_clr);
|
|
|
|
fl_draw_box(FL_THIN_UP_BOX, xx, yy, W, H, hd_clr);
|
2019-08-03 00:31:48 +00:00
|
|
|
fl_color(FL_FOREGROUND_COLOR);
|
|
|
|
sprintf(s, "%d", C);
|
|
|
|
fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER);
|
|
|
|
fl_pop_clip();
|
|
|
|
return;
|
2019-08-03 03:21:58 +00:00
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
|
2019-08-03 03:21:58 +00:00
|
|
|
case CONTEXT_ROW_HEADER: {
|
2023-04-09 05:41:50 +00:00
|
|
|
fl_font(FL_HELVETICA | FL_BOLD, fontsize);
|
2019-08-03 00:31:48 +00:00
|
|
|
fl_push_clip(xx, yy, W, H);
|
2019-08-03 03:21:58 +00:00
|
|
|
Fl_Color hd_clr = row_header_color();
|
|
|
|
if (R == cursheet->cur[Y]) hd_clr = tpt_selection_version(hd_clr);
|
|
|
|
fl_draw_box(FL_THIN_UP_BOX, xx, yy, W, H, hd_clr);
|
2019-08-03 00:31:48 +00:00
|
|
|
fl_color(FL_FOREGROUND_COLOR);
|
|
|
|
sprintf(s, "%d", R);
|
|
|
|
fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER);
|
|
|
|
fl_pop_clip();
|
|
|
|
return;
|
2019-08-03 03:21:58 +00:00
|
|
|
}
|
|
|
|
|
2019-08-03 00:31:48 +00:00
|
|
|
case CONTEXT_CELL: {
|
2019-09-03 08:41:37 +00:00
|
|
|
Location crz; crz[X] = C; crz[Y] = R; crz[Z] = cursheet->cur[Z];
|
|
|
|
while (shadowed(cursheet, crz)) {
|
|
|
|
crz[X] = --C;
|
|
|
|
xx -= W = col_width(C);
|
|
|
|
}
|
|
|
|
crz[X]++;
|
|
|
|
while (shadowed(cursheet, crz))
|
|
|
|
W += col_width(crz[X]++);
|
2019-08-03 00:31:48 +00:00
|
|
|
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);
|
2019-08-03 03:21:58 +00:00
|
|
|
bool iscurrent = (C == cursheet->cur[X] && R == cursheet->cur[Y]);
|
2019-09-03 08:41:37 +00:00
|
|
|
Style sc = getstyle(cursheet, test);
|
|
|
|
ColorNum bgcn = sc.aspect[BACKGROUND];
|
|
|
|
if (bgcn == NO_COLOR_SET) bgcn = DefaultCN[BACKGROUND];
|
|
|
|
Fl_Color cellbg = ((Fl_Color *)(cursheet->palette))[bgcn];
|
2019-08-03 03:21:58 +00:00
|
|
|
if (selected) cellbg = tpt_selection_version(cellbg);
|
|
|
|
if (!LOC_WITHIN(cursheet,test))
|
2019-09-05 07:24:24 +00:00
|
|
|
cellbg = fl_color_average(cellbg, FL_BLACK, 0.97f);
|
2019-08-03 00:31:48 +00:00
|
|
|
fl_draw_box(iscurrent ? FL_BORDER_BOX : FL_THIN_DOWN_BOX,
|
2019-08-03 03:21:58 +00:00
|
|
|
xx, yy, W, H, cellbg);
|
2019-08-03 00:31:48 +00:00
|
|
|
if (Fl::focus() == this && iscurrent)
|
|
|
|
draw_focus(FL_BORDER_BOX, xx, yy, W, H);
|
|
|
|
fl_pop_clip();
|
|
|
|
|
|
|
|
fl_push_clip(xx+3, yy+3, W-6, H-6);
|
2019-09-03 08:41:37 +00:00
|
|
|
ColorNum fgcn = sc.aspect[FOREGROUND];
|
|
|
|
if (fgcn == NO_COLOR_SET) fgcn = DefaultCN[FOREGROUND];
|
|
|
|
Fl_Color cellfg = ((Fl_Color *)(cursheet->palette))[fgcn];
|
2019-09-18 12:49:53 +00:00
|
|
|
if (sc.dim) cellfg = fl_color_average(cellfg, cellbg, 0.6f);
|
2019-08-03 03:21:58 +00:00
|
|
|
fl_color(cellfg);
|
2019-09-18 12:49:53 +00:00
|
|
|
Fl_Font cellfont = FL_HELVETICA;
|
|
|
|
if (sc.bold) cellfont |= FL_BOLD;
|
|
|
|
if (sc.italic) cellfont |= FL_ITALIC;
|
2023-04-09 05:41:50 +00:00
|
|
|
fl_font(cellfont, fontsize);
|
2019-08-03 00:31:48 +00:00
|
|
|
|
2023-04-08 01:34:37 +00:00
|
|
|
size_t ulen = printvalue(s, sizeof(s), 0, quote, sc.fform,
|
|
|
|
sc.precision, cursheet, test);
|
|
|
|
ptrdiff_t len = ulen;
|
|
|
|
ptrdiff_t nlen = len;
|
2019-08-03 00:31:48 +00:00
|
|
|
int ww = 0, hh = 0;
|
|
|
|
fl_measure(s, ww, hh, 0);
|
2019-09-03 08:41:37 +00:00
|
|
|
while (ww > W-6) {
|
2023-04-08 01:34:37 +00:00
|
|
|
char *dc = mbspos(s+nlen, -1);
|
2019-09-03 08:41:37 +00:00
|
|
|
nlen = dc - s;
|
|
|
|
s[nlen] = (char)0;
|
|
|
|
ww = 0;
|
|
|
|
fl_measure(s, ww, hh, 0);
|
|
|
|
}
|
|
|
|
if (nlen < len) {
|
|
|
|
if (nlen < 1) { s[0] = '\#'; s[1] = (char)0; }
|
|
|
|
else if (nlen < 6) for (int i = 0; s[i]; i++) s[i] = '\#';
|
|
|
|
else {
|
|
|
|
char *ov = mbspos(s+nlen-1, -5);
|
|
|
|
if (ov < s) ov = s;
|
|
|
|
strncpy(ov, "...\#\#", sizeof(s) - nlen);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Adjust adj = sc.adjust;
|
2019-08-03 00:31:48 +00:00
|
|
|
fl_draw(s, xx+3, yy+3, W-6, H-6,
|
|
|
|
adj == RIGHT ? FL_ALIGN_RIGHT :
|
Streamline internals of teapot
The primary change is to add a “funcall” token, so that an entire expression
can be encapsulated as a single token. This change is used to allow a cell to
include simply a selection of appropriate semantic tokens. I.e., the content
and iterative content are now each a single token like the value and the
result value. Token vectors are used only as intermediate results in scanning
and parsing.
Not this means the cells are now in effect storing parse trees, so
computation should be slightly faster and future extensions (like #56) should
be facilitated.
This commit also takes the opportunity while internals are being altered to
add another token to a cell for future use for computed attributes, cf #22,
and to change the internal numerical values from double and ints to long
doubles and long longs. However, the change attempts to encapsulate that
choice so it would be easy to change back or change to another representation.
Note that these changes break savexdr(), as the internal binary format of
a cell is now different. Rather than reimplement it, it is deprecated as
the world does not need another binary spreadsheet format. Hence, the
ascii format for teapot spreadsheets becomes the primary file format.
Loading of old xdr files is still supported for backward compatibility.
Closes #59.
Also along the way, various other slight fixes and enhancements crept in,
a partial but probably not exhaustive list of which follows:
Fixes #31.
Further revisions and improvements to documentation.
Make the approximate comparison of floating point values scale more
accurately with the size of the doubles being compared.
Further extensions of absolute and relative cell addressing.
Addition of (circle constant) tau function/constant.
Modified string conversion to simply use internal printing routines, and
to take "scientific" and "decimal" keywords.
Allowed n() function to take a list of values, or just a single location
defaulting to the current location.
Added floor, ceil, trunc, and round functions, and allowed them to be
keywords controlling the int() integer conversion function as well.
Allowed substr() to drop its last argument to go to the end of the string.
Provided an enum of built-in functions to preserve legacy function
identifiers, allowing the large table inside func.c to be reorganized
in a clearer fashion.
Added additional annotation of properties of the built-in functions,
including precedence.
All operators are now also accessible as built-in functions.
Made precedence of unary - lower than ^ to match python.
Avoided inadvertently using FLTK @symbol abbreviations for formulas with
"@" in them.
2019-08-23 19:12:06 +00:00
|
|
|
adj == LEFT ? FL_ALIGN_LEFT : FL_ALIGN_CENTER,
|
|
|
|
NULL, 0);
|
2019-09-03 08:41:37 +00:00
|
|
|
if (sc.underline) fl_xyline(xx, yy+H-7, xx+W);
|
2019-08-03 00:31:48 +00:00
|
|
|
fl_pop_clip();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} {selected} }
|
|
|
|
|
|
|
|
Function
|
|
|
|
{update_table()} {open return_type void} {code
|
|
|
|
{
|
|
|
|
if (updating) return;
|
|
|
|
updating = true;
|
2023-04-09 05:41:50 +00:00
|
|
|
if (debug_level > 1)
|
|
|
|
printf("update_table: %zux%zu@%i,%i; %i[%lu], %i[%lu]\\n",
|
2019-09-05 07:24:24 +00:00
|
|
|
cursheet->dim[X], cursheet->dim[Y],
|
2019-08-03 00:31:48 +00:00
|
|
|
cursheet->cur[X], cursheet->cur[Y],
|
|
|
|
cursheet->offx, cursheet->maxx,
|
|
|
|
cursheet->offy, cursheet->maxy);
|
|
|
|
|
2023-04-09 05:41:50 +00:00
|
|
|
bool no_table = (cols() == 0) || (rows() == 0);
|
2019-09-05 07:24:24 +00:00
|
|
|
if (cursheet->dim[X] > (size_t)cols()) cols(cursheet->dim[X]);
|
2023-04-09 05:41:50 +00:00
|
|
|
if (no_table) col_width_all(DEF_COLUMNWIDTH*unit_width);
|
2019-09-05 07:24:24 +00:00
|
|
|
if (cursheet->dim[Y] > (size_t)rows()) rows(cursheet->dim[Y]);
|
2023-04-09 05:41:50 +00:00
|
|
|
if (no_table) row_height_all(unit_height);
|
2019-08-03 00:31:48 +00:00
|
|
|
adjust_outside();
|
|
|
|
|
2019-09-05 07:24:24 +00:00
|
|
|
for (int x = 0; (size_t)x < cursheet->dim[X]; x++) {
|
2023-04-09 05:41:50 +00:00
|
|
|
int w = columnwidth(cursheet, x, cursheet->cur[Z])*unit_width;
|
2019-08-03 00:31:48 +00:00
|
|
|
if (col_width(x) != w) col_width(x, w);
|
|
|
|
}
|
2023-04-09 05:41:50 +00:00
|
|
|
for (int y = 0; (size_t)y < cursheet->dim[Y]; ++y) {
|
|
|
|
int h = rowheight(cursheet, y, cursheet->cur[Z])*unit_height
|
|
|
|
/ ROWHEIGHT_DENOMINATOR;
|
|
|
|
if (row_height(y) != h) row_height(y, h);
|
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
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);
|
2023-04-09 05:41:50 +00:00
|
|
|
int lastx, lasty;
|
|
|
|
visible_cells(cursheet->offy, lasty,
|
|
|
|
cursheet->offx, lastx);
|
|
|
|
cursheet->maxx = (size_t)(lastx - cursheet->offx);
|
|
|
|
cursheet->maxy = (size_t)(lasty - cursheet->offy);
|
2019-08-03 00:31:48 +00:00
|
|
|
|
|
|
|
if (is_interactive_resize()) {
|
2019-09-05 07:24:24 +00:00
|
|
|
for (size_t C = 0; C < cursheet->dim[X]; ++C) {
|
2023-04-09 05:41:50 +00:00
|
|
|
size_t w = (col_width(C) + unit_width/2)/unit_width;
|
2019-08-03 00:31:48 +00:00
|
|
|
if (w != columnwidth(cursheet, C, cursheet->cur[Z]))
|
|
|
|
setwidth(cursheet, C, cursheet->cur[Z], w);
|
|
|
|
}
|
2023-04-09 05:41:50 +00:00
|
|
|
for (size_t R = 0; R < cursheet->dim[Y]; ++R) {
|
|
|
|
size_t h =
|
|
|
|
(row_height(R)*ROWHEIGHT_DENOMINATOR + unit_height/2)
|
|
|
|
/ unit_height;
|
|
|
|
if (h != rowheight(cursheet, R, cursheet->cur[Z]))
|
|
|
|
setheight(cursheet, R, cursheet->cur[Z], h);
|
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
updating = false;
|
2023-04-09 05:41:50 +00:00
|
|
|
if (debug_level > 1)
|
|
|
|
printf(
|
|
|
|
"upd_sheet: %ix%i@%i,%i; %i[%lu], %i[%lu] (%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);
|
2019-08-03 00:31:48 +00:00
|
|
|
} {} }
|
|
|
|
|
|
|
|
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;
|
2023-04-09 05:41:50 +00:00
|
|
|
case FL_F+2: k = K_LOADMENU; break;
|
|
|
|
case FL_F+3: k = K_SAVE; break;
|
2019-08-03 00:31:48 +00:00
|
|
|
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;
|
2019-09-09 14:33:41 +00:00
|
|
|
case FL_Tab: if (shift) { k = K_CLOCK; } break;
|
2019-08-03 00:31:48 +00:00
|
|
|
case FL_Enter:
|
2019-09-03 08:41:37 +00:00
|
|
|
case FL_KP_Enter:
|
|
|
|
k = alt ? (shift ? K_EDIT_STYLE_EXPR : K_MENTER) : K_ENTER;
|
|
|
|
break;
|
2019-08-03 00:31:48 +00:00
|
|
|
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;
|
2023-04-09 05:41:50 +00:00
|
|
|
default:
|
|
|
|
/* Handle shifted keys */
|
|
|
|
if (Fl::event_length() == 1) k = (Key)(Fl::event_text()[0]);
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
|
2023-04-09 05:41:50 +00:00
|
|
|
/* This short circuit perhaps needs an explanation: */
|
2019-08-03 00:31:48 +00:00
|
|
|
if (k > 0 && (ctrl || alt)) return 0;
|
|
|
|
|
|
|
|
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()) {
|
2019-07-22 20:32:33 +00:00
|
|
|
int rc = Fl_Table::handle(event);
|
|
|
|
do_callback(ACTION, 0, 0);
|
|
|
|
return rc;
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
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);
|
2023-04-09 05:41:50 +00:00
|
|
|
if (debug_level > 1)
|
2019-08-03 00:31:48 +00:00
|
|
|
printf("adj: (%i,%i)-(%i,%i) %ix%i\\n", x1, y1, x2, y2,
|
|
|
|
cols(), rows());
|
2019-09-05 07:24:24 +00:00
|
|
|
if (x2+2 < cols() && (size_t)cols() > cursheet->dim[X])
|
|
|
|
cols((size_t)x2+2 < cursheet->dim[X] ? cursheet->dim[X] : x2+2);
|
2019-08-03 00:31:48 +00:00
|
|
|
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);
|
|
|
|
}
|
2023-04-09 05:41:50 +00:00
|
|
|
visible_cells(y1, y2, x1, x2);
|
|
|
|
cursheet->width = x2 - x1 + 1;
|
2019-08-03 00:31:48 +00:00
|
|
|
|
2019-09-05 07:24:24 +00:00
|
|
|
if (y2+2 < rows() && (size_t)rows() > cursheet->dim[Y])
|
|
|
|
rows((size_t)y2+2 < cursheet->dim[Y] ? cursheet->dim[Y] : y2+2);
|
2019-08-03 00:31:48 +00:00
|
|
|
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);
|
2019-07-22 20:32:33 +00:00
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
} {} }
|
|
|
|
|
|
|
|
}
|
|
|
|
# End of class TeapotTable
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
2023-04-09 05:41:50 +00:00
|
|
|
open xywh {0 0 800 9999112} class Fl_Sys_Menu_Bar
|
|
|
|
code0 {
|
|
|
|
menu->textsize(fontsize);
|
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
{
|
2023-04-09 05:41:50 +00:00
|
|
|
Submenu {} {label {&File} xywh {25 25 67 24} labelsize 0 } {
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem {} {
|
|
|
|
label {&Open...}
|
|
|
|
user_data K_LOADMENU
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {5 5 30 20} labelsize 0 shortcut 0x4006f
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
MenuItem {} {
|
|
|
|
label {&Save}
|
|
|
|
user_data K_SAVE
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 30 20} labelsize 0 shortcut 0x40073
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
MenuItem {} {
|
|
|
|
label {Save &As...}
|
|
|
|
user_data K_NAME
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 30 20} labelsize 0 shortcut 0x50053 divider
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
MenuItem {} {
|
|
|
|
label {&Quit}
|
|
|
|
user_data K_QUIT
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 30 20} labelsize 0 shortcut 0x40071
|
2019-07-22 20:32:33 +00:00
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
2023-04-09 05:41:50 +00:00
|
|
|
Submenu {} {label {&Block} xywh {25 25 67 24} labelsize 0 } {
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem {} {
|
|
|
|
label {&Insert}
|
|
|
|
user_data BLOCK_INSERT
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 30 20} labelsize 0 shortcut 0x90069
|
2019-07-22 20:32:33 +00:00
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem {} {
|
|
|
|
label {&Delete}
|
|
|
|
user_data BLOCK_DELETE
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 30 20} labelsize 0 shortcut 0x90064 divider
|
2019-07-22 20:32:33 +00:00
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem {} {
|
|
|
|
label {&Move}
|
|
|
|
user_data BLOCK_MOVE
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 30 20} labelsize 0 shortcut 0x9006d
|
2019-07-22 20:32:33 +00:00
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem {} {
|
|
|
|
label {&Copy}
|
|
|
|
user_data BLOCK_COPY
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 36 21} labelsize 0 shortcut 0x90063 divider
|
2019-07-22 20:32:33 +00:00
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem {} {
|
|
|
|
label {&Fill}
|
|
|
|
user_data BLOCK_FILL
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 36 21} labelsize 0 shortcut 0x90066
|
2019-07-22 20:32:33 +00:00
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem {} {
|
|
|
|
label {FillWith}
|
|
|
|
user_data FILL_BLOCK
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 36 30} labelsize 0 }
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem {} {
|
|
|
|
label {C&lear}
|
|
|
|
user_data BLOCK_CLEAR
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 36 21} labelsize 0 shortcut 0x9006c divider
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
MenuItem {} {
|
|
|
|
label {&Sort}
|
|
|
|
user_data BLOCK_SORT
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 36 21} labelsize 0 shortcut 0x90073
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
MenuItem {} {
|
|
|
|
label {Mi&rror}
|
|
|
|
user_data BLOCK_MIRROR
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 36 21} labelsize 0 shortcut 0x90072
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
}
|
2023-04-09 05:41:50 +00:00
|
|
|
Submenu {} {label {&View} xywh {0 0 70 21} labelsize 0 } {
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem {} {
|
|
|
|
label {Column &Width...}
|
|
|
|
user_data K_COLWIDTH
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 36 21} labelsize 0 shortcut 0x80077
|
|
|
|
}
|
|
|
|
MenuItem {} {
|
|
|
|
label {Row &Height...}
|
|
|
|
user_data K_ROWHEIGHT
|
|
|
|
xywh {0 0 36 21} labelsize 0 shortcut 0x80068
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
MenuItem {} {
|
|
|
|
label {&Goto}
|
|
|
|
user_data K_GOTO
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 36 21} labelsize 0 shortcut 0x40067
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
}
|
2023-04-09 05:41:50 +00:00
|
|
|
Submenu {} {label {F&ormat} open xywh {5 5 70 21} labelsize 0 } {
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem {} {
|
|
|
|
label {L&abel...}
|
|
|
|
user_data ADJUST_LABEL
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 36 21} labelsize 0 shortcut 0x80061 divider
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
2019-09-18 12:49:53 +00:00
|
|
|
MenuItem dim {
|
|
|
|
label {&Dim}
|
|
|
|
user_data ADJUST_DIM
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 34 21} labelsize 0 shortcut 0x40064
|
2019-09-18 12:49:53 +00:00
|
|
|
code0 {o->flags |= FL_MENU_TOGGLE;}
|
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem bold {
|
|
|
|
label {&Bold}
|
|
|
|
user_data ADJUST_BOLD
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 34 21} labelsize 0 shortcut 0x40062
|
2019-08-03 00:31:48 +00:00
|
|
|
code0 {o->flags |= FL_MENU_TOGGLE;}
|
|
|
|
}
|
2019-09-18 12:49:53 +00:00
|
|
|
MenuItem italic {
|
|
|
|
label {&Italic}
|
|
|
|
user_data ADJUST_ITALIC
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 34 21} labelsize 0 shortcut 0x40069
|
2019-09-18 12:49:53 +00:00
|
|
|
code0 {o->flags |= FL_MENU_TOGGLE;}
|
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem underline {
|
|
|
|
label {&Underline}
|
|
|
|
user_data ADJUST_UNDERLINE
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 34 21} labelsize 0 shortcut 0x40075
|
|
|
|
divider
|
2019-08-03 00:31:48 +00:00
|
|
|
code0 {o->flags |= FL_MENU_TOGGLE;}
|
|
|
|
}
|
|
|
|
MenuItem left {
|
|
|
|
label {&Left}
|
|
|
|
user_data ADJUST_LEFT
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 36 21} labelsize 0 shortcut 0x8006c
|
2019-08-03 00:31:48 +00:00
|
|
|
code0 {o->flags |= FL_MENU_RADIO;}
|
|
|
|
}
|
|
|
|
MenuItem right {
|
|
|
|
label {&Right}
|
|
|
|
user_data ADJUST_RIGHT
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 36 21} labelsize 0 shortcut 0x80072
|
2019-08-03 00:31:48 +00:00
|
|
|
code0 {o->flags |= FL_MENU_RADIO;}
|
|
|
|
}
|
|
|
|
MenuItem center {
|
|
|
|
label {&Center}
|
|
|
|
user_data ADJUST_CENTER
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 36 21} labelsize 0 shortcut 0x80063
|
|
|
|
divider
|
2019-08-03 00:31:48 +00:00
|
|
|
code0 {o->flags |= FL_MENU_RADIO;}
|
|
|
|
}
|
|
|
|
MenuItem {} {
|
|
|
|
label {&Precision...}
|
|
|
|
user_data ADJUST_PRECISION
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 36 21} labelsize 0 shortcut 0x80070
|
2019-08-29 06:19:08 +00:00
|
|
|
}
|
|
|
|
MenuItem {} {
|
|
|
|
label {&Foreground...}
|
|
|
|
user_data ADJUST_FOREGROUND
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 36 21} labelsize 0
|
2019-08-29 06:19:08 +00:00
|
|
|
}
|
|
|
|
MenuItem {} {
|
|
|
|
label {&Background...}
|
|
|
|
user_data ADJUST_BACKGROUND
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 36 21} labelsize 0 divider
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
menuitem dec {
|
|
|
|
label {&Decimal}
|
|
|
|
user_data ADJUST_DECIMAL
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 36 21} labelsize 0
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
code0 {o->flags |= FL_MENU_RADIO;}
|
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem sci {
|
|
|
|
label {&Scientific}
|
|
|
|
user_data ADJUST_SCIENTIFIC
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 36 21} labelsize 0 shortcut 0x80073
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
code0 {o->flags |= FL_MENU_RADIO;}
|
|
|
|
}
|
|
|
|
MenuItem cpt {
|
|
|
|
label {Co&mpact}
|
|
|
|
user_data ADJUST_COMPACT
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 36 21} labelsize 0
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
code0 {o->flags |= FL_MENU_RADIO;}
|
|
|
|
}
|
|
|
|
MenuItem hex {
|
|
|
|
label {He&xact}
|
|
|
|
user_data ADJUST_COMPACT
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 36 21} labelsize 0 divider
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
code0 {o->flags |= FL_MENU_RADIO;}
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
MenuItem shadow {
|
|
|
|
label {Shadow&ed}
|
|
|
|
user_data ADJUST_SHADOW
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 36 21} labelsize 0 shortcut 0x80065
|
2019-08-03 00:31:48 +00:00
|
|
|
code0 {o->flags |= FL_MENU_TOGGLE;}
|
|
|
|
}
|
|
|
|
MenuItem transparent {
|
|
|
|
label {&Transparent}
|
|
|
|
user_data ADJUST_TRANSPARENT
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 36 21} labelsize 0 shortcut 0x80074
|
|
|
|
divider
|
2019-08-03 00:31:48 +00:00
|
|
|
code0 {o->flags |= FL_MENU_TOGGLE;}
|
|
|
|
}
|
|
|
|
MenuItem lock {
|
|
|
|
label {Lo&ck}
|
|
|
|
user_data ADJUST_LOCK
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 36 21} labelsize 0 shortcut 0x80063
|
2019-08-03 00:31:48 +00:00
|
|
|
code0 {o->flags |= FL_MENU_TOGGLE;}
|
|
|
|
}
|
|
|
|
MenuItem ignore {
|
|
|
|
label {&Ignore}
|
|
|
|
user_data ADJUST_IGNORE
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 0 36 21} labelsize 0 shortcut 0x80069
|
2019-08-03 00:31:48 +00:00
|
|
|
code0 {o->flags |= FL_MENU_TOGGLE;}
|
|
|
|
}
|
|
|
|
}
|
2023-04-09 05:41:50 +00:00
|
|
|
Submenu {} {label {Help} open xywh {25 25 67 24} labelsize 0 } {
|
2019-08-03 00:31:48 +00:00
|
|
|
MenuItem {} {
|
|
|
|
label {&Manual}
|
|
|
|
user_data K_HELP
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 30 20} labelsize 0 shortcut 0xffbe
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
MenuItem {} {
|
|
|
|
label {&About}
|
|
|
|
user_data K_ABOUT
|
2023-04-09 05:41:50 +00:00
|
|
|
xywh {0 0 30 20} labelsize 0
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Fl_Group line_label {
|
|
|
|
label { Input:} open
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 9999112 800 9999112} labelsize 9999100
|
|
|
|
box ROUND_UP_BOX align 20 deactivate
|
2019-07-22 20:32:33 +00:00
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
{
|
|
|
|
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();
|
|
|
|
}
|
2019-07-22 20:32:33 +00:00
|
|
|
}
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {75 9999114 723 9999110} box PLASTIC_DOWN_BOX
|
|
|
|
labelsize 9999100
|
2019-08-03 00:31:48 +00:00
|
|
|
labeltype NO_LABEL align 20 when 6 deactivate
|
2023-04-09 05:41:50 +00:00
|
|
|
code0 {
|
|
|
|
line_input->textsize(fontsize);
|
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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')
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
printvalue(valbuf, sizeof(valbuf), 0, QUOTE_STRING,
|
|
|
|
FLT_COMPACT, 0, sheet, sheet->cur);
|
2019-08-03 00:31:48 +00:00
|
|
|
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 {
|
Streamline internals of teapot
The primary change is to add a “funcall” token, so that an entire expression
can be encapsulated as a single token. This change is used to allow a cell to
include simply a selection of appropriate semantic tokens. I.e., the content
and iterative content are now each a single token like the value and the
result value. Token vectors are used only as intermediate results in scanning
and parsing.
Not this means the cells are now in effect storing parse trees, so
computation should be slightly faster and future extensions (like #56) should
be facilitated.
This commit also takes the opportunity while internals are being altered to
add another token to a cell for future use for computed attributes, cf #22,
and to change the internal numerical values from double and ints to long
doubles and long longs. However, the change attempts to encapsulate that
choice so it would be easy to change back or change to another representation.
Note that these changes break savexdr(), as the internal binary format of
a cell is now different. Rather than reimplement it, it is deprecated as
the world does not need another binary spreadsheet format. Hence, the
ascii format for teapot spreadsheets becomes the primary file format.
Loading of old xdr files is still supported for backward compatibility.
Closes #59.
Also along the way, various other slight fixes and enhancements crept in,
a partial but probably not exhaustive list of which follows:
Fixes #31.
Further revisions and improvements to documentation.
Make the approximate comparison of floating point values scale more
accurately with the size of the doubles being compared.
Further extensions of absolute and relative cell addressing.
Addition of (circle constant) tau function/constant.
Modified string conversion to simply use internal printing routines, and
to take "scientific" and "decimal" keywords.
Allowed n() function to take a list of values, or just a single location
defaulting to the current location.
Added floor, ceil, trunc, and round functions, and allowed them to be
keywords controlling the int() integer conversion function as well.
Allowed substr() to drop its last argument to go to the end of the string.
Provided an enum of built-in functions to preserve legacy function
identifiers, allowing the large table inside func.c to be reorganized
in a clearer fashion.
Added additional annotation of properties of the built-in functions,
including precedence.
All operators are now also accessible as built-in functions.
Made precedence of unary - lower than ^ to match python.
Avoided inadvertently using FLTK @symbol abbreviations for formulas with
"@" in them.
2019-08-23 19:12:06 +00:00
|
|
|
Token t = gettok(curcell(sheet), BASE_CONT);
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
printtok(val, sizeof(val), 0, QUOTE_STRING,
|
2019-09-03 08:41:37 +00:00
|
|
|
FLT_COMPACT, -1, VERBOSE_ERROR, &t);
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
Token t = gettok(curcell(sheet), ITER_CONT);
|
|
|
|
if (t.type != EMPTY) {
|
|
|
|
snprintf(val+strlen(val),sizeof(val)-strlen(val), " -> ");
|
|
|
|
printtok(val+strlen(val), sizeof(val)-strlen(val), 0,
|
2019-09-03 08:41:37 +00:00
|
|
|
QUOTE_STRING, FLT_COMPACT, -1, VERBOSE_ERROR, &t);
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
|
|
|
|
line_edit(sheet, val, 0, buf, 0, 0);
|
|
|
|
Cell *cell = curcell(sheet);
|
2019-09-03 08:41:37 +00:00
|
|
|
Style sc = getstyle(sheet, sheet->cur);
|
|
|
|
switch (sc.adjust) {
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
case LEFT: left->setonly(); break;
|
|
|
|
case RIGHT: right->setonly(); break;
|
|
|
|
case CENTER: center->setonly(); break;
|
2019-09-05 07:24:24 +00:00
|
|
|
case AUTOADJUST: ;
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
}
|
2019-09-03 08:41:37 +00:00
|
|
|
Location nb; LOCATION_GETS(nb, sheet->cur); nb[X]++;
|
|
|
|
if (shadowed(sheet, nb))
|
2019-08-03 00:31:48 +00:00
|
|
|
shadow->set();
|
|
|
|
else shadow->clear();
|
2019-09-03 08:41:37 +00:00
|
|
|
if (sc.transparent) transparent->set();
|
2019-08-03 00:31:48 +00:00
|
|
|
else transparent->clear();
|
|
|
|
if (locked(cell)) lock->set();
|
|
|
|
else lock->clear();
|
|
|
|
if (ignored(cell)) ignore->set();
|
|
|
|
else ignore->clear();
|
2019-09-18 12:49:53 +00:00
|
|
|
if (sc.dim) dim->set(); else dim->clear();
|
|
|
|
if (sc.bold) bold->set(); else bold->clear();
|
|
|
|
if (sc.italic) italic->set(); else italic->clear();
|
2019-09-03 08:41:37 +00:00
|
|
|
if (sc.underline) underline->set();
|
2019-08-03 00:31:48 +00:00
|
|
|
else underline->clear();
|
2019-09-03 08:41:37 +00:00
|
|
|
switch (sc.fform) {
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
case FLT_DECIMAL: dec->setonly(); break;
|
|
|
|
case FLT_SCIENTIFIC: sci->setonly(); break;
|
|
|
|
case FLT_COMPACT: cpt->setonly(); break;
|
|
|
|
case FLT_HEXACT: hex->setonly(); break;
|
2019-09-05 07:24:24 +00:00
|
|
|
case FLT_NO_FORMAT: ;
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
}
|
|
|
|
}
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 9999224 800 99990336} box DOWN_FRAME
|
2019-08-03 00:31:48 +00:00
|
|
|
labeltype NO_LABEL resizable
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
code0 { table->sheet(sheet); }
|
2019-07-22 20:32:33 +00:00
|
|
|
class TeapotTable
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
Fl_Box status {
|
2019-07-22 20:32:33 +00:00
|
|
|
label {teapot ready.}
|
2023-04-09 05:41:50 +00:00
|
|
|
protected xywh {0 99990112 800 9999112}
|
|
|
|
box GTK_ROUND_DOWN_BOX align 20
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
} code {
|
|
|
|
current = this;
|
|
|
|
} {}
|
|
|
|
}
|
2019-07-22 20:32:33 +00:00
|
|
|
|
2019-08-03 00:31:48 +00:00
|
|
|
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
|
|
|
|
|
2019-08-03 03:21:58 +00:00
|
|
|
Function
|
|
|
|
{tpt_selection_version(Fl_Color base)} {open return_type {Fl_Color}} {code
|
|
|
|
{
|
2019-09-05 07:24:24 +00:00
|
|
|
return fl_color_average(base, FL_SELECTION_COLOR, 0.85f);
|
2019-08-03 03:21:58 +00:00
|
|
|
} {} }
|
|
|
|
|
2019-08-03 00:31:48 +00:00
|
|
|
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) {
|
2019-07-22 20:32:33 +00:00
|
|
|
fl_filename_absolute(buf, sizeof(buf), file);
|
|
|
|
char *p = (char *)fl_filename_name(buf);
|
|
|
|
*p = 0;
|
|
|
|
chooser.directory(buf);
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
if (chooser.show()) return NULL;
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
const char *val = fl_input("%s", buf, prompt);
|
|
|
|
if (val) {
|
2019-07-22 20:32:33 +00:00
|
|
|
strncpy(buf, val, size);
|
|
|
|
buf[size-1] = 0;
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
2019-07-22 20:32:33 +00:00
|
|
|
|
2019-08-03 00:31:48 +00:00
|
|
|
return !val;
|
|
|
|
} {} }
|
|
|
|
|
|
|
|
Function
|
|
|
|
{line_ok(const char *prompt, int curx)} {C return_type int} {code
|
|
|
|
{
|
|
|
|
return tpt_choose(prompt, "&No", "&Yes", NULL, curx);
|
|
|
|
} {} }
|
|
|
|
|
|
|
|
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) = '&';
|
2019-07-22 20:32:33 +00:00
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
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);
|
|
|
|
} {} }
|
|
|
|
|
2019-09-03 08:41:37 +00:00
|
|
|
Function {keypressed()} {open C return_type bool} {code
|
2019-08-03 00:31:48 +00:00
|
|
|
{
|
2019-09-03 08:41:37 +00:00
|
|
|
while (Fl::wait(.01)) if (Fl::event_key(FL_Escape)) return true;
|
|
|
|
return false;
|
2019-08-03 00:31:48 +00:00
|
|
|
} {} }
|
|
|
|
|
|
|
|
Function
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
{line_menu(const char *prompt, const char **choice, int curx)}
|
2019-08-03 00:31:48 +00:00
|
|
|
{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
|
2019-07-22 20:32:33 +00:00
|
|
|
}
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
|
|
|
Fl_Button {} {
|
|
|
|
label Cancel
|
|
|
|
callback {line_menu_menu->hide();}
|
|
|
|
xywh {5 205 240 35}
|
|
|
|
}
|
|
|
|
} code
|
|
|
|
{
|
|
|
|
line_menu_browser->clear();
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
while (*choice) {
|
|
|
|
line_menu_browser->add(*choice + 1);
|
2019-07-22 20:32:33 +00:00
|
|
|
choice++;
|
2019-08-03 00:31:48 +00:00
|
|
|
}
|
2019-07-22 20:32:33 +00:00
|
|
|
|
2019-08-03 00:31:48 +00:00
|
|
|
line_menu_menu->show();
|
|
|
|
while (line_menu_menu->shown()) Fl::wait();
|
2019-07-22 20:32:33 +00:00
|
|
|
|
2019-08-03 00:31:48 +00:00
|
|
|
return line_menu_browser->value()-1;
|
|
|
|
} {} }
|
2019-07-22 20:32:33 +00:00
|
|
|
|
2019-08-03 00:31:48 +00:00
|
|
|
Function
|
|
|
|
{redraw_sheet(Sheet *sheet)} {C return_type void} {code
|
|
|
|
{
|
|
|
|
TeapotTable *t = (TeapotTable*)sheet->display;
|
|
|
|
t->update_table();
|
|
|
|
t->redraw();} {}
|
2019-07-22 20:32:33 +00:00
|
|
|
}
|
|
|
|
|
2019-08-03 00:31:48 +00:00
|
|
|
Function
|
|
|
|
{redraw_cell(Sheet *sheet, const Location /* at */)} {C return_type void}
|
|
|
|
{ code
|
|
|
|
{
|
2019-09-03 08:41:37 +00:00
|
|
|
update(sheet);
|
2019-08-03 00:31:48 +00:00
|
|
|
} {} }
|
2019-07-22 20:32:33 +00:00
|
|
|
|
2019-08-03 00:31:48 +00:00
|
|
|
Function
|
2019-09-05 07:24:24 +00:00
|
|
|
{display_init(Sheet *sheet, bool always_redraw)}
|
2019-08-03 00:31:48 +00:00
|
|
|
{open C return_type void} {code
|
|
|
|
{
|
|
|
|
Fl::get_system_colors();
|
2019-07-22 20:32:33 +00:00
|
|
|
\#ifdef ENABLE_HELP
|
2019-08-03 00:31:48 +00:00
|
|
|
Fl_File_Icon::load_system_icons();
|
2019-07-22 20:32:33 +00:00
|
|
|
\#endif
|
2019-08-03 00:31:48 +00:00
|
|
|
Fl::scheme("gtk+");
|
Make tpa the default file format for Teapot
There turned out to be one blocking technical issue for full adpotion of
tpa format, and that was the fact that the printed representation of
floating values inside the tpa file might not reproduce the same double
when read. This change therefore introduces the "hexact" floating point
format, based on the the %La format string, which produces a hex
representation with exact round trips. While working on this, it was
convenient to add a new representation "compact" which is basically the
shorter of decimal and scientific representations, without trailing zeros.
This is now the default float format, but of course one can select decimal
or scientific formats to restore prior appearance. However, full-precision
compact format is now the (only) format for editing cell contents, as it
is accurate and efficient. Of course you can enter floating point values
in any format you like when typing in a formula.
The addition of several new floating point options overloaded the menus
in terminal teapot, so this change also revamps those menus slightly,
including eliminating the unused MenuChoice struct, and just specifying menus
with an array of strings.
Closes #63.
2019-08-24 16:58:46 +00:00
|
|
|
bool ch = sheet->changed;
|
|
|
|
resize(sheet, 1, 1, 1, NULL);
|
2019-08-03 00:31:48 +00:00
|
|
|
sheet->changed = ch;
|
|
|
|
new MainWindow(sheet);
|
2019-08-03 03:21:58 +00:00
|
|
|
/* allocate and initialize the palette */
|
|
|
|
Fl_Color* palt = new Fl_Color[sheet->max_colors];
|
|
|
|
sheet->palette = (void *) palt;
|
2019-08-03 16:42:32 +00:00
|
|
|
palt[DefaultCN[FOREGROUND]] = FL_FOREGROUND_COLOR;
|
|
|
|
palt[DefaultCN[BACKGROUND]] = FL_BACKGROUND2_COLOR;
|
2019-08-03 03:21:58 +00:00
|
|
|
ColorNum c = 0; SKIPDEFCOLS(c);
|
2019-09-03 08:41:37 +00:00
|
|
|
palt[c++] = FL_FOREGROUND_COLOR; SKIPDEFCOLS(c);
|
2019-08-03 03:21:58 +00:00
|
|
|
palt[c++] = FL_BACKGROUND_COLOR; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_INACTIVE_COLOR; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_SELECTION_COLOR; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_GRAY0; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_DARK3; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_DARK2; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_DARK1; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_LIGHT1; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_LIGHT2; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_LIGHT3; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_BLACK; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_RED; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_GREEN; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_YELLOW; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_BLUE; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_MAGENTA; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_CYAN; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_DARK_RED; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_DARK_GREEN; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_DARK_YELLOW; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_DARK_BLUE; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_DARK_MAGENTA; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_DARK_CYAN; SKIPDEFCOLS(c);
|
|
|
|
palt[c++] = FL_WHITE; SKIPDEFCOLS(c);
|
|
|
|
while (c < sheet->max_colors) { palt[c++] = FL_WHITE; SKIPDEFCOLS(c); }
|
2019-08-03 00:31:48 +00:00
|
|
|
} {} }
|
|
|
|
|
|
|
|
Function
|
|
|
|
{display_end(Sheet* sheet)} {C return_type void} {code
|
|
|
|
{
|
2019-08-03 03:21:58 +00:00
|
|
|
ColorNum* palt = (ColorNum *)sheet->palette;
|
|
|
|
delete [] palt;
|
2019-08-03 00:31:48 +00:00
|
|
|
} {} }
|
|
|
|
|
|
|
|
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 <FL/Fl_Help_Dialog.H>} {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
|
2019-09-09 14:33:41 +00:00
|
|
|
{find_helpfile(char *buf, size_t size, const char *argv0)}
|
2019-08-03 00:31:48 +00:00
|
|
|
{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;
|
|
|
|
} {} }
|