public virtual void AddRootShapesForElement(DomainModelElement modelElement)//, bool bIgnoreVisualizationBehavior) { DiagramDomainDataDirectory data = modelElement.Store.DomainDataAdvDirectory.ResolveExtensionDirectory <DiagramDomainDataDirectory>(); IDomainModelServices topMost = modelElement.GetDomainModelServices().TopMostService; List <Guid> shapeIds = data.GetRootShapeTypesForElement(modelElement.GetDomainClassId()); if (shapeIds != null) { foreach (Guid shapeId in shapeIds) { ShapeClassInfo shapeInfo = data.ShapeClassInfos[shapeId]; ReadOnlyCollection <ModelElement> diagrams = modelElement.Store.ElementDirectory.FindElements(shapeInfo.DiagramClassType); if (diagrams.Count == 0) { continue; } foreach (Diagram d in diagrams) { if (d.IsVisible && d.CanHostShape(shapeId)) { if (!DiagramHelper.IsElementDisplayedOn(d, shapeId, modelElement.Id)) { NodeShape shape = topMost.ShapeProvider.CreateShapeForElement(shapeId, modelElement) as NodeShape; d.Children.Add(shape); DiagramsShapeStore.AddToStore(shape.Element.Id, shape.Id); shape.FixUpMissingLinkShapes(); } } } } } }
/* * /// <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(); } } } } } }
/// <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); }