MODULE WMInspector;
IMPORT
Modules, Strings, XMLObjects, Texts,
WMRectangles, WMGraphics, WMMessages, WMRestorable, WMWindowManager,
WMComponents, WMStandardComponents, WMTrees, WMTabComponents, WMInspectionComponents, XML, Raster, WMPopups, Models;
CONST
WindowWidth = 800; WindowHeight = 500;
MaxNofWindows = 100;
Bearing = 2;
TYPE
Windows = ARRAY MaxNofWindows OF WMWindowManager.Window;
InspectionTree* = OBJECT(WMComponents.VisualComponent)
VAR
treeView- : WMTrees.TreeView;
tree- : WMTrees.Tree;
selected: WMTrees.TreeNode;
dragged: WMTrees.TreeNode;
PROCEDURE &Init;
BEGIN
Init^;
NEW(treeView); treeView.alignment.Set(WMComponents.AlignClient);
tree := treeView.GetTree();
treeView.onStartDrag.Add(OnStartDrag);
treeView.SetExtDragDroppedHandler(DragDroppedHandler);
END Init;
PROCEDURE DragAccepted(sender, data: ANY);
VAR dragInfo: WMWindowManager.DragInfo; parent: XML.Element;
BEGIN
IF data # NIL THEN
dragInfo := data(WMWindowManager.DragInfo);
data := dragInfo.data;
IF (data # NIL) & (data IS WMComponents.VisualComponent) THEN
parent := data(WMComponents.VisualComponent).GetParent();
IF parent # NIL THEN
parent.RemoveContent(data(WMComponents.VisualComponent));
parent(WMComponents.VisualComponent).Invalidate;
END;
END;
IF (data # NIL) & (data = GetNodeData(dragged)) THEN
tree.Acquire;
tree.RemoveNode(dragged);
tree.Release;
END;
END
END DragAccepted;
PROCEDURE DragRejected(sender, data: ANY);
BEGIN
END DragRejected;
PROCEDURE GetNodeData(node: WMTrees.TreeNode): WMComponents.VisualComponent;
VAR nodeData: ANY;
BEGIN
tree.Acquire;
nodeData := tree.GetNodeData(node);
tree.Release;
IF (nodeData = NIL) OR ~(nodeData IS WMComponents.VisualComponent) THEN RETURN NIL
ELSE RETURN nodeData(WMComponents.VisualComponent)
END;
END GetNodeData;
PROCEDURE DragDroppedHandler(x,y: LONGINT; dragInfo: WMWindowManager.DragInfo; VAR handled: BOOLEAN);
VAR node: WMTrees.TreeNode; destination,source: WMComponents.VisualComponent; data: ANY; parent: XML.Element;
BEGIN
node := treeView.GetNodeAtPos(x,y);
IF node # NIL THEN
destination := GetNodeData(node);
ELSE destination := NIL
END;
data := dragInfo.data;
IF (data # NIL) & (data IS WMComponents.VisualComponent) THEN
source := data(WMComponents.VisualComponent);
END;
IF (source # NIL) & (destination # NIL) THEN
ConfirmDrag(TRUE, dragInfo);
destination.AddContent(source);
destination.Invalidate;
tree.Acquire;
AddComponents(source, node);
tree.Release;
handled := TRUE;
END;
END DragDroppedHandler;
PROCEDURE OnStartDrag(sender, data : ANY);
VAR w, h: LONGINT; img: WMGraphics.Image; canvas: WMGraphics.BufferCanvas; caption: Strings.String;
BEGIN
NEW(img);
dragged := treeView.draggedNode;
treeView.MeasureNode(dragged, w, h);
Raster.Create(img, w, h, Raster.BGRA8888);
NEW(canvas, img);
canvas.SetColor(LONGINT(0FFFF00FFH));
canvas.Fill(WMRectangles.MakeRect(0, 0, w, h), LONGINT(0FFFF00FFH), WMGraphics.ModeCopy);
canvas.SetColor(0FFH);
tree.Acquire();
caption := tree.GetNodeCaption(dragged);
tree.Release();
canvas.DrawString(0,h, caption^);
dragged := treeView.draggedNode;
IF (dragged # NIL) & StartDrag(GetNodeData(dragged), img, 0, 0, DragAccepted, DragRejected) THEN
END;
END OnStartDrag;
PROCEDURE AddComponents(component : WMComponents.Component; parent : WMTrees.TreeNode);
VAR
node : WMTrees.TreeNode;
name, string : Strings.String;
caption : ARRAY 128 OF CHAR;
enum : XMLObjects.Enumerator;
p : ANY; i, len : LONGINT;
id: Strings.String;
BEGIN
name := component.GetName();
IF (name # NIL) THEN
COPY(name^, caption);
ELSE
caption := "NoName";
END;
id := component.id.Get();
IF (id # NIL) & (id^# "") THEN Strings.Append(caption,":"); Strings.Append(caption,id^) END;
id := component.uid.Get();
IF (id # NIL) & (id^# "") THEN Strings.Append(caption,":"); Strings.Append(caption,id^) END;
IF (component IS WMStandardComponents.Button) THEN
string := component(WMStandardComponents.Button).caption.Get();
IF (string # NIL) THEN
Strings.Append(caption, " (");
Strings.Append(caption, string^);
Strings.Append(caption, ")");
END;
ELSIF (component IS WMStandardComponents.Label) THEN
string := component(WMStandardComponents.Label).caption.Get();
IF (string # NIL) THEN
Strings.Append(caption, " (");
IF (Strings.Length(caption) <= 10) THEN
Strings.Append(caption, string^);
ELSE
len := Strings.Length(caption);
i := 0;
WHILE (i < 10) & (string[i] # 0X) & (len + i < LEN(caption) - 1) DO
caption[len + i] := string[i]; INC(i);
END;
caption[len+i] := 0X;
Strings.Append(caption, "...");
END;
Strings.Append(caption, ")");
END;
END;
IF component.internal THEN
Strings.Append(caption, " [internal]");
END;
NEW(node);
tree.SetNodeCaption(node, Strings.NewString(caption));
tree.SetNodeData(node, component);
tree.AddChildNode(parent, node);
enum := component.GetContents();
WHILE enum.HasMoreElements() DO
p := enum.GetNext();
IF (p IS WMComponents.Component) THEN
AddComponents(p(WMComponents.Component), node);
END;
END;
END AddComponents;
PROCEDURE Refresh(sender, data : ANY);
END Refresh;
END InspectionTree;
TYPE
FormComponentsTree* = OBJECT(InspectionTree)
VAR
windows : Windows;
refreshBtn, splitBtn : WMStandardComponents.Button;
dragger: DragCommand;
PROCEDURE &Init;
VAR panel: WMStandardComponents.Panel;
BEGIN
Init^;
Clear(windows);
NEW(dragger); dragger.alignment.Set(WMComponents.AlignBottom);
dragger.bounds.SetHeight(20);
dragger.bearing.Set(WMRectangles.MakeRect(Bearing, Bearing, Bearing, Bearing));
AddContent(dragger);
NEW(panel); panel.alignment.Set(WMComponents.AlignBottom);
panel.bounds.SetHeight(20);
AddContent(panel);
NEW(refreshBtn); refreshBtn.alignment.Set(WMComponents.AlignLeft);
refreshBtn.bounds.SetWidth(100);
refreshBtn.caption.SetAOC("Refresh");
refreshBtn.onClick.Add(Refresh);
panel.AddContent(refreshBtn);
NEW(splitBtn); splitBtn.alignment.Set(WMComponents.AlignClient);
splitBtn.bounds.SetHeight(20);
splitBtn.caption.SetAOC("Split");
splitBtn.isToggle.Set(TRUE);
panel.AddContent(splitBtn);
AddContent(treeView);
END Init;
PROCEDURE AddFormWindow(window : WMComponents.FormWindow; parent : WMTrees.TreeNode);
VAR node : WMTrees.TreeNode; caption : ARRAY 64 OF CHAR; string : Strings.String;
BEGIN
ASSERT((window # NIL) & (parent # NIL));
string := window.GetTitle();
IF (string # NIL) THEN
COPY(string^, caption);
ELSE
caption := "NoTitle";
END;
NEW(node);
tree.SetNodeCaption(node, Strings.NewString(caption));
tree.AddChildNode(parent, node);
tree.InclNodeState(node, WMTrees.NodeExpanded);
tree.ExpandToRoot(node);
IF (window.form # NIL) THEN
AddComponents(window.form, node);
END;
END AddFormWindow;
PROCEDURE Refresh(sender, data : ANY);
VAR root : WMTrees.TreeNode; nofWindows, i : LONGINT;
BEGIN
ASSERT(tree # NIL);
GetWindows(windows, nofWindows);
tree.Acquire;
NEW(root);
tree.SetRoot(root);
tree.SetNodeCaption(root, Strings.NewString("Windows"));
tree.InclNodeState(root, WMTrees.NodeExpanded);
IF (nofWindows > 0) THEN
FOR i := 0 TO nofWindows - 1 DO
IF (windows[i] # NIL) & (windows[i] IS WMComponents.FormWindow) THEN
AddFormWindow(windows[i](WMComponents.FormWindow), root);
END;
END;
END;
tree.Release;
END Refresh;
END FormComponentsTree;
TYPE
TextComponentsTree = OBJECT(InspectionTree)
PROCEDURE &Init;
BEGIN
Init^;
AddContent(treeView);
Texts.onLastTextChanged.Add(Refresh);
END Init;
PROCEDURE Refresh(sender, data : ANY);
VAR
root : WMTrees.TreeNode;
text : Texts.Text; reader : Texts.TextReader;
ignoreCh : Texts.Char32;
BEGIN
ASSERT(tree # NIL);
text := Texts.GetLastText();
IF (text # NIL) THEN
text.AcquireRead;
NEW(reader, text); reader.SetPosition(0);
tree.Acquire;
NEW(root);
tree.SetRoot(root);
tree.SetNodeCaption(root, Strings.NewString("Text"));
WHILE ~reader.eot DO
reader.ReadCh(ignoreCh);
IF (reader.object # NIL) & (reader.object IS WMComponents.Component) THEN
AddComponents(reader.object (WMComponents.Component), root);
END;
END;
tree.InclNodeState(root, WMTrees.NodeExpanded);
tree.Release;
text.ReleaseRead;
ELSE
tree.Acquire;
NEW(root);
tree.SetRoot(root);
tree.SetNodeCaption(root, Strings.NewString("No text selection"));
tree.InclNodeState(root, WMTrees.NodeExpanded);
tree.Release;
END;
END Refresh;
PROCEDURE Finalize;
BEGIN
Finalize^;
Texts.onLastTextChanged.Remove(Refresh);
END Finalize;
END TextComponentsTree;
TYPE
SelectedTextTree = OBJECT(InspectionTree)
PROCEDURE &Init;
BEGIN
Init^;
AddContent(treeView);
Texts.onLastSelectionChanged.Add(Refresh);
END Init;
PROCEDURE Refresh(sender, data : ANY);
VAR
root : WMTrees.TreeNode;
text : Texts.Text; from, to : Texts.TextPosition; reader : Texts.TextReader;
ignoreCh : Texts.Char32;
BEGIN
ASSERT(tree # NIL);
IF Texts.GetLastSelection(text, from, to) THEN
text.AcquireRead;
NEW(reader, text); reader.SetPosition(from.GetPosition());
tree.Acquire;
NEW(root);
tree.SetRoot(root);
tree.SetNodeCaption(root, Strings.NewString("Text"));
WHILE ~reader.eot & (reader.GetPosition() < to.GetPosition()) DO
reader.ReadCh(ignoreCh);
IF (reader.object # NIL) & (reader.object IS WMComponents.Component) THEN
AddComponents(reader.object (WMComponents.Component), root);
END;
END;
tree.InclNodeState(root, WMTrees.NodeExpanded);
tree.Release;
text.ReleaseRead;
ELSE
tree.Acquire;
NEW(root);
tree.SetRoot(root);
tree.SetNodeCaption(root, Strings.NewString("No text selection"));
tree.InclNodeState(root, WMTrees.NodeExpanded);
tree.Release;
END;
END Refresh;
PROCEDURE Finalize;
BEGIN
Finalize^;
Texts.onLastSelectionChanged.Remove(Refresh);
END Finalize;
END SelectedTextTree;
SelectedComponentsTree = OBJECT(InspectionTree)
PROCEDURE &Init;
BEGIN
Init^;
AddContent(treeView);
WMComponents.selection.onChanged.Add(Refresh);
Refresh(SELF, WMComponents.selection);
END Init;
PROCEDURE Refresh(sender, data : ANY);
VAR
root , node: WMTrees.TreeNode;
array: WMComponents.SelectionArray;
selection: WMComponents.SelectionList;
i: LONGINT;
BEGIN
ASSERT(tree # NIL);
IF (data # NIL) & (data IS WMComponents.SelectionList) THEN
selection := data(WMComponents.SelectionList);
array := selection.GetSelection();
tree.Acquire;
NEW(root);
tree.SetRoot(root);
tree.SetNodeCaption(root, Strings.NewString("selection"));
FOR i := 0 TO LEN(array)-1 DO
AddComponents(array[i], root);
END;
IF LEN(array) = 1 THEN
node := tree.GetChildren(root);
treeView.SelectNode(node);
treeView.onClickNode.Call(node);
END;
tree.InclNodeState(root, WMTrees.NodeExpanded);
tree.Release;
END;
END Refresh;
PROCEDURE Finalize;
BEGIN
Finalize^;
WMComponents.selection.onChanged.Remove(Refresh)
END Finalize;
END SelectedComponentsTree;
TYPE
KillerMsg = OBJECT
END KillerMsg;
SelectionWrapper= POINTER TO RECORD tree: WMTrees.Tree; node: WMTrees.TreeNode END;
InspectorComponent= OBJECT (WMComponents.VisualComponent)
VAR
formTree- : FormComponentsTree;
textTree : TextComponentsTree;
selectedTextTree : SelectedTextTree;
selectedComponentTree: SelectedComponentsTree;
currentTree : InspectionTree;
propertyPanel : WMInspectionComponents.PropertyPanel;
libraryPanel : WMInspectionComponents.RepositoryPanel;
xmlPanel : WMInspectionComponents.XMLPanel;
PROCEDURE &InitInspector(simple: BOOLEAN; vis: Models.Boolean);
BEGIN
Init;
Create(simple, vis);
currentTree := formTree;
formTree.treeView.onClickNode.Add(NodeClicked);
formTree.Refresh(NIL, NIL);
textTree.treeView.onClickNode.Add(NodeClicked);
textTree.Refresh(NIL, NIL);
selectedTextTree.treeView.onClickNode.Add(NodeClicked);
selectedTextTree.Refresh(NIL, NIL);
selectedComponentTree.treeView.onClickNode.Add(NodeClicked);
selectedComponentTree.Refresh(NIL, NIL);
formTree.treeView.SetExtContextMenuHandler(ContextMenu);
textTree.treeView.SetExtContextMenuHandler(ContextMenu);
selectedTextTree.treeView.SetExtContextMenuHandler(ContextMenu);
selectedComponentTree.treeView.SetExtContextMenuHandler(ContextMenu);
END InitInspector;
PROCEDURE Create(simple: BOOLEAN; vis: Models.Boolean);
VAR
rightPanel, treePanel, libPanel : WMStandardComponents.Panel; resizer : WMStandardComponents.Resizer;
tabPanel : WMTabComponents.TabPanel; tabControl : WMTabComponents.Tabs; tabEntry : WMTabComponents.TabEntry;
BEGIN
NEW(treePanel); treePanel.alignment.Set(WMComponents.AlignLeft);
treePanel.bounds.SetWidth(200);
AddContent(treePanel);
NEW(resizer); resizer.alignment.Set(WMComponents.AlignRight);
resizer.bounds.SetWidth(5);
treePanel.AddContent(resizer);
NEW(tabPanel); tabPanel.alignment.Set(WMComponents.AlignClient);
treePanel.AddContent(tabPanel);
NEW(tabControl); tabControl.alignment.Set(WMComponents.AlignTop);
tabControl.bounds.SetHeight(20);
tabControl.onSelectTab.Add(TabSelected);
tabPanel.AddContent(tabControl);
NEW(tabEntry); tabEntry.alignment.Set(WMComponents.AlignClient);
tabEntry.caption.SetAOC("Windows");
tabPanel.AddContent(tabEntry);
NEW(formTree); formTree.alignment.Set(WMComponents.AlignClient);
tabEntry.AddContent(formTree);
formTree.dragger.inspector := SELF;
formTree.splitBtn.model.Set(vis);
NEW(tabEntry); tabEntry.alignment.Set(WMComponents.AlignClient);
tabEntry.caption.SetAOC("Selection");
tabPanel.AddContent(tabEntry);
NEW(selectedComponentTree); selectedComponentTree.alignment.Set(WMComponents.AlignClient);
tabEntry.AddContent(selectedComponentTree);
NEW(tabEntry); tabEntry.alignment.Set(WMComponents.AlignClient);
tabEntry.caption.SetAOC("Sel. Text");
tabPanel.AddContent(tabEntry);
NEW(selectedTextTree); selectedTextTree.alignment.Set(WMComponents.AlignClient);
tabEntry.AddContent(selectedTextTree);
NEW(tabEntry); tabEntry.alignment.Set(WMComponents.AlignClient);
tabEntry.caption.SetAOC("Last Text");
tabPanel.AddContent(tabEntry);
NEW(textTree); textTree.alignment.Set(WMComponents.AlignClient);
tabEntry.AddContent(textTree);
NEW(rightPanel); rightPanel.alignment.Set(WMComponents.AlignClient);
AddContent(rightPanel);
IF ~simple THEN
NEW(libPanel); libPanel.alignment.Set(WMComponents.AlignBottom);
libPanel.bounds.SetHeight(60);
libPanel.fillColor.Set(0C0C0C0FFH);
rightPanel.AddContent(libPanel);
NEW(resizer); resizer.alignment.Set(WMComponents.AlignTop);
resizer.bounds.SetHeight(5);
libPanel.AddContent(resizer);
NEW(libraryPanel); libraryPanel.alignment.Set(WMComponents.AlignTop);
libraryPanel.bounds.SetHeight(50);
libraryPanel.bearing.Set(WMRectangles.MakeRect(Bearing, Bearing, Bearing, Bearing));
libPanel.AddContent(libraryPanel);
NEW(xmlPanel); xmlPanel.alignment.Set(WMComponents.AlignTop);
xmlPanel.bounds.SetHeight(20);
xmlPanel.bearing.Set(WMRectangles.MakeRect(2*Bearing, Bearing, Bearing, Bearing));
libPanel.AddContent(xmlPanel);
END;
NEW(propertyPanel); propertyPanel.alignment.Set(WMComponents.AlignClient);
rightPanel.AddContent(propertyPanel);
END Create;
PROCEDURE TabSelected(sender, data : ANY);
VAR caption : Strings.String; node: WMTrees.TreeNode;
BEGIN
IF (data # NIL) & (data IS WMTabComponents.Tab) THEN
caption := data(WMTabComponents.Tab).caption;
IF (caption # NIL) THEN
IF (caption^ = "Windows") THEN currentTree := formTree;
ELSIF (caption^ = "Last Text") THEN currentTree := textTree;
ELSIF (caption^ = "Sel. Text") THEN currentTree := selectedTextTree;
ELSIF (caption^ = "Selection") THEN currentTree := selectedComponentTree;
END;
node := currentTree.selected;
IF node # NIL THEN NodeClicked(currentTree.treeView, node) END;
END;
END;
END TabSelected;
PROCEDURE NodeClicked(sender, data : ANY);
VAR ptr : ANY;
BEGIN
IF (data # NIL) & (data IS WMTrees.TreeNode) THEN
IF sender = currentTree.treeView THEN
currentTree.tree.Acquire;
ptr := currentTree.tree.GetNodeData(data(WMTrees.TreeNode));
currentTree.selected := data(WMTrees.TreeNode);
currentTree.tree.Release;
IF (ptr # NIL) & (ptr IS WMComponents.Component) THEN
propertyPanel.SetComponent(SELF, ptr(WMComponents.Component));
IF libraryPanel # NIL THEN
libraryPanel.SetComponent(ptr(WMComponents.Component));
END;
IF xmlPanel # NIL THEN
xmlPanel.SetComponent(ptr(WMComponents.Component));
END;
ELSE
propertyPanel.SetComponent(SELF, NIL);
IF libraryPanel # NIL THEN
libraryPanel.SetComponent(NIL);
END;
IF xmlPanel # NIL THEN
xmlPanel.SetComponent(NIL);
END;
END;
END;
END;
END NodeClicked;
PROCEDURE GetVisualComponent(sel: SelectionWrapper): WMComponents.VisualComponent;
VAR nodeData: ANY;
BEGIN
sel.tree.Acquire;
nodeData := sel.tree.GetNodeData(sel.node);
sel.tree.Release;
IF (nodeData = NIL) OR ~(nodeData IS WMComponents.VisualComponent) THEN RETURN NIL
ELSE RETURN nodeData(WMComponents.VisualComponent)
END;
END GetVisualComponent;
PROCEDURE ToggleVisibility(sender, data: ANY);
VAR c: WMComponents.VisualComponent;
BEGIN
c := GetVisualComponent(data(SelectionWrapper));
c.visible.Set(~ c.visible.Get());
END ToggleVisibility;
PROCEDURE Select(sender, data: ANY);
VAR c: WMComponents.VisualComponent;
BEGIN
c := GetVisualComponent(data(SelectionWrapper));
WMComponents.selection.Toggle(c);
c.Invalidate;
END Select;
PROCEDURE ToggleEditMode(sender, data: ANY);
VAR c: WMComponents.VisualComponent;
BEGIN
c := GetVisualComponent(data(SelectionWrapper));
c.editMode.Set(~ c.editMode.Get());
END ToggleEditMode;
PROCEDURE UpdateNode(tree: WMTrees.Tree; node: WMTrees.TreeNode; cParent: WMComponents.VisualComponent);
VAR child, parent: WMTrees.TreeNode; enum : XMLObjects.Enumerator; p: ANY;
BEGIN
tree.Acquire;
parent := tree.GetParent(node);
child := tree.GetChildren(parent);
WHILE child # NIL DO
tree.RemoveNode(child);
child := tree.GetChildren(parent);
END;
enum := cParent.GetContents();
WHILE enum.HasMoreElements() DO
p := enum.GetNext();
IF (p IS WMComponents.Component) THEN
currentTree.AddComponents(p(WMComponents.Component), parent);
END;
END;
tree.Release;
END UpdateNode;
PROCEDURE Delete(sender, data: ANY);
VAR c: WMComponents.VisualComponent; parent: XML.Element;
BEGIN
WITH data: SelectionWrapper DO
c := GetVisualComponent(data);
parent := c.GetParent();
parent(WMComponents.VisualComponent).RemoveContent(c);
parent(WMComponents.VisualComponent).Invalidate;
data.tree.Acquire;
data.tree.RemoveNode(data.node);
data.tree.Release;
END;
END Delete;
PROCEDURE MoveUp(sender, data: ANY);
VAR c: WMComponents.VisualComponent; parent: XML.Element; treeParent: WMTrees.TreeNode;
BEGIN
WITH data: SelectionWrapper DO
c := GetVisualComponent(data);
parent := c.GetParent();
parent.RemoveContent(c);
parent.MoveContentBefore(c, NIL);
UpdateNode(data.tree, data.node, parent(WMComponents.VisualComponent));
END;
END MoveUp;
PROCEDURE MoveDown(sender, data: ANY);
VAR c: WMComponents.VisualComponent; parent: XML.Element;treeParent: WMTrees.TreeNode;
BEGIN
WITH data: SelectionWrapper DO
c := GetVisualComponent(data);
parent := c.GetParent();
parent.MoveContentAfter(c, NIL);
parent(WMComponents.VisualComponent).Invalidate;
UpdateNode(data.tree, data.node, parent(WMComponents.VisualComponent));
END;
END MoveDown;
PROCEDURE MoveOneDown(sender, data: ANY);
VAR c: WMComponents.VisualComponent; parent: XML.Element; next: XML.Content; treeParent, nextTreeNode: WMTrees.TreeNode;
BEGIN
WITH data: SelectionWrapper DO
c := GetVisualComponent(data);
parent := c.GetParent();
next := parent.GetNext(c);
IF next # NIL THEN
parent.MoveContentAfter(c,next);
parent(WMComponents.VisualComponent).Invalidate;
UpdateNode(data.tree, data.node, parent(WMComponents.VisualComponent));
END;
END;
END MoveOneDown;
PROCEDURE MoveOneUp(sender, data: ANY);
VAR c: WMComponents.VisualComponent; parent: XML.Element; previous: XML.Content;treeParent, previousTreeNode: WMTrees.TreeNode;
BEGIN
WITH data: SelectionWrapper DO
c := GetVisualComponent(data);
parent := c.GetParent();
previous := parent.GetPrevious(c);
IF previous # NIL THEN
parent.MoveContentBefore(c,previous);
parent(WMComponents.VisualComponent).Invalidate;
UpdateNode(data.tree, data.node, parent(WMComponents.VisualComponent));
END;
END;
END MoveOneUp;
PROCEDURE InvalidateM(sender, data: ANY);
VAR c: WMComponents.VisualComponent; parent: XML.Element;
BEGIN
WITH data: SelectionWrapper DO
c := GetVisualComponent(data);
c.RecacheProperties;
c.Invalidate;
END;
END InvalidateM;
PROCEDURE ContextMenu(sender : ANY; x, y: LONGINT);
VAR popup: WMPopups.Popup; wmx, wmy: LONGINT; node: WMTrees.TreeNode; treeView: WMTrees.TreeView;
par: SelectionWrapper;
BEGIN
NEW(popup);
IF (sender # NIL) & (sender IS WMTrees.TreeView) THEN
treeView := sender(WMTrees.TreeView);
node := treeView.GetNodeAtPos(x,y);
NEW(par);
par.tree := treeView.GetTree();
par.node := node;
popup.AddParButton("Toggle Selection", Select, par);
popup.AddParButton("Toggle Visibility", ToggleVisibility, par);
popup.AddParButton("Toggle EditMode", ToggleEditMode, par);
popup.AddParButton("Delete", Delete, par);
popup.AddParButton("Up", MoveUp, par);
popup.AddParButton("OneUp", MoveOneUp, par);
popup.AddParButton("OneDown", MoveOneDown, par);
popup.AddParButton("Down", MoveDown, par);
popup.AddParButton("Invalidate", InvalidateM, par);
formTree.treeView.ToWMCoordinates(x,y, wmx, wmy);
popup.Popup(wmx, wmy)
END;
END ContextMenu;
END InspectorComponent;
Window* = OBJECT(WMComponents.FormWindow)
VAR
upper, lower: InspectorComponent;
upperVisible: Models.Boolean;
PROCEDURE &New*(context : WMRestorable.Context);
BEGIN
Init(WindowWidth, WindowHeight, FALSE);
IncCount;
NEW(upperVisible); upperVisible.Set(FALSE);
SetContent(CreateF());
SetTitle(Strings.NewString("Inspector"));
SetIcon(WMGraphics.LoadImage("WMInspector.tar://WMInspector.png", TRUE));
END New;
PROCEDURE CreateF(): WMComponents.VisualComponent;
VAR panel: WMStandardComponents.Panel; resizer: WMStandardComponents.Resizer;
BEGIN
NEW(panel); panel.alignment.Set(WMComponents.AlignClient);
panel.fillColor.Set(WMGraphics.White);
NEW(upper,TRUE, upperVisible); upper.alignment.Set(WMComponents.AlignTop);
upper.fillColor.Set(WMGraphics.White);
upper.bounds.SetHeight(200);
panel.AddContent(upper);
upper.visible.SetLink(upperVisible);
NEW(resizer); resizer.alignment.Set(WMComponents.AlignBottom);
resizer.bounds.SetHeight(5);
upper.AddContent(resizer);
NEW(lower,FALSE, upperVisible); lower.alignment.Set(WMComponents.AlignClient);
lower.fillColor.Set(WMGraphics.White);
panel.AddContent(lower);
RETURN panel
END CreateF;
PROCEDURE Handle(VAR x : WMMessages.Message);
BEGIN
IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) THEN
IF (x.ext IS KillerMsg) THEN Close
ELSIF (x.ext IS WMRestorable.Storage) THEN
x.ext(WMRestorable.Storage).Add("WMInspector", "WMInspector.Restore", SELF, NIL);
ELSE Handle^(x)
END
ELSE Handle^(x)
END
END Handle;
PROCEDURE Close;
BEGIN
Close^;
DecCount;
END Close;
END Window;
DragCommand*= OBJECT(WMStandardComponents.Label)
VAR caption: XML.Attribute; inspector: InspectorComponent;
PROCEDURE &Init*;
BEGIN
Init^; SELF.inspector:= NIL;
NEW(caption); caption.SetName("Caption"); caption.SetValue("Drag to Inspect"); AddAttribute(caption);
SetGenerator("WMInspector.NewCommandDragger");
END Init;
PROCEDURE DrawBackground(canvas: WMGraphics.Canvas);
VAR r: WMRectangles.Rectangle; name: XML.String;
BEGIN
r := GetClientRect();
canvas.Fill(r,LONGINT(0FF00FFFFH),WMGraphics.ModeSrcOverDst);
name := caption.GetValue();
IF name # NIL THEN
r := GetClientRect();
canvas.SetColor(0FFH);
WMGraphics.DrawStringInRect(canvas, r, FALSE, 1, 1, name^)
END;
END DrawBackground;
PROCEDURE Accept(sender, par: ANY);
VAR window: Window;
treeView : WMTrees.TreeView;
tree : WMTrees.Tree;
root: WMTrees.TreeNode;
PROCEDURE FindComponent(node: WMTrees.TreeNode): BOOLEAN;
BEGIN
IF node = NIL THEN RETURN FALSE
ELSIF tree.GetNodeData(node)=sender THEN
tree.InclNodeState(node, WMTrees.NodeExpanded);
treeView.SelectNode(node);
treeView.onClickNode.Call(node);
RETURN TRUE
ELSE
IF FindComponent(tree.GetChildren(node)) THEN
tree.InclNodeState(node, WMTrees.NodeExpanded);
RETURN TRUE
ELSE
tree.ExclNodeState(node, WMTrees.NodeExpanded);
RETURN FindComponent(tree.GetNextSibling(node))
END;
END;
END FindComponent;
BEGIN
IF (sender # NIL) & (sender IS WMComponents.Component) THEN
IF SELF.inspector = NIL THEN
NEW(window,NIL);
WMWindowManager.AddWindow(window,100,100);
inspector := window.lower;
ELSE inspector := SELF.inspector
END;
treeView := inspector.formTree.treeView;
tree := inspector.formTree.tree;
inspector.formTree.Refresh(SELF,NIL);
tree.Acquire;
root := tree.GetRoot();
IF FindComponent(root) THEN END;
tree.Release;
END;
END Accept;
PROCEDURE PointerDown(x, y : LONGINT; keys : SET);
VAR
img,icon: WMGraphics.Image; canvas, iconCanvas: WMGraphics.BufferCanvas; color: LONGINT;
r: WMRectangles.Rectangle;
BEGIN
IF 0 IN keys THEN
r := GetClientRect();
color := LONGINT(0AAFF00FFH);
NEW(img);
Raster.Create(img, 30,30, Raster.BGRA8888);
NEW(canvas,img);
canvas.Fill(WMRectangles.MakeRect(0, 0, 30,30), color , WMGraphics.ModeSrcOverDst);
IF StartDrag(NIL, img, 0,0,Accept,Accept) THEN
END;
END
END PointerDown;
END DragCommand;
VAR
nofWindows : LONGINT;
manager : WMWindowManager.WindowManager;
PROCEDURE Open*;
VAR window : Window;
BEGIN
NEW(window, NIL);
WMWindowManager.AddWindow(window, 100, 100);
END Open;
PROCEDURE Restore*(context : WMRestorable.Context);
VAR window : Window;
BEGIN
NEW(window, context);
WMRestorable.AddByContext(window, context);
END Restore;
PROCEDURE Clear(VAR windows : Windows);
VAR i : LONGINT;
BEGIN
FOR i := 0 TO LEN(windows)-1 DO
windows[i] := NIL;
END;
END Clear;
PROCEDURE GetWindows(VAR windows : Windows; VAR nofWindows : LONGINT);
VAR
window : WMWindowManager.Window;
PROCEDURE IsUserWindow(window : WMWindowManager.Window) : BOOLEAN;
BEGIN
ASSERT(window # NIL);
RETURN {WMWindowManager.FlagDecorWindow} * window.flags = {};
END IsUserWindow;
PROCEDURE SortWindowsById(VAR windows : Windows);
VAR temp : WMWindowManager.Window; i, j : LONGINT;
BEGIN
FOR i := 0 TO nofWindows-1 DO
FOR j := 0 TO nofWindows-2 DO
IF (windows[j].id > windows[j+1].id) THEN
temp := windows[j+1];
windows[j+1] := windows[j];
windows[j] := temp;
END;
END;
END;
END SortWindowsById;
BEGIN
ASSERT((manager # NIL));
Clear(windows);
manager.lock.AcquireWrite;
nofWindows := 0;
window := manager.GetFirst();
WHILE (window # NIL) & (nofWindows < MaxNofWindows) DO
IF IsUserWindow(window) THEN
windows[nofWindows] := window;
INC(nofWindows);
END;
window := manager.GetNext(window);
END;
manager.lock.ReleaseWrite;
IF (nofWindows > 1) THEN SortWindowsById(windows); END;
END GetWindows;
PROCEDURE IncCount;
BEGIN {EXCLUSIVE}
INC(nofWindows)
END IncCount;
PROCEDURE DecCount;
BEGIN {EXCLUSIVE}
DEC(nofWindows)
END DecCount;
PROCEDURE Cleanup;
VAR die : KillerMsg;
msg : WMMessages.Message;
m : WMWindowManager.WindowManager;
BEGIN {EXCLUSIVE}
NEW(die);
msg.ext := die;
msg.msgType := WMMessages.MsgExt;
m := WMWindowManager.GetDefaultManager();
m.Broadcast(msg);
AWAIT(nofWindows = 0)
END Cleanup;
PROCEDURE NewCommandDragger*(): XML.Element;
VAR label : DragCommand;
BEGIN NEW(label); RETURN label
END NewCommandDragger;
BEGIN
nofWindows := 0;
manager := WMWindowManager.GetDefaultManager();
Modules.InstallTermHandler(Cleanup);
END WMInspector.
SystemTools.FreeDownTo WMInspector ~
SystemTools.FreeDownTo WMInspectionComponents ~
WMInspector.Open ~
ComponentViewer.Open --client WMInspector.NewCommandDragger ~