Exemplo n.º 1
0
        /*
         * /// <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();
                            }
                        }
                    }
                }
            }
        }