2021-07-13 12:30:43 +02:00
|
|
|
(*
|
2022-01-12 22:15:22 +01:00
|
|
|
Copyright 2021, 2022 Anton Krotov
|
2021-07-11 01:39:41 +02:00
|
|
|
|
|
|
|
This file is part of CEdit.
|
|
|
|
|
|
|
|
CEdit is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
CEdit is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with CEdit. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*)
|
|
|
|
|
|
|
|
MODULE Tabs;
|
|
|
|
|
2021-12-17 07:12:02 +01:00
|
|
|
IMPORT List, K := KolibriOS, RW, U := Utils;
|
2021-07-11 01:39:41 +02:00
|
|
|
|
|
|
|
CONST
|
|
|
|
|
|
|
|
btnID* = 100;
|
2022-02-25 15:34:18 +01:00
|
|
|
btnClose* = btnID + 100;
|
2021-12-20 20:09:01 +01:00
|
|
|
btnLeft* = btnID - 1;
|
|
|
|
btnRight* = btnID - 2;
|
2021-07-11 01:39:41 +02:00
|
|
|
tabHeight* = 22;
|
|
|
|
curTabHeight = 26;
|
2021-09-03 01:15:33 +02:00
|
|
|
scrWidth = 15;
|
2022-02-25 15:34:18 +01:00
|
|
|
btnCloseColor* = 0EF999FH;
|
2021-07-11 01:39:41 +02:00
|
|
|
|
|
|
|
TYPE
|
|
|
|
|
|
|
|
tItem = POINTER TO RECORD (List.tItem)
|
|
|
|
|
2021-12-08 15:02:53 +01:00
|
|
|
val: RW.tFileName;
|
|
|
|
modified: BOOLEAN
|
2021-07-11 01:39:41 +02:00
|
|
|
|
|
|
|
END;
|
|
|
|
|
|
|
|
tTabs* = POINTER TO RECORD
|
|
|
|
|
|
|
|
strings: List.tList;
|
|
|
|
first, current: INTEGER;
|
|
|
|
width, height: INTEGER;
|
2021-12-17 07:12:02 +01:00
|
|
|
x, y, freeX: INTEGER
|
2021-07-11 01:39:41 +02:00
|
|
|
|
|
|
|
END;
|
|
|
|
|
|
|
|
|
2021-12-17 07:12:02 +01:00
|
|
|
PROCEDURE DblClicked* (t: tTabs; x, y: INTEGER): BOOLEAN;
|
|
|
|
RETURN (x > t.freeX) & U.between(t.y, y, t.y + t.height - 1)
|
|
|
|
END DblClicked;
|
|
|
|
|
|
|
|
|
2021-12-08 15:02:53 +01:00
|
|
|
PROCEDURE drawTab (t: tTabs; id, x, y, width, height: INTEGER; s: ARRAY OF CHAR; modified: BOOLEAN);
|
2022-02-25 15:34:18 +01:00
|
|
|
CONST
|
|
|
|
btnCloseSize = 14;
|
2021-07-11 01:39:41 +02:00
|
|
|
VAR
|
2021-07-13 12:30:43 +02:00
|
|
|
x2, y2, color: INTEGER;
|
2022-02-25 15:34:18 +01:00
|
|
|
left, top: INTEGER;
|
2021-07-11 01:39:41 +02:00
|
|
|
BEGIN
|
|
|
|
IF id = t.current THEN
|
|
|
|
INC(height, curTabHeight - tabHeight);
|
2021-07-13 12:30:43 +02:00
|
|
|
DEC(y, curTabHeight - tabHeight);
|
2022-01-12 22:15:22 +01:00
|
|
|
color := K.colors.light
|
2021-07-13 12:30:43 +02:00
|
|
|
ELSE
|
2022-01-12 22:15:22 +01:00
|
|
|
color := K.colors.work
|
2021-07-11 01:39:41 +02:00
|
|
|
END;
|
2021-07-13 12:30:43 +02:00
|
|
|
DEC(x); INC(width);
|
2021-07-11 01:39:41 +02:00
|
|
|
x2 := x + width - 1;
|
|
|
|
y2 := y + height - 1;
|
2021-07-13 12:30:43 +02:00
|
|
|
|
2021-12-30 12:11:45 +01:00
|
|
|
K.DrawRect(x, y, width, height, color);
|
2022-01-12 22:15:22 +01:00
|
|
|
K.DrawLine(x, y, x2, y, K.colors.line);
|
|
|
|
K.DrawLine(x2, y, x2, y2, K.colors.line);
|
2022-02-25 15:34:18 +01:00
|
|
|
|
|
|
|
top := y + 3;
|
2021-07-13 12:30:43 +02:00
|
|
|
IF id # t.current THEN
|
2022-02-25 15:34:18 +01:00
|
|
|
K.DrawLine(x2 - 1, y2, x, y2, K.colors.line)
|
|
|
|
ELSE
|
|
|
|
INC(top, (curTabHeight - tabHeight) DIV 2)
|
2021-07-13 12:30:43 +02:00
|
|
|
END;
|
2022-01-12 22:15:22 +01:00
|
|
|
K.DrawLine(x, y2, x, y, K.colors.line);
|
2021-12-08 15:02:53 +01:00
|
|
|
|
2022-01-12 22:15:22 +01:00
|
|
|
K.DrawText866bk(x + K.fontWidth + K.fontWidth DIV 2, y + (height - K.fontHeight) DIV 2, K.colors.work_text, color, s);
|
2021-12-08 15:02:53 +01:00
|
|
|
IF modified THEN
|
2022-01-12 22:15:22 +01:00
|
|
|
K.DrawText866bk(x + K.fontWidth DIV 2, y + (height - K.fontHeight) DIV 2, K.colors.work_text, color, "*")
|
2021-12-08 15:02:53 +01:00
|
|
|
END;
|
2022-02-25 15:34:18 +01:00
|
|
|
K.CreateButton(id + ORD({30}) + btnID, x + 1, y - 1, width - 1, height - 1, 0, "");
|
|
|
|
left := x + width - btnCloseSize - 5;
|
|
|
|
K.CreateButton(id + btnClose, left, top, btnCloseSize, btnCloseSize, btnCloseColor, "");
|
|
|
|
K.DrawLine(left + 5, top + 4, left + btnCloseSize - 4, top + btnCloseSize - 5, 0FFFFFFH);
|
|
|
|
K.DrawLine(left + 4, top + 4, left + btnCloseSize - 4, top + btnCloseSize - 4, 0FFFFFFH);
|
|
|
|
K.DrawLine(left + 4, top + 5, left + btnCloseSize - 5, top + btnCloseSize - 4, 0FFFFFFH);
|
|
|
|
K.DrawLine(left + 4, top + btnCloseSize - 4, left + btnCloseSize - 4, top + 4, 0FFFFFFH);
|
|
|
|
K.DrawLine(left + 4, top + btnCloseSize - 5, left + btnCloseSize - 5, top + 4, 0FFFFFFH);
|
|
|
|
K.DrawLine(left + 5, top + btnCloseSize - 4, left + btnCloseSize - 4, top + 5, 0FFFFFFH);
|
2021-07-11 01:39:41 +02:00
|
|
|
END drawTab;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE tabWidth (tab: tItem): INTEGER;
|
2022-02-25 15:34:18 +01:00
|
|
|
RETURN (LENGTH(tab.val) + 5)*K.fontWidth
|
2021-07-11 01:39:41 +02:00
|
|
|
END tabWidth;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE Width (t: tTabs; pos, n: INTEGER): INTEGER;
|
|
|
|
VAR
|
|
|
|
res, i: INTEGER;
|
|
|
|
item: List.tItem;
|
|
|
|
BEGIN
|
|
|
|
res := 0;
|
|
|
|
i := pos;
|
|
|
|
item := List.getItem(t.strings, i);
|
|
|
|
WHILE (item # NIL) & (i <= n) DO
|
|
|
|
INC(res, tabWidth(item(tItem)));
|
|
|
|
item := item.next;
|
|
|
|
INC(i)
|
|
|
|
END
|
|
|
|
RETURN res
|
|
|
|
END Width;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE draw* (t: tTabs);
|
|
|
|
VAR
|
2021-12-17 07:12:02 +01:00
|
|
|
x, y, xmax, n, width, i: INTEGER;
|
2021-07-11 01:39:41 +02:00
|
|
|
item: List.tItem;
|
2021-07-13 12:30:43 +02:00
|
|
|
scroll: BOOLEAN;
|
2021-07-11 01:39:41 +02:00
|
|
|
BEGIN
|
|
|
|
y := t.y;
|
|
|
|
x := t.x;
|
2022-01-12 22:15:22 +01:00
|
|
|
K.DrawRect(x, y - (curTabHeight - tabHeight), t.width + (2*scrWidth + 2), t.height + (curTabHeight - tabHeight) - 1, K.colors.work);
|
2021-07-11 01:39:41 +02:00
|
|
|
IF Width(t, 0, t.strings.count - 1) > t.width THEN
|
|
|
|
INC(x, 2*scrWidth);
|
2021-12-20 20:09:01 +01:00
|
|
|
K.DeleteButton(btnLeft);
|
|
|
|
K.DeleteButton(btnRight);
|
2022-01-12 22:15:22 +01:00
|
|
|
K.CreateButton(btnLeft, t.x, y, scrWidth, t.height - 1, K.colors.button, "<");
|
|
|
|
K.CreateButton(btnRight, t.x + scrWidth, y, scrWidth, t.height - 1, K.colors.button, ">");
|
2021-07-13 12:30:43 +02:00
|
|
|
scroll := TRUE
|
2021-07-11 01:39:41 +02:00
|
|
|
ELSE
|
2021-07-13 12:30:43 +02:00
|
|
|
t.first := 0;
|
|
|
|
scroll := FALSE
|
2021-07-11 01:39:41 +02:00
|
|
|
END;
|
|
|
|
xmax := x + t.width - 1;
|
|
|
|
|
|
|
|
n := t.strings.count - 1;
|
2021-12-17 07:12:02 +01:00
|
|
|
FOR i := 0 TO n DO
|
|
|
|
K.DeleteButton(i + btnID)
|
|
|
|
END;
|
2021-07-11 01:39:41 +02:00
|
|
|
WHILE (n >= 0) & (Width(t, n, t.strings.count - 1) <= t.width) DO
|
|
|
|
DEC(n)
|
|
|
|
END;
|
|
|
|
IF n < 0 THEN
|
|
|
|
n := 0
|
|
|
|
ELSE
|
|
|
|
INC(n)
|
|
|
|
END;
|
|
|
|
IF n < t.first THEN
|
|
|
|
t.first := n
|
|
|
|
END;
|
|
|
|
|
2022-01-12 22:15:22 +01:00
|
|
|
K.DrawRect(x, y, t.width, t.height - 1, K.colors.work);
|
|
|
|
K.DrawLine(x, y + tabHeight - 1, x + t.width - 1 + 2*scrWidth*(1 - ORD(scroll)), y + tabHeight - 1, K.colors.line);
|
2021-07-11 01:39:41 +02:00
|
|
|
item := List.getItem(t.strings, t.first);
|
|
|
|
n := t.first;
|
|
|
|
WHILE (item # NIL) & (x <= xmax) DO
|
|
|
|
width := tabWidth(item(tItem));
|
|
|
|
IF x + width - 1 <= xmax THEN
|
2021-12-17 07:12:02 +01:00
|
|
|
drawTab(t, n, x + 1, y, width, t.height, item(tItem).val, item(tItem).modified);
|
|
|
|
INC(n);
|
|
|
|
INC(x, width);
|
|
|
|
item := item.next
|
|
|
|
ELSE
|
|
|
|
item := NIL
|
|
|
|
END
|
|
|
|
END;
|
|
|
|
t.freeX := x
|
2021-07-11 01:39:41 +02:00
|
|
|
END draw;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE add* (t: tTabs; s: ARRAY OF CHAR);
|
|
|
|
VAR
|
|
|
|
item: tItem;
|
|
|
|
BEGIN
|
|
|
|
NEW(item);
|
|
|
|
item.val := s;
|
2021-12-08 15:02:53 +01:00
|
|
|
item.modified := FALSE;
|
2021-07-11 01:39:41 +02:00
|
|
|
List.append(t.strings, item);
|
|
|
|
END add;
|
|
|
|
|
|
|
|
|
2021-12-08 15:02:53 +01:00
|
|
|
PROCEDURE modify* (t: tTabs; n: INTEGER; val: BOOLEAN);
|
|
|
|
VAR
|
|
|
|
item: List.tItem;
|
|
|
|
BEGIN
|
|
|
|
item := List.getItem(t.strings, n);
|
|
|
|
IF item(tItem).modified # val THEN
|
|
|
|
item(tItem).modified := val;
|
|
|
|
draw(t)
|
|
|
|
END
|
|
|
|
END modify;
|
|
|
|
|
|
|
|
|
2021-07-11 01:39:41 +02:00
|
|
|
PROCEDURE rename* (t: tTabs; n: INTEGER; s: ARRAY OF CHAR);
|
|
|
|
VAR
|
|
|
|
item: List.tItem;
|
|
|
|
BEGIN
|
|
|
|
item := List.getItem(t.strings, n);
|
|
|
|
item(tItem).val := s
|
|
|
|
END rename;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE delete* (t: tTabs; n: INTEGER);
|
|
|
|
VAR
|
|
|
|
item: List.tItem;
|
|
|
|
BEGIN
|
|
|
|
item := List.getItem(t.strings, n);
|
2021-12-20 20:09:01 +01:00
|
|
|
List.delete(t.strings, item);
|
|
|
|
DISPOSE(item)
|
2021-07-11 01:39:41 +02:00
|
|
|
END delete;
|
|
|
|
|
|
|
|
|
2022-01-18 17:23:19 +01:00
|
|
|
PROCEDURE scroll* (t: tTabs; btn: INTEGER);
|
2021-07-11 01:39:41 +02:00
|
|
|
VAR
|
|
|
|
pos: INTEGER;
|
|
|
|
BEGIN
|
2022-01-18 17:23:19 +01:00
|
|
|
pos := t.first + ORD(btn = btnRight) - ORD(btn = btnLeft);
|
2021-07-11 01:39:41 +02:00
|
|
|
IF pos < 0 THEN
|
|
|
|
pos := 0
|
|
|
|
ELSIF pos >= t.strings.count THEN
|
|
|
|
pos := t.strings.count - 1
|
|
|
|
END;
|
|
|
|
t.first := pos
|
|
|
|
END scroll;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE switch* (t: tTabs; n: INTEGER);
|
|
|
|
BEGIN
|
|
|
|
IF (0 <= n) & (n < t.strings.count) THEN
|
|
|
|
t.current := n;
|
|
|
|
IF n < t.first THEN
|
|
|
|
t.first := 0
|
|
|
|
END;
|
|
|
|
WHILE Width(t, t.first, n) > t.width DO
|
|
|
|
INC(t.first)
|
|
|
|
END
|
|
|
|
END
|
|
|
|
END switch;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE setArea* (t: tTabs; x, y, width, height: INTEGER);
|
|
|
|
BEGIN
|
|
|
|
t.x := x;
|
|
|
|
t.y := y;
|
2021-07-13 12:30:43 +02:00
|
|
|
t.width := width - 2*scrWidth;
|
2021-07-11 01:39:41 +02:00
|
|
|
t.height := height
|
|
|
|
END setArea;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE create* (): tTabs;
|
|
|
|
VAR
|
|
|
|
res: tTabs;
|
|
|
|
BEGIN
|
|
|
|
NEW(res);
|
|
|
|
res.strings := List.create(NIL);
|
|
|
|
res.current := 0;
|
|
|
|
res.first := 0
|
|
|
|
RETURN res
|
|
|
|
END create;
|
|
|
|
|
|
|
|
|
|
|
|
END Tabs.
|