WMTabComponents.Mod 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. MODULE WMTabComponents; (** AUTHOR "?/staubesv"; PURPOSE "Tab component" *)
  2. IMPORT
  3. KernelLog, Strings, XML, WMEvents, WMProperties,
  4. WMStandardComponents, WMRectangles, WMComponents, WMGraphics;
  5. TYPE
  6. Tab* = OBJECT
  7. VAR
  8. caption- : Strings.String;
  9. w : LONGINT;
  10. width : LONGINT; (* if 0, automatically determine width based on caption string size *)
  11. color- : LONGINT;
  12. data- : ANY;
  13. inserted, attention* : BOOLEAN;
  14. next- : Tab;
  15. PROCEDURE &Init*;
  16. BEGIN
  17. caption := NIL;
  18. w := 0; width := 0; color := 0;
  19. data := NIL;
  20. inserted := FALSE; attention := FALSE;
  21. next := NIL;
  22. END Init;
  23. END Tab;
  24. Tabs* = OBJECT(WMComponents.VisualComponent)
  25. VAR
  26. left, right : WMStandardComponents.Button;
  27. leftOfs, totalWidth, border, lines : LONGINT;
  28. lineHeight-: WMProperties.Int32Property;
  29. tabs-, hover, selected- : Tab;
  30. canvasState : WMGraphics.CanvasState;
  31. onSelectTab- : WMEvents.EventSource;
  32. (* general look *)
  33. useBgBitmaps- : WMProperties.BooleanProperty;
  34. borderWidth- : WMProperties.Int32Property;
  35. (* colors *)
  36. clDefault-, clHover-, clSelected-, clAttention-, clSelectedAttention-,
  37. clTextDefault-, clTextHover-, clTextSelected-, clTextAttention, clTextSelectedAttention- : WMProperties.ColorProperty;
  38. (* background bitmaps *)
  39. bgLeftDefault-, bgMiddleDefault-, bgRightDefault-,
  40. bgLeftHover-, bgMiddleHover-, bgRightHover-,
  41. bgLeftSelected-, bgMiddleSelected-, bgRightSelected-,
  42. bgLeftAttention-, bgMiddleAttention-, bgRightAttention- : WMProperties.StringProperty;
  43. imgLeftDefault, imgMiddleDefault, imgRightDefault,
  44. imgLeftHover, imgMiddleHover, imgRightHover,
  45. imgLeftSelected, imgMiddleSelected, imgRightSelected,
  46. imgLeftAttention, imgMiddleAttention, imgRightAttention : WMGraphics.Image;
  47. PROCEDURE &Init*;
  48. BEGIN
  49. Init^;
  50. SetNameAsString(StrTabs);
  51. SetGenerator("WMTabComponents.GenTabControl");
  52. lines := 1;
  53. NEW(left);
  54. left.alignment.Set(WMComponents.AlignLeft);
  55. left.bounds.SetWidth(10);
  56. left.isRepeating.Set(TRUE);
  57. left.onClick.Add(MoveLeft);
  58. left.visible.Set(FALSE);
  59. NEW(right);
  60. right.alignment.Set(WMComponents.AlignRight);
  61. right.bounds.SetWidth(10);
  62. right.isRepeating.Set(TRUE);
  63. right.onClick.Add(MoveRight);
  64. right.visible.Set(FALSE);
  65. AddInternalComponent(left); AddInternalComponent(right);
  66. NEW(onSelectTab, SELF, Strings.NewString("onSelectTab"), Strings.NewString("if tab clicked"), SELF.StringToCompCommand);
  67. (* general look *)
  68. NEW(borderWidth, ProtoTcBorderWidth, NIL, NIL); properties.Add(borderWidth);
  69. NEW(useBgBitmaps, ProtoTcUseBgBitmaps, NIL, NIL); properties.Add(useBgBitmaps);
  70. (* background colors *)
  71. fillColor.SetPrototype(ProtoTcDefault);
  72. NEW(clDefault, ProtoTcDefault, NIL, NIL); properties.Add(clDefault);
  73. NEW(clHover, ProtoTcHover, NIL, NIL); properties.Add(clHover);
  74. NEW(clSelected, ProtoTcSelected, NIL, NIL); properties.Add(clSelected);
  75. NEW(clAttention, ProtoTcAttention, NIL, NIL); properties.Add(clAttention);
  76. NEW(clSelectedAttention, ProtoTcSelectedAttention, NIL, NIL); properties.Add(clSelectedAttention);
  77. (* text colors *)
  78. NEW(clTextDefault, ProtoTcTextDefault, NIL, NIL); properties.Add(clTextDefault);
  79. NEW(clTextHover, ProtoTcTextHover, NIL, NIL); properties.Add(clTextHover);
  80. NEW(clTextSelected, ProtoTcTextSelected, NIL, NIL); properties.Add(clTextSelected);
  81. NEW(clTextAttention, ProtoTcTextAttention, NIL, NIL); properties.Add(clTextAttention);
  82. NEW(clTextSelectedAttention, ProtoTcTextSelectedAttention, NIL, NIL); properties.Add(clTextSelectedAttention);
  83. (* background bitmaps *)
  84. NEW(bgLeftDefault, ProtoTcBgLeftDefault, NIL, NIL); properties.Add(bgLeftDefault);
  85. NEW(bgMiddleDefault, ProtoTcBgMiddleDefault, NIL, NIL); properties.Add(bgMiddleDefault);
  86. NEW(bgRightDefault, ProtoTcBgRightDefault, NIL, NIL); properties.Add(bgRightDefault);
  87. NEW(bgLeftHover, ProtoTcBgLeftHover, NIL, NIL); properties.Add(bgLeftHover);
  88. NEW(bgMiddleHover, ProtoTcBgMiddleHover, NIL, NIL); properties.Add(bgMiddleHover);
  89. NEW(bgRightHover, ProtoTcBgRightHover, NIL, NIL); properties.Add(bgRightHover);
  90. NEW(bgLeftSelected, ProtoTcBgLeftSelected, NIL, NIL); properties.Add(bgLeftSelected);
  91. NEW(bgMiddleSelected, ProtoTcBgMiddleSelected, NIL, NIL); properties.Add(bgMiddleSelected);
  92. NEW(bgRightSelected, ProtoTcBgRightSelected, NIL, NIL); properties.Add(bgRightSelected);
  93. NEW(bgLeftAttention, ProtoTcBgLeftAttention, NIL, NIL); properties.Add(bgLeftAttention);
  94. NEW(bgMiddleAttention, ProtoTcBgMiddleAttention, NIL, NIL); properties.Add(bgMiddleAttention);
  95. NEW(bgRightAttention, ProtoTcBgRightAttention, NIL, NIL); properties.Add(bgRightAttention);
  96. NEW(lineHeight, ProtoLineHeight, NIL, NIL); properties.Add(lineHeight);
  97. END Init;
  98. PROCEDURE Initialize*;
  99. BEGIN
  100. Initialize^;
  101. CheckLeftRightButtons;
  102. END Initialize;
  103. PROCEDURE PropertyChanged(sender, property : ANY);
  104. BEGIN
  105. IF (property = useBgBitmaps) OR
  106. (property = bgLeftDefault) OR (property = bgMiddleDefault) OR (property = bgRightDefault) OR
  107. (property = bgLeftHover) OR (property = bgMiddleHover) OR (property = bgRightHover) OR
  108. (property = bgLeftSelected) OR (property = bgMiddleSelected) OR (property = bgRightSelected) OR
  109. (property = bgLeftAttention) OR (property = bgMiddleAttention) OR (property = bgRightAttention)
  110. THEN
  111. RecacheProperties; Invalidate;
  112. ELSIF (property = borderWidth) OR
  113. (property = clDefault) OR (property = clHover) OR (property = clSelected) OR (property = clAttention) OR
  114. (property = clSelectedAttention) OR (property = clTextDefault) OR (property = clTextHover) OR
  115. (property = clTextSelected) OR (property = clTextAttention) OR (property = clTextSelectedAttention)
  116. THEN
  117. Invalidate;
  118. ELSIF (property = bounds) THEN
  119. CalcSize; PropertyChanged^(sender, property);
  120. ELSE
  121. PropertyChanged^(sender, property);
  122. END;
  123. END PropertyChanged;
  124. PROCEDURE RecacheProperties;
  125. VAR s : Strings.String;
  126. BEGIN
  127. RecacheProperties^;
  128. IF useBgBitmaps.Get() THEN
  129. s := bgLeftDefault.Get(); IF s # NIL THEN imgLeftDefault := WMGraphics.LoadImage(s^, TRUE) END;
  130. s := bgMiddleDefault.Get(); IF s # NIL THEN imgMiddleDefault := WMGraphics.LoadImage(s^, TRUE) END;
  131. s := bgRightDefault.Get(); IF s # NIL THEN imgRightDefault := WMGraphics.LoadImage(s^, TRUE) END;
  132. s := bgLeftHover.Get(); IF s # NIL THEN imgLeftHover := WMGraphics.LoadImage(s^, TRUE) END;
  133. s := bgMiddleHover.Get(); IF s # NIL THEN imgMiddleHover := WMGraphics.LoadImage(s^, TRUE) END;
  134. s := bgRightHover.Get(); IF s # NIL THEN imgRightHover := WMGraphics.LoadImage(s^, TRUE) END;
  135. s := bgLeftSelected.Get(); IF s # NIL THEN imgLeftSelected := WMGraphics.LoadImage(s^, TRUE) END;
  136. s := bgMiddleSelected.Get(); IF s # NIL THEN imgMiddleSelected := WMGraphics.LoadImage(s^, TRUE) END;
  137. s := bgRightSelected.Get(); IF s # NIL THEN imgRightSelected := WMGraphics.LoadImage(s^, TRUE) END;
  138. s := bgLeftAttention.Get(); IF s # NIL THEN imgLeftAttention := WMGraphics.LoadImage(s^, TRUE) END;
  139. s := bgMiddleAttention.Get(); IF s # NIL THEN imgMiddleAttention := WMGraphics.LoadImage(s^, TRUE) END;
  140. s := bgRightAttention.Get(); IF s # NIL THEN imgRightAttention := WMGraphics.LoadImage(s^, TRUE) END;
  141. ELSE
  142. imgLeftDefault := NIL; imgMiddleDefault := NIL; imgRightDefault := NIL;
  143. imgLeftHover := NIL; imgMiddleHover := NIL; imgRightHover := NIL;
  144. imgLeftSelected := NIL; imgMiddleSelected := NIL; imgRightSelected := NIL;
  145. imgLeftAttention := NIL; imgMiddleAttention := NIL; imgRightAttention := NIL;
  146. END;
  147. (*Invalidate*)
  148. END RecacheProperties;
  149. PROCEDURE FindTabFromPos(x,y: LONGINT) : Tab;
  150. VAR cur : Tab; pos,posy, dl, w,h: LONGINT;
  151. BEGIN
  152. IF left.visible.Get() THEN dl := left.bounds.GetWidth() ELSE dl := 0 END;
  153. h := lineHeight.Get();
  154. IF h = 0 THEN h := bounds.GetHeight() END;
  155. pos := - leftOfs + dl; posy := 0;
  156. cur := tabs;
  157. WHILE cur # NIL DO
  158. w := cur.w;
  159. IF pos + w > bounds.GetWidth() THEN INC(posy, h); pos := dl; (*RETURN NIL*) END;
  160. pos := pos + w;
  161. IF (x < pos) & (y < posy+h) THEN RETURN cur END;
  162. cur := cur.next
  163. END;
  164. RETURN NIL
  165. END FindTabFromPos;
  166. PROCEDURE PointerDown*(x, y: LONGINT; keys: SET); (** PROTECTED *)
  167. VAR new : Tab;
  168. BEGIN
  169. IF 0 IN keys THEN
  170. new := FindTabFromPos(x,y);
  171. IF (selected # new) & (new # NIL) THEN
  172. selected := new;
  173. onSelectTab.Call(selected);
  174. Invalidate
  175. END
  176. END
  177. END PointerDown;
  178. PROCEDURE Select*(new : Tab);
  179. BEGIN
  180. Acquire;
  181. IF selected # new THEN
  182. selected := new;
  183. Invalidate
  184. END;
  185. Release
  186. END Select;
  187. PROCEDURE SelectByName*(CONST name : ARRAY OF CHAR);
  188. VAR tab : Tab; found : BOOLEAN;
  189. BEGIN
  190. found := FALSE;
  191. Acquire;
  192. tab := tabs;
  193. WHILE ~found & (tab # NIL) DO
  194. IF tab.inserted & (tab.caption # NIL) THEN
  195. found := tab.caption^ = name;
  196. END;
  197. IF ~found THEN tab := tab.next; END;
  198. END;
  199. IF found & (selected # tab) THEN selected := tab; Invalidate; END;
  200. Release;
  201. END SelectByName;
  202. PROCEDURE PointerMove*(x, y: LONGINT; keys: SET); (** PROTECTED *)
  203. VAR new : Tab;
  204. BEGIN
  205. new := FindTabFromPos(x,y);
  206. IF hover # new THEN
  207. hover := new;
  208. Invalidate
  209. END
  210. END PointerMove;
  211. PROCEDURE PointerLeave;
  212. BEGIN
  213. hover := NIL;
  214. Invalidate
  215. END PointerLeave;
  216. PROCEDURE GetLeftTabs(VAR w: LONGINT; inner: BOOLEAN): BOOLEAN;
  217. VAR cur : Tab; font : WMGraphics.Font; dx, dy, lh,dl : LONGINT; width, pos: LONGINT;
  218. BEGIN
  219. IF left.visible.Get() THEN dl := left.bounds.GetWidth() ELSE dl := 0 END;
  220. font := GetFont();
  221. cur := tabs;
  222. pos := -leftOfs+dl;
  223. WHILE cur # NIL DO
  224. IF cur.width # 0 THEN
  225. w := cur.width
  226. ELSIF cur.caption # NIL THEN
  227. font.GetStringSize(cur.caption^, dx, dy);
  228. w := dx + 2 * border
  229. ELSE
  230. w := 2 * border
  231. END;
  232. IF (pos >= 0) & inner THEN RETURN TRUE END;
  233. pos := pos + w;
  234. IF (pos >= 0) & ~inner THEN RETURN TRUE END;
  235. cur := cur.next;
  236. END;
  237. RETURN FALSE
  238. END GetLeftTabs;
  239. PROCEDURE MoveLeft(sender, data : ANY);
  240. VAR w: LONGINT;
  241. BEGIN
  242. IF GetLeftTabs(w, FALSE) THEN
  243. DEC(leftOfs, w)
  244. END;
  245. (*DEC(leftOfs, 10);*)
  246. IF leftOfs < 0 THEN leftOfs := 0 END;
  247. CalcSize;
  248. Invalidate;
  249. END MoveLeft;
  250. PROCEDURE MoveRight(sender, data : ANY);
  251. VAR w: LONGINT;
  252. BEGIN
  253. IF GetLeftTabs(w, TRUE) THEN
  254. INC(leftOfs, w)
  255. END;
  256. (*
  257. INC(leftOfs, 10);
  258. *)
  259. IF leftOfs > totalWidth - 10 THEN leftOfs := totalWidth - 10 END;
  260. CalcSize;
  261. Invalidate;
  262. END MoveRight;
  263. PROCEDURE AddTab*(tab : Tab);
  264. VAR cur : Tab;
  265. BEGIN
  266. Acquire;
  267. tab.next := NIL; tab.inserted := TRUE;
  268. IF tabs = NIL THEN tabs := tab; selected := tab;
  269. ELSE
  270. cur := tabs;
  271. WHILE cur.next # NIL DO cur := cur.next END;
  272. cur.next := tab
  273. END;
  274. CalcSize;
  275. Release;
  276. Invalidate
  277. END AddTab;
  278. PROCEDURE RemoveTab*(tab : Tab);
  279. VAR cur : Tab;
  280. BEGIN
  281. IF (tabs = NIL) OR (tab = NIL) THEN RETURN END;
  282. Acquire;
  283. IF tabs = tab THEN tabs := tabs.next
  284. ELSE
  285. cur := tabs;
  286. WHILE (cur # NIL) & (cur.next # tab) DO cur := cur.next END;
  287. IF cur # NIL THEN cur.next := cur.next.next END
  288. END;
  289. CalcSize;
  290. tab.inserted := FALSE;
  291. Release;
  292. Invalidate
  293. END RemoveTab;
  294. PROCEDURE RemoveAllTabs*;
  295. BEGIN
  296. Acquire;
  297. tabs := NIL;
  298. CalcSize;
  299. Release;
  300. Invalidate
  301. END RemoveAllTabs;
  302. PROCEDURE CheckLeftRightButtons;
  303. BEGIN
  304. IF (totalWidth >= bounds.GetWidth()) OR (lines > 1) THEN
  305. right.visible.Set(TRUE);
  306. left.visible.Set(TRUE)
  307. ELSE
  308. leftOfs := 0;
  309. right.visible.Set(FALSE);
  310. left.visible.Set(FALSE)
  311. END
  312. END CheckLeftRightButtons;
  313. PROCEDURE Resized;
  314. BEGIN
  315. Resized^;
  316. CheckLeftRightButtons
  317. END Resized;
  318. PROCEDURE CalcSize;
  319. VAR cur : Tab; font : WMGraphics.Font; dx, dy, lh : LONGINT; width, w, pos: LONGINT;
  320. BEGIN
  321. font := GetFont();
  322. totalWidth := 0; width := 0; lines := 1; lh := lineHeight.Get();
  323. cur := tabs;
  324. pos := -leftOfs;
  325. WHILE cur # NIL DO
  326. IF cur.width # 0 THEN
  327. w := cur.width
  328. ELSIF cur.caption # NIL THEN
  329. font.GetStringSize(cur.caption^, dx, dy);
  330. w := dx + 2 * border
  331. ELSE
  332. w := 2 * border
  333. END;
  334. IF (pos + w > bounds.GetWidth()) & (lh # 0) THEN
  335. width := 0; pos := 0; INC(lines);
  336. END;
  337. width := width + w; pos := pos + w;
  338. cur := cur.next;
  339. IF width > totalWidth THEN totalWidth := width END;
  340. END;
  341. IF lh # 0 THEN bounds.SetHeight(lines * lh) END;
  342. CheckLeftRightButtons
  343. END CalcSize;
  344. PROCEDURE SetTabCaption*(tab : Tab; caption : Strings.String);
  345. BEGIN
  346. Acquire;
  347. tab.caption := caption;
  348. CalcSize;
  349. Release;
  350. IF tab.inserted THEN Invalidate END
  351. END SetTabCaption;
  352. PROCEDURE SetTabColor*(tab : Tab; color : LONGINT);
  353. BEGIN
  354. Acquire;
  355. tab.color := color;
  356. Release;
  357. IF tab.inserted THEN Invalidate END
  358. END SetTabColor;
  359. (* Set fixed width for the specified tab. If width = 0, the width of the tab is detemined by the width of the caption String *)
  360. PROCEDURE SetTabWidth*(tab : Tab; width : LONGINT);
  361. BEGIN
  362. Acquire;
  363. tab.width := width;
  364. CalcSize;
  365. Release;
  366. IF tab.inserted THEN Invalidate; END;
  367. END SetTabWidth;
  368. PROCEDURE SetTabData*(tab : Tab; data : ANY);
  369. BEGIN
  370. Acquire;
  371. tab.data := data;
  372. Release;
  373. IF tab.inserted THEN Invalidate END
  374. END SetTabData;
  375. PROCEDURE NewTab*() : Tab;
  376. VAR tab : Tab;
  377. BEGIN
  378. NEW(tab); RETURN tab
  379. END NewTab;
  380. PROCEDURE DrawBackground*(canvas : WMGraphics.Canvas);
  381. VAR r : WMRectangles.Rectangle;
  382. w, h, lh, dl, dr, wLeft, wRight : LONGINT;
  383. pos,ypos : LONGINT; dx, dy, dc : LONGINT;
  384. cur : Tab; font : WMGraphics.Font;
  385. imgLeft, imgMiddle, imgRight : WMGraphics.Image;
  386. BEGIN
  387. border := borderWidth.Get();
  388. font := GetFont();
  389. dc := font.descent;
  390. (* DrawBackground^(canvas); *)
  391. lh := lineHeight.Get();
  392. IF lh # 0 THEN h := lh ELSE h:= bounds.GetHeight() END;
  393. w := bounds.GetWidth();
  394. IF left.visible.Get() THEN dl := left.bounds.GetWidth() ELSE dl := 0 END;
  395. IF right.visible.Get() THEN dr := right.bounds.GetWidth() ELSE dr := 0 END;
  396. canvas.SaveState(canvasState);
  397. canvas.SetClipRect(WMRectangles.MakeRect(dl, 0, w - dr, bounds.GetHeight()));
  398. canvas.ClipRectAsNewLimits(dl, 0);
  399. pos := - leftOfs;
  400. cur := tabs;
  401. WHILE cur # NIL DO
  402. IF cur.width # 0 THEN
  403. w := cur.width;
  404. ELSIF cur.caption # NIL THEN
  405. font.GetStringSize(cur.caption^, dx, dy); w := dx + 2 * border;
  406. ELSE
  407. w := 2 * border
  408. END;
  409. cur.w := w;
  410. IF pos + w > bounds.GetWidth() THEN
  411. pos := 0;
  412. ypos := ypos + h;
  413. END;
  414. r := WMRectangles.MakeRect(pos, ypos, pos + w, ypos+h);
  415. IF useBgBitmaps.Get() THEN
  416. IF cur = hover THEN
  417. imgLeft := imgLeftHover;
  418. imgMiddle := imgMiddleHover;
  419. imgRight := imgRightHover;
  420. ELSIF cur = selected THEN
  421. imgLeft := imgLeftSelected;
  422. imgMiddle := imgMiddleSelected;
  423. imgRight := imgRightSelected;
  424. ELSIF cur.attention THEN
  425. imgLeft := imgLeftAttention;
  426. imgMiddle := imgMiddleAttention;
  427. imgRight := imgRightAttention;
  428. ELSE
  429. imgLeft := imgLeftDefault;
  430. imgMiddle := imgMiddleDefault;
  431. imgRight := imgRightDefault
  432. END;
  433. (* left *)
  434. IF imgLeft # NIL THEN
  435. wLeft := imgLeft.width;
  436. canvas.ScaleImage( imgLeft,
  437. WMRectangles.MakeRect(0, 0, imgLeft.width, imgLeft.height),
  438. WMRectangles.MakeRect(pos, 0, pos+wLeft, bounds.GetHeight()),
  439. WMGraphics.ModeSrcOverDst, 10)
  440. ELSE
  441. wLeft := 0
  442. END;
  443. (* right *)
  444. IF imgRight # NIL THEN
  445. wRight := imgRight.width;
  446. canvas.ScaleImage( imgRight,
  447. WMRectangles.MakeRect(0, 0, imgRight.width, imgRight.height),
  448. WMRectangles.MakeRect(pos+w-wRight, 0, pos+w, bounds.GetHeight()),
  449. WMGraphics.ModeSrcOverDst, 10)
  450. ELSE
  451. wRight := 0
  452. END;
  453. (* middle *)
  454. IF imgMiddle # NIL THEN
  455. canvas.ScaleImage( imgMiddle,
  456. WMRectangles.MakeRect(0, 0, imgMiddle.width, imgMiddle.height),
  457. WMRectangles.MakeRect(pos+wLeft, 0, pos+w-wRight, bounds.GetHeight()), WMGraphics.ModeSrcOverDst, 10)
  458. END
  459. ELSE (* no bitmaps are used to decorate the background *)
  460. IF cur = hover THEN
  461. canvas.Fill(r, clHover.Get(), WMGraphics.ModeSrcOverDst)
  462. ELSIF cur = selected THEN
  463. IF (cur.attention) THEN
  464. canvas.Fill(r, clSelectedAttention.Get(), WMGraphics.ModeSrcOverDst);
  465. ELSE
  466. canvas.Fill(r, clSelected.Get(), WMGraphics.ModeSrcOverDst)
  467. END;
  468. ELSIF cur.attention THEN
  469. canvas.Fill(r, clAttention.Get(), WMGraphics.ModeSrcOverDst)
  470. ELSE
  471. IF cur.color # 0 THEN canvas.Fill(r, cur.color, WMGraphics.ModeSrcOverDst)
  472. ELSE canvas.Fill(r, clDefault.Get(), WMGraphics.ModeSrcOverDst)
  473. END
  474. END;
  475. RectGlassShade(canvas, r, {2}, 2, cur = selected)
  476. END;
  477. (* caption *)
  478. IF cur = hover THEN
  479. canvas.SetColor(clTextHover.Get());
  480. ELSIF cur = selected THEN
  481. IF (cur.attention) THEN
  482. canvas.SetColor(clTextSelectedAttention.Get());
  483. ELSE
  484. canvas.SetColor(clTextSelected.Get());
  485. END;
  486. ELSIF cur.attention THEN
  487. canvas.SetColor(clTextAttention.Get());
  488. ELSE
  489. canvas.SetColor(clTextDefault.Get());
  490. END;
  491. IF cur.caption # NIL THEN canvas.DrawString(r.l + border , r.b - dc - 1, cur.caption^) END;
  492. pos := pos + w;
  493. cur := cur.next
  494. END;
  495. canvas.RestoreState(canvasState)
  496. END DrawBackground;
  497. END Tabs;
  498. TYPE
  499. TabEntry* = OBJECT(WMStandardComponents.Panel)
  500. VAR
  501. caption- : WMProperties.StringProperty;
  502. color- : WMProperties.ColorProperty;
  503. tabWidth- : WMProperties.Int32Property;
  504. tab : Tab;
  505. tabs : Tabs;
  506. next : TabEntry;
  507. PROCEDURE PropertyChanged(sender, property : ANY);
  508. BEGIN
  509. IF (property = caption) THEN
  510. IF (tabs # NIL) & (tab # NIL) THEN
  511. tabs.SetTabCaption(tab, caption.Get());
  512. END;
  513. ELSIF (property = color) THEN
  514. IF (tabs # NIL) & (tab # NIL) THEN
  515. tabs.SetTabColor(tab, color.Get());
  516. END;
  517. ELSIF (property = tabWidth) THEN
  518. IF (tabs # NIL) & (tab # NIL) THEN
  519. tabs.SetTabWidth(tab, tabWidth.Get());
  520. END;
  521. ELSE
  522. PropertyChanged^(sender, property);
  523. END;
  524. END PropertyChanged;
  525. PROCEDURE &Init*;
  526. BEGIN
  527. Init^;
  528. SetNameAsString(StrTab);
  529. SetGenerator("WMTabComponents.GenTab");
  530. NEW(caption, NIL, StrCaption, StrCaptionDescription); properties.Add(caption);
  531. caption.Set(StrNoCaption);
  532. NEW(color, NIL, StrColor, StrColorDescription); properties.Add(color);
  533. color.Set(0);
  534. NEW(tabWidth, NIL, StrTabWidth, StrTabWidthDescription); properties.Add(tabWidth);
  535. tabWidth.Set(0);
  536. tab := NIL;
  537. tabs := NIL;
  538. next := NIL;
  539. END Init;
  540. END TabEntry;
  541. TYPE
  542. TabPanel* = OBJECT(WMStandardComponents.Panel)
  543. VAR
  544. selection- : WMProperties.StringProperty;
  545. entries : TabEntry;
  546. first : BOOLEAN;
  547. tabs : Tabs;
  548. PROCEDURE &Init*;
  549. BEGIN
  550. Init^;
  551. SetNameAsString(StrTabPanel);
  552. SetGenerator("WMTabComponents.GenTabPanel");
  553. NEW(selection, NIL, StrSelection, StrSelectionDescription); properties.Add(selection);
  554. selection.Set(StrNoSelection);
  555. first := TRUE;
  556. tabs := NIL;
  557. entries := NIL;
  558. END Init;
  559. PROCEDURE PropertyChanged(sender, property : ANY);
  560. VAR string : Strings.String;
  561. BEGIN
  562. IF (property = selection) THEN
  563. string := selection.Get();
  564. IF (tabs # NIL) & (string # NIL) THEN
  565. tabs.SelectByName(string^);
  566. END;
  567. ELSE
  568. PropertyChanged^(sender, property);
  569. END;
  570. END PropertyChanged;
  571. PROCEDURE TabSelected(sender, data : ANY);
  572. VAR e : TabEntry; tab : Tab;
  573. BEGIN
  574. IF (data # NIL) & (data IS Tab) THEN
  575. tab := data(Tab);
  576. DisableUpdate;
  577. BEGIN {EXCLUSIVE}
  578. e := entries;
  579. WHILE (e # NIL) DO
  580. IF (tab.data # NIL) & (tab.data IS TabEntry) THEN
  581. e.visible.Set(tab.data = e);
  582. END;
  583. e := e.next;
  584. END;
  585. END;
  586. EnableUpdate;
  587. Invalidate;
  588. selection.Set(Strings.NewString(data(Tab).caption^));
  589. END;
  590. END TabSelected;
  591. PROCEDURE AddContent*(c : XML.Content);
  592. VAR entry : TabEntry; tab : Tab; string : Strings.String; select : BOOLEAN;
  593. BEGIN
  594. IF (c IS Tabs) THEN
  595. IF (tabs = NIL) THEN
  596. tabs := c(Tabs);
  597. tabs.onSelectTab.Add(TabSelected);
  598. ELSE
  599. KernelLog.String("WMTabComponents: Warning: Cannot add TabControl component (already set)");
  600. KernelLog.Ln;
  601. END;
  602. ELSIF (c IS TabEntry) THEN
  603. entry := c(TabEntry);
  604. IF (tabs # NIL) THEN
  605. tab := tabs.NewTab();
  606. tab.data := entry;
  607. tab.caption := entry.caption.Get();
  608. tab.color := entry.color.Get();
  609. tab.width := entry.tabWidth.Get();
  610. IF (tab.caption = NIL) THEN tab.caption := Strings.NewString("NoCaption"); END;
  611. entry.alignment.Set(WMComponents.AlignClient);
  612. string := selection.Get();
  613. IF (string = StrNoSelection) & first THEN
  614. entry.visible.Set(TRUE);
  615. first := FALSE;
  616. select := TRUE;
  617. ELSIF (string # NIL) & (string^ = tab.caption^) THEN
  618. entry.visible.Set(TRUE);
  619. select := TRUE;
  620. ELSE
  621. entry.visible.Set(FALSE);
  622. select := FALSE;
  623. END;
  624. BEGIN {EXCLUSIVE}
  625. IF (entries = NIL) THEN
  626. entries := entry;
  627. ELSE
  628. entry.next := entries;
  629. entries := entry;
  630. END;
  631. END;
  632. entry.tabs := tabs; entry.tab := tab;
  633. tabs.AddTab(tab);
  634. IF select THEN tabs.Select(tab); END;
  635. ELSE
  636. KernelLog.String("WMTabComponents: Warning: Cannot add tab (missing TabControl component)");
  637. KernelLog.Ln;
  638. END;
  639. END;
  640. AddContent^(c);
  641. END AddContent;
  642. END TabPanel;
  643. VAR
  644. ColorPrototype, ProtoTcDefault*, ProtoTcHover*, ProtoTcSelected*, ProtoTcAttention*, ProtoTcSelectedAttention*,
  645. ProtoTcTextDefault*, ProtoTcTextHover*, ProtoTcTextSelected*, ProtoTcTextAttention, ProtoTcTextSelectedAttention* : WMProperties.ColorProperty;
  646. Int32Prototype, ProtoTcBorderWidth*, ProtoLineHeight : WMProperties.Int32Property;
  647. StringPrototype, ProtoTcBgLeftDefault, ProtoTcBgMiddleDefault, ProtoTcBgRightDefault,
  648. ProtoTcBgLeftHover, ProtoTcBgMiddleHover, ProtoTcBgRightHover,
  649. ProtoTcBgLeftSelected, ProtoTcBgMiddleSelected, ProtoTcBgRightSelected,
  650. ProtoTcBgLeftAttention, ProtoTcBgMiddleAttention, ProtoTcBgRightAttention : WMProperties.StringProperty;
  651. BooleanPrototype, ProtoTcUseBgBitmaps : WMProperties.BooleanProperty;
  652. StrTabs, StrTabPanel, StrTab,
  653. StrCaption, StrCaptionDescription, StrNoCaption,
  654. StrColor, StrColorDescription,
  655. StrTabWidth, StrTabWidthDescription,
  656. StrSelection, StrSelectionDescription, StrNoSelection : Strings.String;
  657. PROCEDURE GenTabPanel*() : XML.Element;
  658. VAR p : TabPanel;
  659. BEGIN
  660. NEW(p); RETURN p;
  661. END GenTabPanel;
  662. PROCEDURE GenTabControl*() : XML.Element;
  663. VAR c : Tabs;
  664. BEGIN
  665. NEW(c); RETURN c;
  666. END GenTabControl;
  667. PROCEDURE GenTab*() : XML.Element;
  668. VAR t : TabEntry;
  669. BEGIN
  670. NEW(t); RETURN t;
  671. END GenTab;
  672. PROCEDURE RectGlassShade*(canvas : WMGraphics.Canvas; rect : WMRectangles.Rectangle; openSides : SET; borderWidth : LONGINT; down : BOOLEAN);
  673. VAR i, ul, dr, da, w, a, b, c, d : LONGINT;
  674. BEGIN
  675. IF down THEN ul := 090H; dr := LONGINT(0FFFFFF90H)
  676. ELSE dr := 090H; ul := LONGINT(0FFFFFF90H)
  677. END;
  678. da := 90H DIV borderWidth;
  679. FOR i := 0 TO borderWidth - 1 DO
  680. IF (0 IN openSides) THEN a := 0 ELSE a := i END;
  681. IF (1 IN openSides) THEN b := 0 ELSE b := i + 1 END;
  682. IF (2 IN openSides) THEN c := 0 ELSE c := i END;
  683. IF (3 IN openSides) THEN d := 0 ELSE d := i + 1 END;
  684. (* top *)
  685. IF ~(0 IN openSides) THEN canvas.Fill(WMRectangles.MakeRect(rect.l + b , rect.t + i, rect.r - d, rect.t + i + 1), ul, WMGraphics.ModeSrcOverDst) END;
  686. (* left *)
  687. IF ~(1 IN openSides) THEN canvas.Fill(WMRectangles.MakeRect(rect.l + i, rect.t + a, rect.l + i + 1, rect.b - c), ul, WMGraphics.ModeSrcOverDst) END;
  688. (* bottom *)
  689. IF ~(2 IN openSides) THEN canvas.Fill(WMRectangles.MakeRect(rect.l + b, rect.b - 1 - i, rect.r - d, rect.b - i), dr, WMGraphics.ModeSrcOverDst) END;
  690. (* right *)
  691. IF ~(3 IN openSides) THEN canvas.Fill(WMRectangles.MakeRect(rect.r - 1 - i, rect.t + a, rect.r - i, rect.b - c), dr, WMGraphics.ModeSrcOverDst) END;
  692. DEC(ul, da); DEC(dr, da)
  693. END;
  694. i := 3; ul := LONGINT(0FFFFFF40H); w := 5;
  695. canvas.Fill(WMRectangles.MakeRect(rect.l + i , rect.t + i, rect.l + i + w, rect.t + i + 2), ul, WMGraphics.ModeSrcOverDst);
  696. canvas.Fill(WMRectangles.MakeRect(rect.l + i, rect.t + i, rect.l + i + 2, rect.t + i + w), ul, WMGraphics.ModeSrcOverDst);
  697. END RectGlassShade;
  698. PROCEDURE InitStrings;
  699. BEGIN
  700. StrTabs := Strings.NewString("Tabs");
  701. StrTabPanel := Strings.NewString("TabPanel");
  702. StrTab := Strings.NewString("Tab");
  703. StrCaption := Strings.NewString("Caption");
  704. StrNoCaption := Strings.NewString("NoCaption");
  705. StrCaptionDescription := Strings.NewString("Caption of tab");
  706. StrColor := Strings.NewString("Color");
  707. StrColorDescription := Strings.NewString("Color of tab (0: use tab default color)");
  708. StrTabWidth := Strings.NewString("TabWidth");
  709. StrTabWidthDescription := Strings.NewString("Width of the tab button");
  710. StrSelection := Strings.NewString("Selection");
  711. StrSelectionDescription := Strings.NewString("SelectionDescription");
  712. StrNoSelection := Strings.NewString("");
  713. END InitStrings;
  714. PROCEDURE InitPrototypes;
  715. VAR plTabs: WMProperties.PropertyList;
  716. BEGIN
  717. NEW(plTabs); WMComponents.propertyListList.Add("Tab", plTabs);
  718. (* tab background *)
  719. NEW(BooleanPrototype, NIL, Strings.NewString("UseBgBitmaps"), Strings.NewString("Will the background be decorated with bitmaps?"));
  720. BooleanPrototype.Set(FALSE);
  721. NEW(ProtoTcUseBgBitmaps, BooleanPrototype, NIL, NIL); plTabs.Add(ProtoTcUseBgBitmaps);
  722. (* background colors *)
  723. NEW(ColorPrototype, NIL, Strings.NewString("ClDefault"), Strings.NewString("color of the tab item"));
  724. ColorPrototype.Set(0000FF88H);
  725. NEW(ProtoTcDefault, ColorPrototype, NIL, NIL); plTabs.Add(ProtoTcDefault);
  726. NEW(ColorPrototype, NIL, Strings.NewString("ClHover"), Strings.NewString("color of the tab item, if the mouse is over it"));
  727. ColorPrototype.Set(LONGINT(0FFFF00FFH));
  728. NEW(ProtoTcHover, ColorPrototype, NIL, NIL); plTabs.Add(ProtoTcHover);
  729. NEW(ColorPrototype, NIL, Strings.NewString("ClSelected"), Strings.NewString("color of the the tab item, if it is selected"));
  730. ColorPrototype.Set(LONGINT(0FFFF00FFH));
  731. NEW(ProtoTcSelected, ColorPrototype, NIL, NIL); plTabs.Add(ProtoTcSelected);
  732. NEW(ColorPrototype, NIL, Strings.NewString("ClAttention"), Strings.NewString("color of the the tab item, if attention is required"));
  733. ColorPrototype.Set(LONGINT(0FF8040FFH));
  734. NEW(ProtoTcAttention, ColorPrototype, NIL, NIL); plTabs.Add(ProtoTcAttention);
  735. NEW(ColorPrototype, NIL, Strings.NewString("ClSelectedAttention"), Strings.NewString("color of the tab item, if it is selected and requires attention"));
  736. ColorPrototype.Set(LONGINT(0FF9020FFH));
  737. NEW(ProtoTcSelectedAttention, ColorPrototype, NIL, NIL); plTabs.Add(ProtoTcSelectedAttention);
  738. (* background bitmaps *)
  739. NEW(StringPrototype, NIL, Strings.NewString("BgLeftDefault"), Strings.NewString("Left default background bitmap"));
  740. StringPrototype.Set(NIL); NEW(ProtoTcBgLeftDefault, StringPrototype, NIL, NIL); plTabs.Add(ProtoTcBgLeftDefault);
  741. NEW(StringPrototype, NIL, Strings.NewString("BgMiddleDefault"), Strings.NewString("Middle default background bitmap"));
  742. StringPrototype.Set(NIL); NEW(ProtoTcBgMiddleDefault, StringPrototype, NIL, NIL); plTabs.Add(ProtoTcBgMiddleDefault);
  743. NEW(StringPrototype, NIL, Strings.NewString("BgRightDefault"), Strings.NewString("Right default background bitmap"));
  744. StringPrototype.Set(NIL); NEW(ProtoTcBgRightDefault, StringPrototype, NIL, NIL); plTabs.Add(ProtoTcBgRightDefault);
  745. NEW(StringPrototype, NIL, Strings.NewString("BgLeftHover"), Strings.NewString("Left mouseover background bitmap"));
  746. StringPrototype.Set(NIL); NEW(ProtoTcBgLeftHover, StringPrototype, NIL, NIL); plTabs.Add(ProtoTcBgLeftHover);
  747. NEW(StringPrototype, NIL, Strings.NewString("BgMiddleHover"), Strings.NewString("Middle mouseover background bitmap"));
  748. StringPrototype.Set(NIL); NEW(ProtoTcBgMiddleHover, StringPrototype, NIL, NIL); plTabs.Add(ProtoTcBgMiddleHover);
  749. NEW(StringPrototype, NIL, Strings.NewString("BgRightHover"), Strings.NewString("Right mouseover background bitmap"));
  750. StringPrototype.Set(NIL); NEW(ProtoTcBgRightHover, StringPrototype, NIL, NIL); plTabs.Add(ProtoTcBgRightHover);
  751. NEW(StringPrototype, NIL, Strings.NewString("BgLeftSelected"), Strings.NewString("Left selected background bitmap"));
  752. StringPrototype.Set(NIL); NEW(ProtoTcBgLeftSelected, StringPrototype, NIL, NIL); plTabs.Add(ProtoTcBgLeftSelected);
  753. NEW(StringPrototype, NIL, Strings.NewString("BgMiddleSelected"), Strings.NewString("Middle selected background bitmap"));
  754. StringPrototype.Set(NIL); NEW(ProtoTcBgMiddleSelected, StringPrototype, NIL, NIL); plTabs.Add(ProtoTcBgMiddleSelected);
  755. NEW(StringPrototype, NIL, Strings.NewString("BgRightSelected"), Strings.NewString("Right selected background bitmap"));
  756. StringPrototype.Set(NIL); NEW(ProtoTcBgRightSelected, StringPrototype, NIL, NIL); plTabs.Add(ProtoTcBgRightSelected);
  757. NEW(StringPrototype, NIL, Strings.NewString("BgLeftAttention"), Strings.NewString("Left background bitmap when attention is required"));
  758. StringPrototype.Set(NIL); NEW(ProtoTcBgLeftAttention, StringPrototype, NIL, NIL); plTabs.Add(ProtoTcBgLeftAttention);
  759. NEW(StringPrototype, NIL, Strings.NewString("BgMiddleAttention"), Strings.NewString("Middle background bitmap when attention is required"));
  760. StringPrototype.Set(NIL); NEW(ProtoTcBgMiddleAttention, StringPrototype, NIL, NIL); plTabs.Add(ProtoTcBgMiddleAttention);
  761. NEW(StringPrototype, NIL, Strings.NewString("BgRightAttention"), Strings.NewString("Right background bitmap when attention is required"));
  762. StringPrototype.Set(NIL); NEW(ProtoTcBgRightAttention, StringPrototype, NIL, NIL); plTabs.Add(ProtoTcBgRightAttention);
  763. (* text colors *)
  764. NEW(ColorPrototype, NIL, Strings.NewString("ClTextDefault"), Strings.NewString("default text color of the tab item")); ColorPrototype.Set(WMGraphics.Yellow);
  765. NEW(ProtoTcTextDefault, ColorPrototype, NIL, NIL); plTabs.Add(ProtoTcTextDefault);
  766. NEW(ColorPrototype, NIL, Strings.NewString("ClTextHover"), Strings.NewString("text color of the tab item, if the mouse is over it")); ColorPrototype.Set(00000FFFFH);
  767. NEW(ProtoTcTextHover, ColorPrototype, NIL, NIL); plTabs.Add(ProtoTcTextHover);
  768. NEW(ColorPrototype, NIL, Strings.NewString("ClTextSelected"), Strings.NewString("text color of the tab item, when selected")); ColorPrototype.Set(0000FFFFH);
  769. NEW(ProtoTcTextSelected, ColorPrototype, NIL, NIL); plTabs.Add(ProtoTcTextSelected);
  770. NEW(ColorPrototype, NIL, Strings.NewString("ClTextAttention"), Strings.NewString("text color of the tab item, when attention is required")); ColorPrototype.Set(0000FFFFH);
  771. NEW(ProtoTcTextAttention, ColorPrototype, NIL, NIL); plTabs.Add(ProtoTcTextAttention);
  772. NEW(ColorPrototype, NIL, Strings.NewString("ClTextSelectedAttention"),
  773. Strings.NewString("text color of the tab item, when selected and attention is required")); ColorPrototype.Set(0000FFFFH);
  774. NEW(ProtoTcTextSelectedAttention, ColorPrototype, NIL, NIL); plTabs.Add(ProtoTcTextSelectedAttention);
  775. (* border width *)
  776. NEW(Int32Prototype, NIL, Strings.NewString("BorderWidth"), Strings.NewString("Width of the border of the tabs")); Int32Prototype.Set(3);
  777. NEW(ProtoTcBorderWidth, Int32Prototype, NIL, NIL); plTabs.Add(ProtoTcBorderWidth);
  778. NEW(ProtoLineHeight, NIL, Strings.NewString("LineHeight"), Strings.NewString("height of a single line. If zero then no multiline support")); ProtoLineHeight.Set(0);
  779. WMComponents.propertyListList.UpdateStyle;
  780. END InitPrototypes;
  781. BEGIN
  782. InitStrings;
  783. InitPrototypes;
  784. END WMTabComponents.
  785. SystemTools.Free WMTabComponents ~
  786. WMTabComponents.Open ~