Further prepare for color rendering; highlight row and column

Now palettes are allocated and deallocated in fteapot as well as teapot;
  both executables have some color rendering, with fteapot using the cell
  foreground and background (there's just no way to set them at the moment).
  teapot is so far only using color in the header.
  Implements #39.
This commit is contained in:
Glen Whitney 2019-08-02 23:21:58 -04:00
parent 2e0a3a480c
commit 91b5ae7e1f
5 changed files with 110 additions and 22 deletions

View File

@ -18,6 +18,8 @@ void initcellcontents(Cell *fresh)
fresh->shadowed=0; fresh->shadowed=0;
fresh->bold=0; fresh->bold=0;
fresh->underline=0; fresh->underline=0;
fresh->foreground = DEF_FG_NUM;
fresh->background = DEF_BG_NUM;
fresh->scientific=DEF_SCIENTIFIC; fresh->scientific=DEF_SCIENTIFIC;
fresh->value.type=EMPTY; fresh->value.type=EMPTY;
fresh->resvalue.type=EMPTY; fresh->resvalue.type=EMPTY;
@ -58,6 +60,18 @@ bool isbold(const Cell* cell)
return (cell != NULLCELL) && cell->bold; return (cell != NULLCELL) && cell->bold;
} }
/* cell_bg -- background of cell */
ColorNum cell_bg(const Cell* cell)
{
return cell == NULLCELL ? DEF_BG_NUM : cell->background;
}
/* cell_fg -- foreground of cell */
ColorNum cell_fg(const Cell* cell)
{
return cell == NULLCELL ? DEF_FG_NUM : cell->foreground;
}
/* isunderline -- is cell underlined? */ /* isunderline -- is cell underlined? */
bool underlined(const Cell *cell) bool underlined(const Cell *cell)
{ {

View File

@ -45,6 +45,8 @@ Adjust getadjust(const Cell *cell);
bool shadowed(const Cell *cell); bool shadowed(const Cell *cell);
bool isbold(const Cell *cell); bool isbold(const Cell *cell);
bool underlined(const Cell *cell); bool underlined(const Cell *cell);
ColorNum cell_bg(const Cell *cell);
ColorNum cell_fg(const Cell *cell);
bool locked(const Cell *cell); bool locked(const Cell *cell);
bool transparent(const Cell *cell); bool transparent(const Cell *cell);
bool ignored(const Cell *cell); bool ignored(const Cell *cell);

View File

@ -12,6 +12,12 @@
/* default is no scientific notation for numbers */ /* default is no scientific notation for numbers */
#define DEF_SCIENTIFIC 0 #define DEF_SCIENTIFIC 0
/* Default ColorNum for foreground */
#define DEF_FG_NUM 0
/* Default ColorNum for background */
#define DEF_BG_NUM 16
/* character attribute for cell and row numbers */ /* character attribute for cell and row numbers */
#define DEF_NUMBER A_BOLD #define DEF_NUMBER A_BOLD

View File

@ -359,7 +359,6 @@ void display_main(Sheet *cursheet)
} while (k == K_INVALID || !do_sheetcmd(cursheet,k,0) || doanyway(cursheet,_("Sheet modified, leave anyway?"))!=1); } while (k == K_INVALID || !do_sheetcmd(cursheet,k,0) || doanyway(cursheet,_("Sheet modified, leave anyway?"))!=1);
} }
#define TEAPOT_WHITE 16
#define CHANNEL_MAX 1000 #define CHANNEL_MAX 1000
typedef short CursesColor[3]; typedef short CursesColor[3];
@ -367,8 +366,8 @@ void display_init(Sheet *cursheet, int always_redraw)
{ {
initscr(); initscr();
start_color(); start_color();
init_color(TEAPOT_WHITE, CHANNEL_MAX, CHANNEL_MAX, CHANNEL_MAX); init_color(DEF_BG_NUM, CHANNEL_MAX, CHANNEL_MAX, CHANNEL_MAX);
assume_default_colors(COLOR_BLACK, TEAPOT_WHITE); assume_default_colors(COLOR_BLACK, DEF_BG_NUM);
if (debug_level > 1) if (debug_level > 1)
printf("Terminal has colors: %d, #colors:%d, #pairs:%d", printf("Terminal has colors: %d, #colors:%d, #pairs:%d",
has_colors(), COLORS, COLOR_PAIRS); has_colors(), COLORS, COLOR_PAIRS);
@ -383,11 +382,11 @@ void display_init(Sheet *cursheet, int always_redraw)
if (always_redraw) typeahead(-1); if (always_redraw) typeahead(-1);
#endif #endif
/* allocate and initialize the palette */ /* allocate and initialize the palette */
cursheet->max_colors = COLORS; if (COLORS < cursheet->max_colors) { cursheet->max_colors = COLORS; }
cursheet->palette = (void *)malloc(COLORS*sizeof(CursesColor)); cursheet->palette = (void *)malloc(cursheet->max_colors*sizeof(CursesColor));
memset(cursheet->palette, '\0', COLORS*sizeof(CursesColor)); memset(cursheet->palette, '\0', cursheet->max_colors*sizeof(CursesColor));
CursesColor *palt = (CursesColor *)(cursheet->palette); CursesColor *palt = (CursesColor *)(cursheet->palette);
for (size_t i = 0; i <= TEAPOT_WHITE; ++i) for (size_t i = 0; i <= DEF_BG_NUM; ++i)
(void)color_content(i, &(palt[i][0]), &(palt[i][1]), &(palt[i][2])); (void)color_content(i, &(palt[i][0]), &(palt[i][1]), &(palt[i][2]));
} }
@ -453,15 +452,19 @@ void redraw_sheet(Sheet *sheet)
} }
} while (again); } while (again);
unsigned short curcp = 1;
init_pair(curcp, DEF_FG_NUM, COLOR_YELLOW);
if (header) { if (header) {
(void)wattron(stdscr,DEF_NUMBER); (void)wattron(stdscr,DEF_NUMBER);
/* draw x numbers */ /* draw x numbers */
for (width=4; width < sheet->maxx; ++width) for (width=4; width < sheet->maxx; ++width)
mvwaddch(stdscr, 0+sheet->oriy, sheet->orix+width, mvwaddch(stdscr, 0+sheet->oriy, sheet->orix+width,
(chtype)(unsigned char)' '); (chtype)(unsigned char)' ');
for (width=4, x=sheet->offx; width<sheet->maxx; width+=col,++x) for (width=4, x=sheet->offx; width<sheet->maxx; width+=col,++x)
{ {
unsigned short usecp = 0;
if (x == sheet->cur[X]) usecp = curcp;
col = columnwidth(sheet, x, sheet->cur[Z]); col = columnwidth(sheet, x, sheet->cur[Z]);
if (bufsz<(size_t)(col*UTF8SZ+1)) buf=realloc(buf,bufsz=(size_t)(col*UTF8SZ+1)); if (bufsz<(size_t)(col*UTF8SZ+1)) buf=realloc(buf,bufsz=(size_t)(col*UTF8SZ+1));
snprintf(buf,bufsz,"%d",x); snprintf(buf,bufsz,"%d",x);
@ -472,18 +475,26 @@ void redraw_sheet(Sheet *sheet)
adjust(CENTER,buf,(size_t)col); adjust(CENTER,buf,(size_t)col);
assert(sheet->maxx>=width); assert(sheet->maxx>=width);
if ((sheet->maxx-width)<col) buf[sheet->maxx-width]='\0'; if ((sheet->maxx-width)<col) buf[sheet->maxx-width]='\0';
wcolor_set(stdscr, usecp, NULL);
mvwaddstr(stdscr,sheet->oriy,sheet->orix+width,buf); mvwaddstr(stdscr,sheet->oriy,sheet->orix+width,buf);
wcolor_set(stdscr, 0, NULL);
} }
/* draw y numbers */ /* draw y numbers */
for (y=1; y<(sheet->maxy-1); ++y) (void)mvwprintw(stdscr,sheet->oriy+y,sheet->orix,"%-4d",y-1+sheet->offy); for (y=1; y<(sheet->maxy-1); ++y) {
unsigned short usecp = 0;
int realy = y-1+sheet->offy;
if (realy == sheet->cur[Y]) usecp = curcp;
wcolor_set(stdscr, usecp, NULL);
(void)mvwprintw(stdscr,sheet->oriy+y,sheet->orix,"%-4d",y-1+sheet->offy);
wcolor_set(stdscr, 0, NULL);
}
(void)wattroff(stdscr,DEF_NUMBER); (void)wattroff(stdscr,DEF_NUMBER);
/* draw z number */ /* draw z number */
(void)mvwprintw(stdscr, sheet->oriy, sheet->orix, "%3d", sheet->cur[Z]); (void)mvwprintw(stdscr, sheet->oriy, sheet->orix, "%3d", sheet->cur[Z]);
} }
++curcp;
/* draw elements */ /* draw elements */
for (y=header; y<sheet->maxy-1; ++y) for (y=header; y<sheet->maxy-1; ++y)
for (width = 4*header, x = sheet->offx; for (width = 4*header, x = sheet->offx;

View File

@ -14,6 +14,8 @@ decl {\#include <stdint.h>} {private global}
decl {\#include <limits.h>} {private global} decl {\#include <limits.h>} {private global}
decl {\#include <fcntl.h>} {private global} decl {\#include <fcntl.h>} {private global}
decl {\#define SKIPDEFCOLS(c) while (c == DEF_BG_NUM || c == DEF_FG_NUM) ++c}
{private global}
decl {\#define shadow _shadow} {private global} decl {\#define shadow _shadow} {private global}
decl {\#define transparent _transparent} {private global} decl {\#define transparent _transparent} {private global}
decl {\#define MenuChoice _MenuChoice} {private global} decl {\#define MenuChoice _MenuChoice} {private global}
@ -31,8 +33,11 @@ decl {\#undef MenuChoice} {private global}
decl {\#undef Cell} {private global} decl {\#undef Cell} {private global}
decl {\#include "tpt_choose.h"} {private global} decl {\#include "tpt_choose.h"} {private global}
decl {\#include "default.h"} {private global}
decl {\#include "misc.h"} {private global} decl {\#include "misc.h"} {private global}
decl {Fl_Color tpt_selection_version(Fl_Color base);} {private global}
class TeapotTable {open : {public Fl_Table}} class TeapotTable {open : {public Fl_Table}}
{ {
decl {Sheet *cursheet;} {protected local} decl {Sheet *cursheet;} {protected local}
@ -96,26 +101,32 @@ class TeapotTable {open : {public Fl_Table}}
if (Fl::event_button1()) update_sheet(); if (Fl::event_button1()) update_sheet();
break; break;
case CONTEXT_COL_HEADER: case CONTEXT_COL_HEADER: {
fl_font(FL_HELVETICA | FL_BOLD, 14); fl_font(FL_HELVETICA | FL_BOLD, 14);
fl_push_clip(xx, yy, W, H); fl_push_clip(xx, yy, W, H);
fl_draw_box(FL_THIN_UP_BOX, xx, yy, W, H, col_header_color()); 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);
fl_color(FL_FOREGROUND_COLOR); fl_color(FL_FOREGROUND_COLOR);
sprintf(s, "%d", C); sprintf(s, "%d", C);
fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER); fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER);
fl_pop_clip(); fl_pop_clip();
return; return;
}
case CONTEXT_ROW_HEADER: case CONTEXT_ROW_HEADER: {
fl_font(FL_HELVETICA | FL_BOLD, 14); fl_font(FL_HELVETICA | FL_BOLD, 14);
fl_push_clip(xx, yy, W, H); fl_push_clip(xx, yy, W, H);
fl_draw_box(FL_THIN_UP_BOX, xx, yy, W, H, row_header_color()); 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);
fl_color(FL_FOREGROUND_COLOR); fl_color(FL_FOREGROUND_COLOR);
sprintf(s, "%d", R); sprintf(s, "%d", R);
fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER); fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER);
fl_pop_clip(); fl_pop_clip();
return; return;
}
case CONTEXT_CELL: { case CONTEXT_CELL: {
while (SHADOWEDC(cursheet, C, R, cursheet->cur[Z])) while (SHADOWEDC(cursheet, C, R, cursheet->cur[Z]))
xx -= W = col_width(--C); xx -= W = col_width(--C);
@ -130,18 +141,23 @@ class TeapotTable {open : {public Fl_Table}}
test[X] = C; test[Y] = R; test[Z] = cursheet->cur[Z]; test[X] = C; test[Y] = R; test[Z] = cursheet->cur[Z];
if (ms != UNMARKED) if (ms != UNMARKED)
selected = loc_in_box(test, cursheet->mark1, cursheet->mark2); selected = loc_in_box(test, cursheet->mark1, cursheet->mark2);
bool iscurrent = C == cursheet->cur[X] && R == cursheet->cur[Y]; bool iscurrent = (C == cursheet->cur[X] && R == cursheet->cur[Y]);
Cell *cell = safe_cell_at(cursheet, test);
Fl_Color cellbg =
((Fl_Color *)(cursheet->palette))[cell_bg(cell)];
if (selected) cellbg = tpt_selection_version(cellbg);
if (!LOC_WITHIN(cursheet,test))
cellbg = fl_color_average(cellbg, FL_BLACK, 0.97);
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, xx, yy, W, H, cellbg);
selected ? FL_SELECTION_COLOR : FL_BACKGROUND2_COLOR);
if (Fl::focus() == this && iscurrent) if (Fl::focus() == this && iscurrent)
draw_focus(FL_BORDER_BOX, xx, yy, W, H); draw_focus(FL_BORDER_BOX, xx, yy, W, H);
fl_pop_clip(); fl_pop_clip();
Cell *cell = safe_cell_at(cursheet, test);
fl_push_clip(xx+3, yy+3, W-6, H-6); fl_push_clip(xx+3, yy+3, W-6, H-6);
fl_color(FL_FOREGROUND_COLOR); Fl_Color cellfg =
((Fl_Color *)(cursheet->palette))[cell_fg(cell)];
fl_color(cellfg);
fl_font(FL_HELVETICA | (isbold(cell) ? FL_BOLD : 0), 14); fl_font(FL_HELVETICA | (isbold(cell) ? FL_BOLD : 0), 14);
printvalue(s, sizeof(s), 0, 0, getscientific(cell), printvalue(s, sizeof(s), 0, 0, getscientific(cell),
@ -740,6 +756,12 @@ class MainWindow {open}
} }
# End of class MainWindow # End of class MainWindow
Function
{tpt_selection_version(Fl_Color base)} {open return_type {Fl_Color}} {code
{
return fl_color_average(base, FL_SELECTION_COLOR, 0.85);
} {} }
Function Function
{line_file(const char *file, const char *pattern, const char *title, {line_file(const char *file, const char *pattern, const char *title,
int create)} {open C return_type {const char *}} {code int create)} {open C return_type {const char *}} {code
@ -889,11 +911,44 @@ Function
resize(sheet, 1, 1, 1); resize(sheet, 1, 1, 1);
sheet->changed = ch; sheet->changed = ch;
new MainWindow(sheet); new MainWindow(sheet);
/* allocate and initialize the palette */
Fl_Color* palt = new Fl_Color[sheet->max_colors];
sheet->palette = (void *) palt;
palt[DEF_FG_NUM] = FL_FOREGROUND_COLOR;
palt[DEF_BG_NUM] = FL_BACKGROUND2_COLOR;
ColorNum c = 0; SKIPDEFCOLS(c);
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); }
} {} } } {} }
Function Function
{display_end(Sheet* sheet)} {C return_type void} {code {display_end(Sheet* sheet)} {C return_type void} {code
{ {
ColorNum* palt = (ColorNum *)sheet->palette;
delete [] palt;
} {} } } {} }
Function Function