[core] add ncplane_resize_placewithin #1478

This commit is contained in:
nick black 2021-11-17 04:02:49 -05:00
parent b91f150e96
commit d1c9dd93cf
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
4 changed files with 61 additions and 7 deletions

View File

@ -29,6 +29,7 @@ rearrangements of Notcurses.
* `ncplayer` now defaults to pixel blitting.
* `NCKEY_SIGNAL` is no longer a synonym for `NCKEY_RESIZE`, but instead
indicates receipt of `SIGCONT`.
* A new resize callback, `ncplane_resize_placewithin()`, has been added.
* 2.4.9 (2021-11-11)
* Added `ncnmetric()`, which uses `snprintf()` internally. `ncmetric()`

View File

@ -61,6 +61,8 @@ typedef struct ncplane_options {
**int ncplane_resize_marginalized(struct ncplane* ***n***);**
**int ncplane_resize_placewithin(struct ncplane* ***n***);**
**void ncplane_set_resizecb(struct ncplane* ***n***, int(*resizecb)(struct ncplane*));**
**int (*ncplane_resizecb(const struct ncplane* ***n***))(struct ncplane*);**

View File

@ -1299,19 +1299,26 @@ API ALLOC struct ncplane* ncplane_create(struct ncplane* n, const ncplane_option
API ALLOC struct ncplane* ncpile_create(struct notcurses* nc, const ncplane_options* nopts)
__attribute__ ((nonnull (1, 2)));
// Suitable for use as a 'resizecb', this will resize the plane to the visual
// region's size. It is used for the standard plane.
// Utility resize callbacks. When a parent plane is resized, it invokes each
// child's resize callback. Any logic can be run in a resize callback, but
// these are some generically useful ones.
// resize the plane to the visual region's size (used for the standard plane).
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.
// resize the plane to its parent's size, attempting to enforce the margins
// supplied along with NCPLANE_OPTION_MARGINALIZED.
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.
// realign the plane 'n' against its parent, using the alignments specified
// with NCPLANE_OPTION_HORALIGNED and/or NCPLANE_OPTION_VERALIGNED.
API int ncplane_resize_realign(struct ncplane* n);
// move the plane such that it is entirely within its parent, if possible.
// no resizing is performed.
API int ncplane_resize_placewithin(struct ncplane* n);
///////////////////////////////////////////////////////////////////////////////
// Replace the ncplane's existing resizecb with 'resizecb' (which may be NULL).
// The standard plane's resizecb may not be changed.
API void ncplane_set_resizecb(struct ncplane* n, int(*resizecb)(struct ncplane*));

View File

@ -2385,6 +2385,50 @@ int (*ncplane_resizecb(const ncplane* n))(ncplane*){
return n->resizecb;
}
int ncplane_resize_placewithin(ncplane* n){
if(n->boundto == n){
return 0;
}
int absy = ncplane_abs_y(n);
int absx = ncplane_abs_x(n);
int ret = 0;
if(absy + ncplane_dim_y(n) > ncplane_dim_y(n->boundto)){
const int dy = (absy + ncplane_dim_y(n)) - ncplane_dim_y(n->boundto);
logdebug("moving up %d\n", dy);
if(ncplane_move_rel(n, -dy, 0)){
ret = -1;
}
absy = ncplane_abs_y(n);
}
if(absx + ncplane_dim_x(n) > ncplane_dim_x(n->boundto)){
const int dx = ncplane_dim_x(n->boundto) - (absx + ncplane_dim_x(n));
logdebug("moving left %d\n", dx);
if(ncplane_move_rel(n, 0, dx)){
ret = -1;
}
absx = ncplane_abs_x(n);
}
// this will prefer upper-left material if the child plane is larger than
// the parent. we might want a smarter rule, one based on origin?
if(absy < 0){
logdebug("moving down %d\n", -absy);
// we're at least partially above our parent
if(ncplane_move_rel(n, -absy, 0)){
ret = -1;
}
absy = ncplane_abs_y(n);
}
if(absx < 0){
logdebug("moving right %d\n", -absx);
// we're at least partially to the left of our parent
if(ncplane_move_rel(n, 0, -absx)){
ret = -1;
}
absx = ncplane_abs_x(n);
}
return ret;
}
int ncplane_resize_marginalized(ncplane* n){
const ncplane* parent = ncplane_parent_const(n);
// a marginalized plane cannot be larger than its oppressor plane =]