File: scroll.c

package info (click to toggle)
wily 0.13.33-3
  • links: PTS
  • area: main
  • in suites: slink
  • size: 1,500 kB
  • ctags: 1,720
  • sloc: ansic: 12,830; sh: 245; makefile: 188
file content (128 lines) | stat: -rw-r--r-- 2,594 bytes parent folder | download | duplicates (2)
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;
}