[planes] implement MARGINALIZED in ncplane_create() #1472

This commit is contained in:
nick black 2021-03-27 06:22:13 -04:00 committed by Nick Black
parent 78c8e70933
commit 50df69ab31
7 changed files with 53 additions and 15 deletions

View File

@ -783,7 +783,7 @@ int ncplane_resize_maximize(struct ncplane* n);
// Suitable for use as a 'resizecb' with planes created with
// NCPLANE_OPTION_MARGINALIZED. This will resize the plane 'n' against its
// parent, attempting to enforce the supplied margins.
int ncplane_resize_marginalize(struct ncplane* n);
int ncplane_resize_marginalized(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.

View File

@ -50,7 +50,7 @@ typedef struct ncplane_options {
**int ncplane_resize_maximize(struct ncplane* ***n***);**
**int ncplane_resize_marginalize(struct ncplane* ***n***);**
**int ncplane_resize_marginalized(struct ncplane* ***n***);**
**void ncplane_set_resizecb(struct ncplane* ***n***, int(*resizecb)(struct ncplane*));**
@ -240,7 +240,7 @@ will be interpreted as top and left margins. ***margin_b*** and ***margin_r***
will be interpreted as bottom and right margins. The plane will take the maximum
space possible subject to its parent planes and these margins. The plane cannot
become smaller than 1x1 (the margins are best-effort).
**ncplane_resize_marginalize** should usually be used together with this flag,
**ncplane_resize_marginalized** should usually be used together with this flag,
so that the plane is automatically resized.
**ncplane_reparent** detaches the plane ***n*** from any plane to which it is

View File

@ -1173,7 +1173,7 @@ API int ncplane_resize_maximize(struct ncplane* n);
// Suitable for use as a 'resizecb' with planes created with
// NCPLANE_OPTION_MARGINALIZED. This will resize the plane 'n' against its
// parent, attempting to enforce the supplied margins.
API int ncplane_resize_marginalize(struct ncplane* n);
API int ncplane_resize_marginalized(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.

View File

@ -29,6 +29,8 @@ impl NcPlaneOptions {
cols: NcDim,
resizecb: Option<NcResizeCb>,
flags: u64,
margin_b: NcOffset,
margin_r: NcOffset,
) -> Self {
NcPlaneOptions {
y: y as i32,
@ -39,6 +41,8 @@ impl NcPlaneOptions {
name: null(),
resizecb: crate::ncresizecb_to_c(resizecb),
flags,
margin_b: margin_b as i32,
margin_r: margin_r as i32,
}
}
@ -64,6 +68,8 @@ impl NcPlaneOptions {
name: null(),
resizecb: crate::ncresizecb_to_c(resizecb),
flags,
0,
0,
}
}
}

View File

@ -94,6 +94,8 @@ typedef struct ncplane {
// plane is bound, but absx/absy are always relative to the terminal origin.
// they must thus be translated by any function which moves a parent plane.
int absx, absy; // origin of the plane relative to the pile's origin
// also used as left and top margin on resize by
// ncplane_resize_marginalized()
int lenx, leny; // size of the plane, [0..len{x,y}) is addressable
egcpool pool; // attached storage pool for UTF-8 EGCs
uint64_t channels; // works the same way as cells
@ -122,6 +124,7 @@ typedef struct ncplane {
ncalign_e halign; // relative to parent plane, for automatic realignment
ncalign_e valign; // relative to parent plane, for automatic realignment
uint16_t stylemask; // same deal as in a cell
int margin_b, margin_r;// bottom and right margins, stored for resize
bool scrolling; // is scrolling enabled? always disabled by default
} ncplane;

View File

@ -296,10 +296,22 @@ make_ncpile(notcurses* nc, ncplane* n){
// (as once more is n).
ncplane* ncplane_new_internal(notcurses* nc, ncplane* n,
const ncplane_options* nopts){
if(nopts->flags >= (NCPLANE_OPTION_VERALIGNED << 1u)){
if(nopts->flags >= (NCPLANE_OPTION_MARGINALIZED << 1u)){
logwarn(nc, "Provided unsupported flags %016jx\n", (uintmax_t)nopts->flags);
}
if(nopts->rows <= 0 || nopts->cols <= 0){
if(nopts->flags & NCPLANE_OPTION_HORALIGNED || nopts->flags & NCPLANE_OPTION_VERALIGNED){
if(n == NULL){
logerror(nc, "Alignment requires a parent plane\n");
return NULL;
}
}
if(nopts->flags & NCPLANE_OPTION_MARGINALIZED){
if(nopts->rows != 0 || nopts->cols != 0){
logerror(nc, "Geometry specified with margins (r=%d, c=%d)\n",
nopts->rows, nopts->cols);
return NULL;
}
}else if(nopts->rows <= 0 || nopts->cols <= 0){
logerror(nc, "Won't create denormalized plane (r=%d, c=%d)\n",
nopts->rows, nopts->cols);
return NULL;
@ -317,8 +329,25 @@ ncplane* ncplane_new_internal(notcurses* nc, ncplane* n,
}
memset(p->fb, 0, fbsize);
p->scrolling = false;
if(nopts->flags & NCPLANE_OPTION_MARGINALIZED){
p->margin_b = nopts->margin_b;
p->margin_r = nopts->margin_r;
if(n){ // use parent size
p->leny = ncplane_dim_y(n);
p->lenx = ncplane_dim_x(n);
}else{ // use pile size
notcurses_term_dim_yx(nc, &p->leny, &p->lenx);
}
if((p->leny -= p->margin_b) <= 0){
p->leny = 1;
}
if((p->lenx -= p->margin_r) <= 0){
p->lenx = 1;
}
}else{
p->leny = nopts->rows;
p->lenx = nopts->cols;
}
p->x = p->y = 0;
p->logrow = 0;
p->sprite = NULL;
@ -354,6 +383,7 @@ ncplane* ncplane_new_internal(notcurses* nc, ncplane* n,
*p->bprev = p;
p->boundto = n;
}
// FIXME handle top/left margins
p->resizecb = nopts->resizecb;
p->stylemask = 0;
p->channels = 0;
@ -416,7 +446,6 @@ const ncplane* notcurses_stdplane_const(const notcurses* nc){
}
ncplane* ncplane_create(ncplane* n, const ncplane_options* nopts){
fprintf(stderr, "nopts: %p name: %s\n", nopts, nopts->name);
return ncplane_new_internal(ncplane_notcurses(n), n, nopts);
}
@ -2154,8 +2183,9 @@ int (*ncplane_resizecb(const ncplane* n))(ncplane*){
return n->resizecb;
}
int ncplane_resize_marginalize(ncplane* n){
int ncplane_resize_marginalized(ncplane* n){
(void)n;// FIXME uhhh do something here
fprintf(stderr, "NEED TO RESIZE THIS MARGINALIZED-ASS PLANE\n");
return 0;
}
@ -2172,10 +2202,9 @@ int ncplane_resize_maximize(ncplane* n){
int ncplane_resize_realign(ncplane* n){
const ncplane* parent = ncplane_parent_const(n);
// FIXME this *should* be allowed for other root planes, though, right?
if(parent == n){ // somehow got stdplane, should never get here
logerror(ncplane_notcurses(n), "Passed the standard plane");
return -1;
if(parent == n){
logerror(ncplane_notcurses(n), "Can't realign a root plane");
return 0;
}
if(n->halign == NCALIGN_UNALIGNED && n->valign == NCALIGN_UNALIGNED){
logerror(ncplane_notcurses(n), "Passed a non-aligned plane");

View File

@ -346,7 +346,7 @@ int rendered_mode_player_inner(NotCurses& nc, int argc, char** argv,
// leave a line at the bottom. perhaps one day we'll put information there.
// for now, this keeps us from scrolling when we use bitmaps.
nopts.margin_b = 1;
nopts.resizecb = ncplane_resize_marginalize;
nopts.resizecb = ncplane_resize_marginalized;
nopts.flags = NCPLANE_OPTION_MARGINALIZED;
auto n = ncplane_create(*stdn, &nopts);
if(!n){