Subversion Repositories Kolibri OS

Rev

Rev 8762 | Rev 9180 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8762 Rev 9174
Line 19... Line 19...
19
 
19
 
Line 20... Line 20...
20
MODULE Scroll;
20
MODULE Scroll;
Line -... Line 21...
-
 
21
 
-
 
22
IMPORT G := Graph, K := KolibriOS;
-
 
23
 
-
 
24
CONST
21
 
25
 
Line 22... Line 26...
22
IMPORT G := Graph, K := KolibriOS;
26
	ScrollIPC* = 0;
23
 
27
 
-
 
28
TYPE
24
TYPE
29
 
25
 
30
	tScroll* = RECORD
26
    tScroll* = POINTER TO RECORD
31
		vertical, Inc*, Dec*, mouse*: BOOLEAN;
-
 
32
		top*, left*,
27
        vertical, mouse: BOOLEAN;
33
		width*, height*: INTEGER; (* read only *)
Line -... Line 34...
-
 
34
		btnSize, sliderSize: INTEGER;
-
 
35
		pos, Slider, pos0, maxVal*, value*: INTEGER;
-
 
36
		canvas*: G.tCanvas
-
 
37
	END;
-
 
38
 
-
 
39
 
-
 
40
PROCEDURE create* (vertical: BOOLEAN; width, height: INTEGER; btnSize, sliderSize: INTEGER; VAR scroll: tScroll);
-
 
41
BEGIN
-
 
42
	scroll.vertical := vertical;
-
 
43
	scroll.Inc := FALSE;
-
 
44
	scroll.Dec := FALSE;
-
 
45
	scroll.Slider := -1;
-
 
46
	scroll.mouse := FALSE;
-
 
47
	scroll.left := 0;
-
 
48
	scroll.top := 0;
-
 
49
	scroll.width := width;
-
 
50
	scroll.height := height;
-
 
51
	scroll.btnSize := btnSize;
-
 
52
	scroll.sliderSize := sliderSize;
-
 
53
	scroll.pos := 0;
-
 
54
	scroll.maxVal := 0;
-
 
55
	scroll.canvas := G.CreateCanvas(width, height)
-
 
56
END create;
-
 
57
 
-
 
58
 
-
 
59
PROCEDURE Rect (canvas: G.tCanvas; left, top, right, bottom: INTEGER);
-
 
60
BEGIN
28
        canvas: G.tCanvas;
61
	G.FillRect(canvas, left, top, right, bottom);
29
        xSize*, ySize*, pos, mousePos: INTEGER;
62
	G.SetColor(canvas, K.borderColor);
30
        value*, maxVal*: INTEGER
-
 
31
    END;
63
	G.Rect(canvas, left, top, right, bottom);
-
 
64
END Rect;
-
 
65
 
-
 
66
 
-
 
67
PROCEDURE _paint (scroll: tScroll);
-
 
68
VAR
-
 
69
	canvas: G.tCanvas;
-
 
70
	x, y, d, x1, x2, y1, y2,
32
 
71
	width, height, btn: INTEGER;
33
 
-
 
34
PROCEDURE draw* (scroll: tScroll; x, y: INTEGER);
-
 
35
VAR
-
 
36
    pos, a, b: INTEGER;
72
 
37
    canvas: G.tCanvas;
-
 
38
BEGIN
73
 
39
    IF scroll.vertical THEN
-
 
40
        a := scroll.ySize;
-
 
41
        b := scroll.xSize
-
 
42
    ELSE
74
	PROCEDURE SetColor (canvas: G.tCanvas; c: BOOLEAN);
43
        a := scroll.xSize;
75
	VAR
44
        b := scroll.ySize
76
		color: INTEGER;
-
 
77
	BEGIN
-
 
78
		IF c THEN
-
 
79
			color := K.btnColor
-
 
80
		ELSE
-
 
81
			color := K.btnTextColor
-
 
82
		END;
-
 
83
		G.SetColor(canvas, color)
-
 
84
	END SetColor;
45
    END;
85
 
46
    IF scroll.maxVal > 0 THEN
86
 
