restore ncselector_destroy API, set widget in ncreader #2347

This commit is contained in:
nick black 2021-11-17 02:02:55 -05:00
parent c5986ef508
commit 0124daf8b7
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
8 changed files with 76 additions and 62 deletions

View File

@ -55,7 +55,7 @@ typedef struct ncselector_options {
**bool ncselector_offer_input(struct ncselector* ***n***, const ncinput* ***nc***);** **bool ncselector_offer_input(struct ncselector* ***n***, const ncinput* ***nc***);**
**void ncselector_destroy(struct ncselector* ***n***);** **void ncselector_destroy(struct ncselector* ***n***, char** ***item***);**
# DESCRIPTION # DESCRIPTION

View File

@ -38,7 +38,7 @@ namespace ncpp
~Selector () ~Selector ()
{ {
if (!is_notcurses_stopped ()) if (!is_notcurses_stopped ())
ncselector_destroy (selector); ncselector_destroy (selector, nullptr);
} }
int additem (const ncselector_item *item) const NOEXCEPT_MAYBE int additem (const ncselector_item *item) const NOEXCEPT_MAYBE

View File

@ -3609,7 +3609,7 @@ API bool ncselector_offer_input(struct ncselector* n, const ncinput* nc)
__attribute__ ((nonnull (1, 2))); __attribute__ ((nonnull (1, 2)));
// Destroy the ncselector. // Destroy the ncselector.
API void ncselector_destroy(struct ncselector* n); API void ncselector_destroy(struct ncselector* n, char** item);
struct ncmselector_item { struct ncmselector_item {
const char* option; const char* option;

View File

@ -429,7 +429,7 @@ reader_demo(struct notcurses* nc){
} }
done: done:
ncselector_destroy(selector); ncselector_destroy(selector, NULL);
ncmultiselector_destroy(mselector); ncmultiselector_destroy(mselector);
ncplane_destroy(rp); ncplane_destroy(rp);
return ret; return ret;

View File

@ -1,5 +1,26 @@
#include "internal.h" #include "internal.h"
static void
ncreader_destroy_internal(ncreader* n){
if(n){
if(n->manage_cursor){
notcurses_cursor_disable(ncplane_notcurses(n->ncp));
}
ncplane_destroy(n->textarea);
ncplane_destroy(n->ncp);
free(n);
}
}
void ncreader_destroy(ncreader* n, char** contents){
if(n){
if(contents){
*contents = ncreader_contents(n);
}
ncreader_destroy_internal(n);
}
}
ncreader* ncreader_create(ncplane* n, const ncreader_options* opts){ ncreader* ncreader_create(ncplane* n, const ncreader_options* opts){
ncreader_options zeroed = {}; ncreader_options zeroed = {};
if(!opts){ if(!opts){
@ -37,6 +58,12 @@ ncreader* ncreader_create(ncplane* n, const ncreader_options* opts){
nr->manage_cursor = opts->flags & NCREADER_OPTION_CURSOR; nr->manage_cursor = opts->flags & NCREADER_OPTION_CURSOR;
ncplane_set_channels(nr->ncp, opts->tchannels); ncplane_set_channels(nr->ncp, opts->tchannels);
ncplane_set_styles(nr->ncp, opts->tattrword); ncplane_set_styles(nr->ncp, opts->tattrword);
if(ncplane_set_widget(n, nr, (void(*)(void*))ncreader_destroy_internal)){
ncplane_destroy(nr->textarea);
ncplane_destroy(nr->ncp);
free(nr);
return NULL;
}
return nr; return nr;
} }
@ -383,17 +410,3 @@ bool ncreader_offer_input(ncreader* n, const ncinput* ni){
char* ncreader_contents(const ncreader* n){ char* ncreader_contents(const ncreader* n){
return ncplane_contents(n->ncp, 0, 0, 0, 0); return ncplane_contents(n->ncp, 0, 0, 0, 0);
} }
void ncreader_destroy(ncreader* n, char** contents){
if(n){
if(contents){
*contents = ncreader_contents(n);
}
if(n->manage_cursor){
notcurses_cursor_disable(ncplane_notcurses(n->ncp));
}
ncplane_destroy(n->textarea);
ncplane_destroy(n->ncp);
free(n);
}
}

View File

@ -249,6 +249,34 @@ ncselector_dim_yx(const ncselector* n, unsigned* ncdimy, unsigned* ncdimx){
*ncdimx = cols; *ncdimx = cols;
} }
static void
ncselector_destroy_internal(ncselector* n){
if(n){
while(n->itemcount--){
free(n->items[n->itemcount].option);
free(n->items[n->itemcount].desc);
}
if(ncplane_set_widget(n->ncp, NULL, NULL) == 0){
ncplane_destroy(n->ncp);
}
free(n->items);
free(n->title);
free(n->secondary);
free(n->footer);
free(n);
}
}
void ncselector_destroy(ncselector* n, char** item){
if(n){
if(item){
*item = n->items[n->selected].option;
n->items[n->selected].option = NULL;
}
ncselector_destroy_internal(n);
}
}
ncselector* ncselector_create(ncplane* n, const ncselector_options* opts){ ncselector* ncselector_create(ncplane* n, const ncselector_options* opts){
if(n == notcurses_stdplane(ncplane_notcurses(n))){ if(n == notcurses_stdplane(ncplane_notcurses(n))){
logerror("won't use the standard plane\n"); // would fail later on resize logerror("won't use the standard plane\n"); // would fail later on resize
@ -269,13 +297,11 @@ ncselector* ncselector_create(ncplane* n, const ncselector_options* opts){
} }
ncselector* ns = malloc(sizeof(*ns)); ncselector* ns = malloc(sizeof(*ns));
if(ns == NULL){ if(ns == NULL){
fprintf(stderr, "SHIT -3\n");
return NULL; return NULL;
} }
memset(ns, 0, sizeof(*ns)); memset(ns, 0, sizeof(*ns));
if(opts->defidx && opts->defidx >= itemcount){ if(opts->defidx && opts->defidx >= itemcount){
logerror("default index %u too large (%u items)\n", opts->defidx, itemcount); logerror("default index %u too large (%u items)\n", opts->defidx, itemcount);
fprintf(stderr, "SHIT -2\n");
goto freeitems; goto freeitems;
} }
ns->title = opts->title ? strdup(opts->title) : NULL; ns->title = opts->title ? strdup(opts->title) : NULL;
@ -305,7 +331,6 @@ fprintf(stderr, "SHIT -2\n");
ns->darrowy = ns->uarrowy = ns->arrowx = -1; ns->darrowy = ns->uarrowy = ns->arrowx = -1;
if(itemcount){ if(itemcount){
if(!(ns->items = malloc(sizeof(*ns->items) * itemcount))){ if(!(ns->items = malloc(sizeof(*ns->items) * itemcount))){
fprintf(stderr, "SHIT -1\n");
goto freeitems; goto freeitems;
} }
}else{ }else{
@ -315,7 +340,6 @@ fprintf(stderr, "SHIT -1\n");
const struct ncselector_item* src = &opts->items[ns->itemcount]; const struct ncselector_item* src = &opts->items[ns->itemcount];
int unsafe = ncstrwidth(src->option); int unsafe = ncstrwidth(src->option);
if(unsafe < 0){ if(unsafe < 0){
fprintf(stderr, "SHIT 0\n");
goto freeitems; goto freeitems;
} }
unsigned cols = unsafe; unsigned cols = unsafe;
@ -326,7 +350,6 @@ fprintf(stderr, "SHIT 0\n");
const char *desc = src->desc ? src->desc : ""; const char *desc = src->desc ? src->desc : "";
unsafe = ncstrwidth(desc); unsafe = ncstrwidth(desc);
if(unsafe < 0){ if(unsafe < 0){
fprintf(stderr, "SHIT 1\n");
goto freeitems; goto freeitems;
} }
cols = unsafe; cols = unsafe;
@ -337,7 +360,6 @@ fprintf(stderr, "SHIT 1\n");
ns->items[ns->itemcount].option = strdup(src->option); ns->items[ns->itemcount].option = strdup(src->option);
ns->items[ns->itemcount].desc = strdup(desc); ns->items[ns->itemcount].desc = strdup(desc);
if(!(ns->items[ns->itemcount].desc && ns->items[ns->itemcount].option)){ if(!(ns->items[ns->itemcount].desc && ns->items[ns->itemcount].option)){
fprintf(stderr, "SHIT 2\n");
free(ns->items[ns->itemcount].option); free(ns->items[ns->itemcount].option);
free(ns->items[ns->itemcount].desc); free(ns->items[ns->itemcount].desc);
goto freeitems; goto freeitems;
@ -347,15 +369,12 @@ fprintf(stderr, "SHIT 2\n");
ns->ncp = n; ns->ncp = n;
ncselector_dim_yx(ns, &dimy, &dimx); ncselector_dim_yx(ns, &dimy, &dimx);
if(ncplane_resize_simple(n, dimy, dimx)){ if(ncplane_resize_simple(n, dimy, dimx)){
fprintf(stderr, "SHIT 3\n");
goto freeitems; goto freeitems;
} }
if(ncplane_set_widget(ns->ncp, ns, (void(*)(void*))ncselector_destroy)){ if(ncplane_set_widget(ns->ncp, ns, (void(*)(void*))ncselector_destroy_internal)){
fprintf(stderr, "SHIT 4\n");
goto freeitems; goto freeitems;
} }
ncselector_draw(ns); // deal with error here? ncselector_draw(ns); // deal with error here?
fprintf(stderr, "RETURNING %p\n", ns);
return ns; return ns;
freeitems: freeitems:
@ -367,7 +386,6 @@ freeitems:
free(ns->title); free(ns->secondary); free(ns->footer); free(ns->title); free(ns->secondary); free(ns->footer);
free(ns); free(ns);
ncplane_destroy(n); ncplane_destroy(n);
fprintf(stderr, "RETURNING %p\n", NULL);
return NULL; return NULL;
} }
@ -565,23 +583,6 @@ bool ncselector_offer_input(ncselector* n, const ncinput* nc){
return false; return false;
} }
void ncselector_destroy(ncselector* n){
if(n){
while(n->itemcount--){
free(n->items[n->itemcount].option);
free(n->items[n->itemcount].desc);
}
if(ncplane_set_widget(n->ncp, NULL, NULL) == 0){
ncplane_destroy(n->ncp);
}
free(n->items);
free(n->title);
free(n->secondary);
free(n->footer);
free(n);
}
}
ncplane* ncmultiselector_plane(ncmultiselector* n){ ncplane* ncmultiselector_plane(ncmultiselector* n){
return n->ncp; return n->ncp;
} }

View File

@ -39,8 +39,8 @@ run_selector(struct notcurses* nc, struct ncselector* ns){
continue; continue;
} }
switch(keypress){ switch(keypress){
case NCKEY_ENTER: ncselector_destroy(ns); return; case NCKEY_ENTER: ncselector_destroy(ns, NULL); return;
case 'M': case 'J': if(ni.ctrl){ ncselector_destroy(ns); return; } case 'M': case 'J': if(ni.ctrl){ ncselector_destroy(ns, NULL); return; }
} }
if(keypress == 'q'){ if(keypress == 'q'){
break; break;
@ -48,7 +48,7 @@ run_selector(struct notcurses* nc, struct ncselector* ns){
} }
notcurses_render(nc); notcurses_render(nc);
} }
ncselector_destroy(ns); ncselector_destroy(ns, NULL);
} }
int main(void){ int main(void){

View File

@ -65,7 +65,7 @@ TEST_CASE("Selectors") {
ncplane_dim_yx(ncsp, &dimy, &dimx); ncplane_dim_yx(ncsp, &dimy, &dimx);
CHECK(4 == dimy); CHECK(4 == dimy);
CHECK(5 == dimx); CHECK(5 == dimx);
ncselector_destroy(ncs); ncselector_destroy(ncs, nullptr);
} }
SUBCASE("TitledSelector") { SUBCASE("TitledSelector") {
@ -86,7 +86,7 @@ TEST_CASE("Selectors") {
ncplane_dim_yx(ncsp, &dimy, &dimx); ncplane_dim_yx(ncsp, &dimy, &dimx);
CHECK(6 == dimy); CHECK(6 == dimy);
CHECK(strlen(opts.title) + 4 == dimx); CHECK(strlen(opts.title) + 4 == dimx);
ncselector_destroy(ncs); ncselector_destroy(ncs, nullptr);
} }
SUBCASE("SecondarySelector") { SUBCASE("SecondarySelector") {
@ -107,7 +107,7 @@ TEST_CASE("Selectors") {
ncplane_dim_yx(ncsp, &dimy, &dimx); ncplane_dim_yx(ncsp, &dimy, &dimx);
CHECK(4 == dimy); CHECK(4 == dimy);
CHECK(strlen(opts.secondary) + 2 == dimx); CHECK(strlen(opts.secondary) + 2 == dimx);
ncselector_destroy(ncs); ncselector_destroy(ncs, nullptr);
} }
SUBCASE("FooterSelector") { SUBCASE("FooterSelector") {
@ -128,7 +128,7 @@ TEST_CASE("Selectors") {
ncplane_dim_yx(ncsp, &dimy, &dimx); ncplane_dim_yx(ncsp, &dimy, &dimx);
CHECK(4 == dimy); CHECK(4 == dimy);
CHECK(strlen(opts.footer) + 2 == dimx); CHECK(strlen(opts.footer) + 2 == dimx);
ncselector_destroy(ncs); ncselector_destroy(ncs, nullptr);
} }
SUBCASE("PopulatedSelector") { SUBCASE("PopulatedSelector") {
@ -136,7 +136,7 @@ TEST_CASE("Selectors") {
{ "op1", "this is option 1", }, { "op1", "this is option 1", },
{ "2ndop", "this is option #2", }, { "2ndop", "this is option #2", },
{ "tres", "option the third", }, { "tres", "option the third", },
{ NULL, NULL, }, { nullptr, nullptr, },
}; };
struct ncselector_options opts{}; struct ncselector_options opts{};
opts.items = items; opts.items = items;
@ -154,7 +154,7 @@ TEST_CASE("Selectors") {
ncplane_dim_yx(ncsp, &dimy, &dimx); ncplane_dim_yx(ncsp, &dimy, &dimx);
CHECK(7 == dimy); CHECK(7 == dimy);
CHECK(15 < dimx); CHECK(15 < dimx);
ncselector_destroy(ncs); ncselector_destroy(ncs, nullptr);
} }
SUBCASE("EmptySelectorMovement") { SUBCASE("EmptySelectorMovement") {
@ -175,7 +175,7 @@ TEST_CASE("Selectors") {
sel = ncselector_previtem(ncs); sel = ncselector_previtem(ncs);
REQUIRE(nullptr == sel); REQUIRE(nullptr == sel);
CHECK(0 == notcurses_render(nc_)); CHECK(0 == notcurses_render(nc_));
ncselector_destroy(ncs); ncselector_destroy(ncs, nullptr);
} }
SUBCASE("SelectorMovement") { SUBCASE("SelectorMovement") {
@ -183,7 +183,7 @@ TEST_CASE("Selectors") {
{ "op1", "this is option 1", }, { "op1", "this is option 1", },
{ "2ndop", "this is option #2", }, { "2ndop", "this is option #2", },
{ "tres", "option the third", }, { "tres", "option the third", },
{ NULL, NULL, }, { nullptr, nullptr, },
}; };
struct ncselector_options opts{}; struct ncselector_options opts{};
opts.items = items; opts.items = items;
@ -216,7 +216,7 @@ TEST_CASE("Selectors") {
REQUIRE(nullptr != sel); REQUIRE(nullptr != sel);
CHECK(0 == strcmp(sel, items[0].option)); CHECK(0 == strcmp(sel, items[0].option));
CHECK(0 == notcurses_render(nc_)); CHECK(0 == notcurses_render(nc_));
ncselector_destroy(ncs); ncselector_destroy(ncs, nullptr);
} }
// Provide three items, limited to 1 shown at a time // Provide three items, limited to 1 shown at a time
@ -225,7 +225,7 @@ TEST_CASE("Selectors") {
{ "op1", "this is option 1", }, { "op1", "this is option 1", },
{ "2ndop", "this is option #2", }, { "2ndop", "this is option #2", },
{ "tres", "option the third", }, { "tres", "option the third", },
{ NULL, NULL, }, { nullptr, nullptr, },
}; };
struct ncselector_options opts{}; struct ncselector_options opts{};
opts.maxdisplay = 1; opts.maxdisplay = 1;
@ -264,7 +264,7 @@ TEST_CASE("Selectors") {
unsigned dimy, dimx; unsigned dimy, dimx;
ncplane_dim_yx(ncsp, &dimy, &dimx); ncplane_dim_yx(ncsp, &dimy, &dimx);
CHECK(5 == dimy); CHECK(5 == dimy);
ncselector_destroy(ncs); ncselector_destroy(ncs, nullptr);
} }
// Provide three items, limited to 2 shown at a time // Provide three items, limited to 2 shown at a time
@ -273,7 +273,7 @@ TEST_CASE("Selectors") {
{ "op1", "this is option 1", }, { "op1", "this is option 1", },
{ "2ndop", "this is option #2", }, { "2ndop", "this is option #2", },
{ "tres", "option the third", }, { "tres", "option the third", },
{ NULL, NULL, }, { nullptr, nullptr, },
}; };
struct ncselector_options opts{}; struct ncselector_options opts{};
opts.maxdisplay = 2; opts.maxdisplay = 2;
@ -311,7 +311,7 @@ TEST_CASE("Selectors") {
unsigned dimy, dimx; unsigned dimy, dimx;
ncplane_dim_yx(ncsp, &dimy, &dimx); ncplane_dim_yx(ncsp, &dimy, &dimx);
CHECK(6 == dimy); CHECK(6 == dimy);
ncselector_destroy(ncs); ncselector_destroy(ncs, nullptr);
} }
CHECK(0 == notcurses_stop(nc_)); CHECK(0 == notcurses_stop(nc_));