diff --git a/NEWS.md b/NEWS.md index 7d959a006..7391543e8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,8 +9,6 @@ rearrangements of Notcurses. * `selector_options` has been renamed to `ncselector_options`, and `multiselector_options` has been renamed to `ncmultiselector_options`. This matches the other widget option struct's nomenclature. - * `ncselector_create()` and `ncmultiselector_create()` now take a `struct - notcurses*` instead of a `struct ncplane`, as they create their own planes. * `ncplane_set_channels()` and `ncplane_set_attr()` have been added to allow `ncplane` attributes to be set directly and in toto. * `NULL` can now be passed as the `FILE*` argument to `notcurses_init()` and diff --git a/doc/man/man3/notcurses_multiselector.3.md b/doc/man/man3/notcurses_multiselector.3.md index 68a1ed72f..2cdf8275b 100644 --- a/doc/man/man3/notcurses_multiselector.3.md +++ b/doc/man/man3/notcurses_multiselector.3.md @@ -42,7 +42,7 @@ typedef struct ncmultiselector_options { } ncmultiselector_options; ``` -**struct ncmultiselector* ncmultiselector_create(struct notcurses* n, int y, int x, const ncmultiselector_options* opts);** +**struct ncmultiselector* ncmultiselector_create(struct ncplane* n, int y, int x, const ncmultiselector_options* opts);** **int ncmultiselector_selected(bool* selected, unsigned n);** @@ -56,6 +56,11 @@ typedef struct ncmultiselector_options { # NOTES +Currently, the **ncplane** **n** provided to **ncmultiselector_create** must +not be **NULL**, though the **ncmultiselector** will always get its own plane, +and this plane will not (currently) be bound to **n**. + + # RETURN VALUES # SEE ALSO diff --git a/doc/man/man3/notcurses_selector.3.md b/doc/man/man3/notcurses_selector.3.md index 2ee9a6c76..eafb9e02e 100644 --- a/doc/man/man3/notcurses_selector.3.md +++ b/doc/man/man3/notcurses_selector.3.md @@ -41,7 +41,7 @@ typedef struct ncselector_options { } ncselector_options; ``` -**struct ncselector* ncselector_create(struct notcrses* n, int y, int x, const ncselector_options* opts);** +**struct ncselector* ncselector_create(struct ncplane* n, int y, int x, const ncselector_options* opts);** **int ncselector_additem(struct ncselector* n, const struct ncselector_item* item);** @@ -63,6 +63,10 @@ typedef struct ncselector_options { # NOTES +Currently, the **ncplane** **n** provided to **ncselector_create** must not be +**NULL**, though the **ncselector** will always get its own plane, and this +plane will not (currently) be bound to **n**. + # RETURN VALUES # SEE ALSO diff --git a/include/ncpp/MultiSelector.hh b/include/ncpp/MultiSelector.hh index c0e731b71..83e2f860d 100644 --- a/include/ncpp/MultiSelector.hh +++ b/include/ncpp/MultiSelector.hh @@ -5,7 +5,6 @@ #include "Root.hh" #include "NCAlign.hh" -#include "NotCurses.hh" namespace ncpp { @@ -17,27 +16,30 @@ namespace ncpp static ncmultiselector_options default_options; public: - explicit MultiSelector (NotCurses *nc, int y, int x, const ncmultiselector_options *opts = nullptr) - : MultiSelector (reinterpret_cast(nc), y, x, opts) + explicit MultiSelector (Plane *plane, int y, int x, const ncmultiselector_options *opts = nullptr) + : MultiSelector (reinterpret_cast(plane), y, x, opts) {} - explicit MultiSelector (NotCurses const* nc, int y, int x, const ncmultiselector_options *opts = nullptr) - : MultiSelector (const_cast(nc), y, x, opts) + explicit MultiSelector (Plane const* plane, int y, int x, const ncmultiselector_options *opts = nullptr) + : MultiSelector (const_cast(plane), y, x, opts) {} - explicit MultiSelector (NotCurses &nc, int y, int x, const ncmultiselector_options *opts = nullptr) - : MultiSelector (reinterpret_cast(&nc), y, x, opts) + explicit MultiSelector (Plane &plane, int y, int x, const ncmultiselector_options *opts = nullptr) + : MultiSelector (reinterpret_cast(&plane), y, x, opts) {} - explicit MultiSelector (NotCurses const& nc, int y, int x, const ncmultiselector_options *opts = nullptr) - : MultiSelector (const_cast(&nc), y, x, opts) + explicit MultiSelector (Plane const& plane, int y, int x, const ncmultiselector_options *opts = nullptr) + : MultiSelector (const_cast(&plane), y, x, opts) {} - explicit MultiSelector (notcurses *nc, int y, int x, const ncmultiselector_options *opts = nullptr) + explicit MultiSelector (ncplane *plane, int y, int x, const ncmultiselector_options *opts = nullptr) { - multiselector = ncmultiselector_create (nc, y, x, opts == nullptr ? &default_options : opts); + if (plane == nullptr) + throw invalid_argument ("'plane' must be a valid pointer"); + + multiselector = ncmultiselector_create (plane, y, x, opts == nullptr ? &default_options : opts); if (multiselector == nullptr) - throw init_error ("notcurses failed to create a new ncmultiselector"); + throw init_error ("notcurses failed to create a new multiselector"); } ~MultiSelector () diff --git a/include/ncpp/Selector.hh b/include/ncpp/Selector.hh index 60b7ea024..76a88eede 100644 --- a/include/ncpp/Selector.hh +++ b/include/ncpp/Selector.hh @@ -5,7 +5,6 @@ #include "Root.hh" #include "NCAlign.hh" -#include "NotCurses.hh" namespace ncpp { @@ -17,25 +16,28 @@ namespace ncpp static ncselector_options default_options; public: - explicit Selector (NotCurses *nc, int y, int x, const ncselector_options *opts = nullptr) - : Selector (reinterpret_cast(nc), y, x, opts) + explicit Selector (Plane *plane, int y, int x, const ncselector_options *opts = nullptr) + : Selector (reinterpret_cast(plane), y, x, opts) {} - explicit Selector (NotCurses const* nc, int y, int x, const ncselector_options *opts = nullptr) - : Selector (const_cast(nc), y, x, opts) + explicit Selector (Plane const* plane, int y, int x, const ncselector_options *opts = nullptr) + : Selector (const_cast(plane), y, x, opts) {} - explicit Selector (NotCurses &nc, int y, int x, const ncselector_options *opts = nullptr) - : Selector (reinterpret_cast(&nc), y, x, opts) + explicit Selector (Plane &plane, int y, int x, const ncselector_options *opts = nullptr) + : Selector (reinterpret_cast(&plane), y, x, opts) {} - explicit Selector (NotCurses const& nc, int y, int x, const ncselector_options *opts = nullptr) - : Selector (const_cast(&nc), y, x, opts) + explicit Selector (Plane const& plane, int y, int x, const ncselector_options *opts = nullptr) + : Selector (const_cast(&plane), y, x, opts) {} - explicit Selector (notcurses* nc, int y, int x, const ncselector_options *opts = nullptr) + explicit Selector (ncplane *plane, int y, int x, const ncselector_options *opts = nullptr) { - selector = ncselector_create (nc, y, x, opts == nullptr ? &default_options : opts); + if (plane == nullptr) + throw invalid_argument ("'plane' must be a valid pointer"); + + selector = ncselector_create (plane, y, x, opts == nullptr ? &default_options : opts); if (selector == nullptr) throw init_error ("notcurses failed to create a new selector"); } diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index f71316570..6b08a5a06 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -2480,7 +2480,7 @@ typedef struct ncselector_options { uint64_t bgchannels; // background channels, used only in body } ncselector_options; -API struct ncselector* ncselector_create(struct notcurses* n, int y, int x, +API struct ncselector* ncselector_create(struct ncplane* n, int y, int x, const ncselector_options* opts); API int ncselector_additem(struct ncselector* n, const struct ncselector_item* item); @@ -2554,7 +2554,7 @@ typedef struct ncmultiselector_options { uint64_t bgchannels; // background channels, used only in body } ncmultiselector_options; -API struct ncmultiselector* ncmultiselector_create(struct notcurses* n, int y, int x, +API struct ncmultiselector* ncmultiselector_create(struct ncplane* n, int y, int x, const ncmultiselector_options* opts); // Return selected vector. An array of bools must be provided, along with its diff --git a/python/src/notcurses/build_notcurses.py b/python/src/notcurses/build_notcurses.py index b4cbb61d4..7fa87a953 100644 --- a/python/src/notcurses/build_notcurses.py +++ b/python/src/notcurses/build_notcurses.py @@ -326,7 +326,7 @@ typedef struct ncselector_options { uint64_t boxchannels; // border channels uint64_t bgchannels; // background channels, used only in body } ncselector_options; -struct ncselector* ncselector_create(struct notcurses* n, int y, int x, const ncselector_options* opts); +struct ncselector* ncselector_create(struct ncplane* n, int y, int x, const ncselector_options* opts); int ncselector_additem(struct ncselector* n, const struct ncselector_item* item); int ncselector_delitem(struct ncselector* n, const char* item); const char* ncselector_selected(const struct ncselector* n); @@ -356,7 +356,7 @@ typedef struct ncmultiselector_options { uint64_t boxchannels; // border channels uint64_t bgchannels; // background channels, used only in body } ncmultiselector_options; -struct ncmultiselector* ncmultiselector_create(struct notcurses* n, int y, int x, const ncmultiselector_options* opts); +struct ncmultiselector* ncmultiselector_create(struct ncplane* n, int y, int x, const ncmultiselector_options* opts); int ncmultiselector_selected(struct ncmultiselector* n, bool* selected, unsigned count); struct ncplane* ncmultiselector_plane(struct ncmultiselector* n); bool ncmultiselector_offer_input(struct ncmultiselector* n, const struct ncinput* nc); @@ -484,6 +484,22 @@ struct ncsubproc* ncsubproc_createvp(struct ncplane* n, const ncsubproc_options* struct ncsubproc* ncsubproc_createvpe(struct ncplane* n, const ncsubproc_options* opts, const char* bin, char* const arg[], char* const env[], ncfdplane_callback cbfxn, ncfdplane_done_cb donecbfxn); struct ncplane* ncsubproc_plane(struct ncsubproc* n); int ncsubproc_destroy(struct ncsubproc* n); +typedef struct ncreader_options { + uint64_t tchannels; // channels used for input + uint64_t echannels; // channels used for empty space + uint32_t tattrword; // attributes used for input + uint32_t eattrword; // attributes used for empty space + char* egc; // egc used for empty space + int physrows; + int physcols; + bool scroll; // allow more than the physical area's worth of input +} ncreader_options; +struct ncreader* ncreader_create(struct notcurses* nc, int y, int x, const ncreader_options* opts); +int ncreader_clear(struct ncreader* n); +struct ncplane* ncreader_plane(struct ncreader* n); +bool ncreader_offer_input(struct ncreader* n, const struct ncinput* ni); +char* ncreader_contents(const struct ncreader* n); +void ncreader_destroy(struct ncreader* n, char** contents); """) if __name__ == "__main__": diff --git a/src/demo/demo.h b/src/demo/demo.h index fb3a69998..da484b2f4 100644 --- a/src/demo/demo.h +++ b/src/demo/demo.h @@ -134,6 +134,10 @@ timespec_mul(const struct timespec* ts, unsigned multiplier, struct timespec* pr } /*-------------------------------time helpers----------------------------*/ +/*---------------------------------FPS plot-------------------------------*/ +int fpsgraph_init(struct notcurses* nc); +int fpsgraph_stop(struct notcurses* nc); + /*----------------------------------HUD----------------------------------*/ extern struct ncplane* hud; struct ncplane* hud_create(struct notcurses* nc); diff --git a/src/lib/selector.c b/src/lib/selector.c index e2195ca1d..a5b1eaa50 100644 --- a/src/lib/selector.c +++ b/src/lib/selector.c @@ -157,7 +157,7 @@ ncselector_dim_yx(notcurses* nc, const ncselector* n, int* ncdimy, int* ncdimx){ return 0; } -ncselector* ncselector_create(notcurses* nc, int y, int x, const ncselector_options* opts){ +ncselector* ncselector_create(ncplane* nc, int y, int x, const ncselector_options* opts){ if(opts->defidx && opts->defidx >= opts->itemcount){ return NULL; } @@ -210,10 +210,10 @@ ncselector* ncselector_create(notcurses* nc, int y, int x, const ncselector_opti } } int dimy, dimx; - if(ncselector_dim_yx(nc, ns, &dimy, &dimx)){ + if(ncselector_dim_yx(nc->nc, ns, &dimy, &dimx)){ goto freeitems; } - if(!(ns->ncp = ncplane_new(nc, dimy, dimx, y, x, NULL))){ + if(!(ns->ncp = ncplane_new(nc->nc, dimy, dimx, y, x, NULL))){ goto freeitems; } cell_init(&ns->background); @@ -654,7 +654,7 @@ ncmultiselector_dim_yx(notcurses* nc, const ncmultiselector* n, int* ncdimy, int return 0; } -ncmultiselector* ncmultiselector_create(notcurses* nc, int y, int x, +ncmultiselector* ncmultiselector_create(ncplane* nc, int y, int x, const ncmultiselector_options* opts){ ncmultiselector* ns = malloc(sizeof(*ns)); ns->title = opts->title ? strdup(opts->title) : NULL; @@ -703,10 +703,10 @@ ncmultiselector* ncmultiselector_create(notcurses* nc, int y, int x, } } int dimy, dimx; - if(ncmultiselector_dim_yx(nc, ns, &dimy, &dimx)){ + if(ncmultiselector_dim_yx(nc->nc, ns, &dimy, &dimx)){ goto freeitems; } - if(!(ns->ncp = ncplane_new(nc, dimy, dimx, y, x, NULL))){ + if(!(ns->ncp = ncplane_new(nc->nc, dimy, dimx, y, x, NULL))){ goto freeitems; } cell_init(&ns->background); diff --git a/src/poc/multiselect.c b/src/poc/multiselect.c index e047c1194..c5312438a 100644 --- a/src/poc/multiselect.c +++ b/src/poc/multiselect.c @@ -98,28 +98,28 @@ int main(void){ ncplane_set_fg(n, 0x40f040); ncplane_putstr_aligned(n, 0, NCALIGN_RIGHT, "multiselect widget demo"); - struct ncmultiselector* ns = ncmultiselector_create(nc, 3, 0, &sopts); + struct ncmultiselector* ns = ncmultiselector_create(n, 3, 0, &sopts); run_mselect(nc, ns); sopts.title = "short round title"; - ns = ncmultiselector_create(nc, 3, 0, &sopts); + ns = ncmultiselector_create(n, 3, 0, &sopts); run_mselect(nc, ns); sopts.title = "short round title"; sopts.secondary = "now this secondary is also very, very, very outlandishly long, you see"; - ns = ncmultiselector_create(nc, 3, 0, &sopts); + ns = ncmultiselector_create(n, 3, 0, &sopts); run_mselect(nc, ns); sopts.title = "the whole world is watching"; sopts.secondary = NULL; sopts.footer = "now this FOOTERFOOTER is also very, very, very outlandishly long, you see"; - ns = ncmultiselector_create(nc, 3, 0, &sopts); + ns = ncmultiselector_create(n, 3, 0, &sopts); run_mselect(nc, ns); sopts.title = "chomps"; sopts.secondary = NULL; sopts.footer = NULL; - ns = ncmultiselector_create(nc, 3, 0, &sopts); + ns = ncmultiselector_create(n, 3, 0, &sopts); run_mselect(nc, ns); if(notcurses_stop(nc)){ diff --git a/src/poc/selector.c b/src/poc/selector.c index 33c2df48e..6a480e158 100644 --- a/src/poc/selector.c +++ b/src/poc/selector.c @@ -99,28 +99,28 @@ int main(void){ ncplane_set_fg(n, 0x40f040); ncplane_putstr_aligned(n, 0, NCALIGN_RIGHT, "selector widget demo"); - struct ncselector* ns = ncselector_create(nc, 3, 0, &sopts); + struct ncselector* ns = ncselector_create(n, 3, 0, &sopts); run_selector(nc, ns); sopts.title = "short round title"; - ns = ncselector_create(nc, 3, 0, &sopts); + ns = ncselector_create(n, 3, 0, &sopts); run_selector(nc, ns); sopts.title = "short round title"; sopts.secondary = "now this secondary is also very, very, very outlandishly long, you see"; - ns = ncselector_create(nc, 3, 0, &sopts); + ns = ncselector_create(n, 3, 0, &sopts); run_selector(nc, ns); sopts.title = "the whole world is watching"; sopts.secondary = NULL; sopts.footer = "now this FOOTERFOOTER is also very, very, very outlandishly long, you see"; - ns = ncselector_create(nc, 3, 0, &sopts); + ns = ncselector_create(n, 3, 0, &sopts); run_selector(nc, ns); sopts.title = "chomps"; sopts.secondary = NULL; sopts.footer = NULL; - ns = ncselector_create(nc, 3, 0, &sopts); + ns = ncselector_create(n, 3, 0, &sopts); run_selector(nc, ns); if(notcurses_stop(nc)){ diff --git a/tests/selector.cpp b/tests/selector.cpp index b5021e37b..2eb2d2a54 100644 --- a/tests/selector.cpp +++ b/tests/selector.cpp @@ -19,7 +19,7 @@ TEST_CASE("Selectors") { SUBCASE("EmptySelector") { struct ncselector_options opts{}; - struct ncselector* ncs = ncselector_create(nc_, 0, 0, &opts); + struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts); REQUIRE(nullptr != ncs); CHECK(0 == notcurses_render(nc_)); CHECK(nullptr == ncselector_selected(ncs)); @@ -35,7 +35,7 @@ TEST_CASE("Selectors") { SUBCASE("TitledSelector") { struct ncselector_options opts{}; opts.title = strdup("hey hey whaddya say"); - struct ncselector* ncs = ncselector_create(nc_, 0, 0, &opts); + struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts); REQUIRE(nullptr != ncs); CHECK(0 == notcurses_render(nc_)); struct ncplane* ncsp = ncselector_plane(ncs); @@ -50,7 +50,7 @@ TEST_CASE("Selectors") { SUBCASE("SecondarySelector") { struct ncselector_options opts{}; opts.secondary = strdup("this is not a title, but it's not *not* a title"); - struct ncselector* ncs = ncselector_create(nc_, 0, 0, &opts); + struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts); REQUIRE(nullptr != ncs); CHECK(0 == notcurses_render(nc_)); struct ncplane* ncsp = ncselector_plane(ncs); @@ -65,7 +65,7 @@ TEST_CASE("Selectors") { SUBCASE("FooterSelector") { struct ncselector_options opts{}; opts.footer = strdup("i am a lone footer, little old footer"); - struct ncselector* ncs = ncselector_create(nc_, 0, 0, &opts); + struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts); REQUIRE(nullptr != ncs); CHECK(0 == notcurses_render(nc_)); struct ncplane* ncsp = ncselector_plane(ncs); @@ -86,7 +86,7 @@ TEST_CASE("Selectors") { struct ncselector_options opts{}; opts.items = items; opts.itemcount = sizeof(items) / sizeof(*items); - struct ncselector* ncs = ncselector_create(nc_, 0, 0, &opts); + struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts); REQUIRE(nullptr != ncs); CHECK(0 == notcurses_render(nc_)); struct ncplane* ncsp = ncselector_plane(ncs); @@ -100,7 +100,7 @@ TEST_CASE("Selectors") { SUBCASE("EmptySelectorMovement") { struct ncselector_options opts{}; - struct ncselector* ncs = ncselector_create(nc_, 0, 0, &opts); + struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts); REQUIRE(nullptr != ncs); CHECK(0 == notcurses_render(nc_)); auto sel = ncselector_selected(ncs); @@ -123,7 +123,7 @@ TEST_CASE("Selectors") { struct ncselector_options opts{}; opts.items = items; opts.itemcount = sizeof(items) / sizeof(*items); - struct ncselector* ncs = ncselector_create(nc_, 0, 0, &opts); + struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts); REQUIRE(nullptr != ncs); auto sel = ncselector_selected(ncs); REQUIRE(nullptr != sel); @@ -161,7 +161,7 @@ TEST_CASE("Selectors") { opts.maxdisplay = 1; opts.items = items; opts.itemcount = sizeof(items) / sizeof(*items); - struct ncselector* ncs = ncselector_create(nc_, 0, 0, &opts); + struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts); REQUIRE(nullptr != ncs); CHECK(0 == notcurses_render(nc_)); auto sel = ncselector_selected(ncs); @@ -204,7 +204,7 @@ TEST_CASE("Selectors") { opts.maxdisplay = 2; opts.items = items; opts.itemcount = sizeof(items) / sizeof(*items); - struct ncselector* ncs = ncselector_create(nc_, 0, 0, &opts); + struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts); REQUIRE(nullptr != ncs); CHECK(0 == notcurses_render(nc_)); const char* sel = ncselector_selected(ncs);