ref: 0adb432869b58347d874cd8961584817cd478c26
dir: /scroll.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <thread.h> #include <mouse.h> #include <frame.h> #include "scroll.h" enum { Scrollwid = 12, /* width of scroll bar */ Scrollgap = 4, /* gap right of scroll bar */ }; Rectangle scrollinit(Scroll *s, Rectangle r, Image *b, Image **cols) { if(cols != nil) memmove(s->cols, cols, sizeof(s->cols)); s->r = r; s->r.max.x = r.min.x + Scrollwid; s->image = b; r.min.x += Scrollwid + Scrollgap; return r; } void scrollpos(Scroll *s, uint p₀, uint p₁, uint tot) { Rectangle q; int h; q = s->r; h = Dy(q); s->tot = tot; s->p₀ = p₀; s->p₁ = p₁; if(tot > 1024*1024){ tot >>= 10; p₀ >>= 10; p₁ >>= 10; } if(tot > 0){ q.min.y += h*p₀/tot; q.max.y = q.min.y+h*(p₁-p₀)/tot; } draw(s->image, s->r, s->cols[BORD], nil, ZP); draw(s->image, insetrect(q, 1), s->cols[BACK], nil, ZP); } int scrollactive(Scroll *s, Mouse *m) { return ptinrect(m->xy, s->r) && m->buttons; } uint scrollscr(Scroll *s, Mouse *m) { int y, h; uint p₀; p₀ = 0; h = Dy(s->r); y = m->xy.y; if(y < s->r.min.y) y = s->r.min.y; if(y > s->r.max.y) y = s->r.max.y; switch(m->buttons){ case 2: if(y > s->r.max.y-2) y = s->r.max.y-2; if(s->tot > 1024*1024) p₀ = ((s->tot>>10)*(y-s->r.min.y)/h)<<10; else p₀ = s->tot*(y-s->r.min.y)/h; break; case 1: case 8: p₀ = (s->p₁-s->p₀)*(y-s->r.min.y)/h+s->p₀; if(s->p₀ > p₀-s->p₀) p₀ = s->p₀-p₀+s->p₀; else p₀ = 0; break; case 4: case 16: p₀ = (s->p₁-s->p₀)*(y-s->r.min.y)/h+s->p₀; break; } return p₀; }