mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
add notcurses_drop_planes, use from demo #346
This commit is contained in:
parent
ab9cbf82dc
commit
c6520ab84c
17
README.md
17
README.md
@ -275,6 +275,9 @@ Utility functions operating on the toplevel `notcurses` object include:
|
||||
// Return the topmost ncplane, of which there is always at least one.
|
||||
struct ncplane* notcurses_top(struct notcurses* n);
|
||||
|
||||
// Destroy any ncplanes other than the stdplane.
|
||||
void notcurses_drop_planes(struct notcurses* nc);
|
||||
|
||||
// Refresh our idea of the terminal's dimensions, reshaping the standard plane
|
||||
// if necessary. Without a call to this function following a terminal resize
|
||||
// (as signaled via SIGWINCH), notcurses_render() might not function properly.
|
||||
@ -1109,9 +1112,14 @@ int ncplane_gradient(struct ncplane* n, const char* egc, uint32_t attrword,
|
||||
|
||||
// Draw a gradient with its upper-left corner at the current cursor position,
|
||||
// having dimensions 'ylen'x'xlen'. See ncplane_gradient for more information.
|
||||
int ncplane_gradient_sized(struct ncplane* n, const char* egc,
|
||||
uint32_t attrword, uint64_t ul, uint64_t ur,
|
||||
uint64_t ll, uint64_t lr, int ylen, int xlen);
|
||||
static inline int
|
||||
ncplane_gradient_sized(struct ncplane* n, const char* egc, uint32_t attrword,
|
||||
uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr,
|
||||
int ylen, int xlen){
|
||||
int y, x;
|
||||
ncplane_cursor_yx(n, &y, &x);
|
||||
return ncplane_gradient(n, egc, attrword, ul, ur, ll, lr, y + ylen - 1, x + xlen - 1);
|
||||
}
|
||||
```
|
||||
|
||||
My 14 year-old self would never forgive me if we didn't have sweet palette fades.
|
||||
@ -1201,7 +1209,8 @@ static inline unsigned
|
||||
ncplane_fg_alpha(const struct ncplane* nc){
|
||||
return channels_fg_alpha(ncplane_channels(nc));
|
||||
}
|
||||
/ Extract 2 bits of background alpha from 'struct ncplane', shifted to LSBs.
|
||||
|
||||
// Extract 2 bits of background alpha from 'struct ncplane', shifted to LSBs.
|
||||
static inline unsigned
|
||||
ncplane_bg_alpha(const struct ncplane* nc){
|
||||
return channels_bg_alpha(ncplane_channels(nc));
|
||||
|
@ -61,7 +61,7 @@ ncplane_box_sized(struct ncplane* n, const cell* ul, const cell* ur,
|
||||
|
||||
**int ncplane_gradient(struct ncplane* n, const char* egc, uint32_t attrword, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ystop, int xstop);**
|
||||
|
||||
**int ncplane_gradient_sized(struct ncplane* n, const char* egc, uint32_t attrword, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ylen, int xlen);**
|
||||
**static inline int ncplane_gradient_sized(struct ncplane* n, const char* egc, uint32_t attrword, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ylen, int xlen);**
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
|
@ -116,6 +116,8 @@ notcurses_ncplane - operations on notcurses planes
|
||||
|
||||
**int ncblit_rgba(struct ncplane* nc, int placey, int placex, int linesize, const unsigned char* data, int begy, int begx, int leny, int lenx);**
|
||||
|
||||
**void notcurses_drop_planes(struct notcurses* nc);**
|
||||
|
||||
## DESCRIPTION
|
||||
|
||||
Ncplanes are the fundamental drawing object of notcurses. All output functions
|
||||
@ -132,6 +134,9 @@ anywhere. In addition to its framebuffer--a rectilinear matrix of cells
|
||||
* its position relative to the visible plane, and
|
||||
* its z-index.
|
||||
|
||||
**notcurses_drop_planes** destroys all ncplanes other than the stdplane. Any
|
||||
references to such planes are, of course, invalidated.
|
||||
|
||||
# RETURN VALUES
|
||||
|
||||
**ncplane_new(3)**, **ncplane_aligned(3)**, and **ncplane_dup(3)** all return a
|
||||
@ -145,7 +150,7 @@ plane is the bottommost plane, NULL is returned. It cannot fail.
|
||||
|
||||
Functions returning **int** return 0 on success, and non-zero on error.
|
||||
|
||||
All other functions either cannot fail (and return **void**).
|
||||
All other functions cannot fail (and return **void**).
|
||||
|
||||
# NOTES
|
||||
|
||||
|
@ -246,6 +246,9 @@ API int notcurses_render(struct notcurses* nc);
|
||||
// Return the topmost ncplane, of which there is always at least one.
|
||||
API struct ncplane* notcurses_top(struct notcurses* n);
|
||||
|
||||
// Destroy any ncplanes other than the stdplane.
|
||||
API void notcurses_drop_planes(struct notcurses* nc);
|
||||
|
||||
// All input is currently taken from stdin, though this will likely change. We
|
||||
// attempt to read a single UTF8-encoded Unicode codepoint, *not* an entire
|
||||
// Extended Grapheme Cluster. It is also possible that we will read a special
|
||||
@ -958,9 +961,14 @@ API int ncplane_gradient(struct ncplane* n, const char* egc, uint32_t attrword,
|
||||
|
||||
// Draw a gradient with its upper-left corner at the current cursor position,
|
||||
// having dimensions 'ylen'x'xlen'. See ncplane_gradient for more information.
|
||||
API int ncplane_gradient_sized(struct ncplane* n, const char* egc,
|
||||
uint32_t attrword, uint64_t ul, uint64_t ur,
|
||||
uint64_t ll, uint64_t lr, int ylen, int xlen);
|
||||
static inline int
|
||||
ncplane_gradient_sized(struct ncplane* n, const char* egc, uint32_t attrword,
|
||||
uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr,
|
||||
int ylen, int xlen){
|
||||
int y, x;
|
||||
ncplane_cursor_yx(n, &y, &x);
|
||||
return ncplane_gradient(n, egc, attrword, ul, ur, ll, lr, 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
|
||||
|
@ -87,6 +87,7 @@ int ncplane_set_base_cell(struct ncplane* ncp, const cell* c);
|
||||
int ncplane_set_base(struct ncplane* ncp, uint64_t channels, uint32_t attrword, const char* egc);
|
||||
int ncplane_base(struct ncplane* ncp, cell* c);
|
||||
struct ncplane* notcurses_top(struct notcurses* n);
|
||||
void notcurses_drop_planes(struct notcurses* nc);
|
||||
int notcurses_refresh(struct notcurses* n);
|
||||
int notcurses_resize(struct notcurses* n, int* y, int* x);
|
||||
struct ncplane* ncplane_new(struct notcurses* nc, int rows, int cols, int yoff, int xoff, void* opaque);
|
||||
|
@ -423,9 +423,6 @@ int main(int argc, char** argv){
|
||||
if(notcurses_mouse_enable(nc)){
|
||||
goto err;
|
||||
}
|
||||
if(menu_create(nc) == NULL){
|
||||
goto err;
|
||||
}
|
||||
if(input_dispatcher(nc)){
|
||||
goto err;
|
||||
}
|
||||
@ -444,13 +441,17 @@ int main(int argc, char** argv){
|
||||
do{
|
||||
restart_demos = false;
|
||||
interrupted = false;
|
||||
notcurses_drop_planes(nc);
|
||||
if(menu_create(nc) == NULL){
|
||||
goto err;
|
||||
}
|
||||
if(ext_demos(nc, spec, ignore_failures) == NULL){
|
||||
goto err;
|
||||
}
|
||||
if(hud_destroy()){ // destroy here since notcurses_drop_planes will kill it
|
||||
goto err;
|
||||
}
|
||||
}while(restart_demos);
|
||||
if(hud_destroy()){
|
||||
goto err;
|
||||
}
|
||||
if(stop_input()){
|
||||
goto err;
|
||||
}
|
||||
|
@ -176,8 +176,8 @@ eagles(struct notcurses* nc){
|
||||
continue;
|
||||
}
|
||||
e[i].yoff += random() % (2 + i) - 1;
|
||||
if(e[i].yoff < 1){
|
||||
e[i].yoff = 1;
|
||||
if(e[i].yoff < 0){
|
||||
e[i].yoff = 0;
|
||||
}else if(e[i].yoff + height >= truey){
|
||||
e[i].yoff = truey - height - 1;
|
||||
}
|
||||
|
@ -1003,6 +1003,20 @@ int ncdirect_stop(ncdirect* nc){
|
||||
return ret;
|
||||
}
|
||||
|
||||
void notcurses_drop_planes(notcurses* nc){
|
||||
ncplane* p = nc->top;
|
||||
while(p){
|
||||
ncplane* tmp = p->z;
|
||||
if(nc->stdscr == p){
|
||||
nc->top = p;
|
||||
p->z = NULL;
|
||||
}else{
|
||||
free_plane(p);
|
||||
}
|
||||
p = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
int notcurses_stop(notcurses* nc){
|
||||
int ret = 0;
|
||||
if(nc){
|
||||
@ -1996,3 +2010,60 @@ int ncplane_polyfill_yx(ncplane* n, int y, int x, const cell* c){
|
||||
ncplane_unlock(n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// calculate one of the channels of a gradient at a particular point.
|
||||
static uint32_t
|
||||
calc_gradient_channel(uint32_t ul, uint32_t ur, uint32_t ll, uint32_t lr,
|
||||
int y, int x, int ylen, int xlen){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// calculate both channels of a gradient at a particular point, storing them
|
||||
// into `c`->channels. x and y ought be the location within the gradient.
|
||||
static void
|
||||
calc_gradient_channels(cell* c, uint64_t ul, uint64_t ur, uint64_t ll,
|
||||
uint64_t lr, int y, int x, int ylen, int xlen){
|
||||
cell_set_fchannel(c, calc_gradient_channel(channels_fchannel(ul),
|
||||
channels_fchannel(ur),
|
||||
channels_fchannel(ll),
|
||||
channels_fchannel(lr),
|
||||
y, x, ylen, xlen));
|
||||
cell_set_bchannel(c, calc_gradient_channel(channels_fchannel(ul),
|
||||
channels_fchannel(ur),
|
||||
channels_fchannel(ll),
|
||||
channels_fchannel(lr),
|
||||
y, x, ylen, xlen));
|
||||
}
|
||||
|
||||
int ncplane_gradient(ncplane* n, const char* egc, uint32_t attrword,
|
||||
uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr,
|
||||
int ystop, int xstop){
|
||||
int yoff, xoff, ymax, xmax;
|
||||
ncplane_cursor_yx(n, &yoff, &xoff);
|
||||
// must be at least 1x1, with its upper-left corner at the current cursor
|
||||
if(ystop < yoff){
|
||||
return -1;
|
||||
}
|
||||
if(xstop < xoff){
|
||||
return -1;
|
||||
}
|
||||
ncplane_dim_yx(n, &ymax, &xmax);
|
||||
// must be within the ncplane
|
||||
if(xstop >= xmax || ystop >= ymax){
|
||||
return -1;
|
||||
}
|
||||
const int xlen = xstop - xoff + 1;
|
||||
const int ylen = ystop - ylen + 1;
|
||||
for(int y = yoff ; y < ylen ; ++y){
|
||||
for(int x = xoff ; x < xlen ; ++x){
|
||||
cell* targc = ncplane_cell_ref_yx(n, y, x);
|
||||
targc->channels = 0;
|
||||
targc->attrword = 0;
|
||||
if(cell_load(n, targc, egc) < 0){
|
||||
return -1;
|
||||
}
|
||||
calc_gradient_channels(&targc, ul, ur, ll, lr, y - yoff, x - xoff, ylen, xlen);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -29,6 +29,18 @@ TEST_CASE("Fills") {
|
||||
CHECK(0 > ncplane_polyfill_yx(n_, -1, 0, &c));
|
||||
}
|
||||
|
||||
SUBCASE("PolyfillOnGlyph") {
|
||||
cell c = CELL_SIMPLE_INITIALIZER('+');
|
||||
struct ncplane* pfn = ncplane_new(nc_, 4, 4, 0, 0, nullptr);
|
||||
REQUIRE(nullptr != pfn);
|
||||
CHECK(16 == ncplane_polyfill_yx(pfn, 0, 0, &c));
|
||||
CHECK(0 < ncplane_putc_yx(pfn, 0, 0, &c));
|
||||
// Trying to fill the origin ought fill zero cells
|
||||
CHECK(0 == ncplane_polyfill_yx(pfn, 0, 0, &c));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == ncplane_destroy(pfn));
|
||||
}
|
||||
|
||||
SUBCASE("PolyfillEmptyPlane") {
|
||||
cell c = CELL_SIMPLE_INITIALIZER('+');
|
||||
struct ncplane* pfn = ncplane_new(nc_, 4, 4, 0, 0, nullptr);
|
||||
@ -53,6 +65,16 @@ TEST_CASE("Fills") {
|
||||
CHECK(0 == ncplane_destroy(pfn));
|
||||
}
|
||||
|
||||
SUBCASE("GradientMonochromatic") {
|
||||
struct ncplane* pfn = ncplane_new(nc_, 4, 4, 0, 0, nullptr);
|
||||
REQUIRE(nullptr != pfn);
|
||||
uint64_t ul, ur, ll, lr;
|
||||
ul = ur = ll = lr = 0;
|
||||
CHECK(0 == ncplane_gradient(pfn, " ", 0, ul, ur, ll, lr, 3, 3));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == ncplane_destroy(pfn));
|
||||
}
|
||||
|
||||
CHECK(0 == notcurses_stop(nc_));
|
||||
CHECK(0 == fclose(outfp_));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user