add ncplane_create() + ncplane_options #1020

This commit is contained in:
nick black 2020-09-20 05:30:17 -04:00 committed by Nick Black
parent 607c03edc4
commit 36aed3c521
17 changed files with 247 additions and 94 deletions

View File

@ -4,7 +4,13 @@ rearrangements of Notcurses.
* 1.7.4 (not yet released) * 1.7.4 (not yet released)
* All `_rgb_clipped()` functions have been renamed `_rgb8_clipped()`, to * All `_rgb_clipped()` functions have been renamed `_rgb8_clipped()`, to
match the changes made in 1.7.2. Sorry, I ought have done this before. match the changes made in 1.7.2. Sorry, I ought have done this before.
* `ncplane_create()` has been introduced, taking a `struct ncplane_options`
parameter. This replaces `ncplane_aligned()`, and will replace
`ncplane_new()`. The latter ought be considered deprecated, and will be
removed in the future. To align a place as previously done with
`ncplane_aligned()`, use the `NCPLANE_OPTION_HORALIGNED` flag.
and
* 1.7.3 (2020-09-19) * 1.7.3 (2020-09-19)
* API changes pursuant to 2.0 API finalization: * API changes pursuant to 2.0 API finalization:
* `mbswidth()` has been renamed `ncstrwidth()`. * `mbswidth()` has been renamed `ncstrwidth()`.

View File

@ -600,8 +600,9 @@ In addition to its framebuffer--a rectilinear matrix of cells
* a current style, foreground channel, and background channel, * a current style, foreground channel, and background channel,
* its geometry, * its geometry,
* a configured user curry (a `void*`), * a configured user curry (a `void*`),
* its position relative to the visible plane, and * its position relative to the visible plane,
* its z-index. * its z-index, and
* a name (used only for debugging).
If opaque, a `cell` on a higher `ncplane` completely obstructs a corresponding If opaque, a `cell` on a higher `ncplane` completely obstructs a corresponding
`cell` from a lower `ncplane` from being seen. An `ncplane` corresponds loosely `cell` from a lower `ncplane` from being seen. An `ncplane` corresponds loosely
@ -609,23 +610,34 @@ to an [NCURSES Panel](https://invisible-island.net/ncurses/ncurses-intro.html#pa
but is the primary drawing surface of notcurses—there is no object but is the primary drawing surface of notcurses—there is no object
corresponding to a bare NCURSES `WINDOW`. corresponding to a bare NCURSES `WINDOW`.
In addition to `ncplane_new()`, an `ncplane` can be created aligned relative An `ncplane` can be created aligned relative to an existing `ncplane`
to an existing `ncplane` (including the standard plane) using (including the standard plane) using `NCPLANE_OPTION_ALIGNED`.
`ncplane_aligned()`. When an `ncplane` is no longer needed, free it with
When an `ncplane` is no longer needed, free it with
`ncplane_destroy()`. To quickly reset the `ncplane`, use `ncplane_erase()`. `ncplane_destroy()`. To quickly reset the `ncplane`, use `ncplane_erase()`.
```c ```c
// Create a new ncplane bound to plane 'n', at the offset 'y'x'x' (relative to #define NCPLANE_OPTION_HORALIGNED 0x0001ull
// the origin of 'n') and the specified size. The number of rows and columns
// must both be positive. This plane is initially at the top of the z-buffer,
// as if ncplane_move_top() had been called on it. The void* 'opaque' can be
// retrieved (and reset) later. A name can be set, used in debugging.
struct ncplane* ncplane_new(struct ncplane* n, int rows, int cols,
int y, int x, void* opaque, const char* name);
// Create a plane bound to 'n', and aligned relative to it using 'align'. typedef struct ncplane_options {
struct ncplane* ncplane_aligned(struct ncplane* n, int rows, int cols, int y; // vertical placement relative to parent plane
int y, ncalign_e align, void* opaque, const char* name); union {
int x;
ncalign_e align;
} horiz; // horizontal placement relative to parent plane
int rows; // number of rows, must be positive
int cols; // number of columns, must be positive
void* userptr; // user curry, may be NULL
const char* name; // name (used only for debugging), may be NULL
uint64_t flags; // closure over NCPLANE_OPTION_*
} ncplane_options;
// Create a new ncplane bound to plane 'n', at THE OFFset 'y'x'x' (relative to
// the origin of 'n') and the specified size. The number of 'rows' and 'cols'
// must both be positive. This plane is initially at the top of the z-buffer,
// as if ncplane_move_top() had been called on it. The void* 'userptr' can be
// retrieved (and reset) later. A 'name' can be set, used in debugging.
struct ncplane* ncplane_create(struct ncplane* n, const ncplane_options* nopts);
// Plane 'n' will be unbound from its parent plane, if it is currently bound, // Plane 'n' will be unbound from its parent plane, if it is currently bound,
// and will be made a bound child of 'newparent', if 'newparent' is not NULL. // and will be made a bound child of 'newparent', if 'newparent' is not NULL.