47
        pos := (a - b)*scroll.value DIV scroll.maxVal
87
BEGIN
48
    ELSE
88
	btn := scroll.btnSize;
49
        pos := 0
89
	width := scroll.width;
50
    END;
-
 
51
    canvas := scroll.canvas;
-
 
52
    G.SetColor(canvas, K.scrollBkColor);
90
	height := scroll.height;
-
 
91
	canvas := scroll.canvas;
53
    G.clear(canvas);
92
	G.SetColor(canvas, K.winColor);
-
 
93
	G.FillRect(canvas, 0, 0, width - 1, height - 1);
-
 
94
	G.SetColor(canvas, K.borderColor);
54
    G.SetColor(canvas, K.borderColor);
95
	G.Rect(canvas, 0, 0, width - 1, height - 1);
55
    G.Rect(canvas, 0, 0, scroll.xSize - 1, scroll.ySize - 1);
96
	IF scroll.vertical THEN
-
 
97
		SetColor(canvas, ~scroll.Dec);
56
    G.SetColor(canvas, K.scrollColor);
98
		Rect(canvas, 0, 0, width - 1, btn - 1);
-
 
99
		SetColor(canvas, ~scroll.Inc);
-
 
100
		Rect(canvas, 0, height - btn, width - 1, height - 1);
57
    DEC(b, 2);
101
		G.SetColor(canvas, K.btnColor);
58
    IF scroll.vertical THEN
102
		Rect(canvas, 0, btn + scroll.pos - 1, width - 1, btn + scroll.pos + scroll.sliderSize - 1);
59
        G.FillRect(canvas, 1, pos + 1, b, pos + b);
103
 
-
 
104
		G.SetColor(canvas, K.btnTextColor);
-
 
105
 
-
 
106
		y := btn + scroll.pos + scroll.sliderSize DIV 2 - 1;
-
 
107
		G.HLine(canvas, y, width DIV 4, 3*width DIV 4);
-
 
108
		G.HLine(canvas, y - 3, width DIV 3, 2*width DIV 3);
-
 
109
		G.HLine(canvas, y + 3, width DIV 3, 2*width DIV 3);
-
 
110
 
-
 
111
		d := 4*width DIV 10;
-
 
112
		x1 := (width - d) DIV 2;
-
 
113
		x2 := x1 + d;
-
 
114
 
-
 
115
		SetColor(canvas, scroll.Dec);
60
        G.SetColor(canvas, K.borderColor);
116
		y := (btn - d DIV 2) DIV 2 + d DIV 2 - 1;
-
 
117
		G.Triangle(canvas, x1 - 1, y, x2, y, G.triUp);
61
        G.Rect(canvas, 0, pos, b + 2, pos + b + 1);
118
 
-
 
119
		SetColor(canvas, scroll.Inc);
-
 
120
		y := y + height - btn - d DIV 2 + 1;
62
        G.SetColor(canvas, K.btnTextColor);
121
		G.Triangle(canvas, x1 - 1, y, x2, y, G.triDown);
63
        G.HLine(canvas, pos + 1 + b DIV 2, 4, b - 4);
122
	ELSE
-
 
123
		SetColor(canvas, ~scroll.Dec);
64
        G.HLine(canvas, pos + 1 + b DIV 2 - 3, 6, b - 6);
124
		Rect(canvas, 0, 0, btn - 1, height - 1);
-
 
125
		SetColor(canvas, ~scroll.Inc);
-
 
126
		Rect(canvas, width - btn, 0, width - 1, height - 1);
65
        G.HLine(canvas, pos + 1 + b DIV 2 + 3, 6, b - 6);
127
		G.SetColor(canvas, K.btnColor);
66
    ELSE
128
		Rect(canvas, btn + scroll.pos - 1, 0, btn + scroll.pos + scroll.sliderSize - 1, height - 1);
67
        G.FillRect(canvas, pos + 1, 1, pos + b, b);
129
 
-
 
130
		G.SetColor(canvas, K.btnTextColor);
-
 
131
 
-
 
132
		x := btn + scroll.pos + scroll.sliderSize DIV 2 - 1;
-
 
