From ccb3c137b328f548c7ebdc81f27e3a97aece4752 Mon Sep 17 00:00:00 2001 From: nick black Date: Tue, 26 Nov 2019 21:29:56 -0500 Subject: [PATCH] add ncplane_box_sized() and ncplane_rounded_box_cells() --- include/notcurses.h | 29 ++++++++++++++++++++++----- src/lib/notcurses.c | 48 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 61 insertions(+), 16 deletions(-) diff --git a/include/notcurses.h b/include/notcurses.h index 0d2243ea2..767d2c55f 100644 --- a/include/notcurses.h +++ b/include/notcurses.h @@ -187,15 +187,28 @@ int ncplane_vprintf(struct ncplane* n, const char* format, va_list ap); int ncplane_hline(struct ncplane* n, const cell* c, int len); int ncplane_vline(struct ncplane* n, const cell* c, int len); -// Draw a box with its upper-left corner at the current cursor position, having -// dimensions |ylen| x |xlen|. The 6 cells provided are used to draw the +// Draw a box with its upper-left corner at the current cursor position, and its +// lower-right corner at 'ystop'x'xstop'. The 6 cells provided are used to draw the // upper-left, ur, ll, and lr corners, then the horizontal and vertical lines. int ncplane_box(struct ncplane* n, const cell* ul, const cell* ur, const cell* ll, const cell* lr, const cell* hline, - const cell* vline, int ylen, int xlen); + const cell* vline, int ystop, int xstop); -// Erase all content in the ncplane, resetting all attributes to normal, all -// colors to -1, and all cells to undrawn. +// Draw a box with its upper-left corner at the current cursor position, having +// dimensions 'ylen'x'xlen'. See ncplane_box() for more information. The +// minimum box size is 2x2, and it cannot be drawn off-screen. +static inline int +ncplane_box_sized(struct ncplane* n, const cell* ul, const cell* ur, + const cell* ll, const cell* lr, const cell* hline, + const cell* vline, int ylen, int xlen){ + int y, x; + ncplane_cursor_yx(n, &y, &x); + return ncplane_box(n, ul, ur, ll, lr, hline, vline, y + ylen - 1, x + xlen - 1); +} + +// Erase every cell in the ncplane, resetting all attributes to normal, all +// colors to the default color, and all cells to undrawn. All cells associated +// with this ncplane is invalidated, and must not be used after the call. void ncplane_erase(struct ncplane* n); // Set the current fore/background color using RGB specifications. If the @@ -356,6 +369,12 @@ cell_wide_p(const cell* c){ return (c->channels & CELL_WIDEASIAN_MASK); } +// load up six cells with the EGCs necessary to draw a light, rounded box. +// returns 0 on success, -1 on error. on error, any cells this function might +// have loaded before the error are cell_release()d. +int ncplane_rounded_box_cells(struct ncplane* n, cell* ul, cell* ur, cell* ll, + cell* lr, cell* hl, cell* vl); + // multimedia functionality int notcurses_visual_open(struct notcurses* nc, const char* filename); diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 4a959a11c..e4d2f06ec 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -822,21 +822,24 @@ int ncplane_vline(ncplane* n, const cell* c, int len){ int ncplane_box(ncplane* n, const cell* ul, const cell* ur, const cell* ll, const cell* lr, const cell* hl, - const cell* vl, int ylen, int xlen){ - if(xlen < 2 || ylen < 2){ - return -1; - } + const cell* vl, int ystop, int xstop){ int yoff, xoff, ymax, xmax; ncplane_cursor_yx(n, &yoff, &xoff); + if(ystop < yoff + 1){ + return -1; + } + if(xstop < xoff + 1){ + return -1; + } ncplane_dimyx(n, &ymax, &xmax); - if(xmax - xoff < xlen || ymax - yoff < ylen){ + if(xstop >= xmax || ystop >= ymax){ return -1; } if(ncplane_putc(n, ul) < 0){ return -1; } - if(xlen > 2){ - if(ncplane_hline(n, hl, xlen - 2) < 0){ + if(xstop - xoff >= 2){ + if(ncplane_hline(n, hl, xstop - xoff - 1) < 0){ return -1; } } @@ -844,14 +847,14 @@ int ncplane_box(ncplane* n, const cell* ul, const cell* ur, return -1; } ++yoff; - while(yoff < ylen - 1){ + while(yoff < ystop){ if(ncplane_cursor_move_yx(n, yoff, xoff)){ return -1; } if(ncplane_putc(n, vl) < 0){ return -1; } - if(ncplane_cursor_move_yx(n, yoff, xoff + xlen - 1)){ + if(ncplane_cursor_move_yx(n, yoff, xstop)){ return -1; } if(ncplane_putc(n, vl) < 0){ @@ -865,8 +868,8 @@ int ncplane_box(ncplane* n, const cell* ul, const cell* ur, if(ncplane_putc(n, ll) < 0){ return -1; } - if(xlen > 2){ - if(ncplane_hline(n, hl, xlen - 2) < 0){ + if(xstop - xoff >= 2){ + if(ncplane_hline(n, hl, xstop - xoff - 1) < 0){ return -1; } } @@ -881,3 +884,26 @@ void ncplane_erase(ncplane* n){ egcpool_dump(&n->pool); egcpool_init(&n->pool); } + +int ncplane_rounded_box_cells(ncplane* n, cell* ul, cell* ur, cell* ll, + cell* lr, cell* hl, cell* vl){ + if(cell_load(n, ul, "╭") > 0){ + if(cell_load(n, ur, "╮") > 0){ + if(cell_load(n, ll, "╰") > 0){ + if(cell_load(n, lr, "╯") > 0){ + if(cell_load(n, hl, "─") > 0){ + if(cell_load(n, vl, "│") > 0){ + return 0; + } + cell_release(n, hl); + } + cell_release(n, lr); + } + cell_release(n, ll); + } + cell_release(n, ur); + } + cell_release(n, ul); + } + return -1; +}