WMOverlay.Mod 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. MODULE WMOverlay; (** AUTHOR "staubesv"; PURPOSE "Drawing over the screen"; *)
  2. IMPORT
  3. Modules, Files, Inputs, Strings,
  4. Raster, WMRectangles, WMGraphics, WMGraphicUtilities, WMWindowManager, WMRestorable, WMDialogs;
  5. CONST
  6. (* Window.mode *)
  7. Mode_Idle = 0;
  8. Mode_Drawing = 1;
  9. Pointer_Arrow = 0;
  10. Pointer_Crosshair = 1;
  11. NofImages = 4;
  12. NofFunctions = 3;
  13. Function_Close = 0;
  14. Function_Clear = 1;
  15. Function_ToggleMode = 2;
  16. IconWidth = 48;
  17. IconHeight = 48;
  18. Border = 16;
  19. FontName = "Vera";
  20. FontSize = 24;
  21. TYPE
  22. Item = RECORD
  23. isEnabled : BOOLEAN;
  24. bgEnabled : LONGINT;
  25. rect : WMRectangles.Rectangle;
  26. image, imageHover : WMGraphics.Image;
  27. END;
  28. TYPE
  29. Window = OBJECT (WMWindowManager.BufferWindow);
  30. VAR
  31. lx, ly, stringX, stringY, stringX0, stringY0 : LONGINT;
  32. mode : LONGINT;
  33. currentString : ARRAY 1024 OF CHAR;
  34. currentIdx : LONGINT;
  35. mrEnabled : BOOLEAN;
  36. mouseOver : LONGINT; (* index of mouse over icon, -1 of no mouse over *)
  37. currentPointer : LONGINT;
  38. currentIndex : LONGINT;
  39. color, bgColor : LONGINT;
  40. dragStartX, dragStartY : LONGINT;
  41. dragging, noDrag : BOOLEAN;
  42. modifierFlags : SET;
  43. items : ARRAY NofFunctions + NofImages OF Item;
  44. PROCEDURE &New*;
  45. VAR
  46. image, imageHover : Files.FileName; font : WMGraphics.Font;
  47. i : LONGINT;
  48. BEGIN
  49. Init(viewport.width0, viewport.height0, TRUE);
  50. lx := -1; ly := -1;
  51. stringX := lx; stringY := ly;
  52. stringX0 := stringX; stringY0 := stringY;
  53. currentString := ""; currentIdx := 0;
  54. mode := Mode_Idle;
  55. mrEnabled := FALSE;
  56. mouseOver := -1;
  57. color := WMGraphics.Red;
  58. bgColor := 0;
  59. dragging := FALSE; noDrag := FALSE;
  60. modifierFlags := {};
  61. FOR i := 0 TO LEN(items)-1 DO
  62. items[i].isEnabled := FALSE;
  63. items[i].bgEnabled := 0;
  64. items[i].rect := WMRectangles.MakeRect(
  65. viewport.width0 - Border - (i + 1) * (Border + IconWidth), viewport.height0 - Border - IconHeight,
  66. viewport.width0 - Border - i * (Border + IconWidth), viewport.height0 - Border
  67. );
  68. IF (i < NofFunctions) THEN
  69. image := ""; imageHover := "";
  70. CASE i OF
  71. |Function_Close:
  72. image := "WMIcons.tar://WMKernelLog";
  73. |Function_Clear:
  74. image := "WMOverlay.tar://trashcan.png"; imageHover := "WMOverlay.tar://trashcanHover.png";
  75. |Function_ToggleMode:
  76. image := "WMOverlay.tar://feather.png"; imageHover := "WMOverlay.tar://featherHover.png";
  77. items[i].bgEnabled := 0FF0030H;
  78. ELSE
  79. END;
  80. items[i].image := WMGraphics.LoadImage(image, TRUE);
  81. items[i].imageHover := WMGraphics.LoadImage(imageHover, TRUE);
  82. ELSE
  83. NEW(items[i].image);
  84. Raster.Create(items[i].image, img.width, img.height, img.fmt);
  85. Raster.Clear(items[i].image);
  86. END;
  87. END;
  88. currentIndex := LEN(items)-1;
  89. items[currentIndex].isEnabled := TRUE;
  90. WMWindowManager.ExtAddWindow(SELF, 0, 0, {WMWindowManager.FlagStayOnTop, WMWindowManager.FlagNavigation});
  91. SetTitle(Strings.NewString("Overlay"));
  92. SetIcon(WMGraphics.LoadImage("WMIcons.tar://WMScribble.png", TRUE));
  93. Fill(0);
  94. SetPointerInfo(manager.pointerCrosshair);
  95. currentPointer := Pointer_Crosshair;
  96. font := WMGraphics.GetFont(FontName, FontSize, {});
  97. IF (font # NIL) THEN canvas.SetFont(font); END;
  98. END New;
  99. PROCEDURE GetItemIndex(x, y : LONGINT) : LONGINT;
  100. VAR i, result : LONGINT;
  101. BEGIN
  102. i := 0; result := -1;
  103. WHILE (result < 0) & (i < LEN(items)) DO
  104. IF WMRectangles.PointInRect(x, y, items[i].rect) THEN result := i; END;
  105. INC(i);
  106. END;
  107. RETURN result;
  108. END GetItemIndex;
  109. PROCEDURE IsHit*(x, y : LONGINT) : BOOLEAN;
  110. BEGIN
  111. RETURN (mode = Mode_Drawing) OR (GetItemIndex(x, y) >= 0);
  112. END IsHit;
  113. PROCEDURE Draw*(canvas : WMGraphics.Canvas; width, height, quality : LONGINT);
  114. CONST IconBorder = 8;
  115. VAR image : WMGraphics.Image; nbr : ARRAY 8 OF CHAR; color, i : LONGINT;
  116. BEGIN
  117. Draw^(canvas, width, height, quality);
  118. FOR i := 0 TO LEN(items)-1 DO
  119. IF (i < NofFunctions) THEN
  120. IF (items[i].image # NIL) THEN
  121. IF (i = mouseOver) & (items[i].imageHover # NIL) THEN
  122. image := items[i].imageHover;
  123. ELSE
  124. image := items[i].image;
  125. END;
  126. IF items[i].isEnabled & (items[i].bgEnabled # 0) THEN
  127. canvas.Fill(items[i].rect, items[i].bgEnabled, WMGraphics.ModeSrcOverDst);
  128. END;
  129. canvas.ScaleImage(image,
  130. WMRectangles.MakeRect(0, 0, image.width, image.height),
  131. WMRectangles.MakeRect(items[i].rect.l + IconBorder, items[i].rect.t + IconBorder, items[i].rect.r - IconBorder, items[i].rect.b - IconBorder), WMGraphics.ModeSrcOverDst, quality)
  132. END;
  133. ELSE
  134. IF (i = mouseOver) THEN color := WMGraphics.Blue; ELSE color := WMGraphics.White; END;
  135. WMGraphicUtilities.DrawRect(canvas, items[i].rect, color, WMGraphics.ModeCopy);
  136. IF items[i].isEnabled THEN canvas.Fill(items[i].rect, 0FF40H, WMGraphics.ModeSrcOverDst); END;
  137. Strings.IntToStr(NofImages - (i - NofFunctions), nbr);
  138. WMGraphics.DrawStringInRect(canvas, items[i].rect, FALSE , WMGraphics.AlignCenter, WMGraphics.AlignCenter, nbr);
  139. END;
  140. END;
  141. END Draw;
  142. PROCEDURE PointerMove*(x, y : LONGINT; keys : SET);
  143. VAR icon, oldMouseOver : LONGINT;
  144. PROCEDURE InvalidateIcon(idx : LONGINT);
  145. BEGIN
  146. IF (0 <= idx) & (idx < LEN(items)) THEN
  147. Invalidate(items[idx].rect);
  148. END;
  149. END InvalidateIcon;
  150. BEGIN
  151. PointerMove^(x, y, keys);
  152. stringX := x; stringY := y;
  153. stringX0 := x; stringY0 := y;
  154. currentString := ""; currentIdx := 0;
  155. icon := GetItemIndex(x, y);
  156. IF (icon # mouseOver) THEN
  157. oldMouseOver := mouseOver;
  158. mouseOver := icon;
  159. InvalidateIcon(oldMouseOver);
  160. InvalidateIcon(mouseOver);
  161. END;
  162. IF (icon < 0) THEN
  163. IF (currentPointer # Pointer_Crosshair) THEN
  164. currentPointer := Pointer_Crosshair;
  165. SetPointerInfo(manager.pointerCrosshair);
  166. END;
  167. IF (0 IN keys) & ~dragging THEN
  168. IF (color # 0) THEN
  169. canvas.Line(lx, ly, x, y, color, WMGraphics.ModeSrcOverDst);
  170. ELSE
  171. canvas.Line(lx, ly, x, y, color, WMGraphics.ModeCopy);
  172. END;
  173. Invalidate(WMRectangles.MakeRect(Strings.Min(lx, x), Strings.Min(ly, y), Strings.Max(lx, x) + 1, Strings.Max(ly, y) + 1));
  174. END;
  175. ELSIF (currentPointer # Pointer_Arrow) THEN
  176. currentPointer := Pointer_Arrow;
  177. SetPointerInfo(manager.pointerStandard);
  178. END;
  179. lx := x; ly := y
  180. END PointerMove;
  181. PROCEDURE PointerDown*(x, y : LONGINT; keys : SET);
  182. VAR rect : WMRectangles.Rectangle; index : LONGINT;
  183. BEGIN
  184. PointerDown^(x, y, keys);
  185. lx := x; ly := y;
  186. IF (keys = {1}) THEN
  187. mode := Mode_Idle;
  188. items[Function_ToggleMode].isEnabled := FALSE;
  189. Invalidate(items[Function_ToggleMode].rect);
  190. ELSIF (keys = {2}) THEN
  191. Fill(bgColor);
  192. ELSIF 0 IN keys THEN
  193. IF dragging & (2 IN keys) THEN
  194. rect := WMRectangles.MakeRect(dragStartX, dragStartY, x, y);
  195. canvas.Fill(rect, bgColor, WMGraphics.ModeCopy);
  196. Invalidate(rect);
  197. noDrag := TRUE;
  198. END;
  199. index := GetItemIndex(x, y);
  200. IF (index >= 0) THEN
  201. items[index].isEnabled := ~items[index].isEnabled;
  202. IF (items[index].bgEnabled # 0) THEN
  203. Invalidate(items[index].rect);
  204. END;
  205. ProcessCommand(items[index], index);
  206. ELSE
  207. IF (Inputs.Shift * modifierFlags # {}) & ~dragging THEN
  208. dragStartX := x; dragStartY := y;
  209. dragging := TRUE;
  210. END;
  211. END;
  212. END;
  213. END PointerDown;
  214. PROCEDURE PointerUp*(x, y : LONGINT; keys : SET);
  215. VAR rect : WMRectangles.Rectangle;
  216. BEGIN
  217. PointerUp^(x, y, keys);
  218. IF dragging & ~(0 IN keys) THEN
  219. IF ~noDrag THEN
  220. rect := WMRectangles.MakeRect(dragStartX, dragStartY, x, y);
  221. WMGraphicUtilities.DrawRect(canvas, rect, color, WMGraphics.ModeCopy);
  222. Invalidate(rect);
  223. END;
  224. dragging := FALSE; noDrag := FALSE;
  225. END;
  226. END PointerUp;
  227. PROCEDURE PointerLeave*;
  228. BEGIN
  229. PointerLeave^;
  230. IF (mouseOver >= 0) THEN mouseOver := -1; Invalidate(bounds); END;
  231. END PointerLeave;
  232. PROCEDURE ProcessCommand(item : Item; index : LONGINT);
  233. VAR i : LONGINT; c : WMGraphics.BufferCanvas;
  234. BEGIN
  235. IF (index = Function_Close) THEN
  236. Close;
  237. ELSIF (index = Function_ToggleMode) THEN
  238. mrEnabled := FALSE;
  239. IF (mode = Mode_Idle) THEN mode := Mode_Drawing; ELSE mode := Mode_Idle; END;
  240. ELSIF (index = Function_Clear) THEN
  241. Fill(0);
  242. ELSE
  243. FOR i := NofFunctions TO LEN(items)-1 DO
  244. items[i].isEnabled := (i = index);
  245. END;
  246. IF (currentIndex # index) THEN
  247. NEW(c, items[currentIndex].image);
  248. c.DrawImage(0, 0, img, WMGraphics.ModeCopy);
  249. currentIndex := index;
  250. canvas.DrawImage(0, 0, items[index].image, WMGraphics.ModeCopy);
  251. END;
  252. Invalidate(WMRectangles.MakeRect(0, 0, GetWidth(), GetHeight()));
  253. END;
  254. END ProcessCommand;
  255. PROCEDURE FocusLost*;
  256. BEGIN
  257. FocusLost^;
  258. modifierFlags := {};
  259. END FocusLost;
  260. PROCEDURE Fill(color : LONGINT);
  261. BEGIN
  262. canvas.Fill(WMRectangles.MakeRect(0, 0, GetWidth(), GetHeight()), color, WMGraphics.ModeCopy);
  263. Invalidate(WMRectangles.MakeRect(0, 0, GetWidth(), GetHeight()))
  264. END Fill;
  265. PROCEDURE KeyEvent*(ucs : LONGINT; flags : SET; keySym : LONGINT);
  266. VAR
  267. filename : Files.FileName; newImg : WMGraphics.Image; oldMode: LONGINT; res: WORD;
  268. string : ARRAY 2 OF CHAR; dx, dy : LONGINT;
  269. font : WMGraphics.Font;
  270. BEGIN
  271. modifierFlags := flags;
  272. IF (Inputs.Release IN flags) THEN RETURN; END;
  273. IF (Inputs.Ctrl * flags # {}) THEN
  274. IF (Inputs.Shift * flags # {}) THEN
  275. IF (ucs = ORD("1")) THEN bgColor := WMGraphics.Red;
  276. ELSIF (ucs = ORD("2")) THEN bgColor := WMGraphics.Black;
  277. ELSIF (ucs = ORD("3")) THEN bgColor := WMGraphics.White;
  278. ELSIF (ucs = ORD("4")) THEN bgColor := WMGraphics.Blue;
  279. ELSIF (ucs = ORD("5")) THEN bgColor := WMGraphics.Green;
  280. ELSIF (ucs = ORD("0")) THEN bgColor := 0;
  281. END;
  282. Fill(bgColor);
  283. ELSE
  284. IF (ucs = ORD("1")) THEN color := WMGraphics.Red;
  285. ELSIF (ucs = ORD("2")) THEN color := WMGraphics.Black;
  286. ELSIF (ucs = ORD("3")) THEN color := WMGraphics.White;
  287. ELSIF (ucs = ORD("4")) THEN color := WMGraphics.Blue;
  288. ELSIF (ucs = ORD("5")) THEN color := WMGraphics.Green;
  289. ELSIF (ucs = ORD("0")) THEN color := 0;
  290. ELSIF ucs = ORD("s") THEN
  291. filename := "scribble.bmp";
  292. oldMode := mode;
  293. mode := Mode_Idle;
  294. IF WMDialogs.QueryString("Save as :", filename) = WMDialogs.ResOk THEN
  295. WMGraphics.StoreImage(img, filename, res);
  296. IF (res # 0) THEN
  297. WMDialogs.Error("Sorry", "The image could not be stored. Try another file name.");
  298. END;
  299. END;
  300. mode := oldMode;
  301. ELSIF (ucs= ORD("l")) THEN
  302. filename := "";
  303. oldMode := mode;
  304. mode := Mode_Idle;
  305. IF WMDialogs.QueryString("Load from: ", filename) = WMDialogs.ResOk THEN
  306. newImg := WMGraphics.LoadImage(filename, FALSE);
  307. IF (res = 0) THEN
  308. Fill(0);
  309. img := newImg;
  310. Invalidate(WMRectangles.MakeRect(0, 0, GetWidth(), GetHeight()));
  311. ELSE
  312. WMDialogs.Error("Sorry", "Could not load the image file");
  313. END;
  314. END;
  315. mode := oldMode;
  316. END;
  317. END;
  318. ELSIF (32 <= ucs) & (ucs < 128) & (keySym # 0FF08H) THEN
  319. string[0] := CHR(ucs); string[1] := 0X;
  320. canvas.SetColor(color);
  321. canvas.DrawString(stringX, stringY, string);
  322. font := canvas.GetFont();
  323. font.GetStringSize(string, dx, dy);
  324. Invalidate(WMRectangles.MakeRect(stringX, stringY - dy, stringX + dx, stringY + dy));
  325. stringX := stringX + dx;
  326. IF (currentIdx < LEN(currentString)) THEN currentString[currentIdx] := CHR(ucs); INC(currentIdx); END;
  327. ELSIF (ucs = 13) THEN
  328. font := canvas.GetFont();
  329. font.GetStringSize("X", dx, dy);
  330. stringX := stringX0;
  331. stringY := stringY + dy + 4;
  332. currentString := "";
  333. currentIndex := 0;
  334. ELSIF (keySym = 0FF08H) THEN (* backspace *)
  335. IF (currentIdx > 0) THEN
  336. font := canvas.GetFont();
  337. string[0] := currentString[currentIdx-1]; string[1] := 0X;
  338. font.GetStringSize(string, dx, dy);
  339. canvas.SetColor(bgColor);
  340. stringX := stringX - dx;
  341. canvas.DrawString(stringX, stringY, string);
  342. Invalidate(WMRectangles.MakeRect(stringX, stringY - dy, stringX + dx, stringY + dy));
  343. DEC(currentIdx);
  344. END;
  345. END;
  346. END KeyEvent;
  347. END Window;
  348. VAR
  349. window : Window;
  350. viewport : WMWindowManager.ViewPort;
  351. PROCEDURE Open*;
  352. BEGIN {EXCLUSIVE}
  353. IF (window # NIL) THEN window.Close; END;
  354. NEW(window);
  355. END Open;
  356. PROCEDURE Close*;
  357. BEGIN {EXCLUSIVE}
  358. IF (window # NIL) THEN window.Close; window := NIL; END;
  359. END Close;
  360. PROCEDURE Toggle*;
  361. BEGIN {EXCLUSIVE}
  362. IF (window = NIL) THEN
  363. NEW(window);
  364. ELSE
  365. window.Close; window := NIL;
  366. END;
  367. END Toggle;
  368. PROCEDURE ToggleMode*;
  369. BEGIN {EXCLUSIVE}
  370. IF (window = NIL) THEN
  371. NEW(window);
  372. window.mode := Mode_Drawing;
  373. ELSE
  374. IF window.mode = Mode_Drawing THEN window.mode := Mode_Idle; ELSE window.mode := Mode_Drawing; END;
  375. END;
  376. END ToggleMode;
  377. PROCEDURE Restore*(context : WMRestorable.Context);
  378. BEGIN {EXCLUSIVE}
  379. IF (window = NIL) THEN
  380. NEW(window); (* ignore context information here *)
  381. END;
  382. END Restore;
  383. PROCEDURE Cleanup;
  384. BEGIN
  385. IF (window # NIL) THEN window.Close; window := NIL; END;
  386. END Cleanup;
  387. BEGIN
  388. viewport := WMWindowManager.GetDefaultView();
  389. ASSERT(viewport # NIL);
  390. Modules.InstallTermHandler(Cleanup)
  391. END WMOverlay.
  392. System.Free WMOverlay ~
  393. WMOverlay.Open ~