WMDefaultWindows.Mod 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. MODULE WMDefaultWindows; (** AUTHOR "TF"; PURPOSE "Decoration windows, background window for WM"; *)
  2. IMPORT
  3. Strings, WM := WMWindowManager, WMRectangles, Raster, Graphics := WMGraphics,
  4. Messages := WMMessages, Inputs, KernelLog, WMGraphicUtilities;
  5. CONST
  6. DraggingSnapRangeBase = 40;
  7. (* Dragging: Window corners *)
  8. NoCorner = 0;
  9. UpperLeft = 1;
  10. UpperRight = 2;
  11. BottomLeft = 3;
  12. BottomRight = 4;
  13. TYPE
  14. Window = WM.Window;
  15. Message = Messages.Message;
  16. String = Strings.String;
  17. DecorWindow* = OBJECT(Window);
  18. VAR
  19. lastX, lastY : LONGINT;
  20. useBitmaps*, dragging : BOOLEAN;
  21. resized : BOOLEAN;
  22. mode* : LONGINT;
  23. corner : LONGINT;
  24. mode0Move : BOOLEAN; (* Move window in mode 0 or resize it? *)
  25. hasFocus : BOOLEAN;
  26. picAa*, picBa*, picCa*,
  27. picAb*, picBb*, picCb* : Graphics.Image;
  28. distXY* : LONGINT;
  29. vertical* : BOOLEAN;
  30. focusthreshold*, threshold* : LONGINT;
  31. draggingWidth, draggingHeight : LONGINT;
  32. draggingSnapRange : LONGINT;
  33. sac, sic, basw, bisw : LONGINT;
  34. modKeys : SET;
  35. PROCEDURE SetMasterFocus*(hasFocus : BOOLEAN);
  36. BEGIN
  37. SELF.hasFocus := hasFocus; Invalidate(WMRectangles.MakeRect(0, 0, GetWidth(), GetHeight()))
  38. END SetMasterFocus;
  39. PROCEDURE GetActivePics*(VAR a, b, c : Graphics.Image);
  40. BEGIN
  41. IF hasFocus THEN a := picAa; b := picBa; c := picCa
  42. ELSE
  43. IF picAb # NIL THEN a := picAb ELSE a := picAa END;
  44. IF picBb # NIL THEN b := picBb ELSE b := picBa END;
  45. IF picCb # NIL THEN c := picCb ELSE c := picCa END;
  46. END
  47. END GetActivePics;
  48. PROCEDURE CheckHorizontal*(x, y : LONGINT) : BOOLEAN;
  49. VAR t, th : LONGINT; a, b, c: Graphics.Image;
  50. BEGIN
  51. GetActivePics(a, b, c);
  52. IF hasFocus THEN th := focusthreshold ELSE th := threshold END;
  53. IF (c # NIL) & (x >= GetWidth() - c.width) THEN
  54. RETURN Graphics.IsBitmapHit(x - (GetWidth() - c.width), y, th, c)
  55. ELSIF (a # NIL) & (x < a.width) THEN
  56. RETURN Graphics.IsBitmapHit(x, y, th, a)
  57. ELSIF (b # NIL) THEN
  58. IF a # NIL THEN t := a.width ELSE t := 0 END;
  59. RETURN Graphics.IsBitmapHit((x - t) MOD b.width, y, th, b)
  60. ELSE RETURN FALSE
  61. END
  62. END CheckHorizontal;
  63. PROCEDURE CheckVertical*(x, y : LONGINT) : BOOLEAN;
  64. VAR t, th : LONGINT; a, b, c: Graphics.Image;
  65. BEGIN
  66. GetActivePics(a, b, c);
  67. IF hasFocus THEN th := focusthreshold ELSE th := threshold END;
  68. IF (c # NIL) & (y >= GetHeight() - c.height) THEN
  69. RETURN Graphics.IsBitmapHit(x, y - (GetHeight() - c.height), th, c)
  70. ELSIF (a # NIL) & (y < a.height) THEN
  71. RETURN Graphics.IsBitmapHit(x, y, th, a)
  72. ELSIF (b # NIL) THEN
  73. IF a # NIL THEN t := a.height ELSE t := 0 END;
  74. RETURN Graphics.IsBitmapHit(x, (y - t) MOD b.height, th, b)
  75. ELSE RETURN FALSE
  76. END
  77. END CheckVertical;
  78. PROCEDURE IsHit*(x, y : LONGINT) : BOOLEAN;
  79. BEGIN
  80. IF ~useBitmaps THEN RETURN TRUE
  81. ELSE
  82. IF vertical THEN RETURN CheckVertical(x, y)
  83. ELSE RETURN CheckHorizontal(x, y)
  84. END
  85. END
  86. END IsHit;
  87. PROCEDURE PointerDown*(x, y : LONGINT; keys : SET);
  88. BEGIN
  89. IF ~hasFocus OR (ABS(lastX - (bounds.l + x)) < 10) & (ABS(lastY - (bounds.t + y)) < 10) THEN manager.ToFront(master) END;
  90. lastX := bounds.l + x; lastY := bounds.t + y;
  91. IF ((mode = 0) & (x < distXY)) OR ((mode = 3) & (y < distXY)) THEN
  92. corner := UpperLeft;
  93. ELSIF ((mode = 0) & (x > GetWidth() - distXY)) OR ((mode = 1) & (y < distXY)) THEN
  94. corner := UpperRight;
  95. ELSIF ((mode = 3) & (y > GetHeight() - distXY)) OR ((mode = 2) & (x < distXY)) THEN
  96. corner := BottomLeft;
  97. ELSIF ((mode = 2) & (x > GetWidth() - distXY)) OR ((mode = 1) & (y > GetHeight() - distXY)) THEN
  98. corner := BottomRight;
  99. ELSE
  100. corner := NoCorner;
  101. END;
  102. mode0Move := (y >= 3) & (3 <= x ) & (x <= GetWidth() - 3);
  103. draggingWidth := master.GetWidth();
  104. draggingHeight := master.GetHeight();
  105. draggingSnapRange := DraggingSnapRangeBase;
  106. IF ~(WM.FlagNoResizing IN flags) OR (mode # 0) OR mode0Move THEN
  107. dragging := TRUE;
  108. ELSE
  109. dragging := FALSE;
  110. END;
  111. IF master # NIL THEN master.HintReduceQuality(TRUE) END
  112. END PointerDown;
  113. PROCEDURE PointerMove*(x, y : LONGINT; keys : SET);
  114. VAR curX, curY, dx, dy, moveX, moveY, newWidth, newHeight, snapWidth, snapHeight: LONGINT;
  115. tx, ty : LONGINT;
  116. BEGIN
  117. IF dragging THEN
  118. curX := bounds.l + x; curY := bounds.t + y; dx := curX - lastX; dy := curY - lastY;
  119. lastX := lastX + dx; lastY := lastY + dy;
  120. IF (dx # 0) OR (dy # 0) THEN
  121. moveX := 0; moveY := 0;
  122. IF (mode = 0) & mode0Move THEN (* move the window *)
  123. moveX := dx; moveY := dy;
  124. ELSE (* resize the window *)
  125. IF (corner = NoCorner) THEN
  126. IF (mode = 0) THEN (* Top *)
  127. draggingHeight := draggingHeight - dy; moveY := dy;
  128. ELSIF (mode = 1) THEN (* Right *)
  129. draggingWidth := draggingWidth + dx;
  130. ELSIF (mode = 2) THEN (* Bottom *)
  131. draggingHeight := draggingHeight + dy;
  132. ELSIF (mode = 3) THEN (* Left *)
  133. draggingWidth := draggingWidth - dx; moveX := dx;
  134. END;
  135. ELSIF (corner = UpperLeft) THEN
  136. draggingWidth := draggingWidth - dx; moveX := dx;
  137. draggingHeight := draggingHeight - dy; moveY := dy;
  138. ELSIF (corner = UpperRight) THEN
  139. draggingWidth := draggingWidth + dx;
  140. draggingHeight := draggingHeight - dy; moveY := dy;
  141. ELSIF (corner = BottomLeft) THEN
  142. draggingHeight := draggingHeight + dy;
  143. draggingWidth := draggingWidth - dx; moveX := dx;
  144. ELSIF (corner = BottomRight) THEN
  145. draggingHeight := draggingHeight + dy;
  146. draggingWidth := draggingWidth + dx;
  147. END;
  148. newWidth := Strings.Max(1, draggingWidth);
  149. newHeight := Strings.Max(1, draggingHeight);
  150. IF modKeys * Inputs.Alt # {} THEN
  151. snapWidth := newWidth; snapHeight := newHeight;
  152. SnapDraggingSize(snapWidth, snapHeight);
  153. newWidth := snapWidth;
  154. newHeight := snapHeight;
  155. IF (newWidth # draggingWidth) THEN
  156. IF (moveX # 0) THEN
  157. moveX := moveX - (newWidth - draggingWidth);
  158. draggingWidth := newWidth;
  159. END;
  160. END;
  161. IF (newHeight # draggingHeight) THEN
  162. IF (moveY # 0) THEN
  163. moveY := moveY - (newHeight - draggingHeight);
  164. draggingHeight := newHeight;
  165. END;
  166. END;
  167. END;
  168. tx := newWidth; ty := newHeight;
  169. manager.SetWindowSize(master, newWidth, newHeight);
  170. (* If the window has not accepted the new size, we have to potentially correct its movement *)
  171. IF (tx # newWidth) THEN
  172. IF (moveX # 0) THEN moveX := moveX - (newWidth - draggingWidth); END;
  173. draggingWidth := newWidth;
  174. END;
  175. IF (ty # newHeight) THEN
  176. IF (moveY # 0) THEN moveY := moveY - (newHeight - draggingHeight); END;
  177. draggingHeight := newHeight;
  178. END;
  179. resized := TRUE
  180. END;
  181. IF (moveX # 0) OR (moveY # 0) THEN
  182. manager.SetWindowPos(SELF, bounds.l + moveX, bounds.t + moveY);
  183. END;
  184. END;
  185. END;
  186. END PointerMove;
  187. PROCEDURE SnapDraggingSize(VAR width, height : LONGINT);
  188. VAR
  189. ow, oh, snapWidth, snapHeight : LONGINT;
  190. PROCEDURE Pow2(x : INTEGER) : LONGINT;
  191. VAR
  192. r : LONGINT;
  193. i : INTEGER;
  194. BEGIN
  195. r := 1;
  196. FOR i := 1 TO x DO
  197. r := r * 2
  198. END;
  199. RETURN r;
  200. END Pow2;
  201. PROCEDURE FindNearestPow2 (value: REAL): LONGINT;
  202. VAR result: LONGINT;
  203. BEGIN
  204. result := 1;
  205. WHILE result < value DO INC (result, result) END;
  206. IF value - result DIV 2 < result - value THEN result := result DIV 2 END;
  207. RETURN result;
  208. END FindNearestPow2;
  209. BEGIN
  210. ow := master.initialBounds.r - master.initialBounds.l;
  211. oh := master.initialBounds.b - master.initialBounds.t;
  212. (* find multiple nearest to current size *)
  213. IF width > ow THEN
  214. snapWidth := ENTIER(width / ow + 0.5) * ow
  215. ELSE
  216. snapWidth := ENTIER ((1 / FindNearestPow2 (ow / width)) * ow);
  217. (*
  218. snapWidth := ENTIER((1 / Pow2(SHORT(ENTIER((Math.ln(ow / width) / Math.ln(2)) + 0.5)))) * ow)
  219. *)
  220. END;
  221. IF height > oh THEN
  222. snapHeight := ENTIER(height / oh + 0.5) * oh
  223. ELSE
  224. snapHeight := ENTIER ((1 / FindNearestPow2 (oh / height)) * oh);
  225. (*
  226. snapHeight := ENTIER((1 / Pow2(SHORT(ENTIER((Math.ln(oh / height) / Math.ln(2)) + 0.5)))) * oh)
  227. *)
  228. END;
  229. IF (height > snapHeight - draggingSnapRange) & (height < snapHeight + draggingSnapRange) THEN height := snapHeight END;
  230. IF (width > snapWidth - draggingSnapRange) & (width < snapWidth + draggingSnapRange) THEN width := snapWidth END;
  231. END SnapDraggingSize;
  232. PROCEDURE PointerUp*(x, y : LONGINT; keys:SET);
  233. VAR m : Messages.Message;
  234. BEGIN
  235. IF master # NIL THEN master.HintReduceQuality(FALSE) END;
  236. IF resized & (master # NIL) THEN
  237. m.msgType := Messages.MsgResized;
  238. m.x := master.bounds.r - master.bounds.l;
  239. m.y := master.bounds.b - master.bounds.t;
  240. IF ~master.sequencer.Add(m) THEN KernelLog.String(" resized message was not queued") END;
  241. resized := FALSE;
  242. END;
  243. dragging := FALSE;
  244. corner := NoCorner;
  245. END PointerUp;
  246. PROCEDURE Handle*(VAR m : Messages.Message);
  247. BEGIN
  248. IF m.msgType = Messages.MsgFocus THEN
  249. IF m.msgSubType = Messages.MsgSubMasterFocusGot THEN hasFocus := TRUE
  250. ELSIF m.msgSubType = Messages.MsgSubMasterFocusLost THEN hasFocus := FALSE
  251. END;
  252. Invalidate(WMRectangles.MakeRect(0, 0, GetWidth(), GetHeight()))
  253. ELSE
  254. (* read the modifier keys from the view where the message originates *)
  255. IF (m.originator # NIL) & (m.originator IS WM.ViewPort) THEN
  256. m.originator(WM.ViewPort).GetKeyState(modKeys);
  257. END;
  258. Handle^(m)
  259. END
  260. END Handle;
  261. END DecorWindow;
  262. CONST
  263. NoButton = 0;
  264. CloseButton = 1;
  265. MinimizeButton = 2;
  266. TYPE
  267. TopWindow* = OBJECT(DecorWindow)
  268. VAR
  269. closeInactive*, closeActive*, closeSelected*, closeHover*,
  270. minimizeInactive*, minimizeActive*, minimizeHover*, titleImg : Graphics.Image;
  271. minimizeOffset : LONGINT;
  272. titleCanvas : Graphics.BufferCanvas;
  273. down, hover : LONGINT;
  274. tac, tic, tax, tix, tay, tiy : LONGINT;
  275. PROCEDURE CheckButtons(x, y : LONGINT; VAR button : LONGINT);
  276. VAR img : Graphics.Image; closeImageWidth : LONGINT;
  277. BEGIN
  278. button := NoButton;
  279. (* check close button *)
  280. IF (master # NIL) & (WM.FlagClose IN master.flags) THEN
  281. IF hasFocus THEN img := closeActive ELSE img := closeInactive END;
  282. IF (img # NIL) THEN
  283. IF Graphics.IsBitmapHit(x - (GetWidth() - img.width), y, 64, img) THEN button := CloseButton; END;
  284. closeImageWidth := img.width;
  285. ELSE
  286. IF (x > GetWidth() - 20) & (y > 2) THEN button := CloseButton; END;
  287. closeImageWidth := 20;
  288. END;
  289. END;
  290. (* check minimize button *)
  291. IF (master # NIL) & (WM.FlagMinimize IN master.flags) & (button = NoButton) THEN
  292. IF hasFocus THEN img := minimizeActive; ELSE img := minimizeInactive; END;
  293. IF (img # NIL) THEN
  294. IF Graphics.IsBitmapHit(x - (GetWidth() - closeImageWidth + minimizeOffset - img.width), y, 64, img) THEN button := MinimizeButton; END;
  295. END;
  296. END;
  297. END CheckButtons;
  298. PROCEDURE PointerMove*(x, y : LONGINT; keys : SET);
  299. VAR oldHover : LONGINT;
  300. BEGIN
  301. IF ~dragging THEN
  302. oldHover := hover;
  303. CheckButtons(x, y, hover);
  304. IF (hover # oldHover) THEN Invalidate(WMRectangles.MakeRect(0, 0, GetWidth(), GetHeight())); END;
  305. IF (hover # NoButton) THEN
  306. SetPointerInfo(manager.pointerStandard);
  307. ELSIF (y < 3) OR (x < 3) OR (x > GetWidth() - 3) THEN
  308. IF ~(WM.FlagNoResizing IN flags) THEN
  309. IF (x < distXY) THEN SetPointerInfo(manager.pointerULDR);
  310. ELSIF (x > GetWidth() - distXY) THEN SetPointerInfo(manager.pointerURDL);
  311. ELSE SetPointerInfo(manager.pointerUpDown);
  312. END;
  313. END;
  314. ELSE
  315. SetPointerInfo(manager.pointerMove);
  316. END;
  317. END;
  318. PointerMove^(x, y, keys);
  319. END PointerMove;
  320. PROCEDURE PointerDown*(x, y : LONGINT; keys : SET);
  321. BEGIN
  322. CheckButtons(x, y, down);
  323. PointerDown^(x, y, keys);
  324. IF (down # NoButton) THEN dragging := FALSE; END;
  325. END PointerDown;
  326. PROCEDURE PointerUp*(x, y:LONGINT; keys:SET);
  327. VAR temp : LONGINT;
  328. BEGIN
  329. IF (down # NoButton) THEN
  330. CheckButtons(x, y, temp);
  331. IF (temp = CloseButton) THEN CloseDispatch(SELF, NIL);
  332. ELSIF (temp = MinimizeButton) THEN
  333. IF (master # NIL) THEN
  334. manager.SetIsVisible(master, ~master.isVisible);
  335. END;
  336. ELSE
  337. PointerUp^(x, y, keys);
  338. END;
  339. ELSE PointerUp^(x, y, keys)
  340. END;
  341. down := NoButton;
  342. END PointerUp;
  343. PROCEDURE PointerLeave*;
  344. BEGIN
  345. PointerLeave^;
  346. IF (hover # NoButton) THEN
  347. Invalidate(WMRectangles.MakeRect(0, 0, GetWidth(), GetHeight()));
  348. hover := NoButton;
  349. END;
  350. END PointerLeave;
  351. PROCEDURE Draw*(canvas : Graphics.Canvas; w, h, q : LONGINT);
  352. CONST IconBorder = 5;
  353. VAR
  354. color, sw, tc, tx, ty, dx, dy : LONGINT; fw, fh : REAL; a, b, c, img : Graphics.Image; title : String;
  355. f : Graphics.Font;
  356. iconSize, closeImageWidth : LONGINT;
  357. BEGIN
  358. fw := w / GetWidth(); fh := h / GetHeight();
  359. IF hasFocus THEN
  360. tc := tac; color := sac; sw := basw; tx := tax; ty := tay
  361. ELSE
  362. tc := tic; color := sic; sw := bisw; tx := tix; ty := tiy
  363. END;
  364. IF useBitmaps THEN
  365. GetActivePics(a, b, c);
  366. RepeatMiddleHorizontal(canvas, GetWidth(), GetHeight(), w, h, q, a, b, c)
  367. ELSE
  368. canvas.Fill(WMRectangles.MakeRect(0, 0, w, h), color, Graphics.ModeSrcOverDst);
  369. END;
  370. (* Close button *)
  371. IF (master # NIL) & (WM.FlagClose IN master.flags) THEN
  372. IF (hover = CloseButton) & (closeHover # NIL) THEN img := closeHover;
  373. ELSIF hasFocus THEN img := closeActive ELSE img := closeInactive END;
  374. IF img # NIL THEN
  375. canvas.ScaleImage(img, WMRectangles.MakeRect(0, 0, img.width, img.height),
  376. WMRectangles.MakeRect(w - ENTIER(img.width * fw), 0, w, ENTIER(img.height * fh)), Graphics.ModeSrcOverDst, q);
  377. closeImageWidth := img.width;
  378. ELSE
  379. canvas.Fill(WMRectangles.MakeRect(w - ENTIER(20 * fw), ENTIER(2 * fh), w, h), LONGINT(0FF0000C0H), Graphics.ModeSrcOverDst);
  380. closeImageWidth := 20;
  381. END;
  382. END;
  383. (* Minimize button *)
  384. IF (master # NIL) & (WM.FlagMinimize IN master.flags) THEN
  385. IF (hover = MinimizeButton) & (minimizeHover # NIL) THEN img := minimizeHover;
  386. ELSIF hasFocus THEN img := minimizeActive ELSE img := minimizeInactive END;
  387. IF img # NIL THEN
  388. canvas.ScaleImage(img, WMRectangles.MakeRect(0, 0, img.width, img.height),
  389. WMRectangles.MakeRect(w - ENTIER((img.width + closeImageWidth - minimizeOffset) * fw), 0, w - ENTIER((closeImageWidth - minimizeOffset) * fw), ENTIER(img.height * fh)), Graphics.ModeSrcOverDst, q)
  390. ELSE
  391. (* canvas.Fill(WMRectangles.MakeRect(w - ENTIER(20 * fw), ENTIER(2 * fh), w, h), LONGINT(0FF0000C0H), Graphics.ModeSrcOverDst); *)
  392. END;
  393. END;
  394. IF master # NIL THEN
  395. IF (master.icon # NIL) THEN
  396. iconSize := GetHeight()- 2*IconBorder;
  397. IF (iconSize * fw > 4) THEN
  398. canvas.ScaleImage(master.icon,
  399. WMRectangles.MakeRect(0, 0, master.icon.width, master.icon.height),
  400. WMRectangles.MakeRect(ENTIER(tx * fw), h - ENTIER((iconSize + IconBorder) * fh), ENTIER((tx + iconSize) * fw), h - ENTIER(IconBorder * fh)),
  401. Graphics.ModeSrcOverDst, q);
  402. tx := tx + iconSize + 2;
  403. END;
  404. END;
  405. title := master.GetTitle();
  406. IF title # NIL THEN
  407. IF (w = GetWidth()) & (h = GetHeight()) THEN
  408. canvas.SetColor(tc);
  409. canvas.DrawString(tx, ty, title^)
  410. ELSE
  411. f := Graphics.GetDefaultFont();
  412. f.GetStringSize(title^, dx, dy);
  413. IF (titleImg = NIL) OR (tx + dx > titleImg.width) OR (GetHeight() > titleImg.height) THEN NEW(titleImg);
  414. Raster.Create(titleImg, tx + dx + 10, GetHeight(), Raster.BGRA8888);
  415. NEW(titleCanvas, titleImg);
  416. END;
  417. titleCanvas.Fill(WMRectangles.MakeRect(0, 0, titleImg.width, titleImg.height), 0, Graphics.ModeCopy);
  418. titleCanvas.SetColor(tc);
  419. titleCanvas.DrawString(tx, ty, title^);
  420. canvas.ScaleImage(titleImg, WMRectangles.MakeRect(0, 0, titleImg.width, titleImg.height),
  421. WMRectangles.MakeRect(0, 0, ENTIER(titleImg.width * fw), ENTIER(titleImg.height * fh)), Graphics.ModeSrcOverDst, q)
  422. END
  423. END
  424. END;
  425. IF ~useBitmaps THEN
  426. WMGraphicUtilities.ExtRectGlassShade(canvas, WMRectangles.MakeRect(0, 0, w, h), {2}, sw, FALSE)
  427. END
  428. END Draw;
  429. PROCEDURE CloseDispatch*(sender, data : ANY);
  430. VAR m : Message;
  431. BEGIN
  432. IF master = NIL THEN RETURN END;
  433. m.msgType := Messages.MsgClose;
  434. IF master.sequencer # NIL THEN
  435. IF ~master.sequencer.Add(m) THEN KernelLog.String("Close message could not be queued."); KernelLog.Ln END
  436. ELSE master.Handle(m)
  437. END;
  438. END CloseDispatch;
  439. PROCEDURE StyleChanged*;
  440. VAR s : WM.WindowStyle; r : WMRectangles.Rectangle;
  441. BEGIN
  442. s := manager.GetStyle();
  443. useBitmaps := s.useBitmaps; sac := s.baCol; sic := s.biCol; basw := s.basw; bisw := s.bisw;
  444. focusthreshold := s.topFocusThreshold; threshold := s.topThreshold;
  445. picAa := s.taa; picBa := s.tab; picCa := s.tac;
  446. picAb := s.tia; picBb := s.tib; picCb := s.tic;
  447. tac := s.atextColor; tic := s.itextColor;
  448. tax := s.atextX; tix := s.itextX;
  449. tay := s.atextY; tiy := s.itextY;
  450. closeActive := s.ca; closeInactive := s.ci; closeHover := s.closeHover;
  451. minimizeActive := s.ma; minimizeInactive := s.mi; minimizeHover := s.minimizeHover;
  452. minimizeOffset := s.minimizeOffset;
  453. manager.lock.AcquireWrite;
  454. r := bounds;
  455. bounds := Graphics.MakeRectangle(master.bounds.l - s.lw, master.bounds.t - s.th, master.bounds.r + s.rw, master.bounds.t);
  456. WMRectangles.ExtendRect(r, bounds);
  457. manager.lock.ReleaseWrite;
  458. manager.AddDirty(r)
  459. END StyleChanged;
  460. END TopWindow;
  461. LeftWindow* = OBJECT(DecorWindow)
  462. PROCEDURE Draw*(canvas : Graphics.Canvas; w, h, q : LONGINT);
  463. VAR color, sw : LONGINT; a, b, c : Graphics.Image;
  464. BEGIN
  465. IF hasFocus THEN color := sac; sw := basw ELSE color := sic; sw := bisw END;
  466. IF useBitmaps THEN
  467. GetActivePics(a, b, c);
  468. RepeatMiddleVertical(canvas, GetWidth(), GetHeight(), w, h, q, a, b, c)
  469. ELSE
  470. canvas.Fill(Graphics.MakeRectangle(0, 0, w, h), color, Graphics.ModeSrcOverDst);
  471. WMGraphicUtilities.ExtRectGlassShade(canvas, WMRectangles.MakeRect(0, 0, w, h), {0, 2, 3}, sw, FALSE);
  472. END
  473. END Draw;
  474. PROCEDURE PointerMove*(x, y : LONGINT; keys : SET);
  475. BEGIN
  476. IF ~dragging & ~(WM.FlagNoResizing IN flags) THEN
  477. IF (y < distXY) THEN SetPointerInfo(manager.pointerULDR);
  478. ELSIF (y > GetHeight() - distXY) THEN SetPointerInfo(manager.pointerURDL)
  479. ELSE SetPointerInfo(manager.pointerLeftRight)
  480. END;
  481. END;
  482. PointerMove^(x, y, keys)
  483. END PointerMove;
  484. PROCEDURE StyleChanged*;
  485. VAR s : WM.WindowStyle; r : WMRectangles.Rectangle;
  486. BEGIN
  487. s := manager.GetStyle();
  488. useBitmaps := s.useBitmaps; sac := s.baCol; sic := s.biCol; basw := s.basw; bisw := s.bisw;
  489. focusthreshold := s.leftFocusThreshold; threshold := s.leftThreshold;
  490. picAa := s.laa; picBa := s.lab; picCa := s.lac;
  491. picAb := s.lia; picBb := s.lib; picCb := s.lic;
  492. manager.lock.AcquireWrite;
  493. r :=bounds;
  494. bounds := Graphics.MakeRectangle(master.bounds.l - s.lw, master.bounds.t, master.bounds.l, master.bounds.b);
  495. WMRectangles.ExtendRect(r, bounds);
  496. manager.lock.ReleaseWrite;
  497. manager.AddDirty(r)
  498. END StyleChanged;
  499. END LeftWindow;
  500. RightWindow* = OBJECT(DecorWindow)
  501. PROCEDURE Draw*(canvas : Graphics.Canvas; w, h, q : LONGINT);
  502. VAR color, sw : LONGINT; a, b, c : Graphics.Image;
  503. BEGIN
  504. IF hasFocus THEN color := sac; sw := basw ELSE color := sic; sw := bisw END;
  505. IF useBitmaps THEN
  506. GetActivePics(a, b, c);
  507. RepeatMiddleVertical(canvas, GetWidth(), GetHeight(), w, h, q, a, b, c)
  508. ELSE
  509. canvas.Fill(Graphics.MakeRectangle(0, 0, w, h), color, Graphics.ModeSrcOverDst);
  510. WMGraphicUtilities.ExtRectGlassShade(canvas, WMRectangles.MakeRect(0, 0, w, h), {0, 1, 2}, sw, FALSE);
  511. END
  512. END Draw;
  513. PROCEDURE PointerMove*(x, y : LONGINT; keys : SET);
  514. BEGIN
  515. IF ~dragging & ~(WM.FlagNoResizing IN flags) THEN
  516. IF (y < distXY) THEN SetPointerInfo(manager.pointerURDL);
  517. ELSIF (y > GetHeight() - distXY) THEN SetPointerInfo(manager.pointerULDR)
  518. ELSE SetPointerInfo(manager.pointerLeftRight)
  519. END;
  520. END;
  521. PointerMove^(x, y, keys)
  522. END PointerMove;
  523. PROCEDURE StyleChanged*;
  524. VAR s : WM.WindowStyle; r : WMRectangles.Rectangle;
  525. BEGIN
  526. s := manager.GetStyle();
  527. useBitmaps := s.useBitmaps; sac := s.baCol; sic := s.biCol; basw := s.basw; bisw := s.bisw;
  528. focusthreshold := s.rightFocusThreshold; threshold := s.rightThreshold;
  529. picAa := s.raa; picBa := s.rab; picCa := s.rac;
  530. picAb := s.ria; picBb := s.rib; picCb := s.ric;
  531. manager.lock.AcquireWrite;
  532. r :=bounds;
  533. bounds := Graphics.MakeRectangle(master.bounds.r, master.bounds.t, master.bounds.r + s.rw, master.bounds.b);
  534. WMRectangles.ExtendRect(r, bounds);
  535. manager.lock.ReleaseWrite;
  536. manager.AddDirty(r)
  537. END StyleChanged;
  538. END RightWindow;
  539. BottomWindow* = OBJECT(DecorWindow)
  540. PROCEDURE Draw*(canvas : Graphics.Canvas; w, h, q : LONGINT);
  541. VAR color, sw : LONGINT; a, b, c : Graphics.Image;
  542. BEGIN
  543. IF hasFocus THEN color := sac; sw := basw ELSE color := sic; sw := bisw END;
  544. IF useBitmaps THEN
  545. GetActivePics(a, b, c);
  546. RepeatMiddleHorizontal(canvas, GetWidth(), GetHeight(), w, h, q, a, b, c)
  547. ELSE
  548. canvas.Fill(WMRectangles.MakeRect(0, 0, w, h), color, Graphics.ModeSrcOverDst);
  549. WMGraphicUtilities.ExtRectGlassShade(canvas, WMRectangles.MakeRect(0, 0, w, h), {0}, sw, FALSE);
  550. END
  551. END Draw;
  552. PROCEDURE PointerMove*(x, y : LONGINT; keys : SET);
  553. BEGIN
  554. IF ~dragging & ~(WM.FlagNoResizing IN flags) THEN
  555. IF (x < distXY) THEN SetPointerInfo(manager.pointerURDL);
  556. ELSIF (x > GetWidth() - distXY) THEN SetPointerInfo(manager.pointerULDR);
  557. ELSE SetPointerInfo(manager.pointerUpDown)
  558. END;
  559. END;
  560. PointerMove^(x, y, keys)
  561. END PointerMove;
  562. PROCEDURE StyleChanged*;
  563. VAR s : WM.WindowStyle; r : WMRectangles.Rectangle;
  564. BEGIN
  565. s := manager.GetStyle();
  566. useBitmaps := s.useBitmaps; sac := s.baCol; sic := s.biCol; basw := s.basw; bisw := s.bisw;
  567. focusthreshold := s.bottomFocusThreshold; threshold := s.bottomThreshold;
  568. picAa := s.baa; picBa := s.bab; picCa := s.bac;
  569. picAb := s.bia; picBb := s.bib; picCb := s.bic;
  570. manager.lock.AcquireWrite;
  571. r := bounds;
  572. bounds := Graphics.MakeRectangle(master.bounds.l - s.lw, master.bounds.b, master.bounds.r + s.rw, master.bounds.b + s.bh);
  573. WMRectangles.ExtendRect(r, bounds);
  574. manager.lock.ReleaseWrite;
  575. manager.AddDirty(r)
  576. END StyleChanged;
  577. END BottomWindow;
  578. BackWindow* = OBJECT(WM.Window)
  579. VAR color : Graphics.Color;
  580. PROCEDURE &New*(bgColor: LONGINT);
  581. BEGIN
  582. color := bgColor;
  583. isVisible := TRUE;
  584. END New;
  585. PROCEDURE StyleChanged*;
  586. VAR s : WM.WindowStyle; r : WMRectangles.Rectangle;
  587. BEGIN
  588. s := manager.GetStyle();
  589. IF s # NIL THEN
  590. IF s.desktopColor # color THEN
  591. color := s.desktopColor;
  592. r := WMRectangles.MakeRect(-10000, -10000, 10000, 10000);
  593. manager.AddDirty(r)
  594. END
  595. END;
  596. END StyleChanged;
  597. PROCEDURE Draw*(canvas : Graphics.Canvas; w, h, q : LONGINT);
  598. VAR rect : WMRectangles.Rectangle;
  599. BEGIN
  600. canvas.GetClipRect(rect);
  601. canvas.Fill(rect, color, Graphics.ModeCopy);
  602. END Draw;
  603. END BackWindow;
  604. (** GRAPHIC TOOLS *)
  605. (** Fill a rectangle vertically with images, repeating the middle if needed *)
  606. PROCEDURE RepeatMiddleVertical*(canvas : Graphics.Canvas; csw, csh, w, h, q : LONGINT; top, middle, bottom : Graphics.Image);
  607. VAR fh : REAL; y, t : LONGINT;
  608. BEGIN
  609. IF (csw = 0) OR (csh = 0) OR (w = 0) OR (h = 0) THEN RETURN END;
  610. fh := h / csh;
  611. y := 0;
  612. (* left border *)
  613. IF top # NIL THEN
  614. canvas.ScaleImage(top, WMRectangles.MakeRect(0, 0, top.width, top.height),
  615. WMRectangles.MakeRect(0, 0, w, ENTIER(top.height * fh)), Graphics.ModeSrcOverDst, q);
  616. y := top.height; DEC(csh, top.height)
  617. END;
  618. IF bottom # NIL THEN t := bottom.height ELSE t := 0 END;
  619. IF middle # NIL THEN
  620. WHILE csh - t > middle.height DO
  621. canvas.ScaleImage(middle, WMRectangles.MakeRect(0, 0, middle.width, middle.height),
  622. WMRectangles.MakeRect(0, ENTIER(y * fh), w, ENTIER((y + middle.height) * fh)), Graphics.ModeSrcOverDst, q);
  623. INC(y, middle.height); DEC(csh, middle.height)
  624. END;
  625. IF (csh - t) > 0 THEN
  626. canvas.ScaleImage(middle, WMRectangles.MakeRect(0, 0, middle.width, (csh - t)),
  627. WMRectangles.MakeRect(0, ENTIER(y * fh), w, ENTIER((y + (csh - t)) * fh+ 0.5)), Graphics.ModeSrcOverDst, q);
  628. INC(y, (csh - t));
  629. END;
  630. END;
  631. IF bottom # NIL THEN
  632. canvas.ScaleImage(bottom, WMRectangles.MakeRect(0, 0, bottom.width, bottom.height),
  633. WMRectangles.MakeRect(0, ENTIER(y * fh + 0.5), w, h), Graphics.ModeSrcOverDst, q)
  634. END;
  635. END RepeatMiddleVertical;
  636. (** Fill a rectangle vertically with images, repeating the middle if needed *)
  637. PROCEDURE RepeatMiddleHorizontal*(canvas : Graphics.Canvas; csw, csh, w, h, q : LONGINT; left, middle, right : Graphics.Image);
  638. VAR fw : REAL; x, t : LONGINT;
  639. BEGIN
  640. IF (csw = 0) OR (csh = 0) OR (w = 0) OR (h = 0) THEN RETURN END;
  641. fw := w / csw;
  642. x := 0;
  643. (* left border *)
  644. IF left # NIL THEN
  645. canvas.ScaleImage(left, WMRectangles.MakeRect(0, 0, left.width, left.height),
  646. WMRectangles.MakeRect(0, 0, ENTIER(left.width * fw), h), Graphics.ModeSrcOverDst, q);
  647. x := left.width; DEC(csw, left.width)
  648. END;
  649. IF right # NIL THEN t := right.width ELSE t := 0 END;
  650. IF middle # NIL THEN
  651. WHILE csw - t > middle.width DO
  652. canvas.ScaleImage(middle, WMRectangles.MakeRect(0, 0, middle.width, middle.height),
  653. WMRectangles.MakeRect(ENTIER(x * fw), 0, ENTIER((x + middle.width) * fw), h), Graphics.ModeSrcOverDst, q);
  654. INC(x, middle.width); DEC(csw, middle.width)
  655. END;
  656. IF (csw - t) > 0 THEN
  657. canvas.ScaleImage(middle, WMRectangles.MakeRect(0, 0, (csw - t), middle.height),
  658. WMRectangles.MakeRect(ENTIER(x * fw), 0, ENTIER((x + (csw - t)) * fw + 0.5), h), Graphics.ModeSrcOverDst, q);
  659. INC(x, (csw - t));
  660. END;
  661. END;
  662. IF right # NIL THEN
  663. canvas.ScaleImage(right, WMRectangles.MakeRect(0, 0, right.width, right.height),
  664. WMRectangles.MakeRect(ENTIER(x * fw + 0.5), 0, w, h), Graphics.ModeSrcOverDst, q)
  665. END;
  666. END RepeatMiddleHorizontal;
  667. END WMDefaultWindows.