MainMenu.Mod 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. MODULE MainMenu; (** AUTHOR "TF"; PURPOSE "Menu for Bluebottle"; *)
  2. IMPORT
  3. KernelLog, XML, Modules, Files, Inputs,
  4. WMMessages, WMStandardComponents, WMComponents, WMTabComponents,
  5. Strings, WM := WMWindowManager;
  6. CONST
  7. MenuFilePrefix = "MenuPage";
  8. TYPE
  9. Window* = OBJECT (WMComponents.FormWindow)
  10. VAR
  11. tabs : WMTabComponents.Tabs;
  12. pages : ARRAY 100 OF WMComponents.VisualComponent;
  13. tabList : ARRAY 100 OF WMTabComponents.Tab;
  14. currentPage : WMComponents.VisualComponent;
  15. currentPageNr : LONGINT;
  16. page : WMStandardComponents.Panel;
  17. moveToFront : BOOLEAN;
  18. PROCEDURE CreateForm(): WMComponents.VisualComponent;
  19. VAR
  20. panel : WMStandardComponents.Panel;
  21. pagePanel : WMStandardComponents.Panel;
  22. tabs : WMTabComponents.Tabs;
  23. BEGIN
  24. NEW(panel); panel.bounds.SetExtents(1024, 60); panel.fillColor.Set(0); panel.takesFocus.Set(TRUE);
  25. NEW(tabs); tabs.fillColor.Set(000600080H); tabs.bounds.SetHeight(20); tabs.alignment.Set(WMComponents.AlignTop);
  26. panel.AddContent(tabs);
  27. SELF.tabs := tabs;
  28. NEW(pagePanel); pagePanel.fillColor.Set(0H); pagePanel.alignment.Set(WMComponents.AlignClient);
  29. panel.AddContent(pagePanel);
  30. page := pagePanel;
  31. RETURN panel
  32. END CreateForm;
  33. PROCEDURE &New*;
  34. VAR vc : WMComponents.VisualComponent;
  35. view : WM.ViewPort;
  36. BEGIN
  37. vc := CreateForm();
  38. moveToFront := TRUE;
  39. currentPageNr := -1;
  40. tabs.onSelectTab.Add(TabSelected);
  41. Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), TRUE);
  42. SetContent(vc);
  43. SetTitle(Strings.NewString("MainMenu"));
  44. pointerThreshold := 10;
  45. manager := WM.GetDefaultManager();
  46. view := WM.GetDefaultView();
  47. manager.Add(0, view.height0 - GetHeight(), SELF, {WM.FlagNavigation, WM.FlagHidden});
  48. END New;
  49. PROCEDURE PointerMove*(x, y : LONGINT; keys : SET);
  50. BEGIN
  51. PointerMove^(x, y, keys);
  52. moveToFront := FALSE;
  53. manager.ToFront(SELF);
  54. END PointerMove;
  55. PROCEDURE PointerLeave*;
  56. BEGIN
  57. PointerLeave^;
  58. moveToFront := TRUE;
  59. END PointerLeave;
  60. PROCEDURE SetOriginator*(extView : ANY);
  61. VAR view : WM.ViewPort;
  62. BEGIN
  63. IF (extView # NIL) & (extView IS WM.ViewPort) THEN
  64. view := extView(WM.ViewPort)
  65. ELSE view := WM.GetDefaultView()
  66. END;
  67. Refresh(NIL, NIL);
  68. IF ~(WM.FlagNavigation IN SELF.flags) THEN
  69. manager.SetWindowPos(SELF, ENTIER(view.range.l), ENTIER(view.range.b) - GetHeight());
  70. END;
  71. manager.ToFront(SELF)
  72. END SetOriginator;
  73. PROCEDURE UpdatePages;
  74. VAR i : LONGINT;
  75. tab : WMTabComponents.Tab;
  76. s : Strings.String;
  77. BEGIN
  78. DisableUpdate;
  79. tabs.RemoveAllTabs;
  80. IF currentPage # NIL THEN page.RemoveContent(currentPage);
  81. currentPage := NIL
  82. END;
  83. IF currentPageNr >= 0 THEN currentPage := pages[currentPageNr] END;
  84. FOR i := 0 TO 99 DO
  85. tabList[i] := NIL;
  86. IF pages[i] # NIL THEN
  87. pages[i].alignment.Set(WMComponents.AlignClient);
  88. tab := tabs.NewTab();
  89. tabs.AddTab(tab);
  90. tabList[i] := tab;
  91. s := pages[i].GetAttributeValue("caption");
  92. IF s = NIL THEN s := Strings.NewString("Untitled") END;
  93. tabs.SetTabCaption(tab, s);
  94. tabs.SetTabData(tab, pages[i])
  95. END
  96. END;
  97. IF currentPage = NIL THEN
  98. i := 0;
  99. WHILE (i < 100) & (currentPage = NIL) DO
  100. IF pages[i] # NIL THEN currentPage := pages[i]; currentPageNr := i END;
  101. INC(i);
  102. END
  103. END;
  104. EnableUpdate;
  105. IF currentPage # NIL THEN
  106. page.AddContent(currentPage);
  107. currentPage.Reset(SELF, NIL);
  108. page.AlignSubComponents;
  109. page.Invalidate;
  110. IF tabList[currentPageNr] # NIL THEN tabs.Select(tabList[currentPageNr]) END
  111. END;
  112. tabs.Invalidate
  113. END UpdatePages;
  114. PROCEDURE TryLoad(CONST name : ARRAY OF CHAR; pos : LONGINT);
  115. VAR x : XML.Content;
  116. BEGIN
  117. IF (pos >= 0) & (pos <= 99) THEN
  118. x := WMComponents.Load(name);
  119. IF x # NIL THEN
  120. IF x IS WMComponents.VisualComponent THEN
  121. pages[pos] := x(WMComponents.VisualComponent);
  122. END
  123. END
  124. END
  125. END TryLoad;
  126. PROCEDURE LoadPages*;
  127. VAR mask : ARRAY 64 OF CHAR;
  128. name : ARRAY 256 OF CHAR; flags : SET;
  129. time, date, size : LONGINT;
  130. i: LONGINT;
  131. enumerator : Files.Enumerator;
  132. number: LONGINT;
  133. PROCEDURE IsNum(ch : CHAR) : BOOLEAN;
  134. BEGIN
  135. RETURN (ch >= '0') & (ch <= '9')
  136. END IsNum;
  137. BEGIN
  138. DisableUpdate;
  139. NEW(enumerator);
  140. FOR i := 0 TO 99 DO
  141. IF pages[i] = currentPage THEN currentPageNr := i END;
  142. pages[i] := NIL
  143. END;
  144. mask := MenuFilePrefix;
  145. i := Strings.Length(mask);
  146. Strings.Append(mask, "*.XML");
  147. enumerator.Open(mask, {});
  148. WHILE enumerator.HasMoreEntries() DO
  149. IF enumerator.GetEntry(name, flags, time, date, size) THEN
  150. i := Strings.Length(name);
  151. IF IsNum(name[i - 6]) & IsNum(name[i - 5]) THEN
  152. number := (ORD(name[i - 6]) - ORD('0')) * 10 + (ORD(name[i - 5]) - ORD('0'));
  153. IF pages[number] = NIL THEN (* use first incident for respecting the search path order *)
  154. TryLoad(name, number);
  155. END;
  156. END
  157. END
  158. END;
  159. enumerator.Close;
  160. EnableUpdate;
  161. UpdatePages
  162. END LoadPages;
  163. PROCEDURE Refresh(sender, data : ANY);
  164. BEGIN
  165. LoadPages
  166. END Refresh;
  167. PROCEDURE TabSelected(sender, data : ANY);
  168. VAR tab : WMTabComponents.Tab;
  169. BEGIN
  170. IF (data # NIL) & (data IS WMTabComponents.Tab) THEN
  171. DisableUpdate;
  172. page.RemoveContent(currentPage);
  173. tab := data(WMTabComponents.Tab);
  174. IF (tab.data # NIL) & (tab.data IS WMComponents.VisualComponent) THEN
  175. currentPage := tab.data(WMComponents.VisualComponent);
  176. page.AddContent(currentPage);
  177. IF ~currentPage.initialized THEN currentPage.Initialize END;
  178. currentPage.Reset(SELF, NIL);
  179. page.AlignSubComponents;
  180. END;
  181. EnableUpdate;
  182. page.Invalidate
  183. END
  184. END TabSelected;
  185. PROCEDURE Close*;
  186. BEGIN
  187. Close^;
  188. window := NIL
  189. END Close;
  190. END Window;
  191. (* the starter decouples the sensitive callback from the WindowManager. *)
  192. TYPE
  193. Starter = OBJECT
  194. VAR
  195. originator : ANY;
  196. w : Window;
  197. PROCEDURE &Init*(o : ANY);
  198. BEGIN
  199. originator := o;
  200. w := NIL;
  201. END Init;
  202. BEGIN {ACTIVE}
  203. BEGIN {EXCLUSIVE}
  204. IF (window = NIL) THEN NEW(window); w := window;
  205. ELSE window.SetOriginator(originator);
  206. END;
  207. END;
  208. IF (w # NIL) THEN w.LoadPages; END;
  209. END Starter;
  210. VAR
  211. window : Window;
  212. manager : WM.WindowManager;
  213. (* This procedure is directly called by the window manager. It must be safe. *)
  214. PROCEDURE MessagePreview(VAR m : WMMessages.Message; VAR discard : BOOLEAN);
  215. VAR starter : Starter;
  216. BEGIN
  217. IF m.msgType = WMMessages.MsgKey THEN
  218. IF (m.y = 0FF1BH) & ((m.flags * Inputs.Ctrl # {}) OR (m.flags * Inputs.Meta # {})) THEN
  219. NEW(starter, m.originator); discard := TRUE
  220. END
  221. END
  222. END MessagePreview;
  223. PROCEDURE Open*;
  224. VAR w : Window;
  225. BEGIN
  226. BEGIN {EXCLUSIVE}
  227. IF window = NIL THEN NEW(window); w := window;
  228. ELSE window.SetOriginator(NIL)
  229. END;
  230. END;
  231. IF w # NIL THEN w.LoadPages END;
  232. END Open;
  233. PROCEDURE Cleanup;
  234. BEGIN {EXCLUSIVE}
  235. KernelLog.String("Cleanup"); KernelLog.Ln;
  236. (* removal must be done in all cases to avoid system freeze *)
  237. manager.RemoveMessagePreview(MessagePreview);
  238. IF window # NIL THEN window.Close END;
  239. END Cleanup;
  240. BEGIN
  241. manager := WM.GetDefaultManager();
  242. Modules.InstallTermHandler(Cleanup)
  243. END MainMenu.
  244. SystemTools.Free MainMenu WMTabComponents ~
  245. MainMenu.Open ~