ComponentViewer.Mod 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. MODULE ComponentViewer; (** AUTHOR "TF"; PURPOSE "Testbed for the component system"; *)
  2. IMPORT
  3. Modules, Commands, Options, XML, Repositories, WMMessages, WMWindowManager, WMComponents,
  4. WMRestorable, Streams, D:= Debugging, Files, WMRectangles;
  5. CONST
  6. DefaultWidth = 320;
  7. DefaultHeight = 240;
  8. InvalidPosition* =MIN(LONGINT);
  9. FlagMoveable = 20;
  10. TYPE
  11. KillerMsg = OBJECT
  12. END KillerMsg;
  13. Window* = OBJECT(WMComponents.FormWindow)
  14. VAR dragging: BOOLEAN; lastX, lastY: LONGINT;
  15. PROCEDURE RestoreWindow*(c : WMRestorable.Context);
  16. BEGIN
  17. ReInit(c.r-c.l, c.b-c.t);
  18. (*
  19. Init(c.r - c.l, c.b - c.t, FALSE);
  20. *)
  21. IF c.appData # NIL THEN
  22. DisableUpdate;
  23. LoadComponents(c.appData(XML.Element));
  24. EnableUpdate;
  25. END;
  26. WMRestorable.AddByContext(SELF, c);
  27. Resized(c.r-c.l,c.b-c.t);
  28. END RestoreWindow;
  29. PROCEDURE &InitWindow(width, height : LONGINT; alpha : BOOLEAN);
  30. BEGIN
  31. IncCount;
  32. Init(width, height, alpha);
  33. END InitWindow;
  34. PROCEDURE Close;
  35. BEGIN
  36. Close^;
  37. DecCount
  38. END Close;
  39. PROCEDURE Handle(VAR m : WMMessages.Message);
  40. VAR data: XML.Element;
  41. BEGIN
  42. IF (m.msgType = WMMessages.MsgExt) & (m.ext # NIL) THEN
  43. IF (m.ext IS KillerMsg) THEN Close
  44. ELSIF (m.ext IS WMRestorable.Storage) THEN
  45. data := StoreComponents();
  46. m.ext(WMRestorable.Storage).Add("ComponentViewer", "ComponentViewer.Restore", SELF, data)
  47. ELSE Handle^(m);
  48. END;
  49. ELSE Handle^(m);
  50. END;
  51. END Handle;
  52. PROCEDURE PointerDown(x, y:LONGINT; keys:SET);
  53. BEGIN
  54. lastX := bounds.l + x; lastY:=bounds.t + y;
  55. IF (keys = {0}) & (FlagMoveable IN flags) THEN
  56. dragging := TRUE
  57. ELSE
  58. PointerDown^(x,y,keys);
  59. END;
  60. END PointerDown;
  61. PROCEDURE PointerMove(x,y:LONGINT; keys:SET);
  62. VAR dx, dy, width, height : LONGINT;
  63. BEGIN
  64. IF dragging THEN
  65. x := bounds.l + x; y := bounds.t + y; dx := x - lastX; dy := y - lastY;
  66. lastX := lastX + dx; lastY := lastY + dy;
  67. IF (dx # 0) OR (dy # 0) THEN
  68. manager.SetWindowPos(SELF, bounds.l + dx, bounds.t + dy);
  69. END;
  70. END;
  71. END PointerMove;
  72. PROCEDURE PointerUp(x, y:LONGINT; keys:SET);
  73. BEGIN
  74. dragging := FALSE;
  75. PointerDown^(x,y,keys);
  76. END PointerUp;
  77. END Window;
  78. VAR
  79. nofWindows : LONGINT;
  80. PROCEDURE DoShow*( vc: WMComponents.VisualComponent; VAR window: Window; x,y,width, height: LONGINT; client, alpha, fullscreen: BOOLEAN;flags: SET);
  81. VAR
  82. fx,fy,fw,fh: LONGINT;
  83. viewPort: WMWindowManager.ViewPort;
  84. manager: WMWindowManager.WindowManager;
  85. BEGIN
  86. IF width # 0 THEN
  87. vc.bounds.SetWidth(width);
  88. ELSE
  89. width := vc.bounds.GetWidth();
  90. IF (width <= 0) THEN width := DefaultWidth; vc.bounds.SetWidth(width) END;
  91. END;
  92. IF height # 0 THEN
  93. vc.bounds.SetHeight(height);
  94. ELSE
  95. height := vc.bounds.GetHeight();
  96. IF (height <= 0) THEN height := DefaultHeight; vc.bounds.SetHeight(height) END;
  97. END;
  98. IF client THEN vc.alignment.Set(WMComponents.AlignClient) END;
  99. IF fullscreen THEN
  100. viewPort := WMWindowManager.GetDefaultView();
  101. fx := 0; fy := 0; fw := 1; fh := 1; (* full screen on screen number 4 *)
  102. x := fx * viewPort.width0;
  103. y := fy * viewPort.height0;
  104. width := fw* viewPort.width0;
  105. height := fh * viewPort.height0;
  106. END;
  107. IF window = NIL THEN
  108. NEW(window, width, height, alpha);
  109. window.SetTitle(vc.GetName());
  110. window.SetContent(vc);
  111. window.flags := window.flags + flags;
  112. manager := WMWindowManager.GetDefaultManager();
  113. IF (x = InvalidPosition) OR (y = InvalidPosition) THEN
  114. WMWindowManager.GetNextPosition(window, manager, WMWindowManager.GetDefaultView(),x,y);
  115. ELSIF fullscreen THEN
  116. x := 0; y := 0
  117. END;
  118. manager := WMWindowManager.GetDefaultManager();
  119. IF vc.sequencer # NIL THEN vc.sequencer.WaitFree() END;
  120. manager.Add(x, y, window, flags);
  121. ELSE
  122. window.SetContent(vc);
  123. END;
  124. END DoShow;
  125. PROCEDURE DoLoad*(CONST filename: ARRAY OF CHAR; error: Streams.Writer): WMComponents.VisualComponent;
  126. VAR
  127. repositoryName, componentName : ARRAY 128 OF CHAR;
  128. moduleName, procedureName : Modules.Name;
  129. ignoreMsg : ARRAY 1 OF CHAR;
  130. generatorProc : XML.GeneratorProcedure;
  131. c : XML.Content; component : Repositories.Component;
  132. id, res : LONGINT;
  133. BEGIN
  134. IF Repositories.SplitName(filename, repositoryName, componentName, id) & (repositoryName # "") THEN
  135. (* Retrieve component from repository *)
  136. Repositories.GetComponentByString(filename, component, res);
  137. IF (res = Repositories.Ok) THEN
  138. c := component;
  139. ELSIF error # NIL THEN
  140. error.String("Could not load "); error.String(filename);
  141. error.String(" from repository, res: "); error.Int(res, 0); error.Ln;
  142. END;
  143. ELSE
  144. Commands.Split(filename, moduleName, procedureName, res, ignoreMsg);
  145. IF (res = Commands.Ok) THEN
  146. (* Assume argument is a generator procedure *)
  147. GETPROCEDURE(moduleName, procedureName, generatorProc);
  148. IF (generatorProc # NIL) THEN
  149. c := generatorProc();
  150. ELSE
  151. (* Maybe argument is a filename *)
  152. c := WMComponents.Load(filename);
  153. END;
  154. ELSE
  155. (* Load component from XML file *)
  156. c := WMComponents.Load(filename);
  157. END;
  158. END;
  159. IF ( c # NIL ) & (c IS WMComponents.VisualComponent) THEN RETURN c(WMComponents.VisualComponent) ELSE RETURN NIL END;
  160. END DoLoad;
  161. PROCEDURE DoOpen*(CONST filename: ARRAY OF CHAR; error: Streams.Writer; x,y,width, height: LONGINT; client, alpha, fullscreen: BOOLEAN; flags:SET): WMComponents.VisualComponent;
  162. VAR
  163. window : Window;
  164. c : WMComponents.VisualComponent
  165. BEGIN
  166. c := DoLoad(filename, error);
  167. IF (c # NIL) THEN
  168. DoShow(c(WMComponents.VisualComponent), window, x,y,width,height, client, alpha, fullscreen, flags);
  169. ELSIF error # NIL THEN
  170. IF (c = NIL) THEN error.String("Could not load/generate component "); error.String(filename);
  171. ELSE error.String(filename); error.String(" is not a VisualComponent.");
  172. END;
  173. error.Ln;
  174. END;
  175. IF (c # NIL) & (c IS WMComponents.VisualComponent) THEN RETURN c(WMComponents.VisualComponent)
  176. ELSE RETURN NIL
  177. END
  178. END DoOpen;
  179. PROCEDURE Open*(context : Commands.Context); (** [Options] <RepositoryName:ComponentName:ID> | <ModuleName.ProcedureName> | <Filename> ~ *)
  180. VAR
  181. options : Options.Options;
  182. filename : ARRAY 128 OF CHAR;
  183. x,y, width, height: LONGINT;
  184. flags: SET;
  185. c: WMComponents.Component;
  186. BEGIN
  187. NEW(options);
  188. options.Add("x", "xPosition", Options.Integer);
  189. options.Add("y", "yPosition", Options.Integer);
  190. options.Add("h", "height", Options.Integer);
  191. options.Add("w", "width", Options.Integer);
  192. options.Add("c", "client", Options.Flag);
  193. options.Add("a","alpha", Options.Flag);
  194. options.Add("f","fullscreen", Options.Flag);
  195. options.Add("n","noFocus", Options.Flag);
  196. options.Add("t","onTop", Options.Flag);
  197. options.Add("F","noFrame",Options.Flag);
  198. options.Add("m","moveable",Options.Flag);
  199. IF options.Parse(context.arg, context.error) & context.arg.GetString(filename) THEN
  200. IF ~options.GetInteger("width",width) THEN width := 0 END;
  201. IF ~options.GetInteger("height",height) THEN height := 0 END;
  202. IF ~options.GetInteger("x",x) THEN x := InvalidPosition END;
  203. IF ~options.GetInteger("y",y) THEN y := InvalidPosition END;
  204. IF options.GetFlag("fullscreen") THEN flags := {} ELSE flags := {WMWindowManager.FlagFrame, WMWindowManager.FlagClose, WMWindowManager.FlagMinimize} END;
  205. IF options.GetFlag("noFrame") THEN flags := {} ELSE flags := {WMWindowManager.FlagFrame, WMWindowManager.FlagClose, WMWindowManager.FlagMinimize} END;
  206. IF options.GetFlag("moveable") THEN flags := {FlagMoveable} ELSE flags := {WMWindowManager.FlagFrame, WMWindowManager.FlagClose, WMWindowManager.FlagMinimize} END;
  207. IF options.GetFlag("noFocus") THEN INCL(flags, WMWindowManager.FlagNoFocus) END;
  208. IF options.GetFlag("onTop") THEN INCL(flags, WMWindowManager.FlagStayOnTop) END;
  209. c := DoOpen(filename, context.error, x , y, width, height, options.GetFlag("client"), options.GetFlag("alpha"), options.GetFlag("fullscreen"), flags);
  210. ELSE
  211. context.error.String("Usage: ComponentViewer.Open [Options] <string> ~"); context.error.Ln;
  212. END;
  213. END Open;
  214. PROCEDURE Store*(context: Commands.Context);
  215. VAR
  216. filename, name, ext, formName : ARRAY 256 OF CHAR;
  217. form: WMComponents.Component;
  218. id,res: LONGINT;
  219. originator: WMComponents.Component;
  220. parent: XML.Element;
  221. BEGIN{EXCLUSIVE}
  222. context.arg.SkipWhitespace; context.arg.String(filename); D.String(filename); D.Ln;
  223. IF (context # NIL) & (context IS WMComponents.EventContext) THEN
  224. originator := context(WMComponents.EventContext).originator;
  225. parent := originator.GetParent();
  226. WHILE (parent # NIL) & (parent IS WMComponents.Component) & ~(parent IS WMComponents.Form) DO
  227. originator := parent(WMComponents.Component);
  228. parent := originator.GetParent();
  229. END;
  230. END;
  231. form := originator;
  232. (*form := GetForm(current);*)
  233. IF (form # NIL) & (filename # "") THEN
  234. Repositories.CreateRepository(filename,res);
  235. ASSERT(res = Repositories.Ok);
  236. Files.SplitExtension(filename, name, ext);
  237. id:= 1;
  238. COPY(form.GetName()^,formName);
  239. Repositories.PutComponent(form,name,form.GetName()^,id,res);
  240. ASSERT(res = Repositories.Ok);
  241. Repositories.StoreRepository(name,res);
  242. ASSERT(res = Repositories.Ok);
  243. Repositories.UnloadRepository(name,res);
  244. ASSERT(res = Repositories.Ok);
  245. context.out.String("stored component in repository "); context.out.String(filename); context.out.Ln;
  246. END;
  247. FINALLY
  248. END Store;
  249. PROCEDURE Restore*(context : WMRestorable.Context);
  250. VAR w : Window;
  251. BEGIN
  252. IF context # NIL THEN
  253. NEW(w, 100,100,FALSE);
  254. w.RestoreWindow(context);
  255. END;
  256. END Restore;
  257. PROCEDURE IncCount;
  258. BEGIN {EXCLUSIVE}
  259. INC(nofWindows)
  260. END IncCount;
  261. PROCEDURE DecCount;
  262. BEGIN {EXCLUSIVE}
  263. DEC(nofWindows)
  264. END DecCount;
  265. PROCEDURE Cleanup;
  266. VAR
  267. die : KillerMsg;
  268. msg : WMMessages.Message;
  269. m : WMWindowManager.WindowManager;
  270. BEGIN {EXCLUSIVE}
  271. NEW(die);
  272. msg.ext := die;
  273. msg.msgType := WMMessages.MsgExt;
  274. m := WMWindowManager.GetDefaultManager();
  275. m.Broadcast(msg);
  276. (*AWAIT(nofWindows = 0)*)
  277. END Cleanup;
  278. BEGIN
  279. nofWindows := 0;
  280. Modules.InstallTermHandler(Cleanup)
  281. END ComponentViewer.
  282. SystemTools.FreeDownTo ComponentViewer ~
  283. ComponentViewer.Open FractalDemo.XML ~
  284. ComponentViewer.Open ComponentHelper:Panel:1 ~
  285. ComponentViewer.Open TLEmulator:Panel:1 ~