diff --git a/NEWS.md b/NEWS.md index dd88a5fd6..26bfd740d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,12 +12,13 @@ rearrangements of Notcurses. * `NCOPTION_RETAIN_CURSOR` has been removed. * `ncreader` now implements `NCREADER_OPTION_HORSCROLL` for horizontal scrolling. In addition, the following functions have been added: - * `int ncreader_move_left(struct ncreader* n);` - * `int ncreader_move_right(struct ncreader* n);` - * `int ncreader_move_up(struct ncreader* n);` - * `int ncreader_move_down(struct ncreader* n);` - * `int ncreader_write_egc(struct ncreader* n, const char* egc);` + * `int ncreader_move_left(struct ncreader* n)` + * `int ncreader_move_right(struct ncreader* n)` + * `int ncreader_move_up(struct ncreader* n)` + * `int ncreader_move_down(struct ncreader* n)` + * `int ncreader_write_egc(struct ncreader* n, const char* egc)`. * Added `ncplane_above()` and `notcurses_bottom()`. + * Added `ncplane_set_fchannel()` and `ncplane_set_bchannel()`. * 1.6.17 (2020-08-22) * `ncdirect_flush()` now takes a `const struct ncdirect*`. diff --git a/USAGE.md b/USAGE.md index 209ab815c..e5d553c81 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1404,6 +1404,10 @@ all implemented in terms of the lower-level [Channels API](#channels). uint64_t ncplane_channels(const struct ncplane* n); uint16_t ncplane_attr(const struct ncplane* n); +// Set an entire 32-bit channel of the plane 'n' +int ncplane_set_fchannel(struct ncplane* n, uint32_t channel); +int ncplane_set_bchannel(struct ncplane* n, uint32_t channel); + // Extract the 32-bit working background channel from an ncplane. static inline unsigned ncplane_bchannel(const struct ncplane* nc){ @@ -1470,8 +1474,8 @@ void ncplane_set_bg_rgb_clipped(struct ncplane* n, int r, int g, int b); void ncplane_set_fg_rgb_clipped(struct ncplane* n, int r, int g, int b); // Same, but with rgb assembled into a channel (i.e. lower 24 bits). -int ncplane_set_fg(struct ncplane* n, unsigned channel); -int ncplane_set_bg(struct ncplane* n, unsigned channel); +int ncplane_set_fg(struct ncplane* n, uint32_t channel); +int ncplane_set_bg(struct ncplane* n, uint32_t channel); // Use the default color for the foreground/background. void ncplane_set_fg_default(struct ncplane* n); @@ -1753,25 +1757,25 @@ implemented in terms of the lower-level [Channels API](#channels). ```c // Extract the 32-bit background channel from a cell. -static inline unsigned +static inline uint32_t cell_bchannel(const cell* cl){ return channels_bchannel(cl->channels); } // Extract the 32-bit foreground channel from a cell. -static inline unsigned +static inline uint32_t cell_fchannel(const cell* cl){ return channels_fchannel(cl->channels); } // Extract 24 bits of foreground RGB from 'cell', shifted to LSBs. -static inline unsigned +static inline uint32_t cell_fg(const cell* cl){ return channels_fg(cl->channels); } // Extract 24 bits of background RGB from 'cell', shifted to LSBs. -static inline unsigned +static inline uint32_t cell_bg(const cell* cl){ return channels_bg(cl->channels); } @@ -1789,13 +1793,13 @@ cell_bg_alpha(const cell* cl){ } // Extract 24 bits of foreground RGB from 'cell', split into subcell. -static inline unsigned +static inline uint32_t cell_fg_rgb(const cell* cl, unsigned* r, unsigned* g, unsigned* b){ return channels_fg_rgb(cl->channels, r, g, b); } // Extract 24 bits of background RGB from 'cell', split into subcell. -static inline unsigned +static inline uint32_t cell_bg_rgb(const cell* cl, unsigned* r, unsigned* g, unsigned* b){ return channels_bg_rgb(cl->channels, r, g, b); } @@ -2303,25 +2307,25 @@ and `cell` functionality is implemented in terms of this API. ```c // Extract the 8-bit red component from a 32-bit channel. static inline unsigned -channel_r(unsigned channel){ +channel_r(uint32_t channel){ return (channel & 0xff0000u) >> 16u; } // Extract the 8-bit green component from a 32-bit channel. static inline unsigned -channel_g(unsigned channel){ +channel_g(uint32_t channel){ return (channel & 0x00ff00u) >> 8u; } // Extract the 8-bit blue component from a 32-bit channel. static inline unsigned -channel_b(unsigned channel){ +channel_b(uint32_t channel){ return (channel & 0x0000ffu); } // Extract the three 8-bit R/G/B components from a 32-bit channel. static inline unsigned -channel_rgb(unsigned channel, unsigned* r, unsigned* g, unsigned* b){ +channel_rgb(uint32_t channel, unsigned* r, unsigned* g, unsigned* b){ *r = channel_r(channel); *g = channel_g(channel); *b = channel_b(channel); diff --git a/doc/man/man3/notcurses_cell.3.md b/doc/man/man3/notcurses_cell.3.md index 069d47b11..f389450b2 100644 --- a/doc/man/man3/notcurses_cell.3.md +++ b/doc/man/man3/notcurses_cell.3.md @@ -78,17 +78,17 @@ typedef struct cell { **char* cell_extract(const struct ncplane* n, const cell* c, uint16_t* stylemask, uint64_t* channels);** -**unsigned cell_bchannel(const cell* cl);** +**uint32_t cell_bchannel(const cell* cl);** -**unsigned cell_fchannel(const cell* cl);** +**uint32_t cell_fchannel(const cell* cl);** **uint64_t cell_set_bchannel(cell* cl, uint32_t channel);** **uint64_t cell_set_fchannel(cell* cl, uint32_t channel);** -**unsigned cell_fg(const cell* cl);** +**uint32_t cell_fg(const cell* cl);** -**unsigned cell_bg(const cell* cl);** +**uint32_t cell_bg(const cell* cl);** **unsigned cell_fg_alpha(const cell* cl);** diff --git a/doc/man/man3/notcurses_plane.3.md b/doc/man/man3/notcurses_plane.3.md index c37148028..f89639960 100644 --- a/doc/man/man3/notcurses_plane.3.md +++ b/doc/man/man3/notcurses_plane.3.md @@ -118,9 +118,9 @@ notcurses_plane - operations on ncplanes **void ncplane_set_bg_rgb_clipped(struct ncplane* n, int r, int g, int b);** -**int ncplane_set_fg(struct ncplane* n, unsigned channel);** +**int ncplane_set_fg(struct ncplane* n, uint32_t channel);** -**int ncplane_set_bg(struct ncplane* n, unsigned channel);** +**int ncplane_set_bg(struct ncplane* n, uint32_t channel);** **void ncplane_set_fg_default(struct ncplane* n);** diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 2b590a70f..becfc376f 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -146,25 +146,25 @@ mbswidth(const char* mbs){ // Extract the 8-bit red component from a 32-bit channel. static inline unsigned -channel_r(unsigned channel){ +channel_r(uint32_t channel){ return (channel & 0xff0000u) >> 16u; } // Extract the 8-bit green component from a 32-bit channel. static inline unsigned -channel_g(unsigned channel){ +channel_g(uint32_t channel){ return (channel & 0x00ff00u) >> 8u; } // Extract the 8-bit blue component from a 32-bit channel. static inline unsigned -channel_b(unsigned channel){ +channel_b(uint32_t channel){ return (channel & 0x0000ffu); } // Extract the three 8-bit R/G/B components from a 32-bit channel. static inline unsigned -channel_rgb(unsigned channel, unsigned* RESTRICT r, unsigned* RESTRICT g, +channel_rgb(uint32_t channel, unsigned* RESTRICT r, unsigned* RESTRICT g, unsigned* RESTRICT b){ *r = channel_r(channel); *g = channel_g(channel); @@ -175,7 +175,7 @@ channel_rgb(unsigned channel, unsigned* RESTRICT r, unsigned* RESTRICT g, // Set the three 8-bit components of a 32-bit channel, and mark it as not using // the default color. Retain the other bits unchanged. static inline int -channel_set_rgb(unsigned* channel, int r, int g, int b){ +channel_set_rgb(uint32_t* channel, int r, int g, int b){ if(r >= 256 || g >= 256 || b >= 256){ return -1; } @@ -1962,6 +1962,10 @@ ncplane_bg_rgb(const struct ncplane* n, unsigned* r, unsigned* g, unsigned* b){ return channels_bg_rgb(ncplane_channels(n), r, g, b); } +// Set an entire 32-bit channel of the plane +API uint64_t ncplane_set_fchannel(struct ncplane* n, uint32_t channel); +API uint64_t ncplane_set_bchannel(struct ncplane* n, uint32_t channel); + // Set the current fore/background color using RGB specifications. If the // terminal does not support directly-specified 3x8b cells (24-bit "TrueColor", // indicated by the "RGB" terminfo capability), the provided values will be @@ -2069,8 +2073,8 @@ cells_load_box(struct ncplane* n, uint32_t styles, uint64_t channels, } API int cells_rounded_box(struct ncplane* n, uint32_t styles, uint64_t channels, - cell* ul, cell* ur, cell* ll, cell* lr, - cell* hl, cell* vl); + cell* ul, cell* ur, cell* ll, + cell* lr, cell* hl, cell* vl); static inline int ncplane_rounded_box(struct ncplane* n, uint32_t styles, uint64_t channels, @@ -2122,8 +2126,8 @@ ncplane_rounded_box_sized(struct ncplane* n, uint32_t styles, uint64_t channels, } API int cells_double_box(struct ncplane* n, uint32_t styles, uint64_t channels, - cell* ul, cell* ur, cell* ll, cell* lr, - cell* hl, cell* vl); + cell* ul, cell* ur, cell* ll, + cell* lr, cell* hl, cell* vl); static inline int ncplane_double_box(struct ncplane* n, uint32_t styles, uint64_t channels, diff --git a/python/notcurses-pydemo b/python/notcurses-pydemo index 6605cd6d8..86a967cbd 100755 --- a/python/notcurses-pydemo +++ b/python/notcurses-pydemo @@ -1,7 +1,9 @@ #!/usr/bin/python3 import locale +import _cffi_backend from notcurses import notcurses +from _notcurses import lib, ffi def demo(): nc = notcurses.Notcurses() @@ -14,6 +16,7 @@ def demo(): b = 0x80 for y in range(dims[0]): for x in range(dims[1]): + lib.ncplane_set_fchannel(nc.stdplane(), r, g, b) nc.stdplane().setFgRGB(r, g, b) nc.stdplane().setBgRGB(b, r, g) nc.stdplane().putSimpleYX(y, x, ord('X')) diff --git a/python/src/notcurses/build_notcurses.py b/python/src/notcurses/build_notcurses.py index 5f33e2b13..9b2a2bf30 100644 --- a/python/src/notcurses/build_notcurses.py +++ b/python/src/notcurses/build_notcurses.py @@ -6,6 +6,8 @@ ffibuild.set_source( """ #include #include + static inline uint64_t ncplane_set_fchannel(struct ncplane* n, uint32_t channel){ return channels_set_fchannel(&n->channels, channel); } + static inline uint64_t ncplane_set_bchannel(struct ncplane* n, uint32_t channel){ return channels_set_bchannel(&n->channels, channel); } """, libraries=["notcurses"], ) diff --git a/python/src/notcurses/notcurses.py b/python/src/notcurses/notcurses.py index 5b82f1ccb..92547e563 100755 --- a/python/src/notcurses/notcurses.py +++ b/python/src/notcurses/notcurses.py @@ -29,23 +29,6 @@ CELL_FG_PALETTE = (CELL_BG_PALETTE << 32) CELL_BG_ALPHA_MASK = NCCHANNEL_ALPHA_MASK CELL_FG_ALPHA_MASK = (CELL_BG_ALPHA_MASK << 32) -def channel_r(channel): - return (channel & 0xff0000) >> 16; - -def channel_g(channel): - return (channel & 0x00ff00) >> 8; - -def channel_b(channel): - return (channel & 0x0000ff); - -def channel_rgb(channel): - return (channel_r(channel), channel_g(channel), channel_b(channel)) - -def channel_set_rgb(channel, r, g, b): - checkRGB(r, g, b) - c = (r << 16) | (g << 8) | b - return (channel & ~CELL_BG_RGB_MASK) | CELL_BGDEFAULT_MASK | c - def channels_fchannel(channels): return channels & 0xffffffff00000000 @@ -74,12 +57,6 @@ def channels_set_bg_rgb(channels, r, g, b): channel = channel_set_rgb(channel, r, g, b) return channels_set_bchannel(channels, channel); -def ncplane_fg_rgb(n, r, g, b): - return channels_fg_rgb(ncplane_channels(n)) - -def ncplane_bg_rgb(n, r, g, b): - return channels_bg_rgb(ncplane_channels(n)) - class NotcursesError(Exception): """Base class for notcurses exceptions.""" def __init__(self, message): diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index d95784c6c..010fbd37c 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -1109,6 +1109,14 @@ void ncplane_set_fg_default(ncplane* n){ channels_set_fg_default(&n->channels); } +uint64_t ncplane_set_fchannel(ncplane* n, uint32_t channel){ + return channels_set_fchannel(&n->channels, channel); +} + +uint64_t ncplane_set_bchannel(ncplane* n, uint32_t channel){ + return channels_set_bchannel(&n->channels, channel); +} + void ncplane_set_bg_default(ncplane* n){ channels_set_bg_default(&n->channels); } diff --git a/src/poc/reader.cpp b/src/poc/reader.cpp index ed9a71f44..ede16edb5 100644 --- a/src/poc/reader.cpp +++ b/src/poc/reader.cpp @@ -34,7 +34,7 @@ auto main(int argc, const char** argv) -> int { std::unique_ptr n = std::make_unique(nc.get_stdplane(&dimy, &dimx)); nc.get_term_dim(&dimy, &dimx); ncreader_options opts{}; - opts.physrows = dimy / 8; + opts.physrows = 2;//dimy / 8; opts.physcols = dimx / 2; opts.egc = "░"; opts.flags = horscroll ? NCREADER_OPTION_HORSCROLL : 0; @@ -50,23 +50,26 @@ auto main(int argc, const char** argv) -> int { ncinput ni; nc.render(); while(nc.getc(true, &ni) != (char32_t)-1){ - if(!ncreader_offer_input(nr, &ni)){ +fprintf(stderr, "ID: %04x %c %lc\n", ni.id, ni.ctrl ? 'C' : 'c', ni.id); + if(ni.ctrl && ni.id == 'L'){ + notcurses_refresh(nc, NULL, NULL); + }else if((ni.ctrl && ni.id == 'D') || ni.id == NCKEY_ENTER){ break; + }else if(ncreader_offer_input(nr, &ni)){ + int y, x; + struct ncplane* ncp = ncreader_plane(nr); + ncplane_cursor_yx(ncp, &y, &x); + nc.cursor_enable(y + 2, 2 + (x >= ncplane_dim_x(ncp) ? ncplane_dim_x(ncp) - 1 : x)); + int ncpy, ncpx; + ncplane_cursor_yx(ncp, &ncpy, &ncpx); + struct ncplane* tplane = ncplane_above(ncp); + int tgeomy, tgeomx, vgeomy, vgeomx; + ncplane_dim_yx(tplane, &tgeomy, &tgeomx); + ncplane_dim_yx(ncp, &vgeomy, &vgeomx); + (*n)->printf(0, 0, "Scroll: %lc Cursor: %03d/%03d Viewgeom: %03d/%03d Textgeom: %03d/%03d", + horscroll ? L'✔' : L'🗴', ncpy, ncpx, vgeomy, vgeomx, tgeomy, tgeomx); + nc.render(); } - int y, x; - struct ncplane* ncp = ncreader_plane(nr); - ncplane_cursor_yx(ncp, &y, &x); - nc.cursor_enable(y + 2, 2 + (x >= ncplane_dim_x(ncp) ? ncplane_dim_x(ncp) - 1 : x)); - int ncpy, ncpx; - ncplane_cursor_yx(ncp, &ncpy, &ncpx); - struct ncplane* tplane = ncplane_above(ncp); - int tgeomy, tgeomx, vgeomy, vgeomx; - ncplane_dim_yx(tplane, &tgeomy, &tgeomx); - ncplane_dim_yx(ncp, &vgeomy, &vgeomx); - (*n)->printf(0, 0, "Scroll: %lc Cursor: %d/%d Viewgeom: %d/%d Textgeom: %d/%d", - horscroll ? L'✔' : L'🗴', - ncpy, ncpx, vgeomy, vgeomx, tgeomy, tgeomx); - nc.render(); } nc.render(); char* contents;