ref: cdb993dffbd3050112b2fc3a93d7f51eead2ec74
parent: 91c36955994c33885bb695aea30d4746c35f4c09
author: phil9 <telephil9@gmail.com>
date: Fri Feb 4 13:15:38 EST 2022
improve selection in index cleanup the code, fix some redraw issues and limit the number of full redraws.
--- a/index.c
+++ b/index.c
@@ -81,25 +81,40 @@
return mbox->list->elts[index];
}
+Rectangle
+messagerect(int index)
+{
+ Point p, q;
+ int n;
+
+ n = index - offset;
+ p = addpt(listr.min, Pt(Padding, n*lineh + Padding));
+ q = Pt(listr.max.x, p.y + lineh);
+ return Rpt(p, q);
+}
+
void
-drawmessage(Message *m, Point p, int selected)
+drawmessage(int index, int selected)
{
const Rune *ellipsis = L"…";
+ Message *m;
Image *fg, *bg;
- char *s, buf[9];
- char n, r;
+ char *s, buf[9], n, r;
Tm t;
Rune rn;
int i, w;
- Point pe;
+ Rectangle lr;
+ Point p, pe;
- bg = cols[HIGH];
+ lr = messagerect(index);
+ bg = selected ? cols[HIGH] : cols[BACK];
fg = cols[TEXT];
- if(selected)
- draw(screen, Rect(p.x, p.y-Padding/2, p.x+Dx(viewr), p.y+lineh-Padding/2), bg, nil, ZP);
+ draw(screen, rectsubpt(lr, Pt(0, Padding/2)), bg, nil, ZP);
+ m = messageat(index);
n = m->flags&Fseen?' ':'N';
r = m->flags&Fanswered ? 'R':' ';
snprint(buf, sizeof buf, "[%c%c] ", n, r);
+ p = lr.min;
p = string(screen, p, fg, ZP, font, buf);
tmtime(&t, m->time, nil);
snprint(buf, sizeof buf, "%τ", tmfmt(&t, "DD/MM/YY"));
@@ -136,7 +151,6 @@
indexdraw(void)
{
Rectangle scrposr;
- Point p;
int i, h, y;
draw(screen, viewr, cols[BACK], nil, ZP);
@@ -147,12 +161,10 @@
h = Scrollminh;
scrposr = Rpt(addpt(scrollr.min, Pt(0,y)), addpt(scrollr.min, Pt(Dx(scrollr)-1, y+h)));
draw(screen, scrposr, cols[BACK], nil, ZP);
- p = addpt(listr.min, Pt(Padding, Padding));
for(i = offset; i < offset + nlines; i++){
if(i >= mbox->list->nelts)
break;
- drawmessage(messageat(i), p, i == sel);
- p.y += lineh;
+ drawmessage(i, i == sel);
}
}
@@ -210,7 +222,7 @@
}
void
-scroll(int Δ, int ssel)
+scroll(int Δ)
{
int nelts;
@@ -226,34 +238,41 @@
offset = 0;
if(offset + nelts%nlines >= nelts)
offset = nelts - nelts%nlines;
- if(ssel){
- if(Δ > 0)
- sel = 0;
- else
- sel = nlines - 1;
- }
indexdrawsync();
}
void
-changesel(int Δ)
+select(int newsel, Channel *c)
{
- if(Δ < 0 && sel == 0)
+ int n;
+
+ if(newsel < 0)
+ newsel = 0;
+ if(newsel >= mbox->count)
+ newsel = mbox->count - 1;
+ if(newsel == sel)
return;
- if(Δ > 0 && sel == mbox->count - 1)
- return;
- sel += Δ;
- indexdrawsync();
+ if(newsel < offset || newsel >= offset + nlines){
+ sel = newsel;
+ offset = nlines*(sel/nlines);
+ n = mbox->list->nelts;
+ if(offset + n%nlines >= n)
+ offset = n - n%nlines;
+ indexdraw();
+ }else{
+ drawmessage(sel, 0);
+ drawmessage(newsel, 1);
+ sel = newsel;
+ }
+ flushimage(display, 1);
+ sendp(c, messageat(sel));
}
-void
-setsel(Point p)
+static
+int
+indexat(Point p)
{
- int n;
-
- n = (p.y-listr.min.y)/lineh;
- sel = n+offset;
- indexdrawsync();
+ return offset + (p.y-listr.min.y)/lineh;
}
void
@@ -263,75 +282,49 @@
if(!ptinrect(m.xy, viewr))
return;
- if(m.buttons & 1){
- setsel(m.xy);
- sendp(selc, messageat(sel));
- }else if(m.buttons & 2){
- /* TODO: menu */
- }else if(m.buttons & 4){
- setsel(m.xy);
- sendp(showc, messageat(sel));
- }else if(m.buttons & 8){
- sl = mousescrollsize(nlines);
- scroll(-sl, 0);
- }else if(m.buttons & 16){
- sl = mousescrollsize(nlines);
- scroll(sl, 0);
+ if(ptinrect(m.xy, listr)){
+ if(m.buttons & 1){
+ select(indexat(m.xy), selc);
+ }else if(m.buttons & 2){
+ /* TODO: menu */
+ }else if(m.buttons & 4){
+ select(indexat(m.xy), showc);
+ }else if(m.buttons & 8){
+ sl = mousescrollsize(nlines);
+ scroll(-sl);
+ }else if(m.buttons & 16){
+ sl = mousescrollsize(nlines);
+ scroll(sl);
+ }
}
}
+
void
indexkey(Rune k)
{
switch(k){
- case Kup:
- if(sel == offset)
- scroll(-nlines, 1);
- else if(sel > offset)
- changesel(-1);
- sendp(selc, messageat(sel));
- break;
- case Kdown:
- if(sel < (mbox->count - 1)){
- if(sel == offset + nlines - 1){
- sel = offset + nlines;
- scroll(nlines, 0);
- }else
- changesel(1);
- sendp(selc, messageat(sel));
- }
- break;
- case '\n':
- sendp(showc, messageat(sel));
- break;
- case Kpgup:
- if(sel > 0){
- sel -= nlines;
- if(sel < 0)
- sel = 0;
- scroll(-nlines, 0);
- sendp(selc, messageat(sel));
- }
- break;
- case Kpgdown:
- if(sel < (mbox->count - 1)){
- sel += nlines;
- if(sel >= mbox->count)
- sel = mbox->count - 1;
- scroll(nlines, 0);
- sendp(selc, messageat(sel));
- }
- break;
- case Khome:
- sel = 0;
- scroll(-mbox->count, 0);
- sendp(selc, messageat(sel));
- break;
- case Kend:
- sel = mbox->count - 1;
- scroll(mbox->count, 0);
- sendp(selc, messageat(sel));
- break;
+ case Kup:
+ select(sel - 1, selc);
+ break;
+ case Kdown:
+ select(sel + 1, selc);
+ break;
+ case Kpgup:
+ select(sel - nlines, selc);
+ break;
+ case Kpgdown:
+ select(sel + nlines, selc);
+ break;
+ case Khome:
+ select(0, selc);
+ break;
+ case Kend:
+ select(mbox->count - 1, selc);
+ break;
+ case '\n':
+ sendp(showc, messageat(sel));
+ break;
}
}