View File

@ -10,14 +10,29 @@ notcurses_plane - operations on ncplanes
**#include <notcurses/notcurses.h>** **#include <notcurses/notcurses.h>**
```c
#define NCPLANE_OPTION_HORALIGNED 0x0001ull
typedef struct ncplane_options {
int y; // vertical placement relative to parent plane
union {
int x;
ncalign_e align;
} horiz; // horizontal placement relative to parent plane
int rows; // number of rows, must be positive
int cols; // number of columns, must be positive
void* userptr; // user curry, may be NULL
const char* name; // name (used only for debugging), may be NULL
uint64_t flags; // closure over NCPLANE_OPTION_*
} ncplane_options;
```
**struct ncplane* ncplane_create(struct ncplane* n, const ncplane_options* nopts);**
**struct ncplane* notcurses_top(struct notcurses* n);** **struct ncplane* notcurses_top(struct notcurses* n);**
**struct ncplane* notcurses_bottom(struct notcurses* n);** **struct ncplane* notcurses_bottom(struct notcurses* n);**
**struct ncplane* ncplane_new(struct ncplane* n, int rows, int cols, int yoff, int xoff, void* opaque, const char* name);**
**struct ncplane* ncplane_aligned(struct ncplane* n, int rows, int cols, int yoff, ncalign_e align, void* opaque, const char* name);**
**struct ncplane* ncplane_reparent(struct ncplane* n, struct ncplane* newparent);** **struct ncplane* ncplane_reparent(struct ncplane* n, struct ncplane* newparent);**
**struct ncplane* ncplane_dup(struct ncplane* n, void* opaque);** **struct ncplane* ncplane_dup(struct ncplane* n, void* opaque);**
@ -174,17 +189,18 @@ anywhere. In addition to its framebuffer--a rectilinear matrix of cells
* position relative to the standard plane, * position relative to the standard plane,
* the plane, if any, to which it is bound, * the plane, if any, to which it is bound,
* the next plane bound by the plane to which it is bound, * the next plane bound by the plane to which it is bound,
* the head of the list of its bound planes, and * the head of the list of its bound planes,
* its z-index. * its z-index, and
* a name (used only for debugging).
New planes can be created with **ncplane_new** and **ncplane_aligned**. If a New planes can be created with **ncplane_create**. If a plane is bound to
plane is bound to another, x and y coordinates are relative to the plane to another, x and y coordinates are relative to the plane to which it is bound,
which it is bound, and if this latter plane moves, all its bound planes move and if this latter plane moves, all its bound planes move along with it. When a
along with it. When a plane is destroyed, all planes bound to it (directly or plane is destroyed, all planes bound to it (directly or transitively) are
transitively) are destroyed. **ncplane_reparent** detaches the plane **n** from destroyed. **ncplane_reparent** detaches the plane **n** from any plane to
any plane to which it is bound, and binds it to **newparent** if **newparent** which it is bound, and binds it to **newparent** if **newparent** is not
is not **NULL**. All planes bound to **n** move along with it during a **NULL**. All planes bound to **n** move along with it during a reparenting
reparenting operation. operation.
**ncplane_destroy** destroys a particular ncplane, after which it must not be **ncplane_destroy** destroys a particular ncplane, after which it must not be
used again. **notcurses_drop_planes** destroys all ncplanes other than the used again. **notcurses_drop_planes** destroys all ncplanes other than the

