From bac02bccd06e328c46365dadf863d35b601ca443 Mon Sep 17 00:00:00 2001 From: nick black Date: Tue, 28 Jul 2020 22:42:49 -0400 Subject: [PATCH] selector/multiselect: kill itemcount options field #831 --- doc/man/man3/notcurses_multiselector.3.md | 1 - doc/man/man3/notcurses_selector.3.md | 1 - include/notcurses/notcurses.h | 6 ++---- src/lib/selector.c | 26 +++++++++++++++++------ src/libcpp/MultiSelector.cc | 1 - src/libcpp/Selector.cc | 1 - src/poc/multiselect.c | 9 +++++--- src/poc/selector.c | 2 +- tests/selector.cpp | 4 ---- 9 files changed, 28 insertions(+), 23 deletions(-) diff --git a/doc/man/man3/notcurses_multiselector.3.md b/doc/man/man3/notcurses_multiselector.3.md index 8f44d7f53..97eeaf564 100644 --- a/doc/man/man3/notcurses_multiselector.3.md +++ b/doc/man/man3/notcurses_multiselector.3.md @@ -27,7 +27,6 @@ typedef struct ncmultiselector_options { char* secondary; // secondary may be NULL char* footer; // footer may be NULL struct ncmselector_item* items; // initial items, statuses - unsigned itemcount; // number of initial items // default item (selected at start) unsigned defidx; // maximum number of options to display at once diff --git a/doc/man/man3/notcurses_selector.3.md b/doc/man/man3/notcurses_selector.3.md index 52e649210..8432b77fd 100644 --- a/doc/man/man3/notcurses_selector.3.md +++ b/doc/man/man3/notcurses_selector.3.md @@ -26,7 +26,6 @@ typedef struct ncselector_options { char* secondary; // secondary may be NULL char* footer; // footer may be NULL struct ncselector_item* items; // initial items and descriptions - unsigned itemcount; // number of initial items and descriptions // default item (selected at start) unsigned defidx; // maximum number of options to display at once diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 1c3efa8d7..fb10bb7d7 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -2664,9 +2664,8 @@ typedef struct ncselector_options { char* secondary; // secondary may be NULL char* footer; // footer may be NULL struct ncselector_item* items; // initial items and descriptions - unsigned itemcount; // number of initial items and descriptions - // default item (selected at start), must be < itemcount unless 'itemcount' - // is 0, in which case 'defidx' must also be 0 + // default item (selected at start), must be < itemcount unless itemcount is + // 0, in which case 'defidx' must also be 0 unsigned defidx; // maximum number of options to display at once, 0 to use all available space unsigned maxdisplay; @@ -2742,7 +2741,6 @@ typedef struct ncmultiselector_options { char* secondary; // secondary may be NULL char* footer; // footer may be NULL struct ncmselector_item* items; // initial items, descriptions, and statuses - unsigned itemcount; // number of items and descriptions, can't be 0 // maximum number of options to display at once, 0 to use all available space unsigned maxdisplay; // exhaustive styling options diff --git a/src/lib/selector.c b/src/lib/selector.c index 6ba504a03..175af598f 100644 --- a/src/lib/selector.c +++ b/src/lib/selector.c @@ -178,7 +178,13 @@ ncselector_dim_yx(notcurses* nc, const ncselector* n, int* ncdimy, int* ncdimx){ } ncselector* ncselector_create(ncplane* nc, int y, int x, const ncselector_options* opts){ - if(opts->defidx && opts->defidx >= opts->itemcount){ + unsigned itemcount = 0; + if(opts->items){ + for(const struct ncselector_item* i = opts->items ; i->option ; ++i){ + ++itemcount; + } + } + if(opts->defidx && opts->defidx >= itemcount){ return NULL; } ncselector* ns = malloc(sizeof(*ns)); @@ -200,8 +206,8 @@ ncselector* ncselector_create(ncplane* nc, int y, int x, const ncselector_option ns->footchannels = opts->footchannels; ns->boxchannels = opts->boxchannels; ns->darrowy = ns->uarrowy = ns->arrowx = -1; - if(opts->itemcount){ - if(!(ns->items = malloc(sizeof(*ns->items) * opts->itemcount))){ + if(itemcount){ + if(!(ns->items = malloc(sizeof(*ns->items) * itemcount))){ free(ns->title); free(ns->secondary); free(ns->footer); free(ns); return NULL; @@ -209,7 +215,7 @@ ncselector* ncselector_create(ncplane* nc, int y, int x, const ncselector_option }else{ ns->items = NULL; } - for(ns->itemcount = 0 ; ns->itemcount < opts->itemcount ; ++ns->itemcount){ + for(ns->itemcount = 0 ; ns->itemcount < itemcount ; ++ns->itemcount){ const struct ncselector_item* src = &opts->items[ns->itemcount]; int cols = mbswidth(src->option); ns->items[ns->itemcount].opcolumns = cols; @@ -675,6 +681,12 @@ ncmultiselector_dim_yx(notcurses* nc, const ncmultiselector* n, int* ncdimy, int ncmultiselector* ncmultiselector_create(ncplane* nc, int y, int x, const ncmultiselector_options* opts){ + unsigned itemcount = 0; + if(opts->items){ + for(const struct ncmselector_item* i = opts->items ; i->option ; ++i){ + ++itemcount; + } + } ncmultiselector* ns = malloc(sizeof(*ns)); ns->title = opts->title ? strdup(opts->title) : NULL; ns->titlecols = opts->title ? mbswidth(opts->title) : 0; @@ -693,8 +705,8 @@ ncmultiselector* ncmultiselector_create(ncplane* nc, int y, int x, ns->footchannels = opts->footchannels; ns->boxchannels = opts->boxchannels; ns->darrowy = ns->uarrowy = ns->arrowx = -1; - if(opts->itemcount){ - if(!(ns->items = malloc(sizeof(*ns->items) * opts->itemcount))){ + if(itemcount){ + if(!(ns->items = malloc(sizeof(*ns->items) * itemcount))){ free(ns->title); free(ns->secondary); free(ns->footer); free(ns); return NULL; @@ -702,7 +714,7 @@ ncmultiselector* ncmultiselector_create(ncplane* nc, int y, int x, }else{ ns->items = NULL; } - for(ns->itemcount = 0 ; ns->itemcount < opts->itemcount ; ++ns->itemcount){ + for(ns->itemcount = 0 ; ns->itemcount < itemcount ; ++ns->itemcount){ const struct ncmselector_item* src = &opts->items[ns->itemcount]; int cols = mbswidth(src->option); if(cols > ns->longitem){ diff --git a/src/libcpp/MultiSelector.cc b/src/libcpp/MultiSelector.cc index 8bb04ef31..4b30aec0e 100644 --- a/src/libcpp/MultiSelector.cc +++ b/src/libcpp/MultiSelector.cc @@ -8,7 +8,6 @@ ncmultiselector_options MultiSelector::default_options = { /* secondary */ nullptr, /* footer */ nullptr, /* items */ nullptr, - /* itemcount */ 0, /* maxdisplay */ 0, /* opchannels */ 0, /* descchannels */ 0, diff --git a/src/libcpp/Selector.cc b/src/libcpp/Selector.cc index c91a7147a..92af68064 100644 --- a/src/libcpp/Selector.cc +++ b/src/libcpp/Selector.cc @@ -8,7 +8,6 @@ ncselector_options Selector::default_options = { /* secondary */ nullptr, /* footer */ nullptr, /* items */ nullptr, - /* itemcount */ 0, /* defidx */ 0, /* maxdisplay */ 0, /* opchannels */ 0, diff --git a/src/poc/multiselect.c b/src/poc/multiselect.c index bdfc88163..33aced471 100644 --- a/src/poc/multiselect.c +++ b/src/poc/multiselect.c @@ -18,6 +18,7 @@ static struct ncmselector_item items[] = { { "9", "And, eventually noticing the rest of the world was there,", .selected = false, }, { "10", "Decided to rule it.", .selected = false, }, { "11", "This is their story.", .selected = false, }, + { NULL, NULL, .selected = false, }, }; static void @@ -66,17 +67,19 @@ int main(void){ memset(&sopts, 0, sizeof(sopts)); sopts.maxdisplay = 10; sopts.items = items; - sopts.itemcount = sizeof(items) / sizeof(*items); sopts.title = "this is truly an awfully long example of a MULTISELECTOR title"; sopts.secondary = "pick one (you will die regardless)"; sopts.footer = "press q to exit (there is sartrev(\"no exit\"))"; channels_set_fg(&sopts.boxchannels, 0x20e0e0); + channels_set_bg(&sopts.boxchannels, 0x200000); channels_set_fg(&sopts.opchannels, 0xe08040); - channels_set_fg(&sopts.descchannels, 0xe0e040); channels_set_bg(&sopts.opchannels, 0); + channels_set_fg(&sopts.descchannels, 0xe0e040); channels_set_bg(&sopts.descchannels, 0); channels_set_fg(&sopts.footchannels, 0xe00040); - channels_set_fg(&sopts.titlechannels, 0x80ffff); + channels_set_bg(&sopts.footchannels, 0x202000); + channels_set_fg(&sopts.titlechannels, 0x20ffff); + channels_set_bg(&sopts.titlechannels, 0x000020); channels_set_fg(&sopts.bgchannels, 0x002000); channels_set_bg(&sopts.bgchannels, 0x002000); channels_set_fg_alpha(&sopts.bgchannels, CELL_ALPHA_BLEND); diff --git a/src/poc/selector.c b/src/poc/selector.c index 6f58e644b..d59000ebb 100644 --- a/src/poc/selector.c +++ b/src/poc/selector.c @@ -17,6 +17,7 @@ static struct ncselector_item items[] = { SITEM("8 8 8", "the chinese 平仮名平平仮名仮名love me, i'm told"), SITEM("nine", "nine, nine, nine 'cause you left me"), SITEM("ten", "stunning and brave"), + SITEM(NULL, NULL), #undef SITEM }; @@ -66,7 +67,6 @@ int main(void){ memset(&sopts, 0, sizeof(sopts)); sopts.maxdisplay = 4; sopts.items = items; - sopts.itemcount = sizeof(items) / sizeof(*items); sopts.title = "this is truly, absolutely an awfully long example of a selector title"; sopts.secondary = "pick one (you will die regardless)"; sopts.footer = "press q to exit (there is no exit)"; diff --git a/tests/selector.cpp b/tests/selector.cpp index aaaa11744..b85a1eab2 100644 --- a/tests/selector.cpp +++ b/tests/selector.cpp @@ -79,7 +79,6 @@ TEST_CASE("Selectors") { }; struct ncselector_options opts{}; opts.items = items; - opts.itemcount = sizeof(items) / sizeof(*items); struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts); REQUIRE(nullptr != ncs); CHECK(0 == notcurses_render(nc_)); @@ -116,7 +115,6 @@ TEST_CASE("Selectors") { }; struct ncselector_options opts{}; opts.items = items; - opts.itemcount = sizeof(items) / sizeof(*items); struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts); REQUIRE(nullptr != ncs); auto sel = ncselector_selected(ncs); @@ -154,7 +152,6 @@ TEST_CASE("Selectors") { struct ncselector_options opts{}; opts.maxdisplay = 1; opts.items = items; - opts.itemcount = sizeof(items) / sizeof(*items); struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts); REQUIRE(nullptr != ncs); CHECK(0 == notcurses_render(nc_)); @@ -197,7 +194,6 @@ TEST_CASE("Selectors") { struct ncselector_options opts{}; opts.maxdisplay = 2; opts.items = items; - opts.itemcount = sizeof(items) / sizeof(*items); struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts); REQUIRE(nullptr != ncs); CHECK(0 == notcurses_render(nc_));