diff --git a/src/demo/hud.c b/src/demo/hud.c index b1305f1ac..9b00d7eb6 100644 --- a/src/demo/hud.c +++ b/src/demo/hud.c @@ -37,7 +37,6 @@ typedef struct elem { struct elem* next; } elem; -static bool menu_unrolled; static struct ncmenu* menu; static struct ncplane* about; // "about" modal popup @@ -162,6 +161,11 @@ bool menu_or_hud_key(struct notcurses *nc, const struct ncinput *ni){ if(sel == NULL){ return false; } + }else if(menu && ni->id == NCKEY_RELEASE){ + const char* sel = ncmenu_mouse_selected(menu, ni, &tmpni); + if(sel == NULL){ + memcpy(&tmpni, ni, sizeof(tmpni)); + } }else{ memcpy(&tmpni, ni, sizeof(tmpni)); } @@ -198,21 +202,11 @@ bool menu_or_hud_key(struct notcurses *nc, const struct ncinput *ni){ if(ncmenu_offer_input(menu, ni)){ return true; }else if(ni->id == 'o' && ni->alt && !ni->ctrl){ - if(ncmenu_unroll(menu, 0) == 0){ - menu_unrolled = true; - } + ncmenu_unroll(menu, 0); return true; }else if(ni->id == 'h' && ni->alt && !ni->ctrl){ - if(ncmenu_unroll(menu, 2) == 0){ - menu_unrolled = true; - } + ncmenu_unroll(menu, 2); return true; - }else if(ni->id == '\x1b'){ - if(menu_unrolled){ - ncmenu_rollup(menu); - menu_unrolled = false; - return true; - } } return false; } diff --git a/src/lib/menu.c b/src/lib/menu.c index 601cd572d..bd6a82ab1 100644 --- a/src/lib/menu.c +++ b/src/lib/menu.c @@ -511,6 +511,38 @@ const char* ncmenu_selected(const ncmenu* n, ncinput* ni){ return sec->items[itemidx].desc; } +const char* ncmenu_mouse_selected(const ncmenu* n, const ncinput* click, + ncinput* ni){ + if(click->id != NCKEY_RELEASE){ + return NULL; + } + int y, x, dimy, dimx; + struct ncplane* nc = n->ncp; + y = click->y; + x = click->x; + ncplane_dim_yx(nc, &dimy, &dimx); + if(!ncplane_translate_abs(nc, &y, &x)){ + return NULL; + } + // FIXME section_x() works only off the section header lenghts, meaning that + // if we click an item outside of those columns covered by the header, it will + // read as a -1 from section_x(). we want to instead get the unrolled section, + // find its boundaries, and verify that we are within them. + int i = section_x(n, x); + if(i < 0 || i != n->unrolledsection){ + return NULL; + } + const struct ncmenu_int_section* sec = &n->sections[n->unrolledsection]; + if(y < 2 || y - 2 >= sec->itemcount){ + return NULL; + } + const int itemidx = y - 2; + if(ni){ + memcpy(ni, &sec->items[itemidx].shortcut, sizeof(*ni)); + } + return sec->items[itemidx].desc; +} + bool ncmenu_offer_input(ncmenu* n, const ncinput* nc){ // we can't actually select menu items in this function, since we need to // invoke an arbitrary function as a result.