feat: Add hashing color for cells (#93)

Co-authored-by: Glen Whitney <glen@studioinfinity.org>
Reviewed-on: #93
This commit is contained in:
Glen Whitney 2023-07-26 03:21:43 +00:00
parent 8db9c30825
commit 00859ecbd2
11 changed files with 122 additions and 27 deletions

2
NEWS
View File

@ -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
change; you may need to wrap comparisons in int() if you are using the result
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 Addition of an if() conditional operator.
o Addition of a find() macro to search for a cell satisfying a condition.

View File

@ -167,8 +167,8 @@ Copyright, Contributors and License
teapot
\noun default
(Table Editor And Planner, Or: Teapot), is copyrighted 19952006 by Michael
Haardt, and 20092010 by Jörg Walter, and 2019 by Glen Whitney, and is
licensed under the Gnu General Public License v3 or later.
Haardt, and 20092010 by Jörg Walter, and 2019-2023 by Glen Whitney, and
is licensed under the Gnu General Public License v3 or later.
\end_layout
\begin_layout Standard
@ -3994,9 +3994,13 @@ foreground
\family sans
background
\family default
() colors used to display a cell may be set.
(Currently this only affects screen display.) The value of these attributes
is a positive integer which acts as an index into the
() colors used to display a cell may be set and the
\family sans
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
\end_inset
@ -8272,6 +8276,37 @@ is
for example.
\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
hexact used as a keyword to the string() function; listed here to record
that this identifier may not be used as a cell label.

View File

@ -1089,6 +1089,7 @@ static Token aspect_func(FunctionIdentifier self, int argc, const Token argv[])
{
ColorAspect ca = FOREGROUND;
if (self == FUNC_BACKGROUND) ca = BACKGROUND;
if (self == FUNC_HASHING) ca = HASHING;
Token result;
if (argc != 1 || argv[0].type != INT) {
const char *templ = _("Usage: %s(int)");
@ -1839,6 +1840,7 @@ Tfunc tfunc[]=
[FUNC_PRECISION] = { "precision", precision_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_FOREGROUND] = { "foreground", 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_FLOATFMT] = { "floatfmt", floatfmt_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_SHADOWED] = { "shadowed", shadowed_func, PREFIX_FUNC, FUNCT, 0 },

View File

@ -44,6 +44,7 @@ typedef enum
FUNC_FUNCALL, FUNC_LIDENT, FUNC_LOCATION, FUNC_NUMBER, FUNC_OPERATOR,
FUNC_IS, FUNC_FIND, FUNC_PRECISION, FUNC_FOREGROUND, FUNC_BACKGROUND,
FUNC_HASHING,
FUNC_JUSTIFY, FUNC_FLOATFMT, FUNC_SHADOWED, FUNC_TRANSPARENT, FUNC_BOLD,
FUNC_UNDERLINE, FUNC_CENTER, FUNC_STYLE,

View File

@ -390,9 +390,8 @@ static void do_attribute(Sheet *cursheet, Key action)
}
/*}}}*/
/* Set a color */ /*{{{*/
case ADJUST_BACKGROUND:
ca = BACKGROUND;
/* FALL THROUGH */
case ADJUST_HASHING: ++ca; /* FALL THROUGH */
case ADJUST_BACKGROUND: ++ca; /* FALL THROUGH */
case ADJUST_FOREGROUND: {
int n = fs.aspect[ca];
const char* prompt = _("%s for block:");
@ -1372,6 +1371,7 @@ int do_sheetcmd(Sheet *cursheet, Key c, bool moveonly)
case ADJUST_UNDERLINE:
case ADJUST_FOREGROUND:
case ADJUST_BACKGROUND:
case ADJUST_HASHING:
case ADJUST_TRANSPARENT:
case ADJUST_LABEL:
case ADJUST_LOCK:

View File

@ -96,7 +96,8 @@ typedef enum
K_EDIT_STYLE_EXPR = -64,
ADJUST_DIM = -65,
ADJUST_ITALIC = -66,
K_ROWHEIGHT = -67
K_ROWHEIGHT = -67,
ADJUST_HASHING = -68
} Key;
extern int do_sheetcmd(Sheet *cursheet, Key c, bool moveonly);

View File

@ -16,10 +16,13 @@ const char *FloatFormat_Name[] =
const char FloatFormat_Char[] = "Ndsch";
const char *ColorAspect_Name[] =
{ [FOREGROUND] = "foreground", [BACKGROUND] = "background"
{ [FOREGROUND] = "foreground", [BACKGROUND] = "background",
[HASHING] = "hashing"
};
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 */
void clearstyle(Style* s) {

View File

@ -32,7 +32,9 @@ typedef unsigned char ColorNum;
#define MAX_MAX_COLORS UCHAR_MAX
#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 ColorNum DefaultCN[];

View File

@ -112,7 +112,9 @@ static int do_attribute(Sheet *cursheet)
{
const char *typemenu[] =
{ _("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))
{
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 3: c = ADJUST_FOREGROUND; break;
case 4: c = ADJUST_BACKGROUND; break;
case 5: c = ADJUST_HASHING; break;
default: assert(0);
}
break;
@ -566,18 +569,33 @@ void redraw_sheet(Sheet *sheet)
}
else realsize = size;
ms = getmarkstate(sheet);
short usecp = 0;
short usecp = -1;
short hashcp = -1;
ColorNum fg = sc.aspect[FOREGROUND];
if (fg == NO_COLOR_SET) fg = DefaultCN[FOREGROUND];
ColorNum bg = sc.aspect[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;
pair_content(usecp, &pfg, &pbg);
if (fg == pfg && bg == pbg) break;
++usecp;
pair_content(trycp, &pfg, &pbg);
if (fg != pfg) continue;
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);
bool invert =
(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.bold) wattron(stdscr, A_BOLD);
if (sc.underline) wattron(stdscr, A_UNDERLINE);
short nextcp = hashcp;
if (hashcp == usecp) {
(void)mvwaddstr(stdscr, (int)(height + sheet->oriy),
(int)(width + sheet->orix),
buf+cutoff);
for (fill=mbslen(buf+cutoff); fill<realsize; ++fill)
} 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)' ');
}
for (RowHgtT extra = 1; extra < rows; ++extra) {
mvwaddstr(stdscr,
(int)(height + extra + sheet->oriy),

View File

@ -171,6 +171,7 @@ class TeapotTable {open : {public Fl_Table}}
bool iscurrent = (C == cursheet->cur[X] && R == cursheet->cur[Y]);
Style sc = getstyle(cursheet, test);
ColorNum bgcn = sc.aspect[BACKGROUND];
ColorNum hgcn = sc.aspect[HASHING];
if (bgcn == NO_COLOR_SET) bgcn = DefaultCN[BACKGROUND];
Fl_Color cellbg = ((Fl_Color *)(cursheet->palette))[bgcn];
if (selected) cellbg = tpt_selection_version(cellbg);
@ -178,6 +179,14 @@ class TeapotTable {open : {public Fl_Table}}
cellbg = fl_color_average(cellbg, FL_BLACK, 0.97f);
fl_draw_box(iscurrent ? FL_BORDER_BOX : FL_THIN_DOWN_BOX,
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)
draw_focus(FL_BORDER_BOX, xx, yy, W, H);
fl_pop_clip();
@ -658,6 +667,11 @@ class MainWindow {open}
MenuItem {} {
label {&Background...}
user_data ADJUST_BACKGROUND
xywh {0 0 36 21} labelsize 0
}
MenuItem {} {
label {&Hashing...}
user_data ADJUST_HASHING
xywh {0 0 36 21} labelsize 0 divider
}
menuitem dec {

View File

@ -84,7 +84,7 @@ Copyright (C) 2009-2012
J\(:org Walter
.Me
.Pp
Copyright (C) 2019
Copyright (C) 2019-2023
.Mt glen@studioinfinity.org
Glen Whitney
.Me