// invalidate the Diagram.Layout if node/link added/removed, // and remove any cached ForceDirectedNetwork public override void InvalidateLayout(Part p, LayoutChange change) { if (this.IsLayingOut) { return; } if (this.SkipsInvalidate) { return; } if (this.Diagram == null) { return; } if (p == null || p.Layer == null || p.Layer.IsTemporary) { return; } var cfdlayout = this.Diagram.Layout as ContinuousForceDirectedLayout; if (cfdlayout != null && (change == LayoutChange.NodeAdded || change == LayoutChange.NodeRemoved || change == LayoutChange.LinkAdded || change == LayoutChange.LinkRemoved)) { cfdlayout.ValidLayout = false; cfdlayout.Network = null; } else { base.InvalidateLayout(p, change); } }
/// <summary> /// Declare that this layout may be invalid, for a given reason. /// </summary> /// <param name="reason">a <see cref="LayoutChange"/> hint</param> /// <param name="part">the <see cref="Northwoods.GoXam.Part"/> that changed</param> /// <remarks> /// For each layout in <see cref="Layouts"/> in which the given part participates, /// call <see cref="IDiagramLayout.Invalidate"/> with the same arguments. /// </remarks> public void Invalidate(LayoutChange reason, Part part) { foreach (IDiagramLayout layout in this.Layouts) { if (reason == LayoutChange.All || layout.CanLayoutPart(part)) { layout.Invalidate(reason, part); } } }
/// <summary> /// Declare that the <see cref="IDiagramLayout"/> including a given <see cref="Part"/> /// is now invalid and may need to be performed again soon. /// </summary> /// <param name="p">must be a <see cref="Part"/></param> /// <param name="change"> /// a hint on the reason for the need for a new layout; /// this is used to decide whether a layout is really needed. /// </param> /// <remarks> /// <para> /// This is called by the diagram's <see cref="PartManager"/> each time /// a node or link or group-membership is added or removed. /// It calls <see cref="IDiagramLayout.Invalidate"/> to let the part's /// responsible <see cref="IDiagramLayout"/> know that there's been a change /// and that the layout may need to be performed again, depending on /// the layout's <see cref="DiagramLayout.Conditions"/>. /// </para> /// <para> /// This method ignores parts in temporary layers. /// This method also does nothing if <see cref="SkipsInvalidate"/> is true /// or if the <see cref="Northwoods.GoXam.Diagram.Model"/>'s /// <see cref="IDiagramModel.SkipsUndoManager"/> property is true. /// </para> /// </remarks> public virtual void InvalidateLayout(Part p, LayoutChange change) { // ignore any invalidations during a layout if (this.IsLayingOut) { return; } // ignore any invalidations during a rebuild (replaced NodesSource or replaced Model or changed templates) if (this.SkipsInvalidate) { return; } // ignore any position changes during animation if (change == LayoutChange.NodeLocationChanged && this.IsAnimating) { return; } // ignore temporary objects if (p != null && (p.Layer == null || p.Layer.IsTemporary)) { return; } Diagram diagram = this.Diagram; if (diagram == null) { return; } // invalidate the layout for the part IDiagramLayout layout; if (p != null) { if ((change == LayoutChange.MemberAdded || change == LayoutChange.MemberRemoved) && p is Group) { layout = ((Group)p).Layout; } else { layout = GetLayoutBy(p); } } else { layout = diagram.Layout; } //if (change != LayoutChange.NodeLocationChanged && change != LayoutChange.NodeSizeChanged && change != LayoutChange.GroupSizeChanged && !(diagram is Palette)) // Diagram.Debug("LayoutManager.InvalidateLayout: " + Diagram.Str(p) + " " + change.ToString() + " in " + (layout == null ? "(no layout)" : (layout.Group == null ? "(diagram)" : Diagram.Str(layout.Group)))); if (layout != null) { layout.Invalidate(change, p); } }
/// <summary> /// Declare that this layout might no longer be valid, depending on the change and the <see cref="Conditions"/>. /// </summary> /// <param name="reason"> /// A <see cref="LayoutChange"/> hint describing what change may have made the layout invalid. /// If the value is <see cref="LayoutChange.All"/>, <see cref="ValidLayout"/> will be set to false unconditionally. /// </param> /// <param name="part"> /// the <see cref="Northwoods.GoXam.Part"/> that has changed /// </param> /// <remarks> /// This method may set <see cref="ValidLayout"/> to false, if the <see cref="Conditions"/> are met. /// This method does not request a new layout -- call <see cref="InvalidateLayout"/> if /// you want to unconditionally set <see cref="ValidLayout"/> to false and ask the /// <see cref="LayoutManager"/> to schedule perform layouts that are invalid. /// </remarks> /// <seealso cref="InvalidateLayout"/> public virtual void Invalidate(LayoutChange reason, Part part) { if (!this.ValidLayout) return; // no Part needed for these two cases: if (reason == LayoutChange.All) { this.ValidLayout = false; return; } // don't care any more? if (this.InitialLayoutCompleted) return; if ((reason&this.Conditions&LayoutChange.DiagramLayoutChanged) == LayoutChange.DiagramLayoutChanged) { this.ValidLayout = false; return; } // now require a Part if (part == null) return; // the rest of the LayoutChanges involve a particular Part Node node = part as Node; if (node != null) { Layer layer = node.Layer; if (layer != null && !layer.IsTemporary) { if ((reason&this.Conditions&LayoutChange.NodeLocationChanged) == LayoutChange.NodeLocationChanged) { if (!node.IsLinkLabel) { this.ValidLayout = false; } } else if ((reason&this.Conditions&LayoutChange.NodeSizeChanged) == LayoutChange.NodeSizeChanged) { if (!node.IsLinkLabel) { this.ValidLayout = false; } } else if ((reason&this.Conditions&LayoutChange.GroupSizeChanged) == LayoutChange.GroupSizeChanged) { if (node is Group) { this.ValidLayout = false; } } else if ((reason&this.Conditions&LayoutChange.NodeAdded) == LayoutChange.NodeAdded) { this.ValidLayout = false; } else if ((reason&this.Conditions&LayoutChange.NodeRemoved) == LayoutChange.NodeRemoved) { this.ValidLayout = false; } else if ((reason&this.Conditions&LayoutChange.MemberAdded) == LayoutChange.MemberAdded) { this.ValidLayout = false; } else if ((reason&this.Conditions&LayoutChange.MemberRemoved) == LayoutChange.MemberRemoved) { this.ValidLayout = false; } else if ((reason&this.Conditions&LayoutChange.GroupLayoutChanged) == LayoutChange.GroupLayoutChanged) { this.ValidLayout = false; } else if ((reason&this.Conditions&LayoutChange.VisibleChanged) == LayoutChange.VisibleChanged) { this.ValidLayout = false; } } } else { Link link = part as Link; if (link != null) { Layer layer = link.Layer; if (layer != null && !layer.IsTemporary) { if ((reason&this.Conditions&LayoutChange.LinkAdded) == LayoutChange.LinkAdded) { this.ValidLayout = false; } else if ((reason&this.Conditions&LayoutChange.LinkRemoved) == LayoutChange.LinkRemoved) { this.ValidLayout = false; } else if ((reason&this.Conditions&LayoutChange.VisibleChanged) == LayoutChange.VisibleChanged) { this.ValidLayout = false; } } } } }
/// <summary> /// Declare that the <see cref="IDiagramLayout"/> including a given <see cref="Part"/> /// is now invalid and may need to be performed again soon. /// </summary> /// <param name="p">must be a <see cref="Part"/></param> /// <param name="change"> /// a hint on the reason for the need for a new layout; /// this is used to decide whether a layout is really needed. /// </param> /// <remarks> /// <para> /// This is called by the diagram's <see cref="PartManager"/> each time /// a node or link or group-membership is added or removed. /// It calls <see cref="IDiagramLayout.Invalidate"/> to let the part's /// responsible <see cref="IDiagramLayout"/> know that there's been a change /// and that the layout may need to be performed again, depending on /// the layout's <see cref="DiagramLayout.Conditions"/>. /// </para> /// <para> /// This method ignores parts in temporary layers. /// This method also does nothing if <see cref="SkipsInvalidate"/> is true /// or if the <see cref="Northwoods.GoXam.Diagram.Model"/>'s /// <see cref="IDiagramModel.SkipsUndoManager"/> property is true. /// </para> /// </remarks> public virtual void InvalidateLayout(Part p, LayoutChange change) { // ignore any invalidations during a layout if (this.IsLayingOut) return; // ignore any invalidations during a rebuild (replaced NodesSource or replaced Model or changed templates) if (this.SkipsInvalidate) return; // ignore any position changes during animation if (change == LayoutChange.NodeLocationChanged && this.IsAnimating) return; // ignore temporary objects if (p != null && (p.Layer == null || p.Layer.IsTemporary)) return; Diagram diagram = this.Diagram; if (diagram == null) return; // invalidate the layout for the part IDiagramLayout layout; if (p != null) { if ((change == LayoutChange.MemberAdded || change == LayoutChange.MemberRemoved) && p is Group) { layout = ((Group)p).Layout; } else { layout = GetLayoutBy(p); } } else { layout = diagram.Layout; } //if (change != LayoutChange.NodeLocationChanged && change != LayoutChange.NodeSizeChanged && change != LayoutChange.GroupSizeChanged && !(diagram is Palette)) // Diagram.Debug("LayoutManager.InvalidateLayout: " + Diagram.Str(p) + " " + change.ToString() + " in " + (layout == null ? "(no layout)" : (layout.Group == null ? "(diagram)" : Diagram.Str(layout.Group)))); if (layout != null) layout.Invalidate(change, p); }
// invalidate the Diagram.Layout when reparenting a part to or from top-level private void InvalidateDiagramLayout(Part p, LayoutChange why) { Diagram diagram = this.Diagram; if (diagram == null) return; // no side-effects during undo/redo IDiagramModel model = diagram.Model; if (model != null && model.IsChangingModel) return; if (p != null && (p.Layer == null || p.Layer.IsTemporary)) return; LayoutManager laymgr = diagram.LayoutManager; if (laymgr != null) laymgr.InvalidateLayout(null, LayoutChange.All); }
/// <summary> /// Declare that this layout might no longer be valid, depending on the change and the <see cref="Conditions"/>. /// </summary> /// <param name="reason"> /// A <see cref="LayoutChange"/> hint describing what change may have made the layout invalid. /// If the value is <see cref="LayoutChange.All"/>, <see cref="ValidLayout"/> will be set to false unconditionally. /// </param> /// <param name="part"> /// the <see cref="Northwoods.GoXam.Part"/> that has changed /// </param> /// <remarks> /// This method may set <see cref="ValidLayout"/> to false, if the <see cref="Conditions"/> are met. /// This method does not request a new layout -- call <see cref="InvalidateLayout"/> if /// you want to unconditionally set <see cref="ValidLayout"/> to false and ask the /// <see cref="LayoutManager"/> to schedule perform layouts that are invalid. /// </remarks> /// <seealso cref="InvalidateLayout"/> public virtual void Invalidate(LayoutChange reason, Part part) { if (!this.ValidLayout) { return; } // no Part needed for this cases: if (reason == LayoutChange.All) { this.ValidLayout = false; return; } // don't care any more? if (this.InitialLayoutCompleted) { return; } // no Part needed for these cases: if ((reason & this.Conditions & LayoutChange.DiagramLayoutChanged) == LayoutChange.DiagramLayoutChanged || (reason & this.Conditions & LayoutChange.ViewportSizeChanged) == LayoutChange.ViewportSizeChanged) { this.ValidLayout = false; return; } // now require a Part if (part == null) { return; } // the rest of the LayoutChanges involve a particular Part Node node = part as Node; if (node != null) { Layer layer = node.Layer; if (layer != null && !layer.IsTemporary) { if ((reason & this.Conditions & LayoutChange.NodeLocationChanged) == LayoutChange.NodeLocationChanged) { if (!node.IsLinkLabel) { this.ValidLayout = false; } } else if ((reason & this.Conditions & LayoutChange.NodeSizeChanged) == LayoutChange.NodeSizeChanged) { if (!node.IsLinkLabel) { this.ValidLayout = false; } } else if ((reason & this.Conditions & LayoutChange.GroupSizeChanged) == LayoutChange.GroupSizeChanged) { if (node is Group) { this.ValidLayout = false; } } else if ((reason & this.Conditions & LayoutChange.NodeAdded) == LayoutChange.NodeAdded) { this.ValidLayout = false; } else if ((reason & this.Conditions & LayoutChange.NodeRemoved) == LayoutChange.NodeRemoved) { this.ValidLayout = false; } else if ((reason & this.Conditions & LayoutChange.MemberAdded) == LayoutChange.MemberAdded) { this.ValidLayout = false; } else if ((reason & this.Conditions & LayoutChange.MemberRemoved) == LayoutChange.MemberRemoved) { this.ValidLayout = false; } else if ((reason & this.Conditions & LayoutChange.GroupLayoutChanged) == LayoutChange.GroupLayoutChanged) { this.ValidLayout = false; } else if ((reason & this.Conditions & LayoutChange.VisibleChanged) == LayoutChange.VisibleChanged) { this.ValidLayout = false; } } } else { Link link = part as Link; if (link != null) { Layer layer = link.Layer; if (layer != null && !layer.IsTemporary) { if ((reason & this.Conditions & LayoutChange.LinkAdded) == LayoutChange.LinkAdded) { this.ValidLayout = false; } else if ((reason & this.Conditions & LayoutChange.LinkRemoved) == LayoutChange.LinkRemoved) { this.ValidLayout = false; } else if ((reason & this.Conditions & LayoutChange.VisibleChanged) == LayoutChange.VisibleChanged) { this.ValidLayout = false; } } } } }
public bool Has(LayoutChange layoutChange) { return (this | layoutChange) == this; }