Subversion Repositories Kolibri OS

Rev

Rev 9731 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. (*
  2.     Copyright 2021-2023 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 <http://www.gnu.org/licenses/>.
  18. *)
  19.  
  20. MODULE Tabs;
  21.  
  22. IMPORT List, K := KolibriOS, RW, U := Utils;
  23.  
  24. CONST
  25.  
  26.     btnID* = 100;
  27.     btnClose* = btnID + 100;
  28.     btnLeft* = btnID - 1;
  29.         btnRight* = btnID - 2;
  30.     tabHeight* = 22;
  31.     curTabHeight = 26;
  32.     scrWidth = 15;
  33.     btnCloseColor* = 0EF999FH;
  34.     modifColor = 0FF0000H;
  35.     strLen = 30;
  36.  
  37. TYPE
  38.  
  39.     tItem = POINTER TO RECORD (List.tItem)
  40.  
  41.         val: ARRAY strLen + 1 OF CHAR;
  42.         modified: BOOLEAN
  43.  
  44.     END;
  45.  
  46.     tTabs* = POINTER TO RECORD
  47.  
  48.         strings: List.tList;
  49.         first, current: INTEGER;
  50.         width, height: INTEGER;
  51.         x, y, freeX: INTEGER
  52.  
  53.     END;
  54.  
  55.  
  56. PROCEDURE DblClicked* (t: tTabs; x, y: INTEGER): BOOLEAN;
  57.         RETURN (x > t.freeX) & U.between(t.y, y, t.y + t.height - 1)
  58. END DblClicked;
  59.  
  60.  
  61. PROCEDURE drawTab (t: tTabs; id, x, y, width, height: INTEGER; s: ARRAY OF CHAR; modified: BOOLEAN);
  62. CONST
  63.         btnCloseSize = 14;
  64. VAR
  65.     x2, y2, color, closeColor, closeForeColor, textColor: INTEGER;
  66.     left, top: INTEGER;
  67. BEGIN
  68.     IF id = t.current THEN
  69.         INC(height, curTabHeight - tabHeight);
  70.         DEC(y, curTabHeight - tabHeight)
  71.     END;
  72.     color := K.colors.work;
  73.     textColor := K.colors.work_text;
  74.     DEC(x); INC(width);
  75.     x2 := x + width - 1;
  76.     y2 := y + height - 1;
  77.  
  78.     K.DrawRect(x, y, width, height, color);
  79.     K.DrawLine(x, y, x2, y, K.colors.line);
  80.     K.DrawLine(x2, y, x2, y2, K.colors.line);
  81.  
  82.     top := y + 3;
  83.     IF id # t.current THEN
  84.         K.DrawLine(x2 - 1, y2, x, y2, K.colors.line);
  85.         closeColor := K.colors.button;
  86.         closeForeColor := K.colors.button_text
  87.     ELSE
  88.         INC(top, (curTabHeight - tabHeight) DIV 2);
  89.         closeColor := btnCloseColor;
  90.         closeForeColor := 0FFFFFFH
  91.     END;
  92.     K.DrawLine(x, y2, x, y, K.colors.line);
  93.  
  94.     K.DrawText866bk(x + K.fontWidth + K.fontWidth DIV 2, y + (height - K.fontHeight) DIV 2, textColor, color, s);
  95.     IF modified THEN
  96.         K.DrawText866bk(x + K.fontWidth DIV 2, y + (height - K.fontHeight) DIV 2, modifColor, color, "*")
  97.     END;
  98.     K.CreateButton(id + ORD({30}) + btnID, x + 1, y - 1, width - 1, height - 1, 0, "");
  99.     left := x + width - btnCloseSize - 5;
  100.     K.CreateButton(id + btnClose, left, top, btnCloseSize, btnCloseSize,  closeColor, "");
  101.     K.DrawLine(left + 5, top + 4, left + btnCloseSize - 4, top + btnCloseSize - 5, closeForeColor);
  102.     K.DrawLine(left + 4, top + 4, left + btnCloseSize - 4, top + btnCloseSize - 4, closeForeColor);
  103.     K.DrawLine(left + 4, top + 5, left + btnCloseSize - 5, top + btnCloseSize - 4, closeForeColor);
  104.     K.DrawLine(left + 4, top + btnCloseSize - 4, left + btnCloseSize - 4, top + 4, closeForeColor);
  105.     K.DrawLine(left + 4, top + btnCloseSize - 5, left + btnCloseSize - 5, top + 4, closeForeColor);
  106.     K.DrawLine(left + 5, top + btnCloseSize - 4, left + btnCloseSize - 4, top + 5, closeForeColor);
  107. END drawTab;
  108.  
  109.  
  110. PROCEDURE tabWidth (tab: tItem): INTEGER;
  111.     RETURN (LENGTH(tab.val) + 5)*K.fontWidth
  112. END tabWidth;
  113.  
  114.  
  115. PROCEDURE Width (t: tTabs; pos, n: INTEGER): INTEGER;
  116. VAR
  117.     res, i: INTEGER;
  118.     item: List.tItem;
  119. BEGIN
  120.     res := 0;
  121.     i := pos;
  122.     item := List.getItem(t.strings, i);
  123.     WHILE (item # NIL) & (i <= n) DO
  124.         INC(res, tabWidth(item(tItem)));
  125.         item := item.next;
  126.         INC(i)
  127.     END
  128.     RETURN res
  129. END Width;
  130.  
  131.  
  132. PROCEDURE draw* (t: tTabs);
  133. VAR
  134.     x, y, xmax, n, width, i: INTEGER;
  135.     item: List.tItem;
  136.     scroll: BOOLEAN;
  137. BEGIN
  138.     y := t.y;
  139.     x := t.x;
  140.     K.DrawRect(x, y - (curTabHeight - tabHeight), t.width + (2*scrWidth + 2), t.height + (curTabHeight - tabHeight) - 1, K.colors.work);
  141.     IF Width(t, 0, t.strings.count - 1) > t.width THEN
  142.         INC(x, 2*scrWidth);
  143.         K.DeleteButton(btnLeft);
  144.         K.DeleteButton(btnRight);
  145.         K.CreateButton(btnLeft, t.x, y, scrWidth, t.height - 1, K.colors.button, "<");
  146.         K.CreateButton(btnRight, t.x + scrWidth, y, scrWidth, t.height - 1, K.colors.button, ">");
  147.         scroll := TRUE
  148.     ELSE
  149.         t.first := 0;
  150.         scroll := FALSE
  151.     END;
  152.     xmax := x + t.width - 1;
  153.  
  154.     n := t.strings.count - 1;
  155.     FOR i := 0 TO n DO
  156.         K.DeleteButton(i + btnID)
  157.     END;
  158.     WHILE (n >= 0) & (Width(t, n, t.strings.count - 1) <= t.width) DO
  159.         DEC(n)
  160.     END;
  161.     IF n < 0 THEN
  162.         n := 0
  163.     ELSE
  164.         INC(n)
  165.     END;
  166.     IF n < t.first THEN
  167.         t.first := n
  168.     END;
  169.  
  170.     K.DrawRect(x, y, t.width, t.height - 1, K.colors.work);
  171.     K.DrawLine(x, y + tabHeight - 1, x + t.width - 1 + 2*scrWidth*(1 - ORD(scroll)), y + tabHeight - 1, K.colors.line);
  172.     item := List.getItem(t.strings, t.first);
  173.     n := t.first;
  174.     WHILE (item # NIL) & (x <= xmax) DO
  175.         width := tabWidth(item(tItem));
  176.         IF x + width - 1 <= xmax THEN
  177.             drawTab(t, n, x + 1, y, width, t.height, item(tItem).val, item(tItem).modified);
  178.                 INC(n);
  179.                 INC(x, width);
  180.                 item := item.next
  181.         ELSE
  182.                 item := NIL
  183.         END
  184.     END;
  185.     t.freeX := x
  186. END draw;
  187.  
  188.  
  189. PROCEDURE setText (item: tItem; s: ARRAY OF CHAR);
  190. VAR
  191.         i: INTEGER;
  192. BEGIN
  193.         IF LENGTH(s) > strLen THEN
  194.                 FOR i := 0 TO strLen - 4 DO
  195.                         item.val[i] := s[i]
  196.                 END;
  197.                 item.val[strLen - 3] := 0X;
  198.                 U.append8(item.val, "...")
  199.         ELSE
  200.                 COPY(s, item.val)
  201.         END
  202. END setText;
  203.  
  204.  
  205. PROCEDURE add* (t: tTabs; s: ARRAY OF CHAR);
  206. VAR
  207.         item: tItem;
  208. BEGIN
  209.         NEW(item);
  210.         setText(item, s);
  211.         item.modified := FALSE;
  212.         List.append(t.strings, item)
  213. END add;
  214.  
  215.  
  216. PROCEDURE modify* (t: tTabs; n: INTEGER; val: BOOLEAN);
  217. VAR
  218.     item: List.tItem;
  219. BEGIN
  220.         item := List.getItem(t.strings, n);
  221.         IF item(tItem).modified # val THEN
  222.                 item(tItem).modified := val;
  223.                 draw(t)
  224.         END
  225. END modify;
  226.  
  227.  
  228. PROCEDURE rename* (t: tTabs; n: INTEGER; s: ARRAY OF CHAR);
  229. VAR
  230.     item: List.tItem;
  231. BEGIN
  232.     item := List.getItem(t.strings, n);
  233.     setText(item(tItem), s)
  234. END rename;
  235.  
  236.  
  237. PROCEDURE delete* (t: tTabs; n: INTEGER);
  238. VAR
  239.     item: List.tItem;
  240. BEGIN
  241.     item := List.getItem(t.strings, n);
  242.     List.delete(t.strings, item);
  243.     DISPOSE(item)
  244. END delete;
  245.  
  246.  
  247. PROCEDURE scroll* (t: tTabs; btn: INTEGER);
  248. VAR
  249.     pos: INTEGER;
  250. BEGIN
  251.     pos := t.first + ORD(btn = btnRight) - ORD(btn = btnLeft);
  252.     IF pos < 0 THEN
  253.         pos := 0
  254.     ELSIF pos >= t.strings.count THEN
  255.         pos := t.strings.count - 1
  256.     END;
  257.     t.first := pos
  258. END scroll;
  259.  
  260.  
  261. PROCEDURE switch* (t: tTabs; n: INTEGER);
  262. BEGIN
  263.     IF (0 <= n) & (n < t.strings.count) THEN
  264.         t.current := n;
  265.         IF n < t.first THEN
  266.             t.first := 0
  267.         END;
  268.         WHILE Width(t, t.first, n) > t.width DO
  269.             INC(t.first)
  270.         END
  271.     END
  272. END switch;
  273.  
  274.  
  275. PROCEDURE setArea* (t: tTabs; x, y, width, height: INTEGER);
  276. BEGIN
  277.     t.x := x;
  278.     t.y := y;
  279.     t.width := width - 2*scrWidth;
  280.     t.height := height
  281. END setArea;
  282.  
  283.  
  284. PROCEDURE create* (): tTabs;
  285. VAR
  286.     res: tTabs;
  287. BEGIN
  288.     NEW(res);
  289.     res.strings := List.create(NIL);
  290.     res.current := 0;
  291.     res.first := 0
  292.     RETURN res
  293. END create;
  294.  
  295.  
  296. END Tabs.