View File

@ -1111,15 +1111,19 @@ namespace ncpp
ncplane* create_plane (Plane &n, int rows, int cols, int yoff, NCAlign align, void *opaque) ncplane* create_plane (Plane &n, int rows, int cols, int yoff, NCAlign align, void *opaque)
{ {
ncplane *ret = ncplane_aligned ( ncplane_options nopts = {
n.plane, yoff,
rows, static_cast<ncalign_e>(align),
cols, rows,
yoff, cols,
static_cast<ncalign_e>(align), opaque,
opaque, nullptr,
nullptr 0
); };
ncplane *ret = ncplane_create (
n.plane,
&nopts
);
if (ret == nullptr) if (ret == nullptr)
throw init_error ("Notcurses failed to create an aligned plane"); throw init_error ("Notcurses failed to create an aligned plane");

View File

@ -993,18 +993,46 @@ notcurses_term_dim_yx(const struct notcurses* n, int* RESTRICT rows, int* RESTRI
API char* notcurses_at_yx(struct notcurses* nc, int yoff, int xoff, API char* notcurses_at_yx(struct notcurses* nc, int yoff, int xoff,
uint16_t* stylemask, uint64_t* channels); uint16_t* stylemask, uint64_t* channels);
// Create a new ncplane bound to plane 'n', at the offset 'y'x'x' (relative to // Horizontal alignment relative to the parent plane. Use 'align' instead of 'x'.
// the origin of 'n') and the specified size. The number of rows and columns #define NCPLANE_OPTION_HORALIGNED 0x0001ull
// must both be positive. This plane is initially at the top of the z-buffer,
// as if ncplane_move_top() had been called on it. The void* 'opaque' can be
// retrieved (and reset) later. A name can be set, used in debugging.
API struct ncplane* ncplane_new(struct ncplane* n, int rows, int cols,
int y, int x, void* opaque, const char* name);
// Create a plane bound to 'n', and aligned relative to it using 'align'. typedef struct ncplane_options {
API struct ncplane* ncplane_aligned(struct ncplane* n, int rows, int cols, int y; // vertical placement relative to parent plane
int yoff, ncalign_e align, void* opaque, union {
const char* name); int x;
ncalign_e align;
} horiz; // horizontal placement relative to parent plane
int rows; // number of rows, must be positive
int cols; // number of columns, must be positive
void* userptr; // user curry, may be NULL
const char* name; // name (used only for debugging), may be NULL
uint64_t flags; // closure over NCPLANE_OPTION_*
} ncplane_options;
// Create a new ncplane bound to plane 'n', at THE OFFset 'y'x'x' (relative to
// the origin of 'n') and the specified size. The number of 'rows' and 'cols'
// must both be positive. This plane is initially at the top of the z-buffer,
// as if ncplane_move_top() had been called on it. The void* 'userptr' can be
// retrieved (and reset) later. A 'name' can be set, used in debugging.
API struct ncplane* ncplane_create(struct ncplane* n, const ncplane_options* nopts);
// This function will be marked deprecated in 2.0 in favor of ncplane_create().
// It persists only for backwards compatibility.
static inline struct ncplane*
ncplane_new(struct ncplane* n, int rows, int cols, int y, int x, void* opaque, const char* name){
ncplane_options nopts = {
.y = y,
.horiz = {
.x = x,
},
.rows = rows,
.cols = cols,
.userptr = opaque,
.name = name,
.flags = 0,
};
return ncplane_create(n, &nopts);
}
// Plane 'n' will be unbound from its parent plane, if it is currently bound, // Plane 'n' will be unbound from its parent plane, if it is currently bound,
// and will be made a bound child of 'newparent', if 'newparent' is not NULL. // and will be made a bound child of 'newparent', if 'newparent' is not NULL.

View File

@ -73,8 +73,19 @@ typedef enum {
NCALIGN_CENTER, NCALIGN_CENTER,
NCALIGN_RIGHT, NCALIGN_RIGHT,
} ncalign_e; } ncalign_e;
struct ncplane* ncplane_new(struct ncplane* n, int rows, int cols, int yoff, int xoff, void* opaque, const char* name); typedef struct ncplane_options {
struct ncplane* ncplane_aligned(struct ncplane* n, int rows, int cols, int yoff, ncalign_e align, void* opaque, const char* name); int y; // vertical placement relative to parent plane
union {
int x;
ncalign_e align;
} horiz; // horizontal placement relative to parent plane
int rows; // number of rows, must be positive
int cols; // number of columns, must be positive
void* userptr; // user curry, may be NULL
const char* name; // name (used only for debugging), may be NULL
uint64_t flags; // closure over NCPLANE_OPTION_*
} ncplane_options;
struct ncplane* ncplane_create(struct ncplane* n, const ncplane_options* nopts);
unsigned notcurses_supported_styles(const struct notcurses* nc); unsigned notcurses_supported_styles(const struct notcurses* nc);
unsigned notcurses_palette_size(const struct notcurses* nc); unsigned notcurses_palette_size(const struct notcurses* nc);
bool notcurses_cantruecolor(const struct notcurses* nc); bool notcurses_cantruecolor(const struct notcurses* nc);

View File

@ -104,8 +104,16 @@ int allglyphs_demo(struct notcurses* nc){
} }
} }
const int planey = (dimy - height) / 2 + 1; const int planey = (dimy - height) / 2 + 1;
struct ncplane* column = ncplane_aligned(n, height, width, planey, ncplane_options nopts = {
NCALIGN_CENTER, NULL, NULL); .y = planey,
.horiz = {
.align = NCALIGN_CENTER,
},
.rows = height,
.cols = width,
.flags = NCPLANE_OPTION_HORALIGNED,
};
struct ncplane* column = ncplane_create(n, &nopts);
if(column == NULL){ if(column == NULL){
return -1; return -1;
} }

