Subversion Repositories Kolibri OS

Rev

Rev 9182 | Rev 9200 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8728 leency 1
(*
2
    Copyright 2021 Anton Krotov
3
 
4
    This file is part of CEdit.
5
 
6
    CEdit is free software: you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation, either version 3 of the License, or
9
    (at your option) any later version.
10
 
11
    CEdit is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with CEdit. If not, see .
18
*)
19
 
20
MODULE Scroll;
21
 
9187 akron1 22
IMPORT G := Graph, K := KolibriOS, U := Utils;
8728 leency 23
 
9174 akron1 24
CONST
25
 
26
	ScrollIPC* = 0;
9187 akron1 27
	Delay* = 40;
9174 akron1 28
 
8728 leency 29
TYPE
30
 
9174 akron1 31
	tScroll* = RECORD
9187 akron1 32
		vertical, Inc*, Dec*, mouse: BOOLEAN;
9174 akron1 33
		top*, left*,
34
		width*, height*: INTEGER; (* read only *)
35
		btnSize, sliderSize: INTEGER;
36
		pos, Slider, pos0, maxVal*, value*: INTEGER;
37
		canvas*: G.tCanvas
38
	END;
8728 leency 39
 
40
 
9174 akron1 41
PROCEDURE create* (vertical: BOOLEAN; width, height: INTEGER; btnSize, sliderSize: INTEGER; VAR scroll: tScroll);
9187 akron1 42
VAR
43
	res: tScroll;
8728 leency 44
BEGIN
9187 akron1 45
	res.vertical := vertical;
46
	res.Inc := FALSE;
47
	res.Dec := FALSE;
48
	res.Slider := -1;
49
	res.mouse := FALSE;
50
	res.left := 0;
51
	res.top := 0;
52
	res.width := width;
53
	res.height := height;
54
	res.btnSize := btnSize;
55
	res.sliderSize := sliderSize;
56
	res.pos := 0;
57
	res.maxVal := 0;
58
	res.canvas := G.CreateCanvas(width, height);
59
	scroll := res
9174 akron1 60
END create;
8728 leency 61
 
62
 
9174 akron1 63
PROCEDURE Rect (canvas: G.tCanvas; left, top, right, bottom: INTEGER);
64
BEGIN
65
	G.FillRect(canvas, left, top, right, bottom);
66
	G.SetColor(canvas, K.borderColor);
67
	G.Rect(canvas, left, top, right, bottom);
68
END Rect;
69
 
70
 
71
PROCEDURE _paint (scroll: tScroll);
8728 leency 72
VAR
9174 akron1 73
	canvas: G.tCanvas;
74
	x, y, d, x1, x2, y1, y2,
75
	width, height, btn: INTEGER;
76
 
77
 
78
	PROCEDURE SetColor (canvas: G.tCanvas; c: BOOLEAN);
79
	VAR
80
		color: INTEGER;
81
	BEGIN
82
		IF c THEN
83
			color := K.btnColor
84
		ELSE
85
			color := K.btnTextColor
86
		END;
87
		G.SetColor(canvas, color)
88
	END SetColor;
89
 
90
 
8728 leency 91
BEGIN
9174 akron1 92
	btn := scroll.btnSize;
93
	width := scroll.width;
94
	height := scroll.height;
95
	canvas := scroll.canvas;
96
	G.SetColor(canvas, K.winColor);
9180 akron1 97
	G.clear(canvas);
9174 akron1 98
	G.SetColor(canvas, K.borderColor);
99
	G.Rect(canvas, 0, 0, width - 1, height - 1);
100
	IF scroll.vertical THEN
101
		SetColor(canvas, ~scroll.Dec);
102
		Rect(canvas, 0, 0, width - 1, btn - 1);
103
		SetColor(canvas, ~scroll.Inc);
104
		Rect(canvas, 0, height - btn, width - 1, height - 1);
105
		G.SetColor(canvas, K.btnColor);
106
		Rect(canvas, 0, btn + scroll.pos - 1, width - 1, btn + scroll.pos + scroll.sliderSize - 1);
8728 leency 107
 
9174 akron1 108
		G.SetColor(canvas, K.btnTextColor);
8728 leency 109
 
9174 akron1 110
		y := btn + scroll.pos + scroll.sliderSize DIV 2 - 1;
111
		G.HLine(canvas, y, width DIV 4, 3*width DIV 4);
112
		G.HLine(canvas, y - 3, width DIV 3, 2*width DIV 3);
113
		G.HLine(canvas, y + 3, width DIV 3, 2*width DIV 3);
114
 
115
		d := 4*width DIV 10;
116
		x1 := (width - d) DIV 2;