133
		G.VLine(canvas, x, height DIV 4, 3*height DIV 4);
-
 
134
		G.VLine(canvas, x - 3, height DIV 3, 2*height DIV 3);
-
 
135
		G.VLine(canvas, x + 3, height DIV 3, 2*height DIV 3);
-
 
136
 
-
 
137
		d := 4*height DIV 10;
-
 
138
		y1 := (height - d) DIV 2;
-
 
139
		y2 := y1 + d;
-
 
140
 
-
 
141
		SetColor(canvas, scroll.Dec);
68
        G.SetColor(canvas, K.borderColor);
142
		x := (btn - d DIV 2) DIV 2 + d DIV 2 - 1;
69
        G.Rect(canvas, pos, 0, pos + b + 1, b + 2);
-
 
70
        G.SetColor(canvas, K.btnTextColor);
143
		G.Triangle(canvas, x, y1 - 1, x, y2, G.triLeft);
71
        G.VLine(canvas, pos + b DIV 2, 4, b - 4);
144
 
Line 72... Line -...
72
        G.VLine(canvas, pos + b DIV 2 - 3, 6, b - 6);
-
 
73
        G.VLine(canvas, pos + b DIV 2 + 3, 6, b - 6);
-
 
74
    END;
145
		SetColor(canvas, scroll.Inc);
75
    scroll.pos := pos;
146
		x := x + width - btn - d DIV 2 + 1;
76
    G.DrawCanvas(canvas, x, y);
-
 
77
END draw;
-
 
78
 
-
 
79
 
-
 
80
PROCEDURE create* (xSize, ySize: INTEGER): tScroll;
147
		G.Triangle(canvas, x, y1 - 1, x, y2, G.triRight);
81
VAR
148
	END;
82
    scroll: tScroll;
-
 
83
BEGIN
-
 
84
    NEW(scroll);
149
	G.DrawCanvas(scroll.canvas, scroll.left, scroll.top)
85
    scroll.xSize := xSize;
150
END _paint;
Line 86... Line 151...
86
    scroll.ySize := ySize;
151
 
87
    scroll.vertical := xSize < ySize;
152
 
88
    scroll.maxVal := 30;
-
 
89
    scroll.value := 0;
-
 
90
    scroll.mouse := FALSE;
-
 
91
    scroll.canvas := G.CreateCanvas(xSize, ySize)
153
PROCEDURE paint* (scroll: tScroll);
92
    RETURN scroll
154
BEGIN
-
 
155
	IF scroll.canvas # NIL THEN
-
 
156
		_paint(scroll)
-
 
157
	END
93
END create;
158
END paint;
Line 94... Line 159...
94
 
159
 
95
 
160
 
96
PROCEDURE resize* (scroll: tScroll; xSize, ySize: INTEGER);
161
PROCEDURE resize* (VAR scroll: tScroll; width, height: INTEGER);
97
BEGIN
162
BEGIN
98
    scroll.xSize := xSize;
163
	G.destroy(scroll.canvas);
99
    scroll.ySize := ySize;
-
 
100
    scroll.vertical := xSize < ySize;
164
	scroll.canvas := G.CreateCanvas(width, height);
101
    G.destroy(scroll.canvas);
165
	scroll.width := width;
102
    scroll.canvas := G.CreateCanvas(xSize, ySize);
-
 
103
END resize;
166
	scroll.height := height;
104
 
167
	paint(scroll)
-
 
168
END resize;
105
 
169
 
106
PROCEDURE mouse* (scroll: tScroll; x, y: INTEGER);
170
 
-
 
171
PROCEDURE setValue* (VAR scroll: tScroll; value: INTEGER);
107
VAR
172
VAR
108
    pos, b: INTEGER;
173
	pos, maxPos, n, m: INTEGER;
-
 
174
BEGIN
109
BEGIN
175
	IF scroll.vertical THEN
110
    IF scroll.vertical THEN
176
		maxPos := scroll.height
-
 
177
	ELSE
-
 
178
		maxPos := scroll.width
-
 
179
	END;
-
 
180
	maxPos := maxPos - scroll.btnSize*2 - scroll.sliderSize + 1;
