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->bold=0;
fresh->underline=0;
fresh->foreground = DEF_FG_NUM;
fresh->background = DEF_BG_NUM;
fresh->scientific=DEF_SCIENTIFIC;
fresh->value.type=EMPTY;
fresh->resvalue.type=EMPTY;
@ -58,6 +60,18 @@ bool isbold(const Cell* cell)
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? */
bool underlined(const Cell *cell)
{

View File

@ -45,6 +45,8 @@ Adjust getadjust(const Cell *cell);
bool shadowed(const Cell *cell);
bool isbold(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 transparent(const Cell *cell);
bool ignored(const Cell *cell);

View File

@ -12,6 +12,12 @@
/* default is no scientific notation for numbers */
#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 */
#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);
}
#define TEAPOT_WHITE 16
#define CHANNEL_MAX 1000
typedef short CursesColor[3];
@ -367,8 +366,8 @@ void display_init(Sheet *cursheet, int always_redraw)
{
initscr();
start_color();
init_color(TEAPOT_WHITE, CHANNEL_MAX, CHANNEL_MAX, CHANNEL_MAX);
assume_default_colors(COLOR_BLACK, TEAPOT_WHITE);
init_color(DEF_BG_NUM, CHANNEL_MAX, CHANNEL_MAX, CHANNEL_MAX);
assume_default_colors(COLOR_BLACK, DEF_BG_NUM);
if (debug_level > 1)
printf("Terminal has colors: %d, #colors:%d, #pairs:%d",
has_colors(), COLORS, COLOR_PAIRS);
@ -383,11 +382,11 @@ void display_init(Sheet *cursheet, int always_redraw)
if (always_redraw) typeahead(-1);
#endif
/* allocate and initialize the palette */
cursheet->max_colors = COLORS;
cursheet->palette = (void *)malloc(COLORS*sizeof(CursesColor));
memset(cursheet->palette, '\0', COLORS*sizeof(CursesColor));
if (COLORS < cursheet->max_colors) { cursheet->max_colors = COLORS; }
cursheet->palette = (void *)malloc(cursheet->max_colors*sizeof(CursesColor));
memset(cursheet->palette, '\0', cursheet->max_colors*sizeof(CursesColor));
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]));
}
@ -453,15 +452,19 @@ void redraw_sheet(Sheet *sheet)
}
} while (again);
unsigned short curcp = 1;
init_pair(curcp, DEF_FG_NUM, COLOR_YELLOW);
if (header) {
(void)wattron(stdscr,DEF_NUMBER);
/* draw x numbers */
for (width=4; width < sheet->maxx; ++width)
mvwaddch(stdscr, 0+sheet->oriy, sheet->orix+width,
(chtype)(unsigned char)' ');
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]);
if (bufsz<(size_t)(col*UTF8SZ+1)) buf=realloc(buf,bufsz=(size_t)(col*UTF8SZ+1));
snprintf(buf,bufsz,"%d",x);
@ -472,18 +475,26 @@ void redraw_sheet(Sheet *sheet)
adjust(CENTER,buf,(size_t)col);
assert(sheet->maxx>=width);
if ((sheet->maxx-width)<col) buf[sheet->maxx-width]='\0';
wcolor_set(stdscr, usecp, NULL);
mvwaddstr(stdscr,sheet->oriy,sheet->orix+width,buf);
wcolor_set(stdscr, 0, NULL);
}
/* 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);
/* draw z number */
(void)mvwprintw(stdscr, sheet->oriy, sheet->orix, "%3d", sheet->cur[Z]);
}
++curcp;
/* draw elements */
for (y=header; y<sheet->maxy-1; ++y)
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 <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 transparent _transparent} {private global}
decl {\#define MenuChoice _MenuChoice} {private global}
@ -31,8 +33,11 @@ decl {\#undef MenuChoice} {private global}
decl {\#undef Cell} {private global}
decl {\#include "tpt_choose.h"} {private global}
decl {\#include "default.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}}
{
decl {Sheet *cursheet;} {protected local}
@ -96,26 +101,32 @@ class TeapotTable {open : {public Fl_Table}}
if (Fl::event_button1()) update_sheet();
break;
case CONTEXT_COL_HEADER:
case CONTEXT_COL_HEADER: {
fl_font(FL_HELVETICA | FL_BOLD, 14);
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);
sprintf(s, "%d", C);
fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER);
fl_pop_clip();
return;
}
case CONTEXT_ROW_HEADER:
case CONTEXT_ROW_HEADER: {
fl_font(FL_HELVETICA | FL_BOLD, 14);
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);
sprintf(s, "%d", R);
fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER);
fl_pop_clip();
return;
}
case CONTEXT_CELL: {
while (SHADOWEDC(cursheet, C, R, cursheet->cur[Z]))
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];
if (ms != UNMARKED)
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,
xx, yy, W, H,
selected ? FL_SELECTION_COLOR : FL_BACKGROUND2_COLOR);
xx, yy, W, H, cellbg);
if (Fl::focus() == this && iscurrent)
draw_focus(FL_BORDER_BOX, xx, yy, W, H);
fl_pop_clip();
Cell *cell = safe_cell_at(cursheet, test);
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);
printvalue(s, sizeof(s), 0, 0, getscientific(cell),
@ -740,6 +756,12 @@ class MainWindow {open}
}
# 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
{line_file(const char *file, const char *pattern, const char *title,
int create)} {open C return_type {const char *}} {code
@ -889,11 +911,44 @@ Function
resize(sheet, 1, 1, 1);
sheet->changed = ch;
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
{display_end(Sheet* sheet)} {C return_type void} {code
{
ColorNum* palt = (ColorNum *)sheet->palette;
delete [] palt;
} {} }
Function