From 91b5ae7e1f4cb7e8a556b2384d37029811510185 Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Fri, 2 Aug 2019 23:21:58 -0400 Subject: [PATCH] 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. --- src/common/cell.c | 14 ++++++++ src/common/cell.h | 2 ++ src/common/default.h | 6 ++++ src/display.c | 33 ++++++++++++------- src/fteapot.fl | 77 +++++++++++++++++++++++++++++++++++++------- 5 files changed, 110 insertions(+), 22 deletions(-) diff --git a/src/common/cell.c b/src/common/cell.c index 828dce6..efb0c8e 100644 --- a/src/common/cell.c +++ b/src/common/cell.c @@ -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) { diff --git a/src/common/cell.h b/src/common/cell.h index 80fd520..b3a267c 100644 --- a/src/common/cell.h +++ b/src/common/cell.h @@ -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); diff --git a/src/common/default.h b/src/common/default.h index 90777e0..332109b 100644 --- a/src/common/default.h +++ b/src/common/default.h @@ -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 diff --git a/src/display.c b/src/display.c index 5c17e8e..736a19b 100644 --- a/src/display.c +++ b/src/display.c @@ -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; widthmaxx; 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)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; ymaxy-1; ++y) for (width = 4*header, x = sheet->offx; diff --git a/src/fteapot.fl b/src/fteapot.fl index 72340b7..1907bb1 100644 --- a/src/fteapot.fl +++ b/src/fteapot.fl @@ -14,6 +14,8 @@ decl {\#include } {private global} decl {\#include } {private global} decl {\#include } {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