117
		x2 := x1 + d;
118
 
119
		SetColor(canvas, scroll.Dec);
120
		y := (btn - d DIV 2) DIV 2 + d DIV 2 - 1;
121
		G.Triangle(canvas, x1 - 1, y, x2, y, G.triUp);
122
 
123
		SetColor(canvas, scroll.Inc);
124
		y := y + height - btn - d DIV 2 + 1;
125
		G.Triangle(canvas, x1 - 1, y, x2, y, G.triDown);
126
	ELSE
127
		SetColor(canvas, ~scroll.Dec);
128
		Rect(canvas, 0, 0, btn - 1, height - 1);
129
		SetColor(canvas, ~scroll.Inc);
130
		Rect(canvas, width - btn, 0, width - 1, height - 1);
131
		G.SetColor(canvas, K.btnColor);
132
		Rect(canvas, btn + scroll.pos - 1, 0, btn + scroll.pos + scroll.sliderSize - 1, height - 1);
133
 
134
		G.SetColor(canvas, K.btnTextColor);
135
 
136
		x := btn + scroll.pos + scroll.sliderSize DIV 2 - 1;
137
		G.VLine(canvas, x, height DIV 4, 3*height DIV 4);
138
		G.VLine(canvas, x - 3, height DIV 3, 2*height DIV 3);
139
		G.VLine(canvas, x + 3, height DIV 3, 2*height DIV 3);
140
 
141
		d := 4*height DIV 10;
142
		y1 := (height - d) DIV 2;
143
		y2 := y1 + d;
144
 
145
		SetColor(canvas, scroll.Dec);
146
		x := (btn - d DIV 2) DIV 2 + d DIV 2 - 1;
147
		G.Triangle(canvas, x, y1 - 1, x, y2, G.triLeft);
148
 
149
		SetColor(canvas, scroll.Inc);
150
		x := x + width - btn - d DIV 2 + 1;
151
		G.Triangle(canvas, x, y1 - 1, x, y2, G.triRight);
152
	END;
153
	G.DrawCanvas(scroll.canvas, scroll.left, scroll.top)
154
END _paint;
155
 
156
 
157
PROCEDURE paint* (scroll: tScroll);
8728 leency 158
BEGIN
9174 akron1 159
	IF scroll.canvas # NIL THEN
160
		_paint(scroll)
161
	END
162
END paint;
163
 
164
 
165
PROCEDURE resize* (VAR scroll: tScroll; width, height: INTEGER);
166
BEGIN
167
	G.destroy(scroll.canvas);
168
	scroll.canvas := G.CreateCanvas(width, height);
169
	scroll.width := width;
170
	scroll.height := height;
171
	paint(scroll)
8728 leency 172
END resize;
173
 
174
 
9174 akron1 175
PROCEDURE setValue* (VAR scroll: tScroll; value: INTEGER);
8728 leency 176
VAR
9174 akron1 177
	pos, maxPos, n, m: INTEGER;
8728 leency 178
BEGIN
9174 akron1 179
	IF scroll.vertical THEN
180
		maxPos := scroll.height
181
	ELSE
182
		maxPos := scroll.width
183
	END;
184
	maxPos := maxPos - scroll.btnSize*2 - scroll.sliderSize + 1;
185
	IF (value < 0) OR (scroll.maxVal <= 0) THEN
186
		value := 0;
187
		pos := 0
188
	ELSIF value > scroll.maxVal THEN
189
		value := scroll.maxVal;
190
		pos := maxPos
191
	ELSE
192
		IF (maxPos + 1) >= scroll.maxVal THEN
193
			n := (maxPos + 1) DIV scroll.maxVal;
194
			m := (maxPos + 1) MOD scroll.maxVal;
195
			pos := value*n + MIN(value, m)
196
		ELSE
197
			pos := value*(maxPos + 1) DIV scroll.maxVal
198
		END;
199
		IF pos > maxPos THEN
200
			pos := maxPos;
201
			value := scroll.maxVal
202
		END
203
	END;
204
	scroll.pos := pos;
205
	scroll.value := value
206
END setValue;
8728 leency 207
 
208
 
9174 akron1 209
PROCEDURE change* (VAR scroll: tScroll);
8728 leency 210
BEGIN
9174 akron1 211
	IF scroll.Inc THEN
212
		setValue(scroll, scroll.value + 1)
213
	ELSIF scroll.Dec THEN
214
		setValue(scroll, scroll.value - 1)
215
	END;
216
	paint(scroll)
217
END change;
218
 
219
 