111
        pos := y - 1;
181
	IF (value < 0) OR (scroll.maxVal <= 0) THEN
-
 
182
		value := 0;
-
 
183
		pos := 0
-
 
184
	ELSIF value > scroll.maxVal THEN
-
 
185
		value := scroll.maxVal;
112
        b := scroll.xSize - 2
186
		pos := maxPos
-
 
187
	ELSE
-
 
188
		IF (maxPos + 1) >= scroll.maxVal THEN
-
 
189
			n := (maxPos + 1) DIV scroll.maxVal;
-
 
190
			m := (maxPos + 1) MOD scroll.maxVal;
-
 
191
			pos := value*n + MIN(value, m)
-
 
192
		ELSE
-
 
193
			pos := value*(maxPos + 1) DIV scroll.maxVal
-
 
194
		END;
-
 
195
		IF pos > maxPos THEN
-
 
196
			pos := maxPos;
-
 
197
			value := scroll.maxVal
-
 
198
		END
-
 
199
	END;
-
 
200
	scroll.pos := pos;
-
 
201
	scroll.value := value
-
 
202
END setValue;
-
 
203
 
-
 
204
 
-
 
205
PROCEDURE change* (VAR scroll: tScroll);
-
 
206
BEGIN
-
 
207
	IF scroll.Inc THEN
-
 
208
		setValue(scroll, scroll.value + 1)
-
 
209
	ELSIF scroll.Dec THEN
-
 
210
		setValue(scroll, scroll.value - 1)
-
 
211
	END;
-
 
212
	paint(scroll)
-
 
213
END change;
-
 
214
 
-
 
215
 
-
 
216
PROCEDURE ceil (p, q: INTEGER): INTEGER;
-
 
