diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index ac31ff6e8..7cca36e82 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -1094,8 +1094,12 @@ API struct ncplane* ncpile_create(struct notcurses* nc, const ncplane_options* n API struct ncplane* ncplane_new(struct ncplane* n, int rows, int cols, int y, int x, void* opaque, const char* name) __attribute__ ((deprecated)); -// Suitable for use as a 'resizecb'. This will realign the plane 'n' against its -// parent, using the alignment specified at ncplane_create()-time. +// Suitable for use as a 'resizecb', this will resize the plane to the visual +// region's size. It is used for the standard plane. +API int ncplane_resize_maximize(struct ncplane* n); + +// Suitable for use as a 'resizecb'. This will realign the plane 'n' against +// its parent, using the alignment specified at ncplane_create()-time. API int ncplane_resize_realign(struct ncplane* n); // Replace the ncplane's existing resizecb with 'resizecb' (which may be NULL). diff --git a/src/lib/internal.h b/src/lib/internal.h index 2ae838824..d16421592 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -1063,6 +1063,8 @@ int ncinputlayer_init(ncinputlayer* nilayer, FILE* infp); // FIXME absorb into ncinputlayer_init() int cbreak_mode(int ttyfd, const struct termios* tpreserved); +int resize_callbacks_children(ncplane* n); + #ifdef __cplusplus } #endif diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 773a20ca6..d66b9c7e1 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -431,7 +431,10 @@ create_initial_ncplane(notcurses* nc, int dimy, int dimx){ .x = nc->margin_l, .rows = dimy - (nc->margin_t + nc->margin_b), .cols = dimx - (nc->margin_l + nc->margin_r), + .userptr = NULL, .name = "std", + .resizecb = ncplane_resize_maximize, + .flags = 0, }; return nc->stdplane = ncplane_new_internal(nc, NULL, &nopts); } @@ -542,8 +545,7 @@ ncplane* ncplane_dup(const ncplane* n, void* opaque){ // call the resize callback for each bound child in turn. we only need to do // the first generation; if they resize, they'll invoke // ncplane_resize_internal(), leading to this function being called anew. -static int -resize_callbacks_children(ncplane* n){ +int resize_callbacks_children(ncplane* n){ int ret = 0; for(struct ncplane* child = n->blist ; child ; child = child->bnext){ if(child->resizecb){ @@ -2194,6 +2196,12 @@ int (*ncplane_resizecb(const ncplane* n))(ncplane*){ return n->resizecb; } +int ncplane_resize_maximize(ncplane* n){ + int rows, cols; + notcurses_term_dim_yx(ncplane_notcurses(n), &rows, &cols); + return ncplane_resize_simple(n, rows, cols); +} + int ncplane_resize_realign(ncplane* n){ const ncplane* parent = ncplane_parent_const(n); if(parent == n){ // somehow got stdplane, should never get here diff --git a/src/lib/render.c b/src/lib/render.c index f4f236ba2..8fb90f60a 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -9,7 +9,8 @@ // be copied from the old stdplane. Assumes that the screen is always anchored at // the same origin. Also syncs up lastframe. static int -notcurses_resize_internal(notcurses* n, int* restrict rows, int* restrict cols){ +notcurses_resize_internal(ncplane* pp, int* restrict rows, int* restrict cols){ + notcurses* n = ncplane_notcurses(pp); int r, c; if(rows == NULL){ rows = &r; @@ -17,8 +18,9 @@ notcurses_resize_internal(notcurses* n, int* restrict rows, int* restrict cols){ if(cols == NULL){ cols = &c; } - int oldrows = n->stdplane->leny; - int oldcols = n->stdplane->lenx; + ncpile* pile = ncplane_pile(pp); + int oldrows = pile->dimy; + int oldcols = pile->dimx; *rows = oldrows; *cols = oldcols; if(update_term_dimensions(n->ttyfd, rows, cols)){ @@ -47,9 +49,12 @@ notcurses_resize_internal(notcurses* n, int* restrict rows, int* restrict cols){ memset(n->lastframe, 0, size); egcpool_dump(&n->pool); } +//fprintf(stderr, "r: %d or: %d c: %d oc: %d\n", *rows, oldrows, *cols, oldcols); if(*rows == oldrows && *cols == oldcols){ return 0; // no change } + pile->dimy = *rows; + pile->dimx = *cols; int keepy = *rows; if(keepy > oldrows){ keepy = oldrows; @@ -58,16 +63,23 @@ notcurses_resize_internal(notcurses* n, int* restrict rows, int* restrict cols){ if(keepx > oldcols){ keepx = oldcols; } - if(ncplane_resize_internal(n->stdplane, 0, 0, keepy, keepx, 0, 0, *rows, *cols)){ + int ret = 0; +notcurses_debug(n, stderr); +// FIXME kill this + /*if(ncplane_resize_simple(n->stdplane, *rows, *cols)){ return -1; + }*/ +// FIXME restore this + for(ncplane* rootn = pile->roots ; rootn ; rootn = rootn->bnext){ + ret |= resize_callbacks_children(rootn); } - return 0; + return ret; } static int notcurses_resize(notcurses* n, int* restrict rows, int* restrict cols){ pthread_mutex_lock(&n->pilelock); - int ret = notcurses_resize_internal(n, rows, cols); + int ret = notcurses_resize_internal(notcurses_stdplane(n), rows, cols); pthread_mutex_unlock(&n->pilelock); return ret; } @@ -778,10 +790,10 @@ notcurses_rasterize_inner(notcurses* nc, const ncpile* p, FILE* out){ // we explicitly move the cursor at the beginning of each output line, so no // need to home it expliticly. update_palette(nc, out); - // FIXME need adapt this to piles - for(y = nc->stdplane->absy ; y < nc->stdplane->leny + nc->stdplane->absy ; ++y){ +//fprintf(stderr, "pile %p ymax: %d xmax: %d\n", p, p->dimy + nc->stdplane->absy, p->dimx + nc->stdplane->absx); + for(y = nc->stdplane->absy ; y < p->dimy + nc->stdplane->absy ; ++y){ const int innery = y - nc->stdplane->absy; - for(x = nc->stdplane->absx ; x < nc->stdplane->lenx + nc->stdplane->absx ; ++x){ + for(x = nc->stdplane->absx ; x < p->dimx + nc->stdplane->absx ; ++x){ const int innerx = x - nc->stdplane->absx; const size_t damageidx = innery * nc->lfdimx + innerx; unsigned r, g, b, br, bg, bb, palfg, palbg; @@ -1091,34 +1103,41 @@ int ncpile_rasterize(ncplane* n){ return 0; } -// ensure the crender vector of 'n' is sufficiently large for 'dimy'x'dimx' +// ensure the crender vector of 'n' is sufficiently large for +// 'n'->dimy x 'n'->dimx, having previously been 'dimy'x'dimx', and initialize +// the rvec afresh for a new render. static int engorge_crender_vector(ncpile* n, int dimy, int dimx){ - const int crenderlen = dimy * dimx; - if(crenderlen > n->dimy * n->dimx){ + const int crenderlen = n->dimy * n->dimx; // desired size + if(crenderlen <= 0){ + return -1; + } +//fprintf(stderr, "crlen: %d y: %d x:%d\n", crenderlen, dimy, dimx); + if(crenderlen > dimy * dimx){ struct crender* tmp = realloc(n->crender, sizeof(*tmp) * crenderlen); if(tmp == NULL){ return -1; } n->crender = tmp; - n->dimy = dimy; - n->dimx = dimx; } init_rvec(n->crender, crenderlen); return 0; } int ncpile_render(ncplane* n){ - notcurses* nc = ncplane_notcurses(n); - int dimy, dimx; - // update our notion of screen geometry, and render against that - notcurses_resize(nc, &dimy, &dimx); struct timespec start, renderdone; clock_gettime(CLOCK_MONOTONIC, &start); - if(engorge_crender_vector(ncplane_pile(n), dimy, dimx)){ + notcurses* nc = ncplane_notcurses(n); + ncpile* pile = ncplane_pile(n); + const int olddimy = pile->dimy; + const int olddimx = pile->dimx; + // update our notion of screen geometry, and render against that + notcurses_resize_internal(n, NULL, NULL); + if(engorge_crender_vector(pile, olddimy, olddimx)){ return -1; } - ncpile_render_internal(n, ncplane_pile(n)->crender, dimy, dimx, + // FIXME notcurses_stdplane() doesn't belong here + ncpile_render_internal(n, pile->crender, pile->dimy, pile->dimx, notcurses_stdplane(nc)->absy, notcurses_stdplane(nc)->absx); clock_gettime(CLOCK_MONOTONIC, &renderdone);