WMInspector.Mod 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115
  1. MODULE WMInspector; (** AUTHOR "staubesv"; PURPOSE "Component inspection"; *)
  2. IMPORT
  3. Modules, Strings, XMLObjects, Texts, Files,
  4. WMRectangles, WMGraphics, WMMessages, WMRestorable, WMWindowManager,
  5. WMComponents, WMStandardComponents, WMTrees, WMTabComponents, WMInspectionComponents, XML, Raster, WMPopups, Models;
  6. CONST
  7. WindowWidth = 800; WindowHeight = 500;
  8. (* Maximum number of windows that can be managed by components inside this module *)
  9. MaxNofWindows = 100;
  10. Bearing = 2;
  11. TYPE
  12. Windows = ARRAY MaxNofWindows OF WMWindowManager.Window;
  13. (** Tree component that displays all window instances and their component hierarchies *)
  14. InspectionTree* = OBJECT(WMComponents.VisualComponent)
  15. VAR
  16. treeView- : WMTrees.TreeView;
  17. tree- : WMTrees.Tree;
  18. selected: WMTrees.TreeNode;
  19. dragged: WMTrees.TreeNode;
  20. PROCEDURE &Init;
  21. BEGIN
  22. Init^;
  23. SetNameAsString(Strings.NewString("InspectionTree"));
  24. NEW(treeView); treeView.alignment.Set(WMComponents.AlignClient);
  25. tree := treeView.GetTree();
  26. treeView.onStartDrag.Add(OnStartDrag);
  27. treeView.SetExtDragDroppedHandler(DragDroppedHandler);
  28. (* add treeView in subclass *)
  29. END Init;
  30. (* drag drop in the following way:
  31. drag starts, data = component
  32. drag destination: EditDragDropped at destination
  33. destination makes sure that drag accepted is called to remove component
  34. destination accepts data from drag
  35. *)
  36. PROCEDURE DragAccepted(sender, data: ANY);
  37. VAR dragInfo: WMWindowManager.DragInfo; parent: XML.Element;
  38. BEGIN
  39. IF data # NIL THEN
  40. dragInfo := data(WMWindowManager.DragInfo);
  41. data := dragInfo.data;
  42. IF (data # NIL) & (data IS WMComponents.VisualComponent) THEN
  43. parent := data(WMComponents.VisualComponent).GetParent();
  44. IF parent # NIL THEN
  45. parent.RemoveContent(data(WMComponents.VisualComponent));
  46. parent(WMComponents.VisualComponent).Invalidate;
  47. END;
  48. END;
  49. IF (data # NIL) & (data = GetNodeData(dragged)) THEN
  50. tree.Acquire;
  51. tree.RemoveNode(dragged);
  52. tree.Release;
  53. END;
  54. END
  55. END DragAccepted;
  56. PROCEDURE DragRejected(sender, data: ANY);
  57. BEGIN
  58. (* no action necessary *)
  59. END DragRejected;
  60. PROCEDURE GetNodeData(node: WMTrees.TreeNode): WMComponents.VisualComponent;
  61. VAR nodeData: ANY;
  62. BEGIN
  63. tree.Acquire;
  64. nodeData := tree.GetNodeData(node);
  65. tree.Release;
  66. IF (nodeData = NIL) OR ~(nodeData IS WMComponents.VisualComponent) THEN RETURN NIL
  67. ELSE RETURN nodeData(WMComponents.VisualComponent)
  68. END;
  69. END GetNodeData;
  70. PROCEDURE DragDroppedHandler(x,y: LONGINT; dragInfo: WMWindowManager.DragInfo; VAR handled: BOOLEAN);
  71. VAR node: WMTrees.TreeNode; destination,source: WMComponents.VisualComponent; data: ANY; parent: XML.Element;
  72. BEGIN
  73. node := treeView.GetNodeAtPos(x,y);
  74. IF node # NIL THEN
  75. destination := GetNodeData(node);
  76. ELSE destination := NIL
  77. END;
  78. data := dragInfo.data;
  79. IF (data # NIL) & (data IS WMComponents.VisualComponent) THEN
  80. source := data(WMComponents.VisualComponent);
  81. END;
  82. IF (source # NIL) & (destination # NIL) THEN
  83. ConfirmDrag(TRUE, dragInfo);
  84. destination.AddContent(source);
  85. destination.Invalidate;
  86. tree.Acquire;
  87. AddComponents(source, node);
  88. tree.Release;
  89. handled := TRUE;
  90. END;
  91. END DragDroppedHandler;
  92. PROCEDURE OnStartDrag(sender, data : ANY);
  93. VAR w, h: LONGINT; img: WMGraphics.Image; canvas: WMGraphics.BufferCanvas; caption: Strings.String;
  94. BEGIN
  95. NEW(img);
  96. dragged := treeView.draggedNode;
  97. treeView.MeasureNode(dragged, w, h);
  98. Raster.Create(img, w, h, Raster.BGRA8888);
  99. NEW(canvas, img);
  100. canvas.SetColor(LONGINT(0FFFF00FFH));
  101. canvas.Fill(WMRectangles.MakeRect(0, 0, w, h), LONGINT(0FFFF00FFH), WMGraphics.ModeCopy);
  102. (*KernelLog.String("w= "); KernelLog.Int(w, 0); KernelLog.String("h= "); KernelLog.Int(h, 0); KernelLog.Ln;*)
  103. canvas.SetColor(0FFH);
  104. tree.Acquire();
  105. caption := tree.GetNodeCaption(dragged);
  106. tree.Release();
  107. canvas.DrawString(0,h, caption^);
  108. dragged := treeView.draggedNode;
  109. IF (dragged # NIL) & StartDrag(GetNodeData(dragged), img, 0, 0, DragAccepted, DragRejected) THEN
  110. END;
  111. END OnStartDrag;
  112. PROCEDURE AddComponents(component : WMComponents.Component; parent : WMTrees.TreeNode);
  113. VAR
  114. node : WMTrees.TreeNode;
  115. name, string : Strings.String;
  116. caption : ARRAY 512 OF CHAR;
  117. enum : XMLObjects.Enumerator;
  118. p : ANY; i, len : LONGINT;
  119. id: Strings.String;
  120. BEGIN
  121. name := component.GetName();
  122. IF (name # NIL) THEN
  123. COPY(name^, caption);
  124. ELSE
  125. caption := "NoName";
  126. END;
  127. id := component.id.Get();
  128. IF (id # NIL) & (id^# "") THEN Strings.Append(caption,":"); Strings.Append(caption,id^) END;
  129. id := component.uid.Get();
  130. IF (id # NIL) & (id^# "") THEN Strings.Append(caption,":"); Strings.Append(caption,id^) END;
  131. IF (component IS WMStandardComponents.Button) THEN
  132. string := component(WMStandardComponents.Button).caption.Get();
  133. IF (string # NIL) THEN
  134. Strings.Append(caption, " (");
  135. Strings.Append(caption, string^);
  136. Strings.Append(caption, ")");
  137. END;
  138. ELSIF (component IS WMStandardComponents.Label) THEN
  139. string := component(WMStandardComponents.Label).caption.Get();
  140. IF (string # NIL) THEN
  141. Strings.Append(caption, " (");
  142. IF (Strings.Length(caption) <= 10) THEN
  143. Strings.Append(caption, string^);
  144. ELSE
  145. len := Strings.Length(caption);
  146. i := 0;
  147. WHILE (i < 10) & (string[i] # 0X) & (len + i < LEN(caption) - 1) DO
  148. caption[len + i] := string[i]; INC(i);
  149. END;
  150. caption[len+i] := 0X;
  151. Strings.Append(caption, "...");
  152. END;
  153. Strings.Append(caption, ")");
  154. END;
  155. END;
  156. IF component.internal THEN
  157. Strings.Append(caption, " [internal]");
  158. END;
  159. NEW(node);
  160. tree.SetNodeCaption(node, Strings.NewString(caption));
  161. tree.SetNodeData(node, component);
  162. tree.AddChildNode(parent, node);
  163. enum := component.GetContents();
  164. WHILE enum.HasMoreElements() DO
  165. p := enum.GetNext();
  166. IF (p IS WMComponents.Component) THEN
  167. AddComponents(p(WMComponents.Component), node);
  168. END;
  169. END;
  170. END AddComponents;
  171. PROCEDURE Refresh(sender, data : ANY);
  172. END Refresh;
  173. END InspectionTree;
  174. TYPE
  175. (** Tree component that displays all window instances and their component hierarchies *)
  176. FormComponentsTree* = OBJECT(InspectionTree)
  177. VAR
  178. windows : Windows;
  179. refreshBtn, splitBtn : WMStandardComponents.Button;
  180. dragger: DragCommand;
  181. PROCEDURE &Init;
  182. VAR panel: WMStandardComponents.Panel;
  183. BEGIN
  184. Init^;
  185. SetNameAsString(Strings.NewString("FormComponentsTree"));
  186. Clear(windows);
  187. NEW(dragger); dragger.alignment.Set(WMComponents.AlignBottom);
  188. dragger.bounds.SetHeight(20);
  189. dragger.bearing.Set(WMRectangles.MakeRect(Bearing, Bearing, Bearing, Bearing));
  190. AddContent(dragger);
  191. NEW(panel); panel.alignment.Set(WMComponents.AlignBottom);
  192. panel.bounds.SetHeight(20);
  193. AddContent(panel);
  194. NEW(refreshBtn); refreshBtn.alignment.Set(WMComponents.AlignLeft);
  195. refreshBtn.bounds.SetWidth(100);
  196. refreshBtn.caption.SetAOC("Refresh");
  197. refreshBtn.onClick.Add(Refresh);
  198. panel.AddContent(refreshBtn);
  199. NEW(splitBtn); splitBtn.alignment.Set(WMComponents.AlignClient);
  200. splitBtn.bounds.SetHeight(20);
  201. splitBtn.caption.SetAOC("Split");
  202. splitBtn.isToggle.Set(TRUE);
  203. panel.AddContent(splitBtn);
  204. AddContent(treeView);
  205. END Init;
  206. PROCEDURE AddFormWindow(window : WMComponents.FormWindow; parent : WMTrees.TreeNode);
  207. VAR node : WMTrees.TreeNode; caption : ARRAY 64 OF CHAR; string : Strings.String;
  208. s: ARRAY 128 OF CHAR; typeDesc:Modules.TypeDesc;
  209. BEGIN
  210. ASSERT((window # NIL) & (parent # NIL));
  211. string := window.GetTitle();
  212. IF (string # NIL) THEN
  213. COPY(string^, caption);
  214. ELSE
  215. caption := "NoTitle";
  216. END;
  217. typeDesc:=Modules.TypeOf(window);
  218. COPY(caption, s); Strings.AppendChar(s,":");
  219. Strings.Append(s, typeDesc.mod.name); Strings.AppendChar(s,".");
  220. Strings.Append(s, typeDesc.name);
  221. NEW(node);
  222. (*tree.SetNodeCaption(node, Strings.NewString(caption));*)
  223. tree.SetNodeCaption(node, Strings.NewString(s));
  224. tree.AddChildNode(parent, node);
  225. tree.InclNodeState(node, WMTrees.NodeExpanded);
  226. tree.ExpandToRoot(node);
  227. IF (window.form # NIL) THEN
  228. AddComponents(window.form, node);
  229. END;
  230. END AddFormWindow;
  231. PROCEDURE AddNonFormWindow(window : WMWindowManager.Window; parent : WMTrees.TreeNode);
  232. VAR node : WMTrees.TreeNode; string : Strings.String;
  233. caption, s,path: ARRAY 256 OF CHAR; typeDesc:Modules.TypeDesc;
  234. BEGIN
  235. ASSERT((window # NIL) & (parent # NIL));
  236. string := window.GetTitle();
  237. IF (string # NIL) THEN COPY(string^, caption);
  238. ELSE caption := "NoTitle";
  239. END;
  240. typeDesc:=Modules.TypeOf(window);
  241. COPY(caption, s); Files.SplitPath(s, path,caption);
  242. Strings.AppendChar(caption,":");
  243. Strings.Append(caption, typeDesc.mod.name); Strings.AppendChar(caption,".");
  244. Strings.Append(caption, typeDesc.name);
  245. NEW(node);
  246. tree.SetNodeCaption(node, Strings.NewString(caption));
  247. tree.AddChildNode(parent, node);
  248. tree.InclNodeState(node, WMTrees.NodeExpanded);
  249. tree.ExpandToRoot(node);
  250. END AddNonFormWindow;
  251. PROCEDURE Refresh(sender, data : ANY);
  252. VAR root : WMTrees.TreeNode; nofWindows, i : LONGINT;
  253. BEGIN
  254. ASSERT(tree # NIL);
  255. GetWindows(windows, nofWindows);
  256. tree.Acquire;
  257. NEW(root);
  258. tree.SetRoot(root);
  259. tree.SetNodeCaption(root, Strings.NewString("Windows"));
  260. tree.InclNodeState(root, WMTrees.NodeExpanded);
  261. IF (nofWindows > 0) THEN
  262. FOR i := 0 TO nofWindows - 1 DO
  263. IF (windows[i] # NIL) & (windows[i] IS WMComponents.FormWindow) THEN
  264. AddFormWindow(windows[i](WMComponents.FormWindow), root);
  265. END;
  266. IF (windows[i] # NIL) & ~(windows[i] IS WMComponents.FormWindow) THEN
  267. AddNonFormWindow(windows[i], root);
  268. END;
  269. END;
  270. END;
  271. tree.Release;
  272. END Refresh;
  273. END FormComponentsTree;
  274. TYPE
  275. TextComponentsTree = OBJECT(InspectionTree)
  276. PROCEDURE &Init;
  277. BEGIN
  278. Init^;
  279. SetNameAsString(Strings.NewString("TextComponentsTree"));
  280. AddContent(treeView);
  281. Texts.onLastTextChanged.Add(Refresh);
  282. END Init;
  283. PROCEDURE Refresh(sender, data : ANY);
  284. VAR
  285. root : WMTrees.TreeNode;
  286. text : Texts.Text; reader : Texts.TextReader;
  287. ignoreCh : Texts.Char32;
  288. BEGIN
  289. ASSERT(tree # NIL);
  290. text := Texts.GetLastText();
  291. IF (text # NIL) THEN
  292. text.AcquireRead;
  293. NEW(reader, text); reader.SetPosition(0);
  294. tree.Acquire;
  295. NEW(root);
  296. tree.SetRoot(root);
  297. tree.SetNodeCaption(root, Strings.NewString("Text"));
  298. WHILE ~reader.eot DO
  299. reader.ReadCh(ignoreCh);
  300. IF (reader.object # NIL) & (reader.object IS WMComponents.Component) THEN
  301. AddComponents(reader.object (WMComponents.Component), root);
  302. END;
  303. END;
  304. tree.InclNodeState(root, WMTrees.NodeExpanded);
  305. tree.Release;
  306. text.ReleaseRead;
  307. ELSE
  308. tree.Acquire;
  309. NEW(root);
  310. tree.SetRoot(root);
  311. tree.SetNodeCaption(root, Strings.NewString("No text selection"));
  312. tree.InclNodeState(root, WMTrees.NodeExpanded);
  313. tree.Release;
  314. END;
  315. END Refresh;
  316. PROCEDURE Finalize;
  317. BEGIN
  318. Finalize^;
  319. Texts.onLastTextChanged.Remove(Refresh);
  320. END Finalize;
  321. END TextComponentsTree;
  322. TYPE
  323. SelectedTextTree = OBJECT(InspectionTree)
  324. PROCEDURE &Init;
  325. BEGIN
  326. Init^;
  327. SetNameAsString(Strings.NewString("SelectedTextTree"));
  328. AddContent(treeView);
  329. Texts.onLastSelectionChanged.Add(Refresh);
  330. END Init;
  331. PROCEDURE Refresh(sender, data : ANY);
  332. VAR
  333. root : WMTrees.TreeNode;
  334. text : Texts.Text; from, to : Texts.TextPosition; reader : Texts.TextReader;
  335. ignoreCh : Texts.Char32;
  336. BEGIN
  337. ASSERT(tree # NIL);
  338. IF Texts.GetLastSelection(text, from, to) THEN
  339. text.AcquireRead;
  340. NEW(reader, text); reader.SetPosition(from.GetPosition());
  341. tree.Acquire;
  342. NEW(root);
  343. tree.SetRoot(root);
  344. tree.SetNodeCaption(root, Strings.NewString("Text"));
  345. WHILE ~reader.eot & (reader.GetPosition() < to.GetPosition()) DO
  346. reader.ReadCh(ignoreCh);
  347. IF (reader.object # NIL) & (reader.object IS WMComponents.Component) THEN
  348. AddComponents(reader.object (WMComponents.Component), root);
  349. END;
  350. END;
  351. tree.InclNodeState(root, WMTrees.NodeExpanded);
  352. tree.Release;
  353. text.ReleaseRead;
  354. ELSE
  355. tree.Acquire;
  356. NEW(root);
  357. tree.SetRoot(root);
  358. tree.SetNodeCaption(root, Strings.NewString("No text selection"));
  359. tree.InclNodeState(root, WMTrees.NodeExpanded);
  360. tree.Release;
  361. END;
  362. END Refresh;
  363. PROCEDURE Finalize;
  364. BEGIN
  365. Finalize^;
  366. Texts.onLastSelectionChanged.Remove(Refresh);
  367. END Finalize;
  368. END SelectedTextTree;
  369. SelectedComponentsTree = OBJECT(InspectionTree)
  370. PROCEDURE &Init;
  371. BEGIN
  372. Init^;
  373. SetNameAsString(Strings.NewString("SelectedComponentsTree"));
  374. AddContent(treeView);
  375. WMComponents.selection.onChanged.Add(Refresh);
  376. Refresh(SELF, WMComponents.selection);
  377. END Init;
  378. PROCEDURE Refresh(sender, data : ANY);
  379. VAR
  380. root , node: WMTrees.TreeNode;
  381. array: WMComponents.SelectionArray;
  382. selection: WMComponents.SelectionList;
  383. i: LONGINT;
  384. BEGIN
  385. ASSERT(tree # NIL);
  386. IF (data # NIL) & (data IS WMComponents.SelectionList) THEN
  387. selection := data(WMComponents.SelectionList);
  388. array := selection.GetSelection();
  389. tree.Acquire;
  390. NEW(root);
  391. tree.SetRoot(root);
  392. tree.SetNodeCaption(root, Strings.NewString("selection"));
  393. FOR i := 0 TO LEN(array)-1 DO
  394. AddComponents(array[i], root);
  395. END;
  396. IF LEN(array) = 1 THEN
  397. node := tree.GetChildren(root);
  398. treeView.SelectNode(node);
  399. treeView.onClickNode.Call(node);
  400. END;
  401. tree.InclNodeState(root, WMTrees.NodeExpanded);
  402. tree.Release;
  403. END;
  404. END Refresh;
  405. PROCEDURE Finalize;
  406. BEGIN
  407. Finalize^;
  408. WMComponents.selection.onChanged.Remove(Refresh)
  409. END Finalize;
  410. END SelectedComponentsTree;
  411. TYPE
  412. KillerMsg = OBJECT
  413. END KillerMsg;
  414. SelectionWrapper= POINTER TO RECORD tree: WMTrees.Tree; node: WMTrees.TreeNode END;
  415. InspectorComponent= OBJECT (WMComponents.VisualComponent)
  416. VAR
  417. formTree- : FormComponentsTree;
  418. textTree : TextComponentsTree;
  419. selectedTextTree : SelectedTextTree;
  420. selectedComponentTree: SelectedComponentsTree;
  421. currentTree : InspectionTree;
  422. propertyPanel : WMInspectionComponents.PropertyPanel;
  423. libraryPanel : WMInspectionComponents.RepositoryPanel;
  424. xmlPanel : WMInspectionComponents.XMLPanel;
  425. PROCEDURE &InitInspector(simple: BOOLEAN; vis: Models.Boolean);
  426. BEGIN
  427. Init;
  428. SetNameAsString(Strings.NewString("InspectorComponent"));
  429. Create(simple, vis);
  430. currentTree := formTree;
  431. formTree.treeView.onClickNode.Add(NodeClicked);
  432. formTree.Refresh(NIL, NIL);
  433. textTree.treeView.onClickNode.Add(NodeClicked);
  434. textTree.Refresh(NIL, NIL);
  435. selectedTextTree.treeView.onClickNode.Add(NodeClicked);
  436. selectedTextTree.Refresh(NIL, NIL);
  437. selectedComponentTree.treeView.onClickNode.Add(NodeClicked);
  438. selectedComponentTree.Refresh(NIL, NIL);
  439. formTree.treeView.SetExtContextMenuHandler(ContextMenu);
  440. textTree.treeView.SetExtContextMenuHandler(ContextMenu);
  441. selectedTextTree.treeView.SetExtContextMenuHandler(ContextMenu);
  442. selectedComponentTree.treeView.SetExtContextMenuHandler(ContextMenu);
  443. END InitInspector;
  444. PROCEDURE Create(simple: BOOLEAN; vis: Models.Boolean);
  445. VAR
  446. rightPanel, treePanel, libPanel : WMStandardComponents.Panel; resizer : WMStandardComponents.Resizer;
  447. tabPanel : WMTabComponents.TabPanel; tabControl : WMTabComponents.Tabs; tabEntry : WMTabComponents.TabEntry;
  448. BEGIN
  449. NEW(treePanel); treePanel.alignment.Set(WMComponents.AlignLeft);
  450. treePanel.bounds.SetWidth(200);
  451. AddContent(treePanel);
  452. NEW(resizer); resizer.alignment.Set(WMComponents.AlignRight);
  453. resizer.bounds.SetWidth(5);
  454. treePanel.AddContent(resizer);
  455. NEW(tabPanel); tabPanel.alignment.Set(WMComponents.AlignClient);
  456. treePanel.AddContent(tabPanel);
  457. NEW(tabControl); tabControl.alignment.Set(WMComponents.AlignTop);
  458. tabControl.bounds.SetHeight(20);
  459. tabControl.onSelectTab.Add(TabSelected);
  460. tabPanel.AddContent(tabControl);
  461. NEW(tabEntry); tabEntry.alignment.Set(WMComponents.AlignClient);
  462. tabEntry.caption.SetAOC("Windows");
  463. tabPanel.AddContent(tabEntry);
  464. NEW(formTree); formTree.alignment.Set(WMComponents.AlignClient);
  465. tabEntry.AddContent(formTree);
  466. formTree.dragger.inspector := SELF;
  467. formTree.splitBtn.model.Set(vis);
  468. NEW(tabEntry); tabEntry.alignment.Set(WMComponents.AlignClient);
  469. tabEntry.caption.SetAOC("Selection");
  470. tabPanel.AddContent(tabEntry);
  471. NEW(selectedComponentTree); selectedComponentTree.alignment.Set(WMComponents.AlignClient);
  472. tabEntry.AddContent(selectedComponentTree);
  473. NEW(tabEntry); tabEntry.alignment.Set(WMComponents.AlignClient);
  474. tabEntry.caption.SetAOC("Sel. Text");
  475. tabPanel.AddContent(tabEntry);
  476. NEW(selectedTextTree); selectedTextTree.alignment.Set(WMComponents.AlignClient);
  477. tabEntry.AddContent(selectedTextTree);
  478. NEW(tabEntry); tabEntry.alignment.Set(WMComponents.AlignClient);
  479. tabEntry.caption.SetAOC("Last Text");
  480. tabPanel.AddContent(tabEntry);
  481. NEW(textTree); textTree.alignment.Set(WMComponents.AlignClient);
  482. tabEntry.AddContent(textTree);
  483. NEW(rightPanel); rightPanel.alignment.Set(WMComponents.AlignClient);
  484. AddContent(rightPanel);
  485. IF ~simple THEN
  486. NEW(libPanel); libPanel.alignment.Set(WMComponents.AlignBottom);
  487. libPanel.bounds.SetHeight(60);
  488. libPanel.fillColor.Set(0C0C0C0FFH);
  489. rightPanel.AddContent(libPanel);
  490. NEW(resizer); resizer.alignment.Set(WMComponents.AlignTop);
  491. resizer.bounds.SetHeight(5);
  492. libPanel.AddContent(resizer);
  493. NEW(libraryPanel); libraryPanel.alignment.Set(WMComponents.AlignTop);
  494. libraryPanel.bounds.SetHeight(50);
  495. libraryPanel.bearing.Set(WMRectangles.MakeRect(Bearing, Bearing, Bearing, Bearing));
  496. libPanel.AddContent(libraryPanel);
  497. NEW(xmlPanel); xmlPanel.alignment.Set(WMComponents.AlignTop);
  498. xmlPanel.bounds.SetHeight(20);
  499. xmlPanel.bearing.Set(WMRectangles.MakeRect(2*Bearing, Bearing, Bearing, Bearing));
  500. libPanel.AddContent(xmlPanel);
  501. END;
  502. NEW(propertyPanel); propertyPanel.alignment.Set(WMComponents.AlignClient);
  503. rightPanel.AddContent(propertyPanel);
  504. END Create;
  505. PROCEDURE TabSelected(sender, data : ANY);
  506. VAR caption : Strings.String; node: WMTrees.TreeNode;
  507. BEGIN
  508. IF (data # NIL) & (data IS WMTabComponents.Tab) THEN
  509. caption := data(WMTabComponents.Tab).caption;
  510. IF (caption # NIL) THEN
  511. IF (caption^ = "Windows") THEN currentTree := formTree;
  512. ELSIF (caption^ = "Last Text") THEN currentTree := textTree;
  513. ELSIF (caption^ = "Sel. Text") THEN currentTree := selectedTextTree;
  514. ELSIF (caption^ = "Selection") THEN currentTree := selectedComponentTree;
  515. END;
  516. node := currentTree.selected;
  517. (* does not work because tree is not rendered yet
  518. node := GetSelectedNode(currentTree.tree);
  519. *)
  520. IF node # NIL THEN NodeClicked(currentTree.treeView, node) END;
  521. END;
  522. END;
  523. END TabSelected;
  524. PROCEDURE NodeClicked(sender, data : ANY);
  525. VAR ptr : ANY;
  526. BEGIN
  527. IF (data # NIL) & (data IS WMTrees.TreeNode) THEN
  528. IF sender = currentTree.treeView THEN
  529. currentTree.tree.Acquire;
  530. ptr := currentTree.tree.GetNodeData(data(WMTrees.TreeNode));
  531. currentTree.selected := data(WMTrees.TreeNode);
  532. currentTree.tree.Release;
  533. IF (ptr # NIL) & (ptr IS WMComponents.Component) THEN
  534. propertyPanel.SetComponent(SELF, ptr(WMComponents.Component));
  535. IF libraryPanel # NIL THEN
  536. libraryPanel.SetComponent(ptr(WMComponents.Component));
  537. END;
  538. IF xmlPanel # NIL THEN
  539. xmlPanel.SetComponent(ptr(WMComponents.Component));
  540. END;
  541. ELSE
  542. propertyPanel.SetComponent(SELF, NIL);
  543. IF libraryPanel # NIL THEN
  544. libraryPanel.SetComponent(NIL);
  545. END;
  546. IF xmlPanel # NIL THEN
  547. xmlPanel.SetComponent(NIL);
  548. END;
  549. END;
  550. END;
  551. END;
  552. END NodeClicked;
  553. PROCEDURE GetVisualComponent(sel: SelectionWrapper): WMComponents.VisualComponent;
  554. VAR nodeData: ANY;
  555. BEGIN
  556. sel.tree.Acquire;
  557. nodeData := sel.tree.GetNodeData(sel.node);
  558. sel.tree.Release;
  559. IF (nodeData = NIL) OR ~(nodeData IS WMComponents.VisualComponent) THEN RETURN NIL
  560. ELSE RETURN nodeData(WMComponents.VisualComponent)
  561. END;
  562. END GetVisualComponent;
  563. PROCEDURE ToggleVisibility(sender, data: ANY);
  564. VAR c: WMComponents.VisualComponent;
  565. BEGIN
  566. c := GetVisualComponent(data(SelectionWrapper));
  567. c.visible.Set(~ c.visible.Get());
  568. END ToggleVisibility;
  569. PROCEDURE Select(sender, data: ANY);
  570. VAR c: WMComponents.VisualComponent;
  571. BEGIN
  572. c := GetVisualComponent(data(SelectionWrapper));
  573. WMComponents.selection.Toggle(c);
  574. c.Invalidate;
  575. END Select;
  576. PROCEDURE ToggleEditMode(sender, data: ANY);
  577. VAR c: WMComponents.VisualComponent;
  578. BEGIN
  579. c := GetVisualComponent(data(SelectionWrapper));
  580. c.editMode.Set(~ c.editMode.Get());
  581. END ToggleEditMode;
  582. PROCEDURE UpdateNode(tree: WMTrees.Tree; node: WMTrees.TreeNode; cParent: WMComponents.VisualComponent);
  583. VAR child, parent: WMTrees.TreeNode; enum : XMLObjects.Enumerator; p: ANY;
  584. BEGIN
  585. tree.Acquire;
  586. parent := tree.GetParent(node);
  587. child := tree.GetChildren(parent);
  588. WHILE child # NIL DO
  589. tree.RemoveNode(child);
  590. child := tree.GetChildren(parent);
  591. END;
  592. enum := cParent.GetContents();
  593. WHILE enum.HasMoreElements() DO
  594. p := enum.GetNext();
  595. IF (p IS WMComponents.Component) THEN
  596. currentTree.AddComponents(p(WMComponents.Component), parent);
  597. END;
  598. END;
  599. tree.Release;
  600. END UpdateNode;
  601. PROCEDURE Delete(sender, data: ANY);
  602. VAR c: WMComponents.VisualComponent; parent: XML.Element;
  603. BEGIN
  604. WITH data: SelectionWrapper DO
  605. c := GetVisualComponent(data);
  606. parent := c.GetParent();
  607. parent(WMComponents.VisualComponent).RemoveContent(c);
  608. parent(WMComponents.VisualComponent).Invalidate;
  609. data.tree.Acquire;
  610. data.tree.RemoveNode(data.node);
  611. data.tree.Release;
  612. END;
  613. END Delete;
  614. PROCEDURE MoveUp(sender, data: ANY);
  615. VAR c: WMComponents.VisualComponent; parent: XML.Element; treeParent: WMTrees.TreeNode;
  616. BEGIN
  617. WITH data: SelectionWrapper DO
  618. c := GetVisualComponent(data);
  619. parent := c.GetParent();
  620. parent.RemoveContent(c);
  621. parent.MoveContentBefore(c, NIL);
  622. UpdateNode(data.tree, data.node, parent(WMComponents.VisualComponent));
  623. END;
  624. END MoveUp;
  625. PROCEDURE MoveDown(sender, data: ANY);
  626. VAR c: WMComponents.VisualComponent; parent: XML.Element;treeParent: WMTrees.TreeNode;
  627. BEGIN
  628. WITH data: SelectionWrapper DO
  629. c := GetVisualComponent(data);
  630. parent := c.GetParent();
  631. parent.MoveContentAfter(c, NIL);
  632. parent(WMComponents.VisualComponent).Invalidate;
  633. UpdateNode(data.tree, data.node, parent(WMComponents.VisualComponent));
  634. END;
  635. END MoveDown;
  636. PROCEDURE MoveOneDown(sender, data: ANY);
  637. VAR c: WMComponents.VisualComponent; parent: XML.Element; next: XML.Content; treeParent, nextTreeNode: WMTrees.TreeNode;
  638. BEGIN
  639. WITH data: SelectionWrapper DO
  640. c := GetVisualComponent(data);
  641. parent := c.GetParent();
  642. next := parent.GetNext(c);
  643. IF next # NIL THEN
  644. parent.MoveContentAfter(c,next);
  645. parent(WMComponents.VisualComponent).Invalidate;
  646. UpdateNode(data.tree, data.node, parent(WMComponents.VisualComponent));
  647. END;
  648. END;
  649. END MoveOneDown;
  650. PROCEDURE MoveOneUp(sender, data: ANY);
  651. VAR c: WMComponents.VisualComponent; parent: XML.Element; previous: XML.Content;treeParent, previousTreeNode: WMTrees.TreeNode;
  652. BEGIN
  653. WITH data: SelectionWrapper DO
  654. c := GetVisualComponent(data);
  655. parent := c.GetParent();
  656. previous := parent.GetPrevious(c);
  657. IF previous # NIL THEN
  658. parent.MoveContentBefore(c,previous);
  659. parent(WMComponents.VisualComponent).Invalidate;
  660. UpdateNode(data.tree, data.node, parent(WMComponents.VisualComponent));
  661. END;
  662. END;
  663. END MoveOneUp;
  664. PROCEDURE InvalidateM(sender, data: ANY);
  665. VAR c: WMComponents.VisualComponent; parent: XML.Element;
  666. BEGIN
  667. WITH data: SelectionWrapper DO
  668. c := GetVisualComponent(data);
  669. c.RecacheProperties;
  670. c.Invalidate;
  671. (*
  672. parent := c.GetParent();
  673. parent(WMComponents.VisualComponent).ContentToFront(c);
  674. parent(WMComponents.VisualComponent).Invalidate;
  675. *)
  676. END;
  677. END InvalidateM;
  678. PROCEDURE ContextMenu(sender : ANY; x, y: LONGINT);
  679. VAR popup: WMPopups.Popup; wmx, wmy: LONGINT; node: WMTrees.TreeNode; treeView: WMTrees.TreeView;
  680. par: SelectionWrapper;
  681. BEGIN
  682. NEW(popup);
  683. IF (sender # NIL) & (sender IS WMTrees.TreeView) THEN
  684. treeView := sender(WMTrees.TreeView);
  685. node := treeView.GetNodeAtPos(x,y);
  686. NEW(par);
  687. par.tree := treeView.GetTree();
  688. par.node := node;
  689. popup.AddParButton("Toggle Selection", Select, par);
  690. popup.AddParButton("Toggle Visibility", ToggleVisibility, par);
  691. popup.AddParButton("Toggle EditMode", ToggleEditMode, par);
  692. popup.AddParButton("Delete", Delete, par);
  693. popup.AddParButton("Up", MoveUp, par);
  694. popup.AddParButton("OneUp", MoveOneUp, par);
  695. popup.AddParButton("OneDown", MoveOneDown, par);
  696. popup.AddParButton("Down", MoveDown, par);
  697. popup.AddParButton("Invalidate", InvalidateM, par);
  698. formTree.treeView.ToWMCoordinates(x,y, wmx, wmy);
  699. popup.Popup(wmx, wmy)
  700. END;
  701. END ContextMenu;
  702. END InspectorComponent;
  703. Window* = OBJECT(WMComponents.FormWindow)
  704. VAR
  705. upper, lower: InspectorComponent;
  706. upperVisible: Models.Boolean;
  707. PROCEDURE &New*(context : WMRestorable.Context);
  708. BEGIN
  709. Init(WindowWidth, WindowHeight, FALSE);
  710. IncCount;
  711. NEW(upperVisible); upperVisible.Set(FALSE);
  712. SetContent(CreateF());
  713. SetTitle(Strings.NewString("Inspector"));
  714. SetIcon(WMGraphics.LoadImage("WMInspector.tar://WMInspector.png", TRUE));
  715. END New;
  716. PROCEDURE CreateF(): WMComponents.VisualComponent;
  717. VAR panel: WMStandardComponents.Panel; resizer: WMStandardComponents.Resizer;
  718. BEGIN
  719. NEW(panel); panel.alignment.Set(WMComponents.AlignClient);
  720. panel.fillColor.Set(WMGraphics.White);
  721. NEW(upper,TRUE, upperVisible); upper.alignment.Set(WMComponents.AlignTop);
  722. upper.fillColor.Set(WMGraphics.White);
  723. upper.bounds.SetHeight(200);
  724. panel.AddContent(upper);
  725. upper.visible.SetLink(upperVisible);
  726. NEW(resizer); resizer.alignment.Set(WMComponents.AlignBottom);
  727. resizer.bounds.SetHeight(5);
  728. upper.AddContent(resizer);
  729. NEW(lower,FALSE, upperVisible); lower.alignment.Set(WMComponents.AlignClient);
  730. lower.fillColor.Set(WMGraphics.White);
  731. panel.AddContent(lower);
  732. RETURN panel
  733. END CreateF;
  734. (*
  735. PROCEDURE GetSelectedNode(tree: WMTrees.Tree): WMTrees.TreeNode;
  736. VAR node: WMTrees.TreeNode;
  737. PROCEDURE FindSelected(node: WMTrees.TreeNode): WMTrees.TreeNode;
  738. VAR state: SET; caption: Strings.String; found: WMTrees.TreeNode;
  739. BEGIN
  740. IF node # NIL THEN
  741. caption := tree.GetNodeCaption(node);
  742. TRACE(caption^);
  743. TRACE(state);
  744. state := tree.GetNodeState(node);
  745. IF (WMTrees.StateSelected IN state) THEN
  746. found := node
  747. ELSE
  748. found := FindSelected(tree.GetChildren(node));
  749. IF found = NIL THEN
  750. found := FindSelected(tree.GetNextSibling(node));
  751. END;
  752. END;
  753. END;
  754. RETURN found
  755. END FindSelected;
  756. BEGIN
  757. tree.Acquire;
  758. node := tree.GetRoot();
  759. node := FindSelected(tree.GetChildren(node));
  760. tree.Release;
  761. RETURN node
  762. END GetSelectedNode;
  763. *)
  764. PROCEDURE Handle(VAR x : WMMessages.Message);
  765. BEGIN
  766. IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) THEN
  767. IF (x.ext IS KillerMsg) THEN Close
  768. ELSIF (x.ext IS WMRestorable.Storage) THEN
  769. x.ext(WMRestorable.Storage).Add("WMInspector", "WMInspector.Restore", SELF, NIL);
  770. ELSE Handle^(x)
  771. END
  772. ELSE Handle^(x)
  773. END
  774. END Handle;
  775. PROCEDURE Close;
  776. BEGIN
  777. Close^;
  778. DecCount;
  779. END Close;
  780. END Window;
  781. (* quick and dirty, preliminary for testing purposes, fof *)
  782. DragCommand*= OBJECT(WMStandardComponents.Label)
  783. VAR caption: XML.Attribute; inspector: InspectorComponent;
  784. PROCEDURE &Init*;
  785. BEGIN
  786. Init^; SELF.inspector:= NIL;
  787. NEW(caption); caption.SetName("Caption"); caption.SetValue("Drag to Inspect"); AddAttribute(caption);
  788. SetGenerator("WMInspector.NewCommandDragger");
  789. END Init;
  790. PROCEDURE DrawBackground(canvas: WMGraphics.Canvas);
  791. VAR r: WMRectangles.Rectangle; name: XML.String;
  792. BEGIN
  793. r := GetClientRect();
  794. canvas.Fill(r,LONGINT(0FF00FFFFH),WMGraphics.ModeSrcOverDst);
  795. name := caption.GetValue();
  796. IF name # NIL THEN
  797. r := GetClientRect();
  798. canvas.SetColor(0FFH);
  799. WMGraphics.DrawStringInRect(canvas, r, FALSE, 1, 1, name^)
  800. END;
  801. END DrawBackground;
  802. PROCEDURE Accept(sender, par: ANY);
  803. VAR window: Window;
  804. treeView : WMTrees.TreeView;
  805. tree : WMTrees.Tree;
  806. root: WMTrees.TreeNode;
  807. (*window: WMInspectionComponents.Window; propertyPanel: WMInspectionComponents.PropertyPanel;*)
  808. PROCEDURE FindComponent(node: WMTrees.TreeNode): BOOLEAN;
  809. BEGIN
  810. IF node = NIL THEN RETURN FALSE
  811. ELSIF tree.GetNodeData(node)=sender THEN
  812. tree.InclNodeState(node, WMTrees.NodeExpanded);
  813. treeView.SelectNode(node);
  814. treeView.onClickNode.Call(node);
  815. RETURN TRUE
  816. ELSE
  817. IF FindComponent(tree.GetChildren(node)) THEN
  818. tree.InclNodeState(node, WMTrees.NodeExpanded);
  819. RETURN TRUE
  820. (* open drag *)
  821. ELSE
  822. tree.ExclNodeState(node, WMTrees.NodeExpanded);
  823. RETURN FindComponent(tree.GetNextSibling(node))
  824. END;
  825. END;
  826. END FindComponent;
  827. BEGIN
  828. IF (sender # NIL) & (sender IS WMComponents.Component) THEN
  829. IF SELF.inspector = NIL THEN
  830. NEW(window,NIL);
  831. WMWindowManager.AddWindow(window,100,100);
  832. inspector := window.lower;
  833. ELSE inspector := SELF.inspector
  834. END;
  835. treeView := inspector.formTree.treeView;
  836. tree := inspector.formTree.tree;
  837. inspector.formTree.Refresh(SELF,NIL);
  838. tree.Acquire;
  839. root := tree.GetRoot();
  840. IF FindComponent(root) THEN END;
  841. tree.Release;
  842. (*
  843. NEW(propertyPanel);
  844. propertyPanel.bounds.SetExtents(300,300);
  845. propertyPanel.fillColor.Set(WMGraphics.Yellow);
  846. NEW(window, propertyPanel);
  847. propertyPanel.SetComponent(SELF,sender);
  848. *)
  849. END;
  850. END Accept;
  851. PROCEDURE PointerDown(x, y : LONGINT; keys : SET);
  852. VAR
  853. img,icon: WMGraphics.Image; canvas, iconCanvas: WMGraphics.BufferCanvas; color: LONGINT;
  854. r: WMRectangles.Rectangle; data: WMComponents.FindComponentMode;
  855. BEGIN
  856. IF 0 IN keys THEN
  857. r := GetClientRect();
  858. color := LONGINT(0AAFF00FFH);
  859. NEW(img);
  860. Raster.Create(img, 30,30, Raster.BGRA8888);
  861. NEW(canvas,img);
  862. canvas.Fill(WMRectangles.MakeRect(0, 0, 30,30), color , WMGraphics.ModeSrcOverDst);
  863. NEW(data);
  864. IF StartDrag(data, img, 0,0,Accept,Accept) THEN
  865. END;
  866. END
  867. END PointerDown;
  868. END DragCommand;
  869. VAR
  870. nofWindows : LONGINT;
  871. manager : WMWindowManager.WindowManager;
  872. PROCEDURE Open*;
  873. VAR window : Window;
  874. BEGIN
  875. NEW(window, NIL);
  876. WMWindowManager.AddWindow(window, 100, 100);
  877. END Open;
  878. PROCEDURE Restore*(context : WMRestorable.Context);
  879. VAR window : Window;
  880. BEGIN
  881. NEW(window, context);
  882. WMRestorable.AddByContext(window, context);
  883. END Restore;
  884. PROCEDURE Clear(VAR windows : Windows);
  885. VAR i : LONGINT;
  886. BEGIN
  887. FOR i := 0 TO LEN(windows)-1 DO
  888. windows[i] := NIL;
  889. END;
  890. END Clear;
  891. (** Postcondition: {(windows # NIL) & (0 <= nofWindows < MaxNofWindows) & (windows[i < nofWindows] # NIL)} *)
  892. PROCEDURE GetWindows(VAR windows : Windows; VAR nofWindows : LONGINT);
  893. VAR
  894. window : WMWindowManager.Window;
  895. PROCEDURE IsUserWindow(window : WMWindowManager.Window) : BOOLEAN;
  896. BEGIN
  897. ASSERT(window # NIL);
  898. RETURN {WMWindowManager.FlagDecorWindow} * window.flags = {};
  899. END IsUserWindow;
  900. PROCEDURE SortWindowsById(VAR windows : Windows);
  901. VAR temp : WMWindowManager.Window; i, j : LONGINT;
  902. BEGIN
  903. (* for now bubble sort is sufficient *)
  904. FOR i := 0 TO nofWindows-1 DO
  905. FOR j := 0 TO nofWindows-2 DO
  906. IF (windows[j].id > windows[j+1].id) THEN
  907. temp := windows[j+1];
  908. windows[j+1] := windows[j];
  909. windows[j] := temp;
  910. END;
  911. END;
  912. END;
  913. END SortWindowsById;
  914. BEGIN
  915. ASSERT((manager # NIL));
  916. (* clear all references *)
  917. Clear(windows);
  918. manager.lock.AcquireWrite;
  919. nofWindows := 0;
  920. window := manager.GetFirst();
  921. WHILE (window # NIL) & (nofWindows < MaxNofWindows) DO
  922. IF IsUserWindow(window) THEN
  923. windows[nofWindows] := window;
  924. INC(nofWindows);
  925. END;
  926. window := manager.GetNext(window);
  927. END;
  928. manager.lock.ReleaseWrite;
  929. IF (nofWindows > 1) THEN SortWindowsById(windows); END;
  930. END GetWindows;
  931. PROCEDURE IncCount;
  932. BEGIN {EXCLUSIVE}
  933. INC(nofWindows)
  934. END IncCount;
  935. PROCEDURE DecCount;
  936. BEGIN {EXCLUSIVE}
  937. DEC(nofWindows)
  938. END DecCount;
  939. PROCEDURE Cleanup;
  940. VAR die : KillerMsg;
  941. msg : WMMessages.Message;
  942. m : WMWindowManager.WindowManager;
  943. BEGIN {EXCLUSIVE}
  944. NEW(die);
  945. msg.ext := die;
  946. msg.msgType := WMMessages.MsgExt;
  947. m := WMWindowManager.GetDefaultManager();
  948. m.Broadcast(msg);
  949. AWAIT(nofWindows = 0)
  950. END Cleanup;
  951. PROCEDURE NewCommandDragger*(): XML.Element;
  952. VAR label : DragCommand;
  953. BEGIN NEW(label); RETURN label
  954. END NewCommandDragger;
  955. BEGIN
  956. nofWindows := 0;
  957. manager := WMWindowManager.GetDefaultManager();
  958. Modules.InstallTermHandler(Cleanup);
  959. END WMInspector.
  960. SystemTools.FreeDownTo WMInspector ~
  961. SystemTools.FreeDownTo WMInspectionComponents ~
  962. WMInspector.Open ~
  963. ComponentViewer.Open --client WMInspector.NewCommandDragger ~