220
PROCEDURE ceil (p, q: INTEGER): INTEGER;
221
	RETURN p DIV q + ORD(p MOD q # 0)
222
END ceil;
223
 
224
 
225
PROCEDURE setPos (VAR scroll: tScroll; pos: INTEGER);
226
VAR
227
	maxPos, value, n, m, x, x0, q: INTEGER;
228
BEGIN
229
	IF scroll.maxVal > 0 THEN
230
		IF scroll.vertical THEN
231
			maxPos := scroll.height
232
		ELSE
233
			maxPos := scroll.width
234
		END;
235
		maxPos := maxPos - scroll.btnSize*2 - scroll.sliderSize + 1;
236
		IF pos <= 0 THEN
237
			pos := 0;
238
			value := 0
239
		ELSIF pos >= maxPos THEN
240
			pos := maxPos;
241
			value := scroll.maxVal
242
		ELSE
243
			IF scroll.maxVal <= maxPos + 1 THEN
244
				n := (maxPos + 1) DIV scroll.maxVal;
245
				m := (maxPos + 1) MOD scroll.maxVal;
246
 
247
				q := m*(n + 1);
248
				IF q < pos THEN
249
					value := ceil(pos - m, n)
250
				ELSIF q > pos THEN
251
					value := ceil(pos, n + 1)
252
				ELSE
253
					value := m
254
				END;
255
 
256
				x := value*n + MIN(value, m);
257
				x0 := (value - 1)*n + MIN(value - 1, m);
258
 
259
				IF x - pos > pos - x0 THEN
260
					pos := x0;
261
					DEC(value)
262
				ELSE
263
					pos := x;
264
					IF pos > maxPos THEN
265
						pos := maxPos;
266
						value := scroll.maxVal
267
					END
268
				END
269
			ELSE
270
				value := scroll.maxVal*pos DIV (maxPos + 1)
271
			END
272
		END
273
	ELSE
274
		pos := 0;
275
		scroll.value := 0
276
	END;
277
	scroll.pos := pos;
278
	scroll.value := value
279
END setPos;
280
 
281
 
282
PROCEDURE isActive* (scroll: tScroll): BOOLEAN;
283
	RETURN scroll.Inc OR scroll.Dec OR (scroll.Slider # -1)
284
END isActive;
285
 
286
 
287
PROCEDURE MouseMove* (VAR scroll: tScroll; x, y: INTEGER);
288
VAR
289
	c: INTEGER;
290
BEGIN
291
	IF scroll.Slider # -1 THEN
292
		IF scroll.vertical THEN
293
			c := y - scroll.top
294
		ELSE
295
			c := x - scroll.left
296
		END;
297
		setPos(scroll, scroll.pos0 + c - scroll.Slider);
298
		paint(scroll)
299
	END
300
END MouseMove;
301
 
302
 
303
PROCEDURE SendIPC*;
304
BEGIN
305
	K.SendIPC(K.ThreadID(), ScrollIPC)
306
END SendIPC;
307
 
308
 
309
PROCEDURE MouseDown* (VAR scroll: tScroll; x, y: INTEGER);
310
VAR
311
	c, size: INTEGER;
312
BEGIN
9187 akron1 313
	IF ~scroll.mouse THEN
314
		DEC(x, scroll.left);
315
		DEC(y, scroll.top);
316
		scroll.mouse := TRUE;
317
		IF U.between(1, x, scroll.width - 2) & U.between(1, y, scroll.height - 2) 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 U.between(scroll.btnSize + scroll.pos - 1, c, scroll.btnSize + scroll.pos + scroll.sliderSize - 1) THEN
326
				scroll.pos0 := scroll.pos;
327
				scroll.Slider := c
328
			ELSIF U.between(0, c, scroll.btnSize - 1) THEN
9174 akron1 329
				scroll.Dec := TRUE;
330
				SendIPC
9187 akron1 331
			ELSIF U.between(size - scroll.btnSize, c, size - 1) THEN
332
				scroll.Inc := TRUE;
333
				SendIPC
9174 akron1 334
			ELSE
9187 akron1 335
				setPos(scroll, c - scroll.btnSize - scroll.sliderSize DIV 2);
336
				scroll.pos0 := scroll.pos;
337
				scroll.Slider := c;
338
				paint(scroll)
9174 akron1 339
			END
340
		END
341
	END
342
END MouseDown;
343
 
344
 
345
PROCEDURE MouseUp* (VAR scroll: tScroll);
346
BEGIN
347
	IF scroll.mouse THEN
348
		scroll.Slider := -1;
349
		scroll.Inc := FALSE;
350
		scroll.Dec := FALSE;
351
		scroll.mouse := FALSE;
352
		paint(scroll)
353
	END
8728 leency 354
END MouseUp;
355
 
356
 
357
END Scroll.