feat: Add hashing color for cells (#93)
Co-authored-by: Glen Whitney <glen@studioinfinity.org> Reviewed-on: #93
This commit is contained in:
parent
8db9c30825
commit
00859ecbd2
2
NEWS
2
NEWS
@ -17,7 +17,7 @@ o New token types: style and bool.
|
|||||||
o Comparison operators return bool rather than int (Note this can be a breaking
|
o Comparison operators return bool rather than int (Note this can be a breaking
|
||||||
change; you may need to wrap comparisons in int() if you are using the result
|
change; you may need to wrap comparisons in int() if you are using the result
|
||||||
in a numerical computation.)
|
in a numerical computation.)
|
||||||
o Foreground and background color style attributes for cells.
|
o Foreground, background, and hashing color style attributes for cells.
|
||||||
o Variable row height for cells.
|
o Variable row height for cells.
|
||||||
o Addition of an if() conditional operator.
|
o Addition of an if() conditional operator.
|
||||||
o Addition of a find() macro to search for a cell satisfying a condition.
|
o Addition of a find() macro to search for a cell satisfying a condition.
|
||||||
|
@ -167,8 +167,8 @@ Copyright, Contributors and License
|
|||||||
teapot
|
teapot
|
||||||
\noun default
|
\noun default
|
||||||
(Table Editor And Planner, Or: Teapot), is copyrighted 1995–2006 by Michael
|
(Table Editor And Planner, Or: Teapot), is copyrighted 1995–2006 by Michael
|
||||||
Haardt, and 2009–2010 by Jörg Walter, and 2019 by Glen Whitney, and is
|
Haardt, and 2009–2010 by Jörg Walter, and 2019-2023 by Glen Whitney, and
|
||||||
licensed under the Gnu General Public License v3 or later.
|
is licensed under the Gnu General Public License v3 or later.
|
||||||
\end_layout
|
\end_layout
|
||||||
|
|
||||||
\begin_layout Standard
|
\begin_layout Standard
|
||||||
@ -3994,9 +3994,13 @@ foreground
|
|||||||
\family sans
|
\family sans
|
||||||
background
|
background
|
||||||
\family default
|
\family default
|
||||||
() colors used to display a cell may be set.
|
() colors used to display a cell may be set and the
|
||||||
(Currently this only affects screen display.) The value of these attributes
|
\family sans
|
||||||
is a positive integer which acts as an index into the
|
hashing
|
||||||
|
\family default
|
||||||
|
() color may be set as well.
|
||||||
|
(Currently this only affects screen display.) The value of each of these
|
||||||
|
attributes is a positive integer which acts as an index into the
|
||||||
\begin_inset Quotes eld
|
\begin_inset Quotes eld
|
||||||
\end_inset
|
\end_inset
|
||||||
|
|
||||||
@ -8272,6 +8276,37 @@ is
|
|||||||
for example.
|
for example.
|
||||||
\end_layout
|
\end_layout
|
||||||
|
|
||||||
|
\begin_layout Description
|
||||||
|
|
||||||
|
\series medium
|
||||||
|
style
|
||||||
|
\emph on
|
||||||
|
|
||||||
|
\begin_inset space ~
|
||||||
|
\end_inset
|
||||||
|
|
||||||
|
|
||||||
|
\series default
|
||||||
|
\emph default
|
||||||
|
hashing
|
||||||
|
\series medium
|
||||||
|
(int
|
||||||
|
\emph on
|
||||||
|
|
||||||
|
\begin_inset space ~
|
||||||
|
\end_inset
|
||||||
|
|
||||||
|
|
||||||
|
\emph default
|
||||||
|
c)
|
||||||
|
\series default
|
||||||
|
evaluates to a style token with the hashing color set to
|
||||||
|
\emph on
|
||||||
|
c
|
||||||
|
\emph default
|
||||||
|
(and no other fields set).
|
||||||
|
\end_layout
|
||||||
|
|
||||||
\begin_layout Description
|
\begin_layout Description
|
||||||
hexact used as a keyword to the string() function; listed here to record
|
hexact used as a keyword to the string() function; listed here to record
|
||||||
that this identifier may not be used as a cell label.
|
that this identifier may not be used as a cell label.
|
||||||
|
@ -1089,6 +1089,7 @@ static Token aspect_func(FunctionIdentifier self, int argc, const Token argv[])
|
|||||||
{
|
{
|
||||||
ColorAspect ca = FOREGROUND;
|
ColorAspect ca = FOREGROUND;
|
||||||
if (self == FUNC_BACKGROUND) ca = BACKGROUND;
|
if (self == FUNC_BACKGROUND) ca = BACKGROUND;
|
||||||
|
if (self == FUNC_HASHING) ca = HASHING;
|
||||||
Token result;
|
Token result;
|
||||||
if (argc != 1 || argv[0].type != INT) {
|
if (argc != 1 || argv[0].type != INT) {
|
||||||
const char *templ = _("Usage: %s(int)");
|
const char *templ = _("Usage: %s(int)");
|
||||||
@ -1839,6 +1840,7 @@ Tfunc tfunc[]=
|
|||||||
[FUNC_PRECISION] = { "precision", precision_func, PREFIX_FUNC, FUNCT, 0 },
|
[FUNC_PRECISION] = { "precision", precision_func, PREFIX_FUNC, FUNCT, 0 },
|
||||||
[FUNC_FOREGROUND] = { "foreground", aspect_func, PREFIX_FUNC, FUNCT, 0 },
|
[FUNC_FOREGROUND] = { "foreground", aspect_func, PREFIX_FUNC, FUNCT, 0 },
|
||||||
[FUNC_BACKGROUND] = { "background", aspect_func, PREFIX_FUNC, FUNCT, 0 },
|
[FUNC_BACKGROUND] = { "background", aspect_func, PREFIX_FUNC, FUNCT, 0 },
|
||||||
|
[FUNC_HASHING] = { "hashing", aspect_func, PREFIX_FUNC, FUNCT, 0 },
|
||||||
[FUNC_JUSTIFY] = { "justify", justify_func, PREFIX_FUNC, FUNCT, 0 },
|
[FUNC_JUSTIFY] = { "justify", justify_func, PREFIX_FUNC, FUNCT, 0 },
|
||||||
[FUNC_FLOATFMT] = { "floatfmt", floatfmt_func, PREFIX_FUNC, FUNCT, 0 },
|
[FUNC_FLOATFMT] = { "floatfmt", floatfmt_func, PREFIX_FUNC, FUNCT, 0 },
|
||||||
[FUNC_SHADOWED] = { "shadowed", shadowed_func, PREFIX_FUNC, FUNCT, 0 },
|
[FUNC_SHADOWED] = { "shadowed", shadowed_func, PREFIX_FUNC, FUNCT, 0 },
|
||||||
|
@ -44,6 +44,7 @@ typedef enum
|
|||||||
FUNC_FUNCALL, FUNC_LIDENT, FUNC_LOCATION, FUNC_NUMBER, FUNC_OPERATOR,
|
FUNC_FUNCALL, FUNC_LIDENT, FUNC_LOCATION, FUNC_NUMBER, FUNC_OPERATOR,
|
||||||
|
|
||||||
FUNC_IS, FUNC_FIND, FUNC_PRECISION, FUNC_FOREGROUND, FUNC_BACKGROUND,
|
FUNC_IS, FUNC_FIND, FUNC_PRECISION, FUNC_FOREGROUND, FUNC_BACKGROUND,
|
||||||
|
FUNC_HASHING,
|
||||||
FUNC_JUSTIFY, FUNC_FLOATFMT, FUNC_SHADOWED, FUNC_TRANSPARENT, FUNC_BOLD,
|
FUNC_JUSTIFY, FUNC_FLOATFMT, FUNC_SHADOWED, FUNC_TRANSPARENT, FUNC_BOLD,
|
||||||
FUNC_UNDERLINE, FUNC_CENTER, FUNC_STYLE,
|
FUNC_UNDERLINE, FUNC_CENTER, FUNC_STYLE,
|
||||||
|
|
||||||
|
@ -390,9 +390,8 @@ static void do_attribute(Sheet *cursheet, Key action)
|
|||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* Set a color */ /*{{{*/
|
/* Set a color */ /*{{{*/
|
||||||
case ADJUST_BACKGROUND:
|
case ADJUST_HASHING: ++ca; /* FALL THROUGH */
|
||||||
ca = BACKGROUND;
|
case ADJUST_BACKGROUND: ++ca; /* FALL THROUGH */
|
||||||
/* FALL THROUGH */
|
|
||||||
case ADJUST_FOREGROUND: {
|
case ADJUST_FOREGROUND: {
|
||||||
int n = fs.aspect[ca];
|
int n = fs.aspect[ca];
|
||||||
const char* prompt = _("%s for block:");
|
const char* prompt = _("%s for block:");
|
||||||
@ -1372,6 +1371,7 @@ int do_sheetcmd(Sheet *cursheet, Key c, bool moveonly)
|
|||||||
case ADJUST_UNDERLINE:
|
case ADJUST_UNDERLINE:
|
||||||
case ADJUST_FOREGROUND:
|
case ADJUST_FOREGROUND:
|
||||||
case ADJUST_BACKGROUND:
|
case ADJUST_BACKGROUND:
|
||||||
|
case ADJUST_HASHING:
|
||||||
case ADJUST_TRANSPARENT:
|
case ADJUST_TRANSPARENT:
|
||||||
case ADJUST_LABEL:
|
case ADJUST_LABEL:
|
||||||
case ADJUST_LOCK:
|
case ADJUST_LOCK:
|
||||||
|
@ -96,7 +96,8 @@ typedef enum
|
|||||||
K_EDIT_STYLE_EXPR = -64,
|
K_EDIT_STYLE_EXPR = -64,
|
||||||
ADJUST_DIM = -65,
|
ADJUST_DIM = -65,
|
||||||
ADJUST_ITALIC = -66,
|
ADJUST_ITALIC = -66,
|
||||||
K_ROWHEIGHT = -67
|
K_ROWHEIGHT = -67,
|
||||||
|
ADJUST_HASHING = -68
|
||||||
} Key;
|
} Key;
|
||||||
|
|
||||||
extern int do_sheetcmd(Sheet *cursheet, Key c, bool moveonly);
|
extern int do_sheetcmd(Sheet *cursheet, Key c, bool moveonly);
|
||||||
|
@ -16,10 +16,13 @@ const char *FloatFormat_Name[] =
|
|||||||
const char FloatFormat_Char[] = "Ndsch";
|
const char FloatFormat_Char[] = "Ndsch";
|
||||||
|
|
||||||
const char *ColorAspect_Name[] =
|
const char *ColorAspect_Name[] =
|
||||||
{ [FOREGROUND] = "foreground", [BACKGROUND] = "background"
|
{ [FOREGROUND] = "foreground", [BACKGROUND] = "background",
|
||||||
|
[HASHING] = "hashing"
|
||||||
};
|
};
|
||||||
const ColorNum DefaultCN[] =
|
const ColorNum DefaultCN[] =
|
||||||
{ [FOREGROUND] = 0, [BACKGROUND] = 16, [NUM_COLOR_ASPECTS] = 255 };
|
{ [FOREGROUND] = 0, [BACKGROUND] = 16, [HASHING] = 16,
|
||||||
|
[NUM_COLOR_ASPECTS] = 255
|
||||||
|
};
|
||||||
|
|
||||||
/* clearstyle -- zero out a style */
|
/* clearstyle -- zero out a style */
|
||||||
void clearstyle(Style* s) {
|
void clearstyle(Style* s) {
|
||||||
|
@ -32,7 +32,9 @@ typedef unsigned char ColorNum;
|
|||||||
#define MAX_MAX_COLORS UCHAR_MAX
|
#define MAX_MAX_COLORS UCHAR_MAX
|
||||||
#define COLOR_FORMAT "%hhu"
|
#define COLOR_FORMAT "%hhu"
|
||||||
|
|
||||||
typedef enum { FOREGROUND = 0, BACKGROUND, NUM_COLOR_ASPECTS } ColorAspect;
|
typedef enum
|
||||||
|
{ FOREGROUND = 0, BACKGROUND, HASHING, NUM_COLOR_ASPECTS }
|
||||||
|
ColorAspect;
|
||||||
extern const char *ColorAspect_Name[];
|
extern const char *ColorAspect_Name[];
|
||||||
extern const ColorNum DefaultCN[];
|
extern const ColorNum DefaultCN[];
|
||||||
|
|
||||||
|
@ -112,7 +112,9 @@ static int do_attribute(Sheet *cursheet)
|
|||||||
{
|
{
|
||||||
const char *typemenu[] =
|
const char *typemenu[] =
|
||||||
{ _("bB)old"), _("dD)im"), _("uU)nderline"),
|
{ _("bB)old"), _("dD)im"), _("uU)nderline"),
|
||||||
_("fF)oreground"), _("kBack)ground"), NULL };
|
_("fF)oreground"), _("kBack)ground"), _("hH)ashing"),
|
||||||
|
NULL
|
||||||
|
};
|
||||||
switch (c = line_menu(prompt, typemenu, 0))
|
switch (c = line_menu(prompt, typemenu, 0))
|
||||||
{
|
{
|
||||||
case -2: case -1: c = K_INVALID; break;
|
case -2: case -1: c = K_INVALID; break;
|
||||||
@ -121,6 +123,7 @@ static int do_attribute(Sheet *cursheet)
|
|||||||
case 2: c = ADJUST_UNDERLINE; break;
|
case 2: c = ADJUST_UNDERLINE; break;
|
||||||
case 3: c = ADJUST_FOREGROUND; break;
|
case 3: c = ADJUST_FOREGROUND; break;
|
||||||
case 4: c = ADJUST_BACKGROUND; break;
|
case 4: c = ADJUST_BACKGROUND; break;
|
||||||
|
case 5: c = ADJUST_HASHING; break;
|
||||||
default: assert(0);
|
default: assert(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -566,18 +569,33 @@ void redraw_sheet(Sheet *sheet)
|
|||||||
}
|
}
|
||||||
else realsize = size;
|
else realsize = size;
|
||||||
ms = getmarkstate(sheet);
|
ms = getmarkstate(sheet);
|
||||||
short usecp = 0;
|
short usecp = -1;
|
||||||
|
short hashcp = -1;
|
||||||
ColorNum fg = sc.aspect[FOREGROUND];
|
ColorNum fg = sc.aspect[FOREGROUND];
|
||||||
if (fg == NO_COLOR_SET) fg = DefaultCN[FOREGROUND];
|
if (fg == NO_COLOR_SET) fg = DefaultCN[FOREGROUND];
|
||||||
ColorNum bg = sc.aspect[BACKGROUND];
|
ColorNum bg = sc.aspect[BACKGROUND];
|
||||||
if (bg == NO_COLOR_SET) bg = DefaultCN[BACKGROUND];
|
if (bg == NO_COLOR_SET) bg = DefaultCN[BACKGROUND];
|
||||||
while (usecp < curcp) {
|
ColorNum hg = sc.aspect[HASHING];
|
||||||
|
if (hg == NO_COLOR_SET) hg = bg;
|
||||||
|
for (short trycp = 0; trycp < curcp; ++trycp) {
|
||||||
short pfg, pbg;
|
short pfg, pbg;
|
||||||
pair_content(usecp, &pfg, &pbg);
|
pair_content(trycp, &pfg, &pbg);
|
||||||
if (fg == pfg && bg == pbg) break;
|
if (fg != pfg) continue;
|
||||||
++usecp;
|
if (bg == pbg) usecp = trycp;
|
||||||
|
if (hg == pbg) hashcp = trycp;
|
||||||
|
if (usecp >= 0 && hashcp >= 0) break;
|
||||||
|
}
|
||||||
|
if (usecp < 0) {
|
||||||
|
usecp = curcp;
|
||||||
|
init_pair(curcp++, fg, bg);
|
||||||
|
}
|
||||||
|
if (hashcp < 0) {
|
||||||
|
if (bg == hg) hashcp = usecp;
|
||||||
|
else {
|
||||||
|
hashcp = curcp;
|
||||||
|
init_pair(curcp++, fg, hg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (usecp == curcp) init_pair(curcp++, fg, bg);
|
|
||||||
wcolor_set(stdscr, usecp, NULL);
|
wcolor_set(stdscr, usecp, NULL);
|
||||||
bool invert =
|
bool invert =
|
||||||
(ms != UNMARKED) && loc_in_box(tmp, sheet->mark1, sheet->mark2);
|
(ms != UNMARKED) && loc_in_box(tmp, sheet->mark1, sheet->mark2);
|
||||||
@ -587,11 +605,30 @@ void redraw_sheet(Sheet *sheet)
|
|||||||
if (sc.dim) wattron(stdscr, A_DIM);
|
if (sc.dim) wattron(stdscr, A_DIM);
|
||||||
if (sc.bold) wattron(stdscr, A_BOLD);
|
if (sc.bold) wattron(stdscr, A_BOLD);
|
||||||
if (sc.underline) wattron(stdscr, A_UNDERLINE);
|
if (sc.underline) wattron(stdscr, A_UNDERLINE);
|
||||||
(void)mvwaddstr(stdscr, (int)(height + sheet->oriy),
|
short nextcp = hashcp;
|
||||||
(int)(width + sheet->orix),
|
if (hashcp == usecp) {
|
||||||
buf+cutoff);
|
(void)mvwaddstr(stdscr, (int)(height + sheet->oriy),
|
||||||
for (fill=mbslen(buf+cutoff); fill<realsize; ++fill)
|
(int)(width + sheet->orix),
|
||||||
|
buf+cutoff);
|
||||||
|
} else { // Alternate colors to simulate hash
|
||||||
|
(void)mvwaddch(stdscr, (int)(height + sheet->oriy),
|
||||||
|
(int)(width + sheet->orix),
|
||||||
|
(chtype)buf[cutoff]);
|
||||||
|
for (size_t ix = cutoff+1; buf[ix]; ++ix) {
|
||||||
|
wcolor_set(stdscr, nextcp, NULL);
|
||||||
|
if (nextcp == hashcp) nextcp = usecp;
|
||||||
|
else nextcp = hashcp;
|
||||||
|
(void)waddch(stdscr, (chtype)buf[ix]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (fill=mbslen(buf+cutoff); fill<realsize; ++fill) {
|
||||||
|
if (usecp != hashcp) {
|
||||||
|
wcolor_set(stdscr, nextcp, NULL);
|
||||||
|
if (nextcp == hashcp) nextcp = usecp;
|
||||||
|
else nextcp = hashcp;
|
||||||
|
}
|
||||||
(void)waddch(stdscr,(chtype)(unsigned char)' ');
|
(void)waddch(stdscr,(chtype)(unsigned char)' ');
|
||||||
|
}
|
||||||
for (RowHgtT extra = 1; extra < rows; ++extra) {
|
for (RowHgtT extra = 1; extra < rows; ++extra) {
|
||||||
mvwaddstr(stdscr,
|
mvwaddstr(stdscr,
|
||||||
(int)(height + extra + sheet->oriy),
|
(int)(height + extra + sheet->oriy),
|
||||||
|
@ -171,13 +171,22 @@ class TeapotTable {open : {public Fl_Table}}
|
|||||||
bool iscurrent = (C == cursheet->cur[X] && R == cursheet->cur[Y]);
|
bool iscurrent = (C == cursheet->cur[X] && R == cursheet->cur[Y]);
|
||||||
Style sc = getstyle(cursheet, test);
|
Style sc = getstyle(cursheet, test);
|
||||||
ColorNum bgcn = sc.aspect[BACKGROUND];
|
ColorNum bgcn = sc.aspect[BACKGROUND];
|
||||||
|
ColorNum hgcn = sc.aspect[HASHING];
|
||||||
if (bgcn == NO_COLOR_SET) bgcn = DefaultCN[BACKGROUND];
|
if (bgcn == NO_COLOR_SET) bgcn = DefaultCN[BACKGROUND];
|
||||||
Fl_Color cellbg = ((Fl_Color *)(cursheet->palette))[bgcn];
|
Fl_Color cellbg = ((Fl_Color *)(cursheet->palette))[bgcn];
|
||||||
if (selected) cellbg = tpt_selection_version(cellbg);
|
if (selected) cellbg = tpt_selection_version(cellbg);
|
||||||
if (!LOC_WITHIN(cursheet,test))
|
if (!LOC_WITHIN(cursheet,test))
|
||||||
cellbg = fl_color_average(cellbg, FL_BLACK, 0.97f);
|
cellbg = fl_color_average(cellbg, FL_BLACK, 0.97f);
|
||||||
fl_draw_box(iscurrent ? FL_BORDER_BOX : FL_THIN_DOWN_BOX,
|
fl_draw_box(iscurrent ? FL_BORDER_BOX : FL_THIN_DOWN_BOX,
|
||||||
xx, yy, W, H, cellbg);
|
xx, yy, W, H, cellbg);
|
||||||
|
if (hgcn != NO_COLOR_SET) {
|
||||||
|
// draw the hashes, even if they are background
|
||||||
|
// since the background might be modified
|
||||||
|
fl_color(((Fl_Color *)(cursheet->palette))[hgcn]);
|
||||||
|
for (int hashoff = -H; hashoff < W; hashoff += 8) {
|
||||||
|
fl_line(xx+hashoff, yy, xx+hashoff+H, yy+H);
|
||||||
|
}
|
||||||
|
}
|
||||||
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);
|
||||||
fl_pop_clip();
|
fl_pop_clip();
|
||||||
@ -658,8 +667,13 @@ class MainWindow {open}
|
|||||||
MenuItem {} {
|
MenuItem {} {
|
||||||
label {&Background...}
|
label {&Background...}
|
||||||
user_data ADJUST_BACKGROUND
|
user_data ADJUST_BACKGROUND
|
||||||
xywh {0 0 36 21} labelsize 0 divider
|
xywh {0 0 36 21} labelsize 0
|
||||||
}
|
}
|
||||||
|
MenuItem {} {
|
||||||
|
label {&Hashing...}
|
||||||
|
user_data ADJUST_HASHING
|
||||||
|
xywh {0 0 36 21} labelsize 0 divider
|
||||||
|
}
|
||||||
menuitem dec {
|
menuitem dec {
|
||||||
label {&Decimal}
|
label {&Decimal}
|
||||||
user_data ADJUST_DECIMAL
|
user_data ADJUST_DECIMAL
|
||||||
|
Loading…
Reference in New Issue
Block a user