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
|
||||
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.
|
||||
|
@ -167,8 +167,8 @@ Copyright, Contributors and License
|
||||
teapot
|
||||
\noun default
|
||||
(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
|
||||
licensed under the Gnu General Public License v3 or later.
|
||||
Haardt, and 2009–2010 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.
|
||||
|
@ -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 },
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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[];
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user