2 Copyright 2021 Anton Krotov
\r
4 This file is part of CEdit.
\r
6 CEdit is free software: you can redistribute it and/or modify
\r
7 it under the terms of the GNU General Public License as published by
\r
8 the Free Software Foundation, either version 3 of the License, or
\r
9 (at your option) any later version.
\r
11 CEdit is distributed in the hope that it will be useful,
\r
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 GNU General Public License for more details.
\r
16 You should have received a copy of the GNU General Public License
\r
17 along with CEdit. If not, see <http://www.gnu.org/licenses/>.
\r
22 IMPORT G := Graph, K := KolibriOS, U := Utils;
\r
32 vertical, Inc*, Dec*, mouse: BOOLEAN;
\r
34 width*, height*: INTEGER; (* read only *)
\r
35 btnSize, sliderSize: INTEGER;
\r
36 pos, Slider, pos0, maxVal*, value*: INTEGER;
\r
41 PROCEDURE create* (vertical: BOOLEAN; width, height: INTEGER; btnSize, sliderSize: INTEGER; VAR scroll: tScroll);
\r
45 res.vertical := vertical;
\r
53 res.height := height;
\r
54 res.btnSize := btnSize;
\r
55 res.sliderSize := sliderSize;
\r
58 res.canvas := G.CreateCanvas(width, height);
\r
63 PROCEDURE Rect (canvas: G.tCanvas; left, top, right, bottom: INTEGER);
\r
65 G.FillRect(canvas, left, top, right, bottom);
\r
66 G.SetColor(canvas, K.borderColor);
\r
67 G.Rect(canvas, left, top, right, bottom);
\r
71 PROCEDURE _paint (scroll: tScroll);
\r
74 x, y, d, x1, x2, y1, y2,
\r
75 width, height, btn: INTEGER;
\r
78 PROCEDURE SetColor (canvas: G.tCanvas; c: BOOLEAN);
\r
85 color := K.btnTextColor
\r
87 G.SetColor(canvas, color)
\r
92 btn := scroll.btnSize;
\r
93 width := scroll.width;
\r
94 height := scroll.height;
\r
95 canvas := scroll.canvas;
\r
96 G.SetColor(canvas, K.winColor);
\r
98 G.SetColor(canvas, K.borderColor);
\r
99 G.Rect(canvas, 0, 0, width - 1, height - 1);
\r
100 IF scroll.vertical THEN
\r
101 SetColor(canvas, ~scroll.Dec);
\r
102 Rect(canvas, 0, 0, width - 1, btn - 1);
\r
103 SetColor(canvas, ~scroll.Inc);
\r
104 Rect(canvas, 0, height - btn, width - 1, height - 1);
\r
105 G.SetColor(canvas, K.btnColor);
\r
106 Rect(canvas, 0, btn + scroll.pos - 1, width - 1, btn + scroll.pos + scroll.sliderSize - 1);
\r
108 G.SetColor(canvas, K.btnTextColor);
\r
110 y := btn + scroll.pos + scroll.sliderSize DIV 2 - 1;
\r
111 G.HLine(canvas, y, width DIV 4, 3*width DIV 4);
\r
112 G.HLine(canvas, y - 3, width DIV 3, 2*width DIV 3);
\r
113 G.HLine(canvas, y + 3, width DIV 3, 2*width DIV 3);
\r
115 d := 4*width DIV 10;
\r
116 x1 := (width - d) DIV 2;
\r
119 SetColor(canvas, scroll.Dec);
\r
120 y := (btn - d DIV 2) DIV 2 + d DIV 2 - 1;
\r
121 G.Triangle(canvas, x1 - 1, y, x2, y, G.triUp);
\r
123 SetColor(canvas, scroll.Inc);
\r
124 y := y + height - btn - d DIV 2 + 1;
\r
125 G.Triangle(canvas, x1 - 1, y, x2, y, G.triDown);
\r
127 SetColor(canvas, ~scroll.Dec);
\r
128 Rect(canvas, 0, 0, btn - 1, height - 1);
\r
129 SetColor(canvas, ~scroll.Inc);
\r
130 Rect(canvas, width - btn, 0, width - 1, height - 1);
\r
131 G.SetColor(canvas, K.btnColor);
\r
132 Rect(canvas, btn + scroll.pos - 1, 0, btn + scroll.pos + scroll.sliderSize - 1, height - 1);
\r
134 G.SetColor(canvas, K.btnTextColor);
\r
136 x := btn + scroll.pos + scroll.sliderSize DIV 2 - 1;
\r
137 G.VLine(canvas, x, height DIV 4, 3*height DIV 4);
\r
138 G.VLine(canvas, x - 3, height DIV 3, 2*height DIV 3);
\r
139 G.VLine(canvas, x + 3, height DIV 3, 2*height DIV 3);
\r
141 d := 4*height DIV 10;
\r
142 y1 := (height - d) DIV 2;
\r
145 SetColor(canvas, scroll.Dec);
\r
146 x := (btn - d DIV 2) DIV 2 + d DIV 2 - 1;
\r
147 G.Triangle(canvas, x, y1 - 1, x, y2, G.triLeft);
\r
149 SetColor(canvas, scroll.Inc);
\r
150 x := x + width - btn - d DIV 2 + 1;
\r
151 G.Triangle(canvas, x, y1 - 1, x, y2, G.triRight);
\r
153 G.DrawCanvas(scroll.canvas, scroll.left, scroll.top)
\r
157 PROCEDURE paint* (scroll: tScroll);
\r
159 IF scroll.canvas # NIL THEN
\r
165 PROCEDURE resize* (VAR scroll: tScroll; width, height: INTEGER);
\r
167 G.destroy(scroll.canvas);
\r
168 scroll.canvas := G.CreateCanvas(width, height);
\r
169 scroll.width := width;
\r
170 scroll.height := height;
\r
175 PROCEDURE setValue* (VAR scroll: tScroll; value: INTEGER);
\r
177 pos, maxPos, n, m: INTEGER;
\r
179 IF scroll.vertical THEN
\r
180 maxPos := scroll.height
\r
182 maxPos := scroll.width
\r
184 maxPos := maxPos - scroll.btnSize*2 - scroll.sliderSize + 1;
\r
185 IF (value < 0) OR (scroll.maxVal <= 0) THEN
\r
188 ELSIF value > scroll.maxVal THEN
\r
189 value := scroll.maxVal;
\r
192 IF (maxPos + 1) >= scroll.maxVal THEN
\r
193 n := (maxPos + 1) DIV scroll.maxVal;
\r
194 m := (maxPos + 1) MOD scroll.maxVal;
\r
195 pos := value*n + MIN(value, m)
\r
197 pos := FLOOR(FLT(value)*FLT(maxPos + 1)/FLT(scroll.maxVal))
\r
199 IF pos > maxPos THEN
\r
201 value := scroll.maxVal
\r
205 scroll.value := value
\r
209 PROCEDURE change* (VAR scroll: tScroll);
\r
212 setValue(scroll, scroll.value + 1)
\r
213 ELSIF scroll.Dec THEN
\r
214 setValue(scroll, scroll.value - 1)
\r
220 PROCEDURE ceil (p, q: INTEGER): INTEGER;
\r
221 RETURN p DIV q + ORD(p MOD q # 0)
\r
225 PROCEDURE setPos (VAR scroll: tScroll; pos: INTEGER);
\r
227 maxPos, value, n, m, x, x0, q: INTEGER;
\r
229 IF scroll.maxVal > 0 THEN
\r
230 IF scroll.vertical THEN
\r
231 maxPos := scroll.height
\r
233 maxPos := scroll.width
\r
235 maxPos := maxPos - scroll.btnSize*2 - scroll.sliderSize + 1;
\r
239 ELSIF pos >= maxPos THEN
\r
241 value := scroll.maxVal
\r
243 IF scroll.maxVal <= maxPos + 1 THEN
\r
244 n := (maxPos + 1) DIV scroll.maxVal;
\r
245 m := (maxPos + 1) MOD scroll.maxVal;
\r
249 value := ceil(pos - m, n)
\r
251 value := ceil(pos, n + 1)
\r
256 x := value*n + MIN(value, m);
\r
257 x0 := (value - 1)*n + MIN(value - 1, m);
\r
259 IF x - pos > pos - x0 THEN
\r
264 IF pos > maxPos THEN
\r
266 value := scroll.maxVal
\r
270 value := FLOOR(FLT(scroll.maxVal)*FLT(pos)/FLT(maxPos + 1))
\r
278 scroll.value := value
\r
282 PROCEDURE isActive* (scroll: tScroll): BOOLEAN;
\r
283 RETURN scroll.Inc OR scroll.Dec OR (scroll.Slider # -1)
\r
287 PROCEDURE MouseMove* (VAR scroll: tScroll; x, y: INTEGER);
\r
291 IF scroll.Slider # -1 THEN
\r
292 IF scroll.vertical THEN
\r
293 c := y - scroll.top
\r
295 c := x - scroll.left
\r
297 setPos(scroll, scroll.pos0 + c - scroll.Slider);
\r
303 PROCEDURE SendIPC*;
\r
305 K.SendIPC(K.ThreadID(), ScrollIPC)
\r
309 PROCEDURE MouseDown* (VAR scroll: tScroll; x, y: INTEGER);
\r
313 IF ~scroll.mouse THEN
\r
314 DEC(x, scroll.left);
\r
315 DEC(y, scroll.top);
\r
316 scroll.mouse := TRUE;
\r
317 IF U.between(1, x, scroll.width - 2) & U.between(1, y, scroll.height - 2) THEN
\r
318 IF scroll.vertical THEN
\r
320 size := scroll.height
\r
323 size := scroll.width
\r
325 IF U.between(scroll.btnSize + scroll.pos - 1, c, scroll.btnSize + scroll.pos + scroll.sliderSize - 1) THEN
\r
326 scroll.pos0 := scroll.pos;
\r
328 ELSIF U.between(0, c, scroll.btnSize - 1) THEN
\r
329 scroll.Dec := TRUE;
\r
331 ELSIF U.between(size - scroll.btnSize, c, size - 1) THEN
\r
332 scroll.Inc := TRUE;
\r
335 setPos(scroll, c - scroll.btnSize - scroll.sliderSize DIV 2);
\r
336 scroll.pos0 := scroll.pos;
\r
337 scroll.Slider := c;
\r
345 PROCEDURE MouseUp* (VAR scroll: tScroll);
\r
347 IF scroll.mouse THEN
\r
348 scroll.Slider := -1;
\r
349 scroll.Inc := FALSE;
\r
350 scroll.Dec := FALSE;
\r
351 scroll.mouse := FALSE;
\r