1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
#include "wily.h"
static Bitmap *dkgrey_o, *dkgrey_e;
struct Scroll {
Rectangle r;
Bitmap *b;
ulong thumb, extent, max;
};
static Rectangle getthumb(Scroll *, ulong , ulong , ulong );
/* Initialize bitmaps for scrollbars. Called once, on system entry. */
void
scroll_init(void) {
int x, y;
int dx = 4, dy = 2;
dkgrey_o = balloc(Rect(0, 0, dx, dy), 0);
bitblt(dkgrey_o, dkgrey_o->r.min, dkgrey_o, dkgrey_o->r, F);
for (x = 0; x < dx; x += 2)
for (y = (x % 4) / 2; y < dy; y += 2)
point(dkgrey_o, Pt(x, y), 0, Zero);
dkgrey_e = balloc(Rect(0, 0, dx, dy), 0);
bitblt(dkgrey_e, dkgrey_e->r.min, dkgrey_e, dkgrey_e->r, F);
for (x = 1; x < dx; x += 2)
for (y = (x % 4) / 2; y < dy; y += 2)
point(dkgrey_e, Pt(x, y), 0, Zero);
}
void
scroll_setrects(Scroll*s, Bitmap *b, Rectangle r) {
if(!s)
return;
s->r = r;
s->b = b;
s->thumb = s->extent = s->max = 0;
if(b) {
bitblt(b, r.min, b, r, Zero);
border(b, r, 1, F);
}
assert(Dx(s->r)<=SCROLLWIDTH);
}
Scroll *
scroll_alloc(Bitmap *b, Rectangle r) {
Scroll *s;
s = NEW(Scroll);
scroll_setrects(s,b,r);
return s;
}
void
scroll_set(Scroll *s, ulong thumb, ulong extent, ulong max) {
Rectangle q, oldr, newr, above, below;
oldr = getthumb(s, s->extent, s->max, s->thumb);
above = below = s->r;
above.max.y = oldr.min.y;
below.min.y = oldr.max.y;
newr = getthumb(s, extent, max, thumb);
/* Sections that before were NOT in the thumb, but now are */
q = newr;
if (rectclip(&q, above))
bitblt(s->b, q.min, s->b, q, Zero);
q = newr;
if (rectclip(&q, below))
bitblt(s->b, q.min, s->b, q, Zero);
above = below = s->r;
above.max.y = newr.min.y;
below.min.y = newr.max.y;
/* Sections that before WERE in the thumb, but now are NOT */
q = oldr;
if (rectclip(&q, above)) {
if (s->r.min.x % 2 == 0)
texture(s->b, q, dkgrey_e, S);
else
texture(s->b, q, dkgrey_o, S);
}
q = oldr;
if (rectclip(&q, below)) {
if (s->r.min.x % 2 == 0)
texture(s->b, q, dkgrey_e, S);
else
texture(s->b, q, dkgrey_o, S);
}
s->thumb = thumb;
s->extent = extent;
s->max = max;
}
static ulong
div_down(ulong p, ulong q) {
return p / q;
}
static ulong
div_up(ulong p, ulong q) {
return (p + q - 1) / q;
}
static Rectangle
getthumb(Scroll *s, ulong extent, ulong max, ulong thumb)
{
Rectangle r;
ulong length;
r = inset(s->r, 1);
assert (Dx(s->r)<= SCROLLWIDTH);
length = Dy(r);
if (extent < max) {
r.min.y = r.min.y + div_down(length * thumb, max);
if (thumb < max) {
r.max.y = r.min.y + div_up(length * extent, max);
} else
r.min.y = r.max.y;
}
return r;
}
|