diff options
author | rodri <rgl@antares-labs.eu> | 2024-11-16 11:22:16 +0000 |
---|---|---|
committer | rodri <rgl@antares-labs.eu> | 2024-11-16 11:22:16 +0000 |
commit | ccd149a329f9a33195c2c6216158e283f8993076 (patch) | |
tree | 75d86a89402c424c23593ae31413c3db79dfab57 | |
parent | b555a1ad730994a42cfecf88bba15ece20d1e6f9 (diff) | |
download | battleship-ccd149a329f9a33195c2c6216158e283f8993076.tar.gz battleship-ccd149a329f9a33195c2c6216158e283f8993076.tar.bz2 battleship-ccd149a329f9a33195c2c6216158e283f8993076.zip |
fix the menulist (make it play nice with periodic refreshing).
before the addition of the timer for periodic matches updates
the menulist was supposed to be refreshed manually by the user,
and we didn't take into account the fact that every time you
clear it and refill it loses its navigational parameters, i.e.
which entry was selected and what's the offset if there are
more entries than the visible window (Maxvisitems).
so now we store those and reconfigure the menulist, adapting
to its new state, so that the user experiences as little
disruption as possible.
-rw-r--r-- | bts.c | 11 | ||||
-rw-r--r-- | dat.h | 3 | ||||
-rw-r--r-- | menulist.c | 13 |
3 files changed, 19 insertions, 8 deletions
@@ -955,6 +955,9 @@ processcmd(char *cmd) Point2 cell; uchar buf[BY2MAP]; int i, idx; + struct { + int high, off; + } menuparams; if(debug) fprint(2, "rcvd '%s'\n", cmd); @@ -987,6 +990,8 @@ processcmd(char *cmd) break; case CMmatches: if(!matches->filling){ + menuparams.high = matches->high; + menuparams.off = matches->off; matches->clear(matches); matches->filling = 1; } @@ -997,8 +1002,12 @@ processcmd(char *cmd) smprint("%s vs %s", cb->f[2], cb->f[3])); break; case CMendmatches: - if(matches->filling) + if(matches->filling){ + matches->high = min(menuparams.high, matches->nentries-1); + matches->off = menuparams.off > matches->nentries - matches->maxvis? + 0: menuparams.off; matches->filling = 0; + } break; case CMwatching: match.id = strtoul(cb->f[1], nil, 10); @@ -236,8 +236,9 @@ struct Menulist Mlist; char *title; Rectangle r, sr; /* content and scroll rects */ + int maxvis; /* max amount of visible entries */ int high; /* [-1,nitems) where -1 is none */ - int off; /* entry offset ∈ [0, nitems-Maxvisitems] */ + int off; /* entry offset ∈ [0, nitems-maxvis] */ void (*add)(Menulist*, int, char*); void (*clear)(Menulist*); @@ -32,7 +32,7 @@ menulist_add(Menulist *ml, int id, char *title) ml->r.max.x = ml->r.min.x + ew; } - if(ml->nentries > Maxvisitems){ + if(ml->nentries > ml->maxvis){ ml->sr.min = subpt(ml->r.min, Pt(Scrollwidth+2*Menuborder,0)); ml->sr.max = Pt(ml->r.min.x-2*Menuborder, ml->r.max.y); }else if(ml->nentries > 1) @@ -74,7 +74,7 @@ menulist_update(Menulist *ml, Mousectl *mc, Channel *drawchan) if(ml->nentries < 1) return -1; - r = ml->nentries > Maxvisitems? Rpt(ml->sr.min, ml->r.max): ml->r; + r = ml->nentries > ml->maxvis? Rpt(ml->sr.min, ml->r.max): ml->r; selected = -1; if(ptinrect(mc->xy, r)){ @@ -88,7 +88,7 @@ menulist_update(Menulist *ml, Mousectl *mc, Channel *drawchan) lastlmbms = mc->msec; } } - if(mc->buttons != oldm.buttons && ml->nentries > Maxvisitems) + if(mc->buttons != oldm.buttons && ml->nentries > ml->maxvis) /* scrolling */ switch(mc->buttons){ case 1: if(!ptinrect(mc->xy, ml->sr)) break; @@ -97,7 +97,7 @@ menulist_update(Menulist *ml, Mousectl *mc, Channel *drawchan) break; case 4: if(!ptinrect(mc->xy, ml->sr)) break; case 16: - ml->off = min(ml->off + (mc->xy.y - ml->sr.min.y)/(font->height+Vspace), ml->nentries-Maxvisitems); + ml->off = min(ml->off + (mc->xy.y - ml->sr.min.y)/(font->height+Vspace), ml->nentries-ml->maxvis); break; } } @@ -145,10 +145,10 @@ menulist_draw(Menulist *ml, Image *dst) } /* draw scroll */ - if(ml->nentries > Maxvisitems){ + if(ml->nentries > ml->maxvis){ border(dst, ml->sr, -Menuborder, bc, ZP); draw(dst, ml->sr, display->black, nil, ZP); - draw(dst, Rpt(addpt(ml->sr.min, Pt(0,ml->off*Dy(ml->sr)/ml->nentries)), Pt(ml->sr.max.x,ml->sr.min.y + (ml->off+Maxvisitems)*Dy(ml->sr)/ml->nentries)), display->white, nil, ZP); + draw(dst, Rpt(addpt(ml->sr.min, Pt(0,ml->off*Dy(ml->sr)/ml->nentries)), Pt(ml->sr.max.x,ml->sr.min.y + (ml->off+ml->maxvis)*Dy(ml->sr)/ml->nentries)), display->white, nil, ZP); } } @@ -164,6 +164,7 @@ newmenulist(int topmargin, char *title) w = max(stringwidth(font, title), stringwidth(font, none)); ml->r.min = Pt(SCRW/2 - w/2, topmargin); ml->r.max = addpt(ml->r.min, Pt(w, font->height+Vspace)); + ml->maxvis = Maxvisitems; ml->high = -1; ml->add = menulist_add; ml->clear = menulist_clear; |