/// <summary> /// Sets the location of this item and propagates it to the hosted shape element if allowed. /// </summary> /// <param name="proposedLocation">Location to apply.</param> /// <param name="bResizeParentIfRequired">Resize parent if required.</param> /// <remarks> /// This function needs to be called withing a modeling transaction. /// </remarks> public virtual void SetLocation(PointD proposedLocation, bool bResizeParentIfRequired) { PointD newLocation = proposedLocation; if (this.IsRelativeChildShape) { // correct the proposed location if (this.MovementBehaviour == ShapeMovementBehaviour.PositionOnEdgeOfParent) { if (this.Parent != null) { newLocation = NodeShape.CorrectPortLocation(this.Parent, this, proposedLocation); } } } PointD oldLocation = this.Location; this.Location = newLocation; this.UpdateAbsoluteLocation(); if (bResizeParentIfRequired) { this.ResizeParentIfRequired(); } }
/// <summary> /// Adds a proto element to the current element. /// </summary> /// <param name="protoElement">Proto element representation of the element that is to be added.</param> /// <param name="groupMerger"> /// Group merger class used to track id mapping, merge errors/warnings and /// postprocess merging by rebuilding reference relationships. /// </param> /// <param name="isRoot">Root element?</param> public virtual void ModelMerge(ModelProtoElement protoElement, ModelProtoGroupMerger groupMerger, bool isRoot) { if (protoElement.CustomArguments is DiagramModelMergeOptions) { DiagramModelMergeOptions options = protoElement.CustomArguments as DiagramModelMergeOptions; Guid elementID = options.ElementId; ModelProtoElement elementP = groupMerger.GetElementById(elementID); if (elementP != null) { (this.Element as IModelMergeElements).ModelMerge(elementP, groupMerger, isRoot); } ModelElement copiedElement = this.Store.ElementDirectory.FindElement(groupMerger.GetIdMapping(options.ElementId)); // create shape for that element this.FixUpMissingShapes(); NodeShape shape = DiagramHelper.FindShape(this.Store, options.ShapeDomainClassId, copiedElement.Id) as NodeShape; if (shape != null) { groupMerger.SetIdMapping(protoElement.ElementId, shape.Id); } } }
/// <summary> /// Finalize. This method is called on each copied element once all the elements and links are processed. /// </summary> /// <param name="protoElement">Proto element representation of the element that is to be added.</param> /// <param name="groupMerger"> /// Group merger class used to track id mapping, merge errors/warnings and /// postprocess merging by rebuilding reference relationships. /// </param> public virtual void ModelFinalize(ModelProtoElement protoElement, ModelProtoGroupMerger groupMerger) { if (protoElement.CustomArguments is DiagramModelMergeOptions) { DiagramModelMergeOptions options = protoElement.CustomArguments as DiagramModelMergeOptions; Guid elementID = options.ElementId; ModelProtoElement elementP = groupMerger.GetElementById(elementID); if (elementP != null) { (this.Element as IModelMergeElements).ModelFinalize(elementP, groupMerger); } NodeShape shape = this.Store.ElementDirectory.FindElement( groupMerger.GetIdMapping(protoElement.ElementId)) as NodeShape; // restore layout Store store = new Microsoft.VisualStudio.Modeling.Store(typeof(DiagramsDSLDomainModel)); LayoutInfo info; using (Transaction t = store.TransactionManager.BeginTransaction()) { info = options.GetLayoutInfo(store); t.Commit(); } LayoutHelper.ApplyLayout(this, this.Diagram, info); store.Dispose(); if (!shape.IsRelativeChildShape) { shape.SetLocation(new PointD(RelativePastePoint.X + options.RelativeLocation.X, RelativePastePoint.Y + options.RelativeLocation.Y)); } } }
/// <summary> /// Called whenever a child element is added to a diagram. /// </summary> /// <param name="e"></param> public override void ElementAdded(ElementAddedEventArgs e) { base.ElementAdded(e); DiagramHasChildren con = e.ModelElement as DiagramHasChildren; if (con != null) { NodeShape nodeShape = con.ChildShape; Diagram diagram = con.Diagram; if (nodeShape != null && diagram != null) { if (nodeShape.IsDeleted) { return; } diagram.AddToShapeMapping(nodeShape); if (nodeShape.Location == PointD.Empty) { nodeShape.SetAtFreePositionOnParent(); } } else { con.Delete(); } } }
private static void ProcessNodeShape(NodeShape shapeElement, LinkedElementCollection <NodeShapeInfo> infos) { // try to find NodeShapeInfo for shape element NodeShapeInfo info = null; foreach (NodeShapeInfo i in infos) { if (i.ElementId == shapeElement.Element.Id) { info = i; break; } } if (info == null) { shapeElement.UpdateAbsoluteLocation(); return; } shapeElement.Size = info.Size; shapeElement.SetLocation(info.RelativeLocation); // children foreach (NodeShape shape in shapeElement.Children) { ProcessNodeShape(shape, info.ChildrenInfos); } }
/// <summary> /// Correct children. /// </summary> public virtual bool CorrectChildren() { bool bRet = false; for (int i = this.Children.Count - 1; i >= 0; i--) { NodeShape shape = this.Children[i]; if (!this.CanHostShape(shape.GetDomainClassId())) { shape.Delete(); bRet = true; } else if (shape.CorrectChildren()) { bRet = true; } } foreach (Diagram d in this.IncludedDiagrams) { if (d.CorrectChildren()) { bRet = true; } } return(bRet); }
/// <summary> /// Calculates an allowed position based on the given proposed position. The Idea behind this is /// to correct the proposed position if we are within an target elements border. /// </summary> /// <param name="targetShape">Target shape.</param> /// <param name="proposedPosition">Proposed position.</param> /// <returns>Corrected position.</returns> public virtual PointD CalculateAllowedPosition(NodeShape targetShape, PointD proposedPosition) { PointD position = proposedPosition; RectangleD absoluteBounds = targetShape.AbsoluteBounds; if (position.Y > absoluteBounds.Top - ConnectorHeight && position.Y < absoluteBounds.Top + ConnectorHeight) { position.Y = absoluteBounds.Top; } else if (position.Y > absoluteBounds.Bottom - ConnectorHeight && position.Y < absoluteBounds.Bottom + ConnectorHeight) { position.Y = absoluteBounds.Bottom; } if (position.X > absoluteBounds.Left - ConnectorWidth && position.X < absoluteBounds.Left + ConnectorWidth) { position.X = absoluteBounds.Left; } else if (position.X > absoluteBounds.Right - ConnectorWidth && position.X < absoluteBounds.Right + ConnectorWidth) { position.X = absoluteBounds.Right; } return(position); }
public override void ElementAdded(ElementAddedEventArgs e) { ShapeElementContainsChildShapes con = e.ModelElement as ShapeElementContainsChildShapes; if (con != null) { NodeShape childShape = con.ChildShape; NodeShape parentShape = con.ParentShape; if (childShape != null && parentShape != null) { if (childShape.IsDeleted) { return; } if (parentShape.IsDeleted) { return; } parentShape.AddToShapeMapping(childShape); childShape.UpdateAbsoluteLocation(); if (childShape.Location == PointD.Empty) { childShape.SetAtFreePositionOnParent(); } } else { con.Delete(); } } }
/// <summary> /// Verifies if the position of the specified shape is acceptable. /// </summary> /// <param name="shape">Node shape.</param> public static bool IsShapePositionAcceptable(NodeShape shape) { if (!shape.IsRelativeChildShape) { if (shape.Parent != null) { if (shape.AbsoluteLocation.X < shape.Parent.AbsoluteLocation.X || shape.AbsoluteLocation.Y < shape.Parent.AbsoluteLocation.Y || shape.AbsoluteBounds.Right > shape.Parent.AbsoluteBounds.Right || shape.AbsoluteBounds.Bottom > shape.Parent.AbsoluteBounds.Bottom) { return(false); } } } else if (shape.Parent != null) { PointD location = NodeShape.CorrectPortLocation(shape.Parent, shape, shape.AbsoluteLocation); if (location != shape.AbsoluteLocation) { return(false); } } return(true); }
public override void ElementDeleting(ElementDeletingEventArgs e) { base.ElementDeleting(e); NodeShape nodeShape = e.ModelElement as NodeShape; if (nodeShape != null) { if (nodeShape.SourceAnchors.Count > 0) { for (int i = nodeShape.SourceAnchors.Count - 1; i >= 0; i--) { if (nodeShape.SourceAnchors[i].LinkShape != null) { nodeShape.SourceAnchors[i].LinkShape.Delete(); } } } if (nodeShape.TargetAnchors.Count > 0) { for (int i = nodeShape.TargetAnchors.Count - 1; i >= 0; i--) { if (nodeShape.TargetAnchors[i].LinkShape != null) { nodeShape.TargetAnchors[i].LinkShape.Delete(); } } } } }
/* * /// <summary> * /// Tries to find a free position on parent and update the location of the shape to that location. * /// </summary> * /// <returns> * /// Coordinates of a free position. * /// </returns> * /// <remarks> * /// Needs to be called within a modeling transaction. * /// </remarks> * public virtual void SetAtFreePositionOnParent() * { * IList<NodeShape> shapes; * if (this.Parent == null) * { * // free position on diagram * Diagram diagram = this.Diagram; * shapes = diagram.Children; * } * else * { * if (this.IsRelativeChildShape) * { * float width = (float)this.Bounds.Width; * float height = (float)this.Bounds.Height; * * float parentWidth = (float)this.Parent.Bounds.Width; * float parentHeight = (float)this.Parent.Bounds.Height; * * Dictionary<PortPlacement, int> dict = new Dictionary<PortPlacement, int>(); * dict.Add(PortPlacement.Left, 0); * dict.Add(PortPlacement.Top, 0); * dict.Add(PortPlacement.Bottom, 0); * dict.Add(PortPlacement.Right, 0); * for (int i = 0; i < this.Parent.RelativeChildren.Count; i++) * { * if (this.Parent.RelativeChildren[i] == this) * continue; * * dict[this.Parent.RelativeChildren[i].PlacementSide]++; * } * List<KeyValuePair<PortPlacement, int>> myList = new List<KeyValuePair<PortPlacement, int>>(dict); * myList.Sort((firstPair, nextPair) => * { * return firstPair.Value.CompareTo(nextPair.Value); * }); * * foreach (KeyValuePair<PortPlacement, int> p in myList) * { * RectangleF rectH; * switch (p.Key) * { * case PortPlacement.Left: * rectH = new RectangleF(-width / 2, 0, width, parentHeight); * break; * * case PortPlacement.Top: * rectH = new RectangleF(0, -height / 2, parentWidth, height); * break; * * case PortPlacement.Right: * rectH = new RectangleF(parentWidth - width / 2, 0, width, parentHeight); * break; * * case PortPlacement.Bottom: * rectH = new RectangleF(0, parentHeight - height / 2, parentWidth, height); * break; * * default: * throw new NotSupportedException(); * } * * if (SetPortAtFreePositionOnParent(p.Key, rectH)) * { * return; * } * } * * this.SetLocation(NodeShape.CorrectPortLocation(this.Parent, this, new PointD(0, 0))); * return; * } * * // free position on parent shape * shapes = this.Parent.NestedChildren; * } * * // trivial algo.. TODO: find something good * RectangleF rect = new RectangleF(0, 0, (float)this.Size.Width, (float)this.Size.Height); * * // find area that is already filled * RectangleF completeBounds = new RectangleF(0, 0, 0, 0); * for (int i = 0; i < shapes.Count; i++) * { * if (shapes[i] == this) * continue; * * if (i == 0) * completeBounds = shapes[i].Bounds.ToRectangleF(); * else * { * RectangleF f = shapes[i].Bounds.ToRectangleF(); * if (completeBounds.X > f.X) * completeBounds.X = f.X; * if (completeBounds.Y > f.Y) * completeBounds.Y = f.Y; * * if (completeBounds.Right < f.Right) * completeBounds.Width = f.Right - completeBounds.X; * * if (completeBounds.Bottom < f.Bottom) * completeBounds.Height = f.Bottom - completeBounds.Y; * } * } * * /* * // see if we can insert shape somewhere in that area * // if not, add shape right at the edge of that area * for (int i = 0; i < shapes.Count; i++) * { * if (shapes[i] == this) * continue; * * // TODO ... (not necessaraly required) * } * * // could not add shape in the completeBounds are, so add it outside of it */ /* * if( completeBounds.Width < completeBounds.Height ) * this.SetLocation(new PointD(completeBounds.Right + 5, 5)); * else * this.SetLocation(new PointD(5, completeBounds.Bottom + 5)); * this.UpdateAbsoluteLocation(); * } * * private bool SetPortAtFreePositionOnParent(PortPlacement side, RectangleF freeRectangle) * { * List<RectangleF> freeRectangles = new List<RectangleF>(); * freeRectangles.Add(freeRectangle); * * for (int i = 0; i < this.Parent.RelativeChildren.Count; i++) * { * if (this.Parent.RelativeChildren[i] == this) * continue; * * if (this.Parent.RelativeChildren[i].PlacementSide != side) * continue; * * RectangleF s = this.Parent.RelativeChildren[i].Bounds.ToRectangleF(); * for (int y = freeRectangles.Count - 1; y >= 0; y--) * { * RectangleF r = freeRectangles[y]; * RectangleF t = r; * r.Intersect(s); * * if (!r.IsEmpty) * { * // remove r from freeRectangley[y] --> yields <=2 rects * // add 2 rects to freeRectangles * freeRectangles.RemoveAt(y); * * switch (side) * { * case PortPlacement.Left: * case PortPlacement.Right: * if (t.Y < r.Y) * { * // first r * RectangleF r1 = new RectangleF(t.X, t.Y, t.Width, r.Y - t.Y); * freeRectangles.Add(r1); * } * * if (r.Bottom < t.Bottom) * { * // second r * RectangleF r2 = new RectangleF(t.X, r.Bottom, t.Width, t.Bottom - r.Bottom); * freeRectangles.Add(r2); * } * break; * * case PortPlacement.Top: * case PortPlacement.Bottom: * if (t.X < r.X) * { * // first r * RectangleF r1 = new RectangleF(t.X, t.Y, r.X-t.X, t.Height); * freeRectangles.Add(r1); * } * * if (r.Right < t.Right) * { * // second r * RectangleF r2 = new RectangleF(r.Right, t.Y, t.Right-r.Right, t.Height); * freeRectangles.Add(r2); * } * break; * } * * } * } * } * * // try to place at a fitting free rectangle * foreach (RectangleF r in freeRectangles) * { * if (r.Width >= this.Bounds.Width && r.Height >= this.Bounds.Height) * { * this.Location = new PointD(r.X, r.Y); * this.PlacementSide = side; * this.UpdateAbsoluteLocation(); * return true; * } * } * * return false; * } */ /// <summary> /// Create missing shapes. /// </summary> public virtual void FixUpMissingShapes() { if (this.Element == null) { return; } DomainModelElement e = this.Element as DomainModelElement; IDomainModelServices topMost = e.GetDomainModelServices().TopMostService; DiagramDomainDataDirectory data = this.Store.DomainDataAdvDirectory.ResolveExtensionDirectory <DiagramDomainDataDirectory>(); List <EmbeddingRelationshipAdvancedInfo> infos = this.Store.DomainDataAdvDirectory.FindDomainClassSourceEmbeddings(e.GetDomainClassId()); if (infos != null) { foreach (EmbeddingRelationshipAdvancedInfo info in infos) { List <Guid> shapes = data.GetShapeTypesForElement(info.TargetElementDomainClassId); if (shapes == null) { continue; } if (shapes.Count == 0) { continue; } ReadOnlyCollection <ElementLink> instances = DomainRoleInfo.GetElementLinks <ElementLink>(this.Element, info.SourceRoleId); foreach (ElementLink link in instances) { DomainModelElement child = DomainRoleInfo.GetTargetRolePlayer(link) as DomainModelElement; if (child == null) { continue; } // see if we need to add shape foreach (Guid elementShapeId in data.GetShapeTypesForElement(child.GetDomainClassId(), this.GetDomainClassId())) { if (!DiagramHelper.IsElementDisplayedOn(this, elementShapeId, child.Id)) { NodeShape shape = topMost.ShapeProvider.CreateShapeForElement(elementShapeId, child) as NodeShape; if (shape.IsRelativeChildShape) { this.AddRelativeChild(shape); } else { this.AddNestedChild(shape); } shape.FixUpMissingShapes(); } } } } } }
public override void ElementAdded(ElementAddedEventArgs e) { NodeShape nodeShape = e.ModelElement as NodeShape; if (nodeShape != null) { //nodeShape.FixUpMissingLinkShapes(); } }
private static void UpdateAbsoluteLocation(NodeShape shapeElement) { shapeElement.UpdateAbsoluteLocation(); foreach (NodeShape shape in shapeElement.Children) { UpdateAbsoluteLocation(shape); } }
public static void ApplyLayout(NodeShape shapeElement, Diagram diagram, LayoutInfo layout) { // apply layout shapeElement.Size = layout.Size; // children foreach (NodeShape shape in shapeElement.Children) { ProcessNodeShape(shape, layout.ChildrenInfos); } RestoreLinkShapes(diagram, layout.LinkShapeInfos); }
/// <summary> /// Called whenever a model element is added to the store. /// </summary> /// <param name="sender">ViewModelStore</param> /// <param name="args">Event Arguments for notification of the creation of new model element.</param> private void OnElementAdded(object sender, ElementAddedEventArgs args) { if (!ModelData.DoSendModelEvents) { return; } // update shape mapping (this is required, becauso undo/redo does not trigger events) if (args.ModelElement is DiagramHasChildren) { DiagramHasChildren con = args.ModelElement as DiagramHasChildren; if (con != null) { NodeShape nodeShape = con.ChildShape; Diagram diagram = con.Diagram; if (nodeShape != null && diagram != null) { if (nodeShape.IsDeleted) { return; } diagram.AddToShapeMapping(nodeShape); } } } else if (args.ModelElement is ShapeElementContainsChildShapes) { ShapeElementContainsChildShapes con = args.ModelElement as ShapeElementContainsChildShapes; if (con != null) { NodeShape childShape = con.ChildShape; NodeShape parentShape = con.ParentShape; if (childShape != null && parentShape != null) { if (childShape.IsDeleted) { return; } if (parentShape.IsDeleted) { return; } parentShape.AddToShapeMapping(childShape); } } } }
public override void RolePlayerChanged(RolePlayerChangedEventArgs e) { ShapeElementContainsChildShapes con = e.ElementLink as ShapeElementContainsChildShapes; if (con == null) { return; } if (e.DomainRole.Id == ShapeElementContainsChildShapes.DomainClassId) { NodeShape childShape = con.ChildShape; NodeShape parentShapeOld = e.OldRolePlayer as NodeShape; NodeShape parentShapeNew = e.NewRolePlayer as NodeShape; // delete from old parent shape if (childShape != null && parentShapeOld != null) { if (childShape.IsDeleted) { return; } parentShapeOld.RemoveFromShapeMapping(childShape); } // add to new parent shape if (childShape != null && parentShapeNew != null) { if (childShape.IsDeleted) { return; } parentShapeNew.AddToShapeMapping(childShape); if (childShape.IsRelativeChildShape && childShape.MovementBehaviour == ShapeMovementBehaviour.PositionOnEdgeOfParent) { childShape.CorrectLocation(); } if (!childShape.IsRelativeChildShape) { childShape.ResizeParentIfRequired(); } } } }
/// <summary> /// Searches for the shape of a specific type hosting a specific element. /// </summary> /// <param name="store">Store.</param> /// <param name="shapeDomainClassType">Type of the shape.</param> /// <param name="elementId">Model element Id.</param> /// <returns>NodeShape if found. Null otherwise.</returns> public static NodeShape FindChildShape(NodeShape parentShape, Guid childShapeDomainClassType, Guid childId) { foreach (NodeShape shape in parentShape.Children) { if (shape.GetDomainClass().IsDerivedFrom(childShapeDomainClassType) && shape.Element != null) { if (shape.Element.Id == childId) { return(shape); } } } return(null); }
/// <summary> /// Verifies if a specific model element is already displayed as a child of the specific shape. /// </summary> /// <param name="parentShape">Parent shape.</param> /// <param name="childShapeDomainClassType">Type of the child shape.</param> /// <param name="childId">Id of the child element.</param> /// <returns>True of the child is hosted on the parent element (shapewise). False otherwise.</returns> public static bool IsElementDisplayedOn(NodeShape parentShape, Guid childShapeDomainClassType, Guid childId) { foreach (NodeShape shape in parentShape.Children) { if (shape.GetDomainClass().IsDerivedFrom(childShapeDomainClassType) && shape.Element != null) { if (shape.Element.Id == childId) { return(true); } } } return(false); }
private static NodeShapeInfo CreateNodeShapeInfo(NodeShape shapeElement, List<NodeShape> allShapes) { NodeShapeInfo info = new NodeShapeInfo(shapeElement.Store); info.ElementId = shapeElement.Element.Id; info.Size = shapeElement.Size; info.RelativeLocation = shapeElement.Location; foreach (NodeShape shape in shapeElement.Children) { allShapes.Add(shape); info.ChildrenInfos.Add(CreateNodeShapeInfo(shape, allShapes)); } return info; }
public static DiagramsModel GetDiagramsModel(NodeShape shapeElement) { Diagram d = shapeElement.Diagram; while (d != null) { if (d.DiagramsModel != null) { return(d.DiagramsModel); } d = d.ParentDiagram; } throw new InvalidOperationException("GetDiagramsModel: Could not find DiagramsModel!"); }
private static NodeShapeInfo CreateNodeShapeInfo(NodeShape shapeElement, List <NodeShape> allShapes) { NodeShapeInfo info = new NodeShapeInfo(shapeElement.Store); info.ElementId = shapeElement.Element.Id; info.Size = shapeElement.Size; info.RelativeLocation = shapeElement.Location; foreach (NodeShape shape in shapeElement.Children) { allShapes.Add(shape); info.ChildrenInfos.Add(CreateNodeShapeInfo(shape, allShapes)); } return(info); }
protected BaseDiagramItemElementViewModel(ViewModelStore viewModelStore, DiagramSurfaceViewModel diagram, NodeShape shapeElement) : base(viewModelStore, diagram, shapeElement) { this.itemLocation = shapeElement.Location; this.itemSize = shapeElement.Size; this.parentItem = null; this.nestedChildItems = new ObservableCollection<BaseDiagramItemElementViewModel>(); this.nestedChildItemsRO = new ReadOnlyObservableCollection<BaseDiagramItemElementViewModel>(nestedChildItems); this.relativeChildItems = new ObservableCollection<BaseDiagramItemElementViewModel>(); this.relativeChildItemsRO = new ReadOnlyObservableCollection<BaseDiagramItemElementViewModel>(relativeChildItems); Subscribe(); }
/// <summary> /// Called whenever a child element is deleted. /// </summary> /// <param name="e"></param> public override void ElementDeleted(ElementDeletedEventArgs e) { base.ElementDeleted(e); DiagramHasChildren con = e.ModelElement as DiagramHasChildren; if (con != null) { NodeShape nodeShape = con.ChildShape; Diagram diagram = con.Diagram; if (nodeShape != null && diagram != null) { diagram.RemoveFromShapeMapping(nodeShape); } } }
public override void ElementDeleted(ElementDeletedEventArgs e) { base.ElementDeleted(e); ShapeElementContainsChildShapes con = e.ModelElement as ShapeElementContainsChildShapes; if (con != null) { NodeShape childShape = con.ChildShape; NodeShape parentShape = con.ParentShape; if (childShape != null && parentShape != null) { parentShape.RemoveFromShapeMapping(childShape); } } }
/// <summary> /// Updates the absolute location of this shape and its child shapes. /// </summary> internal void UpdateAbsoluteLocation() { PointD location = new PointD(0, 0); NodeShape shape = this; while (shape != null) { location.X += shape.Location.X; location.Y += shape.Location.Y; shape = shape.Parent; } PointD oldAbsoluteLocation = this.AbsoluteLocation; UpdateAbsoluteLocation(location.X - this.AbsoluteLocation.X, location.Y - this.AbsoluteLocation.Y); }
/// <summary> /// Adds shapes for a given element. /// </summary> /// <param name="parent">Model element.</param> /// <param name="child"></param> internal void AddShapesForElement(DomainModelElement parent, DomainModelElement child) { if (parent == null || child == null) { return; } DiagramDomainDataDirectory data = child.Store.DomainDataAdvDirectory.ResolveExtensionDirectory <DiagramDomainDataDirectory>(); IDomainModelServices topMost = child.GetDomainModelServices().TopMostService; // find parent shapes List <Guid> shapeIds = DiagramsShapeStore.GetFromStore(parent.Id); if (shapeIds != null) { foreach (Guid shapeId in shapeIds) { // see if each parent shape has a child shape already added to it NodeShape parentShape = child.Store.ElementDirectory.FindElement(shapeId) as NodeShape; if (parentShape == null) { continue; } foreach (Guid elementShapeId in data.GetShapeTypesForElement(child.GetDomainClassId(), parentShape.GetDomainClassId())) { if (!DiagramHelper.IsElementDisplayedOn(parentShape, elementShapeId, child.Id)) { NodeShape shape = topMost.ShapeProvider.CreateShapeForElement(elementShapeId, child) as NodeShape; if (shape.IsRelativeChildShape) { parentShape.AddRelativeChild(shape); } else { parentShape.AddNestedChild(shape); } shape.SetAtFreePositionOnParent(); } } } } //AddRootShapesForElement(child, false); AddRootShapesForElement(child); }
public static LayoutInfo CreateLayoutInfo(NodeShape shapeElement, Diagram diagram) { // create new layout List<NodeShape> allShapes = new List<NodeShape>(); LayoutInfo l = new LayoutInfo(shapeElement.Store); l.HostElementId = shapeElement.Element.Id; l.Size = shapeElement.Size; foreach (NodeShape shape in shapeElement.Children) { allShapes.Add(shape); l.ChildrenInfos.Add(CreateNodeShapeInfo(shape, allShapes)); } ProcessDiagramsLinkShapes(diagram, allShapes, l); return l; }
public void DeleteShapesForElement(DomainModelElement modelElement) { if (modelElement != null) { List <Guid> shapes = DiagramsShapeStore.GetFromStore(modelElement.Id); if (shapes != null) { for (int i = shapes.Count - 1; i >= 0; i--) { NodeShape shape = modelElement.Store.ElementDirectory.FindElement(shapes[i]) as NodeShape; if (shape != null) { shape.Delete(); } } } } }
public static LayoutInfo CreateLayoutInfo(NodeShape shapeElement, Diagram diagram) { // create new layout List <NodeShape> allShapes = new List <NodeShape>(); LayoutInfo l = new LayoutInfo(shapeElement.Store); l.HostElementId = shapeElement.Element.Id; l.Size = shapeElement.Size; foreach (NodeShape shape in shapeElement.Children) { allShapes.Add(shape); l.ChildrenInfos.Add(CreateNodeShapeInfo(shape, allShapes)); } ProcessDiagramsLinkShapes(diagram, allShapes, l); return(l); }
public override void ElementAdded(ElementAddedEventArgs e) { NodeShapeReferencesNestedChildren con = e.ModelElement as NodeShapeReferencesNestedChildren; if (con != null) { NodeShape childShape = con.ChildShape; NodeShape parentShape = con.ParentShape; if (childShape != null && parentShape != null) { childShape.ResizeParentIfRequired(); } else { con.Delete(); } } }
public static void SaveLayout(NodeShape shapeElement, Diagram diagram) { DiagramsModel model = GetDiagramsModel(shapeElement); // see if there is already a layout for the given shape element foreach (LayoutInfo layout in model.LayoutInfos) if (layout.HostElementId == shapeElement.Element.Id) { // delete existing layout model.LayoutInfos.Remove(layout); break; } // create new layout List<NodeShape> allShapes = new List<NodeShape>(); LayoutInfo l = CreateLayoutInfo(shapeElement, diagram); model.LayoutInfos.Add(l); }
public static bool RestoreLayout(NodeShape shapeElement, Diagram diagram) { DiagramsModel model = GetDiagramsModel(shapeElement); foreach (LayoutInfo layout in model.LayoutInfos) { if (layout.HostElementId == shapeElement.Element.Id) { // apply layout ApplyLayout(shapeElement, diagram, layout); return(true); } } Tum.PDE.ToolFramework.Modeling.Diagrams.Layout.GleeLayouter.Layout(shapeElement); return(false); }
public virtual void AddRSShapesForElement(DomainModelElement sourceElement, DomainModelElement targetElement, ModelElement con, Guid shapeType) { List <Guid> shapeIdsSource = DiagramsShapeStore.GetFromStore(sourceElement.Id); List <Guid> shapeIdsTarget = DiagramsShapeStore.GetFromStore(targetElement.Id); if (shapeIdsSource == null || shapeIdsTarget == null) { return; } if (shapeIdsSource.Count == 0 || shapeIdsTarget.Count == 0) { return; } IDomainModelServices topMost = sourceElement.GetDomainModelServices().TopMostService; foreach (Guid sourceShapeId in shapeIdsSource) { NodeShape sourceShape = con.Store.ElementDirectory.FindElement(sourceShapeId) as NodeShape; if (sourceShape == null) { continue; } foreach (Guid targetShapeId in shapeIdsTarget) { NodeShape targetShape = con.Store.ElementDirectory.FindElement(targetShapeId) as NodeShape; if (targetShape != null) { if (sourceShape.Diagram == targetShape.Diagram) { if (!DiagramHelper.IsLinkDisplayedOn(sourceShape.Diagram, shapeType, con.Id, sourceShape.Id, targetShape.Id)) { LinkShape shape = topMost.ShapeProvider.CreateShapeForElementLink(shapeType, con, sourceShape, targetShape) as LinkShape; sourceShape.Diagram.LinkShapes.Add(shape); shape.Layout(FixedGeometryPoints.None); } } } } } }
public static void SaveLayout(NodeShape shapeElement, Diagram diagram) { DiagramsModel model = GetDiagramsModel(shapeElement); // see if there is already a layout for the given shape element foreach (LayoutInfo layout in model.LayoutInfos) { if (layout.HostElementId == shapeElement.Element.Id) { // delete existing layout model.LayoutInfos.Remove(layout); break; } } // create new layout List <NodeShape> allShapes = new List <NodeShape>(); LayoutInfo l = CreateLayoutInfo(shapeElement, diagram); model.LayoutInfos.Add(l); }
public static void SetMainShape(GraphicalDependencyLinkShape element, NodeShape newNodeShape) { DslModeling::DomainRoleInfo.SetLinkedElement(element, GraphicalDependencyLinkShapeDomainRoleId, newNodeShape); }
public static GraphicalDependenciesDiagram GetGraphicalDependenciesDiagram(NodeShape element) { return DslModeling::DomainRoleInfo.GetLinkedElement(element, NodeShapeDomainRoleId) as GraphicalDependenciesDiagram; }
/// <summary> /// Constructor /// Creates a GraphicalDependenciesDiagramReferencesMainElementShape link in the same Partition as the given GraphicalDependenciesDiagram /// </summary> /// <param name="source">GraphicalDependenciesDiagram to use as the source of the relationship.</param> /// <param name="target">NodeShape to use as the target of the relationship.</param> public GraphicalDependenciesDiagramReferencesMainElementShape(GraphicalDependenciesDiagram source, NodeShape target) : base((source != null ? source.Partition : null), new DslModeling::RoleAssignment[]{new DslModeling::RoleAssignment(GraphicalDependenciesDiagramReferencesMainElementShape.GraphicalDependenciesDiagramDomainRoleId, source), new DslModeling::RoleAssignment(GraphicalDependenciesDiagramReferencesMainElementShape.NodeShapeDomainRoleId, target)}, null) { }
/// <summary> /// Calculates a path geometry between the source and the target point. /// </summary> /// <param name="proposedSourcePoint">Source point (Absolute location).</param> /// <param name="targetShape">Target shape.</param> /// <param name="proposedTargetPoint">Target point (Absolute location).</param> /// <param name="fixedPoints">Fixed points.</param> /// <returns>Calculated path geometry.</returns> public virtual List<PointD> CalcPath(PointD proposedSourcePoint, NodeShape targetShape, PointD proposedTargetPoint, FixedGeometryPoints fixedPoints) { PointD sourcePoint = proposedSourcePoint; PointD targetPoint = proposedTargetPoint; if (fixedPoints != FixedGeometryPoints.SourceAndTarget && fixedPoints != FixedGeometryPoints.Source) { // calculate allowed source position // TODO } if (fixedPoints != FixedGeometryPoints.SourceAndTarget && fixedPoints != FixedGeometryPoints.Target) { // calculate allowed target position targetPoint = CalculateAllowedPosition(targetShape, proposedTargetPoint); } List<PointD> edgePoints = CalculatePath(sourcePoint, targetPoint); return edgePoints; }
/// <summary> /// This function corrects the given proposed location if the given child shape is a relative shape and /// is only allowed to be placed on the edge of its parent. /// </summary> /// <param name="parentShape">Parent shape.</param> /// <param name="childShape">Child shape.</param> /// <param name="proposedLocation">Proposed location.</param> /// <remarks> /// This function needs to be called withing a modeling transaction. /// /// This function assigns new values to Location and PortPlacement if necessary. /// </remarks> /// <returns> /// Location that was assigned to the shape. It might have the same value as the location /// the shape had before calling this function. /// </returns> public static PointD CorrectPortLocation(NodeShape parentShape, NodeShape childShape, PointD proposedLocation) { if (parentShape == null) throw new ArgumentNullException("parentShape"); if (childShape == null) throw new ArgumentNullException("childShape"); if (!childShape.IsRelativeChildShape || childShape.MovementBehaviour != ShapeMovementBehaviour.PositionOnEdgeOfParent) return proposedLocation; RectangleD rectParent = parentShape.Bounds; RectangleD proposedBounds = new RectangleD(proposedLocation, childShape.Size); PortPlacement placement = NodeShape.GetPortPlacement(rectParent, proposedBounds); return CorrectPortLocation(placement, parentShape, childShape, proposedLocation); }
public GraphicalDependencyItemViewModel(ViewModelStore viewModelStore, GraphicalDependenciesViewModel diagram, NodeShape shapeElement) : base(viewModelStore, diagram, shapeElement) { }
private static void ProcessNodeShape(NodeShape shapeElement, LinkedElementCollection<NodeShapeInfo> infos) { // try to find NodeShapeInfo for shape element NodeShapeInfo info = null; foreach (NodeShapeInfo i in infos) { if (i.ElementId == shapeElement.Element.Id) { info = i; break; } } if (info == null) { shapeElement.UpdateAbsoluteLocation(); return; } shapeElement.Size = info.Size; shapeElement.SetLocation(info.RelativeLocation); // children foreach (NodeShape shape in shapeElement.Children) { ProcessNodeShape(shape, info.ChildrenInfos); } }
public static DslModeling::LinkedElementCollection<GraphicalDependencyLinkShape> GetLinkShape(NodeShape element) { return GetRoleCollection<DslModeling::LinkedElementCollection<GraphicalDependencyLinkShape>, GraphicalDependencyLinkShape>(element, NodeShapeDomainRoleId); }
/// <summary> /// Constructor /// Creates a ShapeElementContainsChildShapes link in the same Partition as the given NodeShape /// </summary> /// <param name="source">NodeShape to use as the source of the relationship.</param> /// <param name="target">NodeShape to use as the target of the relationship.</param> public ShapeElementContainsChildShapes(NodeShape source, NodeShape target) : base((source != null ? source.Partition : null), new DslModeling::RoleAssignment[]{new DslModeling::RoleAssignment(ShapeElementContainsChildShapes.ParentShapeDomainRoleId, source), new DslModeling::RoleAssignment(ShapeElementContainsChildShapes.ChildShapeDomainRoleId, target)}, null) { }
/// <summary> /// Adds a nested child. /// </summary> /// <param name="shape">Shape to add as a nested child.</param> public void AddNestedChild(NodeShape shape) { this.InternalChildren.Add(shape); this.NestedChildren.Add(shape); }
/// <summary> /// Adds a relative child. /// </summary> /// <param name="shape">Shape to add as a relative child.</param> public void AddRelativeChild(NodeShape shape) { this.InternalChildren.Add(shape); this.RelativeChildren.Add(shape); }
public static DiagramsModel GetDiagramsModel(NodeShape shapeElement) { Diagram d = shapeElement.Diagram; while(d != null) { if( d.DiagramsModel != null ) return d.DiagramsModel; d = d.ParentDiagram; } throw new InvalidOperationException("GetDiagramsModel: Could not find DiagramsModel!"); }
/// <summary> /// Calculates an allowed position based on the given proposed position. The Idea behind this is /// to correct the proposed position if we are within an target elements border. /// </summary> /// <param name="targetShape">Target shape.</param> /// <param name="proposedPosition">Proposed position.</param> /// <returns>Corrected position.</returns> public virtual PointD CalculateAllowedPosition(NodeShape targetShape, PointD proposedPosition) { PointD position = proposedPosition; RectangleD absoluteBounds = targetShape.AbsoluteBounds; if (position.Y > absoluteBounds.Top - ConnectorHeight && position.Y < absoluteBounds.Top + ConnectorHeight) { position.Y = absoluteBounds.Top; } else if (position.Y > absoluteBounds.Bottom - ConnectorHeight && position.Y < absoluteBounds.Bottom + ConnectorHeight) { position.Y = absoluteBounds.Bottom; } if (position.X > absoluteBounds.Left - ConnectorWidth && position.X < absoluteBounds.Left + ConnectorWidth) { position.X = absoluteBounds.Left; } else if (position.X > absoluteBounds.Right - ConnectorWidth && position.X < absoluteBounds.Right + ConnectorWidth) { position.X = absoluteBounds.Right; } return position; }
/// <summary> /// Creates missing links for the added shape. /// </summary> /// <param name="shapeAdded">Shape added.</param> public virtual void FixUpMissingLinkShapes(NodeShape shapeAdded) { DiagramDomainDataDirectory data = this.Store.DomainDataAdvDirectory.ResolveExtensionDirectory<DiagramDomainDataDirectory>(); if (data == null) throw new ArgumentNullException("DiagramDomainDataDirectory can not be null"); ShapeClassInfo info; data.ShapeClassInfos.TryGetValue(shapeAdded.GetDomainClass().Id, out info); if (info == null) return; ModelLinkAddRuleForRSShapes.RSShapesFactoryHelper factory = this.GetRSShapesFactoryHelper(); ModelLinkAddRuleForMappingRSShapes.RSShapesFactoryHelper factoryMapping = this.GetMappingRSShapesFactoryHelper(); if (factory != null) { if (info.RelationshipSourceRoleTypes.Count > 0) foreach (Guid rel in info.RelationshipSourceRoleTypes) { ReadOnlyCollection<DomainModelLink> links = DomainRoleInfo.GetElementLinks<DomainModelLink>(shapeAdded.Element, rel); foreach (DomainModelLink link in links) factory.AddRSShapesForElement(link); } if (info.RelationshipTargetRoleTypes.Count > 0) foreach (Guid rel in info.RelationshipTargetRoleTypes) { ReadOnlyCollection<DomainModelLink> links = DomainRoleInfo.GetElementLinks<DomainModelLink>(shapeAdded.Element, rel); foreach (DomainModelLink link in links) factory.AddRSShapesForElement(link); } } if (factoryMapping != null) { if (info.MappingRelationshipSourceRoleTypes.Count > 0) foreach (Guid rel in info.MappingRelationshipSourceRoleTypes) { ReadOnlyCollection<DomainModelLink> links = DomainRoleInfo.GetElementLinks<DomainModelLink>(shapeAdded.Element, rel); foreach (DomainModelLink link in links) factoryMapping.AddRSShapesForElement(link); } if (info.MappingRelationshipTargetRoleTypes.Count > 0) foreach (Guid rel in info.MappingRelationshipTargetRoleTypes) { ReadOnlyCollection<DomainModelLink> links = DomainRoleInfo.GetElementLinks<DomainModelLink>(shapeAdded.Element, rel); foreach (DomainModelLink link in links) factoryMapping.AddRSShapesForElement(link); } } foreach (Diagram d in this.IncludedDiagrams) d.FixUpMissingLinkShapes(shapeAdded); foreach(NodeShape s in shapeAdded.Children) s.FixUpMissingLinkShapes(); }
protected DiagramItemElementViewModel(ViewModelStore viewModelStore, DiagramSurfaceViewModel diagram, NodeShape shapeElement) : base(viewModelStore, diagram, shapeElement) { }
public static void SetMainElementShape(GraphicalDependenciesDiagram element, NodeShape newNodeShape) { DslModeling::DomainRoleInfo.SetLinkedElement(element, GraphicalDependenciesDiagramDomainRoleId, newNodeShape); }
/// <summary> /// Constructor /// Creates a DiagramHasChildren link in the same Partition as the given Diagram /// </summary> /// <param name="source">Diagram to use as the source of the relationship.</param> /// <param name="target">NodeShape to use as the target of the relationship.</param> public DiagramHasChildren(Diagram source, NodeShape target) : base((source != null ? source.Partition : null), new DslModeling::RoleAssignment[]{new DslModeling::RoleAssignment(DiagramHasChildren.DiagramDomainRoleId, source), new DslModeling::RoleAssignment(DiagramHasChildren.ChildShapeDomainRoleId, target)}, null) { }
public static void SetGraphicalDependenciesDiagram(NodeShape element, GraphicalDependenciesDiagram newGraphicalDependenciesDiagram) { DslModeling::DomainRoleInfo.SetLinkedElement(element, NodeShapeDomainRoleId, newGraphicalDependenciesDiagram); }
public static bool RestoreLayout(NodeShape shapeElement, Diagram diagram) { DiagramsModel model = GetDiagramsModel(shapeElement); foreach (LayoutInfo layout in model.LayoutInfos) if (layout.HostElementId == shapeElement.Element.Id) { // apply layout ApplyLayout(shapeElement, diagram, layout); return true; } Tum.PDE.ToolFramework.Modeling.Diagrams.Layout.GleeLayouter.Layout(shapeElement); return false; }
/// <summary> /// This function corrects the given proposed location if the given child shape is a relative shape and /// is only allowed to be placed on the edge of its parent. /// </summary> /// <param name="placement">Proposed placement.</param> /// <param name="parentShape">Parent shape.</param> /// <param name="childShape">Child shape.</param> /// <param name="proposedLocation">Proposed location.</param> /// <remarks> /// This function needs to be called withing a modeling transaction. /// /// This function assigns new values to Location and PortPlacement if necessary. /// </remarks> /// <returns> /// Location that was assigned to the shape. It might have the same value as the location /// the shape had before calling this function. /// </returns> public static PointD CorrectPortLocation(PortPlacement placement, NodeShape parentShape, NodeShape childShape, PointD proposedLocation) { PointD newLocation = proposedLocation; RectangleD rectParent = parentShape.Bounds; switch (placement) { case PortPlacement.Left: newLocation.X = -childShape.Size.Width / 2.0; if (newLocation.Y < 0.0) newLocation.Y = 0.0; else if (newLocation.Y > (rectParent.Height - childShape.Size.Height)) newLocation.Y = rectParent.Height - childShape.Size.Height; break; case PortPlacement.Top: newLocation.Y = -childShape.Size.Height / 2.0; if (newLocation.X < 0.0) newLocation.X = 0.0; else if (newLocation.X > (rectParent.Width - childShape.Size.Width)) newLocation.X = rectParent.Width - childShape.Size.Width; break; case PortPlacement.Right: newLocation.X = rectParent.Width - (childShape.Size.Width / 2.0); if (newLocation.Y < 0.0) newLocation.Y = 0.0; else if (newLocation.Y > (rectParent.Height - childShape.Size.Height)) newLocation.Y = rectParent.Height - childShape.Size.Height; break; case PortPlacement.Bottom: newLocation.Y = rectParent.Height - (childShape.Size.Height / 2.0); if (newLocation.X < 0.0) newLocation.X = 0.0; else if (newLocation.X > (rectParent.Width - childShape.Size.Width)) newLocation.X = rectParent.Width - childShape.Size.Width; break; } if (childShape.Location != newLocation) { childShape.Location = newLocation; childShape.PlacementSide = placement; childShape.UpdateAbsoluteLocation(); } return newLocation; }
internal static void SetInternalDiagram(NodeShape element, Diagram newDiagram) { DslModeling::DomainRoleInfo.SetLinkedElement(element, ChildShapeDomainRoleId, newDiagram); }
internal static Diagram GetInternalDiagram(NodeShape element) { return DslModeling::DomainRoleInfo.GetLinkedElement(element, ChildShapeDomainRoleId) as Diagram; }
/// <summary> /// Verifies if the given node shape is already displayed as a child of this view model. /// </summary> /// <param name="nodeShape">Node shape to find.</param> /// <returns>True if the given element is already displayed as a child of this view model. False otherwise</returns> public bool IsDisplayingNodeShape(NodeShape nodeShape) { foreach (BaseDiagramItemElementViewModel vm in this.NestedChildren) if (vm.ShapeElement.Id == nodeShape.Id) return true; foreach (BaseDiagramItemElementViewModel vm in this.RelativeChildren) if (vm.ShapeElement.Id == nodeShape.Id) return true; return false; }
/// <summary> /// Creates the view model for the given node shape. /// </summary> /// <param name="nodeShapeType">Shape type for which the view model is to be created.</param> /// <param name="diagram">Diagram surface vm.</param> /// <param name="nodeShape">Node shape.</param> /// <returns> /// View model of type DiagramItemElementViewModel if a view model can be created for the given element. Null otherwise.</returns> public abstract DiagramItemElementViewModel CreateDiagramItemViewModel(Guid nodeShapeType, DiagramSurfaceViewModel diagram, NodeShape nodeShape);