From 1a0e25469913abf3bd493bdc5db6807dee8cd9fd Mon Sep 17 00:00:00 2001 From: nick black Date: Mon, 7 Feb 2022 08:43:00 -0500 Subject: [PATCH] [ncmenu] detect cycles in section with all-disabled items #2606 --- doc/man/man3/notcurses_menu.3.md | 5 +++++ src/lib/menu.c | 12 +++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/doc/man/man3/notcurses_menu.3.md b/doc/man/man3/notcurses_menu.3.md index 1d29a0735..ddd02e57b 100644 --- a/doc/man/man3/notcurses_menu.3.md +++ b/doc/man/man3/notcurses_menu.3.md @@ -87,6 +87,11 @@ menu sections, clicks to dismiss the menu, Escape to dismiss the menu, left and right to change menu sections, and up and down to change menu items (these latter are only consumed if there is an actively unrolled section). +Items can be disabled with **ncmenu_item_set_status**. Pass **false** to +disable the item, or **true** to enable it. All items are enabled by +default. A disabled item will not be returned with **ncmenu_mouse_selected**, +nor reached with **ncmenu_nextsection** nor **ncmenu_prevsection**. + # RETURN VALUES **ncmenu_create** returns **NULL** on error, or a pointer to a valid new ncmenu. diff --git a/src/lib/menu.c b/src/lib/menu.c index ae82bb1bc..1a98a4ded 100644 --- a/src/lib/menu.c +++ b/src/lib/menu.c @@ -588,11 +588,14 @@ int ncmenu_nextitem(ncmenu* n){ } } ncmenu_int_section* sec = &n->sections[n->unrolledsection]; - // FIXME probably best to detect cycles + int origselected = sec->itemselected; do{ if((unsigned)++sec->itemselected == sec->itemcount){ sec->itemselected = 0; } + if(sec->itemselected == origselected){ + break; + } }while(!sec->items[sec->itemselected].desc || sec->items[sec->itemselected].disabled); return ncmenu_unroll(n, n->unrolledsection); } @@ -604,11 +607,14 @@ int ncmenu_previtem(ncmenu* n){ } } ncmenu_int_section* sec = &n->sections[n->unrolledsection]; - // FIXME probably best to detect cycles + int origselected = sec->itemselected; do{ if(sec->itemselected-- == 0){ sec->itemselected = sec->itemcount - 1; } + if(sec->itemselected == origselected){ + break; + } }while(!sec->items[sec->itemselected].desc || sec->items[sec->itemselected].disabled); return ncmenu_unroll(n, n->unrolledsection); } @@ -734,7 +740,7 @@ int ncmenu_item_set_status(ncmenu* n, const char* section, const char* item, for(unsigned ii = 0 ; ii < sec->itemcount ; ++ii){ struct ncmenu_int_item* i = &sec->items[ii]; if(strcmp(i->desc, item) == 0){ - const bool changed = i->disabled == enabled; + const bool changed = (i->disabled != enabled); i->disabled = !enabled; if(changed){ if(i->disabled){