View File

@ -72,8 +72,16 @@ about_toggle(struct notcurses* nc){
const int ABOUT_COLS = 40; const int ABOUT_COLS = 40;
int dimy; int dimy;
notcurses_term_dim_yx(nc, &dimy, NULL); notcurses_term_dim_yx(nc, &dimy, NULL);
struct ncplane* n = ncplane_aligned(notcurses_stdplane(nc), ABOUT_ROWS, ncplane_options nopts = {
ABOUT_COLS, 3, NCALIGN_CENTER, NULL, NULL); .y = 3,
.horiz = {
.align = NCALIGN_CENTER,
},
.rows = ABOUT_ROWS,
.cols = ABOUT_COLS,
.flags = NCPLANE_OPTION_HORALIGNED,
};
struct ncplane* n = ncplane_create(notcurses_stdplane(nc), &nopts);
// let the glyphs below show through, but only dimly // let the glyphs below show through, but only dimly
uint64_t channels = 0; uint64_t channels = 0;
channels_set_fg_alpha(&channels, CELL_ALPHA_BLEND); channels_set_fg_alpha(&channels, CELL_ALPHA_BLEND);

View File

@ -3391,7 +3391,19 @@ const char subdivision_flag[] =
static struct ncplane* static struct ncplane*
mojiplane(struct ncplane* title, int y, int rows, const char* summary){ mojiplane(struct ncplane* title, int y, int rows, const char* summary){
struct ncplane* n = ncplane_aligned(title, rows, planewidth, y, NCALIGN_CENTER, NULL, NULL); ncplane_options nopts = {
.y = y,
.horiz = {
.align = NCALIGN_CENTER,
},
.rows = rows,
.cols = planewidth,
.flags = NCPLANE_OPTION_HORALIGNED,
};
struct ncplane* n = ncplane_create(title, &nopts);
if(n == NULL){
return NULL;
}
uint64_t channels = CHANNELS_RGB_INITIALIZER(0xf0, 0xa0, 0xf0, 0x10, 0x10, 0x60); uint64_t channels = CHANNELS_RGB_INITIALIZER(0xf0, 0xa0, 0xf0, 0x10, 0x10, 0x60);
if(ncplane_perimeter_rounded(n, 0, channels, NCBOXMASK_RIGHT) < 0){ if(ncplane_perimeter_rounded(n, 0, channels, NCBOXMASK_RIGHT) < 0){
ncplane_destroy(n); ncplane_destroy(n);
@ -3545,7 +3557,16 @@ makegroup(struct ncplane* title, int y, const char* emoji, const char* name){
struct ncplane* struct ncplane*
maketitle(struct ncplane* std){ maketitle(struct ncplane* std){
struct ncplane* title = ncplane_aligned(std, 3, 74, 2, NCALIGN_CENTER, NULL, NULL); ncplane_options nopts = {
.y = 2,
.horiz = {
.align = NCALIGN_CENTER,
},
.rows = 3,
.cols = 74,
.flags = NCPLANE_OPTION_HORALIGNED,
};
struct ncplane* title = ncplane_create(std, &nopts);
if(title == NULL){ if(title == NULL){
return NULL; return NULL;
} }

View File

@ -111,9 +111,16 @@ outro_message(struct notcurses* nc, int* rows, int* cols){
const char str1[] = " throw your hands in the air "; const char str1[] = " throw your hands in the air ";
const char str2[] = " hack on! —dank❤ "; const char str2[] = " hack on! —dank❤ ";
int ystart = *rows - 6; int ystart = *rows - 6;
struct ncplane* non = ncplane_aligned(notcurses_stdplane(nc), 5, ncplane_options nopts = {
strlen(str1) + 4, ystart, .rows = 5,
NCALIGN_CENTER, NULL, NULL); .cols = strlen(str1) + 4,
.y = ystart,
.horiz = {
.align = NCALIGN_CENTER,
},
.flags = NCPLANE_OPTION_HORALIGNED,
};
struct ncplane* non = ncplane_create(notcurses_stdplane(nc), &nopts);
if(non == NULL){ if(non == NULL){
return NULL; return NULL;
} }

View File

@ -28,9 +28,16 @@ static struct ncplane*
legend(struct notcurses* nc, const char* msg){ legend(struct notcurses* nc, const char* msg){
int dimx, dimy; int dimx, dimy;
notcurses_term_dim_yx(nc, &dimy, &dimx); notcurses_term_dim_yx(nc, &dimy, &dimx);
struct ncplane* n = ncplane_aligned(notcurses_stdplane(nc), 3, ncplane_options nopts = {
strlen(msg) + 4, 3, .rows = 3,
NCALIGN_CENTER, NULL, NULL); .cols = strlen(msg) + 4,
.y = 3,
.horiz = {
.align = NCALIGN_CENTER,
},
.flags = NCPLANE_OPTION_HORALIGNED,
};
struct ncplane* n = ncplane_create(notcurses_stdplane(nc), &nopts);
if(n == NULL){ if(n == NULL){
return NULL; return NULL;
} }

View File

@ -186,9 +186,16 @@ int unicodeblocks_demo(struct notcurses* nc){
struct timespec subdelay; struct timespec subdelay;
uint64_t nstotal = timespec_to_ns(&demodelay); uint64_t nstotal = timespec_to_ns(&demodelay);
ns_to_timespec(nstotal / 5, &subdelay); ns_to_timespec(nstotal / 5, &subdelay);
struct ncplane* header = ncplane_aligned(notcurses_stdplane(nc), 2, ncplane_options nopts = {
(CHUNKSIZE * 2) - 2, 2, .y = 2,
NCALIGN_CENTER, NULL, NULL); .horiz = {
.align = NCALIGN_CENTER,
},
.rows = 2,
.cols = (CHUNKSIZE * 2) - 2,
.flags = NCPLANE_OPTION_HORALIGNED,
};
struct ncplane* header = ncplane_create(n, &nopts);
if(header == NULL){ if(header == NULL){
return -1; return -1;
} }
@ -209,8 +216,10 @@ int unicodeblocks_demo(struct notcurses* nc){
return -1; return -1;
} }
struct ncplane* nn; struct ncplane* nn;
if((nn = ncplane_aligned(notcurses_stdplane(nc), BLOCKSIZE / CHUNKSIZE + 2, nopts.rows = BLOCKSIZE / CHUNKSIZE + 2;
(CHUNKSIZE * 2) + 2, 4, NCALIGN_CENTER, NULL, NULL)) == NULL){ nopts.cols = (CHUNKSIZE * 2) + 2;
nopts.y = 4;
if((nn = ncplane_create(header, &nopts)) == NULL){
return -1; return -1;
} }
if(draw_block(nn, blockstart)){ if(draw_block(nn, blockstart)){

View File

@ -317,10 +317,16 @@ infoplane(struct ncdirect* ncd, const fetched_info* fi){
} }
int dimy; int dimy;
struct ncplane* std = notcurses_stddim_yx(nc, &dimy, NULL); struct ncplane* std = notcurses_stddim_yx(nc, &dimy, NULL);
struct ncplane* infop = ncplane_aligned(std, struct ncplane_options nopts = {
planeheight, planewidth, .y = dimy - planeheight,
dimy - planeheight, .horiz.align = NCALIGN_CENTER,
NCALIGN_CENTER, NULL, "info"); .rows = planeheight,
.cols = planewidth,
.userptr = NULL,
.name = "info",
.flags = NCPLANE_OPTION_HORALIGNED,
};
struct ncplane* infop = ncplane_create(std, &nopts);
if(infop == NULL){ if(infop == NULL){
return -1; return -1;
} }

View File

@ -442,10 +442,10 @@ int ncdirect_render_image(ncdirect* n, const char* file, ncalign_e align,
leny = (leny / (double)ncv->rows) * ((double)disprows); leny = (leny / (double)ncv->rows) * ((double)disprows);
lenx = (lenx / (double)ncv->cols) * ((double)dispcols); lenx = (lenx / (double)ncv->cols) * ((double)dispcols);
//fprintf(stderr, "render: %d+%d of %d/%d stride %u %p\n", leny, lenx, ncv->rows, ncv->cols, ncv->rowstride, ncv->data); //fprintf(stderr, "render: %d+%d of %d/%d stride %u %p\n", leny, lenx, ncv->rows, ncv->cols, ncv->rowstride, ncv->data);
struct ncplane* faken = ncplane_create(nullptr, nullptr, struct ncplane* faken = ncplane_new_internal(nullptr, nullptr,
disprows / encoding_y_scale(bset), disprows / encoding_y_scale(bset),
dispcols / encoding_x_scale(bset), dispcols / encoding_x_scale(bset),
0, 0, nullptr, nullptr); 0, 0, nullptr, nullptr);
if(faken == nullptr){ if(faken == nullptr){
return -1; return -1;
} }

View File

@ -775,8 +775,9 @@ calc_gradient_channels(uint64_t* channels, uint64_t ul, uint64_t ur,
// ncdirect needs to "fake" an isolated ncplane as a drawing surface for // ncdirect needs to "fake" an isolated ncplane as a drawing surface for
// ncvisual_render(), and thus calls these low-level internal functions. // ncvisual_render(), and thus calls these low-level internal functions.
// they are not for general use -- check ncplane_new() and ncplane_destroy(). // they are not for general use -- check ncplane_new() and ncplane_destroy().
ncplane* ncplane_create(notcurses* nc, ncplane* n, int rows, int cols, ncplane* ncplane_new_internal(notcurses* nc, ncplane* n, int rows, int cols,
int yoff, int xoff, void* opaque, const char* name); int yoff, int xoff, void* opaque, const char* name);
void free_plane(ncplane* p); void free_plane(ncplane* p);
// heap-allocated formatted output // heap-allocated formatted output

View File

@ -295,8 +295,8 @@ void free_plane(ncplane* p){
// there's a denormalized case we also must handle, that of the "fake" isolated // there's a denormalized case we also must handle, that of the "fake" isolated
// ncplane created by ncdirect for rendering visuals. in that case (and only in // ncplane created by ncdirect for rendering visuals. in that case (and only in
// that case), nc is NULL. // that case), nc is NULL.
ncplane* ncplane_create(notcurses* nc, ncplane* n, int rows, int cols, ncplane* ncplane_new_internal(notcurses* nc, ncplane* n, int rows, int cols,
int yoff, int xoff, void* opaque, const char* name){ int yoff, int xoff, void* opaque, const char* name){
if(rows <= 0 || cols <= 0){ if(rows <= 0 || cols <= 0){
logerror(nc, "Won't create denormalized plane (r=%d, c=%d)\n", rows, cols); logerror(nc, "Won't create denormalized plane (r=%d, c=%d)\n", rows, cols);
return NULL; return NULL;
@ -358,9 +358,9 @@ ncplane* ncplane_create(notcurses* nc, ncplane* n, int rows, int cols,
// the z-buffer. clear out all cells. this is for a wholly new context. // the z-buffer. clear out all cells. this is for a wholly new context.
static ncplane* static ncplane*
create_initial_ncplane(notcurses* nc, int dimy, int dimx){ create_initial_ncplane(notcurses* nc, int dimy, int dimx){
nc->stdplane = ncplane_create(nc, NULL, dimy - (nc->margin_t + nc->margin_b), nc->stdplane = ncplane_new_internal(nc, NULL, dimy - (nc->margin_t + nc->margin_b),
dimx - (nc->margin_l + nc->margin_r), 0, 0, NULL, dimx - (nc->margin_l + nc->margin_r), 0, 0, NULL,
"std"); "std");
return nc->stdplane; return nc->stdplane;
} }
@ -372,14 +372,14 @@ const ncplane* notcurses_stdplane_const(const notcurses* nc){
return nc->stdplane; return nc->stdplane;
} }
ncplane* ncplane_new(ncplane* n, int rows, int cols, int y, int x, ncplane* ncplane_create(ncplane* n, const ncplane_options* nopts){
void* opaque, const char* name){ if(nopts->flags > NCPLANE_OPTION_HORALIGNED){
return ncplane_create(n->nc, n, rows, cols, y, x, opaque, name); logwarn(n->nc, "Provided unsupported flags %016lx\n", nopts->flags);
} }
const int x = (nopts->flags & NCPLANE_OPTION_HORALIGNED) ?
ncplane* ncplane_aligned(ncplane* n, int rows, int cols, int y, ncplane_align(n, nopts->horiz.align, nopts->cols) : nopts->horiz.x;
ncalign_e align, void* opaque, const char* name){ return ncplane_new_internal(n->nc, n, nopts->rows, nopts->cols, nopts->y,
return ncplane_create(n->nc, n, rows, cols, y, ncplane_align(n, align, cols), opaque, name); x, nopts->userptr, nopts->name);
} }
void ncplane_home(ncplane* n){ void ncplane_home(ncplane* n){
@ -426,8 +426,8 @@ ncplane* ncplane_dup(const ncplane* n, void* opaque){
const struct notcurses* nc = ncplane_notcurses_const(n); const struct notcurses* nc = ncplane_notcurses_const(n);
const int placey = n->absy - nc->margin_t; const int placey = n->absy - nc->margin_t;
const int placex = n->absx - nc->margin_l; const int placex = n->absx - nc->margin_l;
ncplane* newn = ncplane_create(n->nc, n->boundto, dimy, dimx, ncplane* newn = ncplane_new(n->boundto, dimy, dimx,
placey, placex, opaque, n->name); placey, placex, opaque, n->name);
if(newn){ if(newn){
if(egcpool_dup(&newn->pool, &n->pool)){ if(egcpool_dup(&newn->pool, &n->pool)){
ncplane_destroy(newn); ncplane_destroy(newn);

View File

@ -6,7 +6,16 @@
static int static int
run_menu(struct notcurses* nc, struct ncmenu* ncm){ run_menu(struct notcurses* nc, struct ncmenu* ncm){
struct ncplane* selplane = ncplane_aligned(notcurses_stdplane(nc), 3, 40, 10, NCALIGN_CENTER, NULL, NULL); ncplane_options nopts = {
.y = 10,
.horiz = {
.align = NCALIGN_CENTER,
},
.rows = 3,
.cols = 40,
.flags = NCPLANE_OPTION_HORALIGNED,
};
struct ncplane* selplane = ncplane_create(notcurses_stdplane(nc), &nopts);
if(selplane == NULL){ if(selplane == NULL){
return -1; return -1;
} }