private void SetupQueue(DGraph g) { foreach (DNode n in g.Nodes()) { DNestedGraphLabel l = n.Label as DNestedGraphLabel; if (l != null) { foreach (DGraph graph in l.Graphs) { SetupQueue(graph); //graph.PopulateChildren(); } m_LayoutQueue.Enqueue(l); } } }
public DGraph(DNestedGraphLabel parent) : base(parent) { InitializeComponent(); NeedToCalculateLayout = true; ContentEditorProvider = new ContentEditorProvider(this); Edges = new List<DEdge>(); NodeMap = new Dictionary<IComparable, DNode>(); DrawingLayoutEditor = new LayoutEditor(this); DrawingLayoutEditor.ChangeInUndoRedoList += (sender, args) => { FirePropertyChanged("CanUndo"); FirePropertyChanged("CanRedo"); }; // I'm doing a slight change to the default toggle entity predicate: I don't want the user to be able to select nodes while I'm in // insertion mode. Note that this only concerns the DrawingLayoutEditor, which deals with dragging - by changing the toggle entity // predicate, I affect selection of entities while dragging a selection window, NOT selection by simple click. So, this ensures that // the user cannot draw a selection window (which doesn't make sense in editing mode), but he can still select single entities by // clicking on them. var defaultToggleEntityPredicate = DrawingLayoutEditor.ToggleEntityPredicate; DrawingLayoutEditor.ToggleEntityPredicate = (modKeys, mButtons, dragPar) => defaultToggleEntityPredicate(modKeys, mButtons, dragPar) && MouseMode != DraggingMode.ComboInsertion && MouseMode != DraggingMode.EdgeInsertion; // These decorators are exactly the same as the default ones, but they use my LineWidth fix (see DNode.cs). // Once the LineWidth bug in MSAGL is fixed, we should remove these. DrawingLayoutEditor.DecorateObjectForDragging = DecorateObjectForDragging; DrawingLayoutEditor.RemoveObjDraggingDecorations = RemoveObjDraggingDecorations; EdgeRoutingMode = EdgeRoutingMode.Spline; MouseMode = DefaultMouseMode = DraggingMode.Pan; BeginContentEdit = DefaultBeginContentEdit; //EndContentEdit = DefaultEndContentEdit; MouseLeftButtonDoubleClick += new EventHandler<MsaglMouseEventArgs>(DGraph_MouseLeftButtonDoubleClick); Clear(); }
private void BeginNextLayout() { if (--count > 0) { return; } if (!m_LayoutQueue.Any()) { m_Graph.Dispatcher.BeginInvoke((Action)(() => m_Graph.BeginLayout(true))); return; } DNestedGraphLabel l = m_LayoutQueue.Dequeue(); count = 0; foreach (DGraph graph in l.Graphs) { count++; graph.GraphLayoutDone += SubGraphLayoutDone; graph.Dispatcher.BeginInvoke(() => graph.BeginLayout(true)); } }
/// <summary> /// Creates an auxilliary geometry graph, which contains all the nodes of a flattened nested graph. Produces a map from the original graph nodes to the auxilliary graph nodes. /// </summary> /// <param name="gg">The auxilliary graph to be filled.</param> /// <param name="graph">The original graph.</param> /// <param name="offset">Offset to be applied to all nodes.</param> /// <param name="connectedNodes">Map from original graph nodes to auxilliary graph nodes.</param> private static void FillAuxGraph(GeometryGraph gg, DGraph graph, GeometryPoint offset, Dictionary <DNode, GeometryNode> connectedNodes) { foreach (DNode n in graph.Nodes()) { GeometryNode clone = new GeometryNode(n.GeometryNode.BoundaryCurve.Clone()); clone.BoundaryCurve.Translate(offset); gg.Nodes.Add(clone); connectedNodes[n] = clone; DNestedGraphLabel ngLabel = n.Label as DNestedGraphLabel; if (ngLabel != null) { GeometryPoint labelPosition = new GeometryPoint(Canvas.GetLeft(ngLabel), Canvas.GetTop(ngLabel)); foreach (DGraph dg in ngLabel.Graphs) { Point p = ngLabel.GetDGraphOffset(dg); GeometryPoint offsetToLabel = new GeometryPoint(p.X, p.Y); GeometryPoint graphOffset = labelPosition + offsetToLabel; GeometryPoint normalizedOffset = graphOffset - dg.Graph.BoundingBox.LeftBottom; FillAuxGraph(gg, dg, offset + normalizedOffset, connectedNodes); } } } }