// Expanded is passed so that the correct ContentNodes are expanded in the PositionedNode PositionedGraph BuildPositionedGraph(ObjectGraph objectGraph, Expanded expanded) { var positionedNodeFor = new Dictionary<ObjectGraphNode, PositionedNode>(); var positionedGraph = new PositionedGraph(); // create empty PositionedNodes foreach (ObjectGraphNode objectNode in objectGraph.ReachableNodes) { var posNode = new PositionedNode(objectNode, expanded); posNode.MeasureVisualControl(); positionedGraph.AddNode(posNode); positionedNodeFor[objectNode] = posNode; } // create edges foreach (PositionedNode posNode in positionedGraph.Nodes) { foreach (PositionedNodeProperty property in posNode.Properties) { if (property.ObjectGraphProperty.TargetNode != null) { ObjectGraphNode targetObjectNode = property.ObjectGraphProperty.TargetNode; PositionedNode edgeTarget = positionedNodeFor[targetObjectNode]; property.Edge = new PositionedEdge { Name = property.Name, Source = property, Target = edgeTarget }; } } } positionedGraph.Root = positionedNodeFor[objectGraph.Root]; return positionedGraph; }
/// <summary> /// Creates new PositionedNodeProperty. /// </summary> /// <param name="objectProperty">Underlying <see cref="ObjectProperty"/></param> public PositionedNodeProperty(ObjectGraphProperty objectProperty, PositionedNode containingNode, bool isPropertyExpanded) { if (containingNode == null) throw new ArgumentNullException("containingNode"); if (objectProperty == null) throw new ArgumentNullException("objectProperty"); this.objectGraphProperty = objectProperty; this.containingNode = containingNode; this.IsPropertyExpanded = isPropertyExpanded; }
PositionedNode MatchNode(PositionedNode oldNode, Dictionary<int, PositionedNode> newNodeMap) { PositionedNode newNodeFound = newNodeMap.GetValue(oldNode.ObjectNode.HashCode); if ((newNodeFound != null) && IsSameAddress(oldNode, newNodeFound)) { return newNodeFound; } else { return null; } }
/// <summary> /// Sets the node to be displayed by this control. /// </summary> /// <param name="node"></param> public void SetDataContext(PositionedNode node) { if (node == null) { this.DataContext = null; this.listView.ItemsSource = null; return; } this.DataContext = node; this.Root = node.Content; this.items = GetInitialItems(this.Root); // data virtualization, ContentPropertyNode implements IEvaluate this.listView.ItemsSource = new VirtualizingObservableCollection<ContentNode>(this.items); }
/// <summary> /// Given SubtreeSize for each node, positions the nodes, in a left-to-right or top-to-bottom layout. /// </summary> /// <param name="node"></param> /// <param name="lateralStart"></param> /// <param name="mainStart"></param> void CalculateNodePosRecursive(PositionedNode node, HashSet <PositionedEdge> treeEdges, double lateralBase, double mainBase) { double childsSubtreeSize = TreeChildNodes(node, treeEdges).Sum(child => child.SubtreeSize); double center = TreeEdges(node, treeEdges).Count() == 0 ? 0 : 0.5 * (childsSubtreeSize - (GetLateralSizeWithMargin(node))); if (center < 0) { // if root is larger than subtree, it would be shifted below lateralStart // -> make whole layout start at lateralStart lateralBase -= center; } SetLateral(node, GetLateral(node) + lateralBase + center); SetMain(node, mainBase); double childLateral = lateralBase; double childsMainFixed = GetMain(node) + GetMainSizeWithMargin(node); foreach (var child in TreeChildNodes(node, treeEdges)) { CalculateNodePosRecursive(child, treeEdges, childLateral, childsMainFixed); childLateral += child.SubtreeSize; } }
void CalculateSubtreeSizesRecursive(PositionedNode root, HashSet<PositionedEdge> treeEdges) { double subtreeSize = 0; foreach (var child in TreeChildNodes(root, treeEdges)) { CalculateSubtreeSizesRecursive(child, treeEdges); // just sum up the sizes of children subtreeSize += child.SubtreeSize; } root.SubtreeSize = Math.Max(GetLateralSizeWithMargin(root), subtreeSize); }
internal void SetAdded(PositionedNode addedNode) { addedNodes.Add(addedNode); }
double GetMain(PositionedNode node) { return (this.LayoutDirection == LayoutDirection.LeftRight) ? node.Left : node.Top; }
IEnumerable<PositionedEdge> TreeEdges(PositionedNode node, HashSet<PositionedEdge> treeEdges) { return node.Edges.Where(e => treeEdges.Contains(e)); }
internal void SetAdded(PositionedNode addedNode) { addedNodes.Add(addedNode); }
internal void SetMatching(PositionedNode matchFrom, PositionedNode matchTo) { matching[matchFrom] = matchTo; changedNodes.Add(matchFrom); }
public PositionedNode GetMatchingNewNode(PositionedNode oldNode) { return(matching.GetValue(oldNode)); }
/// <summary> /// Given SubtreeSize for each node, positions the nodes, in a left-to-right or top-to-bottom layout. /// </summary> /// <param name="node"></param> /// <param name="lateralStart"></param> /// <param name="mainStart"></param> void CalculateNodePosRecursive(PositionedNode node, HashSet<PositionedEdge> treeEdges, double lateralBase, double mainBase) { double childsSubtreeSize = TreeChildNodes(node, treeEdges).Sum(child => child.SubtreeSize); double center = TreeEdges(node, treeEdges).Count() == 0 ? 0 : 0.5 * (childsSubtreeSize - (GetLateralSizeWithMargin(node))); if (center < 0) { // if root is larger than subtree, it would be shifted below lateralStart // -> make whole layout start at lateralStart lateralBase -= center; } SetLateral(node, GetLateral(node) + lateralBase + center); SetMain(node, mainBase); double childLateral = lateralBase; double childsMainFixed = GetMain(node) + GetMainSizeWithMargin(node); foreach (var child in TreeChildNodes(node, treeEdges)) { CalculateNodePosRecursive(child, treeEdges, childLateral, childsMainFixed); childLateral += child.SubtreeSize; } }
public PositionedNode GetMatchingNewNode(PositionedNode oldNode) { return matching.GetValue(oldNode); }
public ContentPropertyNode(PositionedNode containingNode, ContentNode parent) : base(containingNode, parent) { }
IEnumerable<PositionedNode> TreeChildNodes(PositionedNode node, HashSet<PositionedEdge> treeEdges) { return TreeEdges(node, treeEdges).Select(e => e.Target); }
void SetLateral(PositionedNode node, double value) { if (this.LayoutDirection == LayoutDirection.LeftRight) { node.Top = value; } else { node.Left = value; } }
double GetLateral(PositionedNode node) { return (this.LayoutDirection == LayoutDirection.LeftRight) ? node.Top : node.Left; }
internal void SetRemoved(PositionedNode removeddNode) { deletedNodes.Add(removeddNode); }
internal void AddNode(PositionedNode node) { this.nodes.Add(node); }
internal void SetMatching(PositionedNode matchFrom, PositionedNode matchTo) { matching[matchFrom] = matchTo; changedNodes.Add(matchFrom); }
IEnumerable <PositionedEdge> TreeEdges(PositionedNode node, HashSet <PositionedEdge> treeEdges) { return(node.Edges.Where(e => treeEdges.Contains(e))); }
public PositionedNode GetMatchingNewNode(PositionedNode oldNode) { return matching.GetOrDefault(oldNode); }
double GetLateralSizeWithMargin(PositionedNode node) { return((this.LayoutDirection == LayoutDirection.LeftRight) ? node.Height + NodeMarginV : node.Width + NodeMarginH); }
internal void SetRemoved(PositionedNode removeddNode) { deletedNodes.Add(removeddNode); }
double GetLateral(PositionedNode node) { return((this.LayoutDirection == LayoutDirection.LeftRight) ? node.Top : node.Left); }
bool IsSameAddress(PositionedNode node1, PositionedNode node2) { return node1.ObjectNode.PermanentReference.GetObjectAddress() == node2.ObjectNode.PermanentReference.GetObjectAddress(); }
double GetLateralSizeWithMargin(PositionedNode node) { return (this.LayoutDirection == LayoutDirection.LeftRight) ? node.Height + NodeMarginV : node.Width + NodeMarginH; }
IEnumerable <PositionedNode> TreeChildNodes(PositionedNode node, HashSet <PositionedEdge> treeEdges) { return(TreeEdges(node, treeEdges).Select(e => e.Target)); }
bool IsSameAddress(PositionedNode node1, PositionedNode node2) { return(node1.ObjectNode.PermanentReference.GetObjectAddress() == node2.ObjectNode.PermanentReference.GetObjectAddress()); }
double GetMain(PositionedNode node) { return((this.LayoutDirection == LayoutDirection.LeftRight) ? node.Left : node.Top); }
internal void AddNode(PositionedNode node) { this.nodes.Add(node); }
public ContentPropertyNode(PositionedNode containingNode, ContentNode parent) : base(containingNode, parent) { }
public PositionedNode GetMatchingNewNode(PositionedNode oldNode) { return(matching.GetOrDefault(oldNode)); }
PositionedGraphNodeControl AddNodeToCanvas(PositionedNode node) { canvas.Children.Add(node.NodeVisualControl); Canvas.SetLeft(node.NodeVisualControl, node.Left); Canvas.SetTop(node.NodeVisualControl, node.Top); return node.NodeVisualControl; }
HashSet<PositionedEdge> DetermineTreeEdges(PositionedNode root) { var treeEdges = new HashSet<PositionedEdge>(); var seenNodes = new HashSet<PositionedNode>(); var q = new Queue<PositionedNode>(); q.Enqueue(root); seenNodes.Add(root); while (q.Count > 0) { var node = q.Dequeue(); foreach (var property in node.Properties) { var edge = property.Edge; if (edge != null && edge.Target != null) { if (!seenNodes.Contains(edge.Target)) { treeEdges.Add(edge); seenNodes.Add(edge.Target); q.Enqueue(edge.Target); } } } } return treeEdges; }