217
	RETURN p DIV q + ORD(p MOD q # 0)
-
 
218
END ceil;
-
 
219
 
-
 
220
 
-
 
221
PROCEDURE setPos (VAR scroll: tScroll; pos: INTEGER);
-
 
222
VAR
-
 
223
	maxPos, value, n, m, x, x0, q: INTEGER;
-
 
224
BEGIN
-
 
225
	IF scroll.maxVal > 0 THEN
113
    ELSE
226
		IF scroll.vertical THEN
-
 
227
			maxPos := scroll.height
114
        pos := x - 1;
228
		ELSE
-
 
229
			maxPos := scroll.width
-
 
230
		END;
-
 
231
		maxPos := maxPos - scroll.btnSize*2 - scroll.sliderSize + 1;
-
 
232
		IF pos <= 0 THEN
-
 
233
			pos := 0;
-
 
234
			value := 0
-
 
235
		ELSIF pos >= maxPos THEN
-
 
236
			pos := maxPos;
-
 
237
			value := scroll.maxVal
115
        b := scroll.ySize - 2
238
		ELSE
-
 
239
			IF scroll.maxVal <= maxPos + 1 THEN
-
 
240
				n := (maxPos + 1) DIV scroll.maxVal;
-
 
241
				m := (maxPos + 1) MOD scroll.maxVal;
-
 
242
 
116
    END;
243
				q := m*(n + 1);
-
 
244
				IF q < pos THEN
-
 
245
					value := ceil(pos - m, n)
-
 
246
				ELSIF q > pos THEN
-
 
247
					value := ceil(pos, n + 1)
-
 
248
				ELSE
-
 
249
					value := m
-
 
250
				END;
-
 
251
 
-
 
252
				x := value*n + MIN(value, m);
-
 
253
				x0 := (value - 1)*n + MIN(value - 1, m);
-
 
254
 
-
 
255
				IF x - pos > pos - x0 THEN
-
 
256
					pos := x0;
-
 
257
					DEC(value)
-
 
258
				ELSE
117
    IF ~scroll.mouse THEN
259
					pos := x;
-
 
260
					IF pos > maxPos THEN
-
 
261
						pos := maxPos;
-
 
262
						value := scroll.maxVal
-
 
263
					END
-
 
264
				END
-
 
265
			ELSE
-
 
266
				value := scroll.maxVal*pos DIV (maxPos + 1)
-
 
267
			END
-
 
268
		END
-
 
269
	ELSE
-
 
270
		pos := 0;
-
 
271
		scroll.value := 0
-
 
272
	END;
-
 
273
	scroll.pos := pos;
-
 
274
	scroll.value := value
-
 
275
END setPos;
-
 
276
 
-
 
277
 
-
 
278
PROCEDURE isActive* (scroll: tScroll): BOOLEAN;
-
 
279
	RETURN scroll.Inc OR scroll.Dec OR (scroll.Slider # -1)
-
 
280
END isActive;
-
 
281
 
-
 
282
 
-
 
283
PROCEDURE MouseMove* (VAR scroll: tScroll; x, y: INTEGER);
-
 
284
VAR
-
 
285
	c: INTEGER;
-
 
286
BEGIN
-
 
287
	IF scroll.Slider # -1 THEN
-
 
288
		IF scroll.vertical THEN
-
 
289
			c := y - scroll.top
-
 
290
		ELSE
-
 
291
			c := x - scroll.left
-
 
292
		END;
-
 
293
		setPos(scroll, scroll.pos0 + c - scroll.Slider);
-
 
294
		paint(scroll)
-
 
295
	END
-
 
296
END MouseMove;
-
 
297
 
-
 
298
 
-
 
299
PROCEDURE between (a, b, c: INTEGER): BOOLEAN;
-
 
300
	RETURN (a <= b) & (b <= c)
-
 
301
END between;
-
 
302
 
-
 
303
 
-
 
304
PROCEDURE SendIPC*;
-
 
305
BEGIN
118
        scroll.mouse := TRUE;
306
	K.SendIPC(K.ThreadID(), ScrollIPC)
-
 
307
END SendIPC;
-
 
308
 
-
 
309
 
-
 
310
PROCEDURE MouseDown* (VAR scroll: tScroll; x, y: INTEGER);
-
 
311
VAR
-
 
312
	c, size: INTEGER;
-
 
313
BEGIN
-
 
314
	x := x - scroll.left;
-
 
315
	y := y - scroll.top;
-
 
316
	scroll.mouse := TRUE;
-
 
317
	IF between(0, x, scroll.width - 1) & between(0, y, scroll.height - 1) THEN
-
 
318
		IF scroll.vertical THEN
-
 
319
			c := y;
-
 
320
			size := scroll.height
-
 
321
		ELSE
-
 
322
			c := x;
-
 
323
			size := scroll.width
-
 
324
		END;
-
 
325
		IF between(scroll.btnSize + scroll.pos - 1, c, scroll.btnSize + scroll.pos + scroll.sliderSize - 1) THEN
119
        IF (scroll.pos <= pos) & (pos <= scroll.pos + b - 1) THEN
326
			scroll.pos0 := scroll.pos;
-
 
327
			scroll.Slider := c
-
 
328
		ELSE
-
 
329
			IF between(0, c, scroll.btnSize - 1) THEN
120
            scroll.mousePos := pos - scroll.pos
330
				scroll.Dec := TRUE;
-
 
331
				SendIPC
-
 
332
			ELSE
121
        ELSE
333
				IF between(size - scroll.btnSize, c, size - 1) THEN
Line 122... Line 334...
122
            scroll.mousePos := b DIV 2;
334
					scroll.Inc := TRUE;
123
            scroll.value := (pos - scroll.mousePos)*scroll.maxVal DIV ABS(scroll.xSize - scroll.ySize)
335
					SendIPC
124
        END
336
				ELSE
-
 
337
					setPos(scroll, c - scroll.btnSize - scroll.sliderSize DIV 2);
-
 
338
					scroll.pos0 := scroll.pos;
-
 
339
					scroll.Slider := c;
125
    ELSE
340
					paint(scroll)
-
 
341
				END
126
        scroll.value := (pos - scroll.mousePos)*scroll.maxVal DIV ABS(scroll.xSize - scroll.ySize)
342
			END
127
    END;
343
		END
Line 128... Line 344...
128
    IF scroll.value < 0 THEN
344
	END
129
        scroll.value := 0
345
END MouseDown;