From a9298e89e39691452a883b053cb138d077938372 Mon Sep 17 00:00:00 2001 From: nick black Date: Sun, 23 Feb 2020 04:14:48 -0500 Subject: [PATCH] selector: scroll with mouse #305 --- src/lib/debug.h | 27 +++++++++++++++++++++++++++ src/lib/internal.h | 1 + src/lib/selector.c | 29 +++++++++++++++++++++++++++++ src/poc/selector.c | 4 ++++ 4 files changed, 61 insertions(+) create mode 100644 src/lib/debug.h diff --git a/src/lib/debug.h b/src/lib/debug.h new file mode 100644 index 000000000..4a08ca52a --- /dev/null +++ b/src/lib/debug.h @@ -0,0 +1,27 @@ +// this file ought not be installed, nor referenced in releases. +// strictly debugging hacks. + +#ifndef NOTCURSES_DEBUG +#define NOTCURSES_DEBUG + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void +dump_plane_info(const struct notcurses* nc){ + const struct ncplane* p = nc->top; + int d = 0; + while(p){ + fprintf(stderr, "%02d] abs: %d/%d len: %d/%d cursor: %d/%d\n", d, p->absy, + p->absx, p->leny, p->lenx, p->y, p->x); + ++d; + p = p->z; + } +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib/internal.h b/src/lib/internal.h index 0a088f3e4..05fc859d9 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -179,6 +179,7 @@ typedef struct ncselector { uint64_t titlechannels; // title channels uint64_t footchannels; // secondary and footer channels uint64_t boxchannels; // border channels + int uarrowy, darrowy, arrowx;// location of scrollarrows, -1 if not present } ncselector; typedef struct ncdirect { diff --git a/src/lib/selector.c b/src/lib/selector.c index ac3c35079..3be20615c 100644 --- a/src/lib/selector.c +++ b/src/lib/selector.c @@ -80,6 +80,10 @@ ncselector_draw(ncselector* n){ if(n->maxdisplay && n->maxdisplay < n->itemcount){ n->ncp->channels = n->descchannels; ncplane_putegc_yx(n->ncp, yoff, bodywidth - (n->longdesc + 3) + xoff, "↑", NULL); + n->uarrowy = yoff; + n->arrowx = bodywidth - (n->longdesc + 3) + xoff; + }else{ + n->darrowy = n->uarrowy = n->arrowx = -1; } unsigned printidx = n->startdisp; int bodyoffset = dimx - bodywidth + 2; @@ -115,6 +119,7 @@ ncselector_draw(ncselector* n){ if(n->maxdisplay && n->maxdisplay < n->itemcount){ n->ncp->channels = n->descchannels; ncplane_putegc_yx(n->ncp, yoff, bodywidth - (n->longdesc + 3) + xoff, "↓", NULL); + n->darrowy = yoff; } return notcurses_render(n->ncp->nc); } @@ -174,6 +179,7 @@ ncselector* ncselector_create(ncplane* n, int y, int x, const selector_options* ns->titlechannels = opts->titlechannels; 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))){ free(ns->title); free(ns->secondary); free(ns->footer); @@ -321,6 +327,29 @@ bool ncselector_offer_input(ncselector* n, const ncinput* nc){ }else if(nc->id == NCKEY_DOWN){ ncselector_nextitem(n); return true; + }else if(nc->id == NCKEY_SCROLL_UP){ + ncselector_previtem(n); + return true; + }else if(nc->id == NCKEY_SCROLL_DOWN){ + ncselector_nextitem(n); + return true; + }else if(nc->id == NCKEY_RELEASE && ncplane_mouseevent_p(n->ncp, nc)){ + int y = nc->y, x = nc->x; + ncplane_translate(ncplane_stdplane(n->ncp), n->ncp, &y, &x); + if(y == n->uarrowy && x == n->arrowx){ + ncselector_previtem(n); + return true; + }else if(y == n->darrowy && x == n->arrowx){ + ncselector_nextitem(n); + return true; + }else{ + // FIXME we probably only want to consider it a click if both the release + // and the depress happened to be on us. for now, just check release. + // FIXME verify we're on the right line + // FIXME verify we're on the left of the split + // FIXME verify that we're on a visible glyph + } + return true; } return false; } diff --git a/src/poc/selector.c b/src/poc/selector.c index a1ac8851b..c166ba5a2 100644 --- a/src/poc/selector.c +++ b/src/poc/selector.c @@ -54,6 +54,10 @@ int main(void){ if(nc == NULL){ return EXIT_FAILURE; } + if(notcurses_mouse_enable(nc)){ + notcurses_stop(nc); + return EXIT_FAILURE; + } selector_options sopts; memset(&sopts, 0, sizeof(sopts)); sopts.maxdisplay = 4;