public void CreateCustomBridge(IRenderContext context, GeneralPath path, PointD start, PointD end, double gapLength)
            {
                // first finish the last segment
                path.LineTo(start);
                // then calculate the gap
                var vectorLength = gapLength;

                if (vectorLength > 1)
                {
                    // some helper vectors first
                    var delta       = end - start;
                    var rightVector = delta / vectorLength;
                    var upVector    = new PointD(rightVector.Y, -rightVector.X);

                    // get the height from the context
                    double height = GetBridgeHeight(context);
                    // determine bending for our arc
                    double arc = 3;
                    // now draw two arcs at the end and the start of the segment
                    path.MoveTo(start + upVector * height - rightVector * arc);
                    path.QuadTo(start + rightVector * arc, start + upVector * -height - rightVector * arc);
                    path.MoveTo(end + rightVector * arc + upVector * height);
                    path.QuadTo(end - rightVector * arc, end + upVector * -height + rightVector * arc);
                    // finally make sure that the edge continues at the right location
                    path.MoveTo(end);
                }
                else
                {
                    // for very short gaps, we use a trivial rendering
                    path.LineTo(start);
                    path.MoveTo(end);
                }
            }
        /// <summary>
        /// Creates the rendering visual.
        /// </summary>
        /// <remarks>
        /// An ellipse with a + or - symbol.
        /// </remarks>
        /// <param name="context">The render context.</param>
        /// <param name="node">The node.to render.</param>
        /// <returns>A visual representation.</returns>
        protected override VisualGroup CreateVisual(IRenderContext context, INode node)
        {
            var vg   = new AggregationVisual();
            var info = (AggregationNodeInfo)node.Tag;

            vg.HasNode      = info.Aggregate.Node != null;
            vg.IsAggregated = info.IsAggregated;

            // draw a grey ellipse
            // if the aggregate represents a node draw a solid border. Draw a dashed border otherwise.
            var pen = info.Aggregate.Node == null
          ? new Pen(Brushes.LightGray)
            {
                DashStyle = DashStyle.Dash, DashPattern = new[] { 2f, 2f }
            }
          : Pens.LightGray;

            vg.Add(new EllipseVisual(new RectD(PointD.Origin, node.Layout.GetSize()))
            {
                Pen   = pen,
                Brush = new SolidBrush(info.IsAggregated
              ? Color.FromArgb(0x11, 0x6c, 0x91, 0xbf)
              : Color.FromArgb(0x09, 0x6c, 0x91, 0xbf))
            });
            // draw a + if aggregated, - otherwise
            GeneralPath gp = new GeneralPath();

            if (info.IsAggregated)
            {
                gp.MoveTo(0, -4);
                gp.LineTo(0, 4);
                gp.MoveTo(-4, 0);
                gp.LineTo(4, 0);
            }
            else
            {
                gp.MoveTo(-4, 0);
                gp.LineTo(4, 0);
            }
            gp.Transform(new Matrix2D(1, 0, 0, 1, node.Layout.Width / 2, node.Layout.Height / 2));
            GeneralPathVisual path = new GeneralPathVisual(gp);

            path.Pen = new Pen(Brushes.DimGray)
            {
                Width = 1.5f
            };
            vg.Add(path);
            vg.Transform = new Matrix(1, 0, 0, 1, (float)node.Layout.X, (float)node.Layout.Y);
            return(vg);
        }
Example #3
0
        public override Visual CreateVisual(IRenderContext context)
        {
            VisualGroup container = new VisualGroup();

            var bounds     = Bounds;
            var width      = bounds.Width;
            var height     = bounds.Height;
            var cornerSize = Math.Min(width, height) * 0.4;

            var path = new GeneralPath();

            path.MoveTo(0, 0);
            path.LineTo(width - cornerSize, 0);
            path.LineTo(width, cornerSize);
            path.LineTo(width, height);
            path.LineTo(0, height);
            path.Close();
            container.Add(path.CreatePath(Brush, Pen, new Matrix2D(), FillMode.Always));

            path = new GeneralPath();
            path.MoveTo(width - cornerSize, 0);
            path.LineTo(width - cornerSize, cornerSize);
            path.LineTo(width, cornerSize);
            container.Add(path.CreatePath(null, Pen, new Matrix2D(), FillMode.Never));

            container.SetRenderDataCache(new PathIconState(width, height, Pen, Brush));
            container.SetCanvasArrangeRect(bounds.ToRectD());
            return(container);
        }
Example #4
0
        public override Visual CreateVisual(IRenderContext context)
        {
            VisualGroup container = new VisualGroup();
            var         bounds    = Bounds;
            var         width     = bounds.Width;
            var         height    = bounds.Height;

            var path = new GeneralPath();

            path.MoveTo(0, TopLeftRadius);
            path.QuadTo(0, 0, TopLeftRadius, 0);
            path.LineTo(width - TopRightRadius, 0);
            path.QuadTo(width, 0, width, TopRightRadius);
            path.LineTo(width, height - BottomRightRadius);
            path.QuadTo(width, height, width - BottomRightRadius, height);
            path.LineTo(BottomLeftRadius, height);
            path.QuadTo(0, height, 0, height - BottomRightRadius);
            path.Close();

            var pathVisual = path.CreatePath(Brush, Pen, new Matrix2D(), FillMode.Always);

            container.Add(pathVisual);

            container.SetRenderDataCache(new PathIconState(width, height, Pen, Brush));
            container.SetCanvasArrangeRect(bounds.ToRectD());
            return(container);
        }
Example #5
0
        public override IVisual CreateVisual(IRenderContext context)
        {
            VisualGroup container = new VisualGroup();

            var bounds     = Bounds;
            var width      = bounds.Width;
            var height     = bounds.Height;
            var cornerSize = Math.Min(width, height) * 0.4;

            var path = new GeneralPath();

            path.MoveTo(0, 0);
            path.LineTo(width - cornerSize, 0);
            path.LineTo(width, cornerSize);
            path.LineTo(width, height);
            path.LineTo(0, height);
            path.Close();
            container.Add(new GeneralPathVisual(path)
            {
                Brush = Brush, Pen = Pen
            });

            path = new GeneralPath();
            path.MoveTo(width - cornerSize, 0);
            path.LineTo(width - cornerSize, cornerSize);
            path.LineTo(width, cornerSize);
            container.Add(new GeneralPathVisual(path)
            {
                Brush = null, Pen = Pen
            });

            container.Transform = new Matrix(1, 0, 0, 1, (float)Bounds.X, (float)Bounds.Y);
            return(container);
        }
Example #6
0
        protected override GeneralPath CreatePath(IStripe stripe, IRectangle layout)
        {
            var         column  = (IColumn)stripe;
            GeneralPath outline = new GeneralPath();

            //Left border:
            outline.MoveTo(0, 0);
            outline.LineTo(layout.Width, 0);
            outline.LineTo(layout.Width + WedgeWidth, WedgeHeight);
            outline.LineTo(layout.Width, 2 * WedgeHeight);
            outline.LineTo(layout.Width, layout.Height);
            outline.LineTo(0, layout.Height);

            if (IsFirst(column))
            {
                outline.Close();
            }
            else
            {
                outline.LineTo(0, layout.Height);
                outline.LineTo(0, 2 * WedgeHeight);
                outline.LineTo(WedgeWidth, WedgeHeight);
                outline.Close();
            }

            return(outline);
        }
        /// <summary>
        /// Creates an <see cref="IVisual"/> which renders the label.
        /// </summary>
        /// <remarks>
        /// Adds separate visuals for background and text in a VisualGroup.
        /// Delegates to method <see cref="LabelStyleBase{TVisual}.GetTransform"/>
        /// to get a valid transform for the label.
        /// </remarks>
        /// <param name="context">The Render Context.</param>
        /// <param name="label">The label to render.</param>
        /// <returns>A visual which renders the label.</returns>
        protected override VisualGroup CreateVisual(IRenderContext context, ILabel label)
        {
            var layout = label.GetLayout();

            // don't render invisible labels
            if (layout.Width < 0 || layout.Height < 0)
            {
                return(null);
            }
            var group = new VisualGroup();

            // convert to convenient coordinate space
            group.Transform = GetTransform(context, layout, true);

            // Draw the label background as a rounded rectangle
            GeneralPath gp   = new GeneralPath(10);
            double      xRad = layout.Width / 4;
            double      yRad = layout.Height / 10;

            gp.MoveTo(0, yRad);
            gp.QuadTo(0, 0, xRad, 0);
            gp.LineTo(layout.Width - xRad, 0);
            gp.QuadTo(layout.Width, 0, layout.Width, yRad);
            gp.LineTo(layout.Width, layout.Height - yRad);
            gp.QuadTo(layout.Width, layout.Height, layout.Width - xRad, layout.Height);
            gp.LineTo(xRad, layout.Height);
            gp.QuadTo(0, layout.Height, 0, layout.Height - yRad);
            gp.Close();
            var pathVisual = new GeneralPathVisual(gp)
            {
                Brush = new SolidBrush(Color.FromArgb(255, 240, 248, 255)), Pen = Pens.SkyBlue
            };

            group.Add(pathVisual);

            // Draw the label's text
            if (context.Zoom >= buttonZoomThreshold)
            {
                // draw the action button
                group.Add(new ImageVisual {
                    Image = Resources.edit_label, Rectangle = new RectD(layout.Width - (inset + buttonWidth), inset, buttonWidth, layout.Height - inset * 2)
                });
                group.Add(new TextVisual {
                    Text = label.Text, Font = Font, Brush = Brushes.Black, Location = PointD.Origin
                });
            }
            else
            {
                group.Add(new TextVisual {
                    Text     = label.Text,
                    Font     = Font,
                    Brush    = Brushes.Black,
                    Location = new PointD((buttonWidth + 2 * inset) * 0.5, 0)
                });
            }

            return(group);
        }
    protected override GeneralPath GetPath(IEdge edge) {
      // Create a general path from the locations of the ports and the bends of the edge.
      GeneralPath path = new GeneralPath();
      path.MoveTo(GetLocation(edge.SourcePort));
      foreach (var bend in edge.Bends) {
        path.LineTo(bend.Location);
      }
      path.LineTo(GetLocation(edge.TargetPort));

      // shorten the path in order to provide room for drawing the arrows.
      return base.CropPath(edge, Arrows, Arrows, path);
    }
        //////////////// New in this sample ////////////////

        // Path creation has been extracted into method CreatePath

        /// <summary>
        /// Creates a general path for the locations of the ports and the bends of the edge.
        /// </summary>
        /// <param name="edge">The edge.</param>
        /// <returns>A general path for the locations of the ports and the bends of the edge.</returns>
        private static GeneralPath CreatePath(IEdge edge)
        {
            GeneralPath path = new GeneralPath();

            path.MoveTo(edge.SourcePort.GetLocation());
            foreach (var bend in edge.Bends)
            {
                path.LineTo(bend.Location);
            }
            path.LineTo(edge.TargetPort.GetLocation());
            return(path);
        }
Example #10
0
            protected override GeneralPath CreatePath()
            {
                var pathPoints = Edge.GetPathPoints();
                var gp         = new GeneralPath(pathPoints.Count + 1);

                gp.MoveTo(pathPoints[0]);

                for (int i = 1; i < pathPoints.Count; ++i)
                {
                    if (i % 3 == 2)
                    {
                        //Skip to the next triple
                        gp.MoveTo(pathPoints[i]);
                    }
                    else
                    {
                        //Draw a line to the next control pint in the triple
                        gp.LineTo(pathPoints[i]);
                    }
                }
                return(gp);
            }
        protected override GeneralPath GetOutline(INode node)
        {
            double size   = Math.Min(node.Layout.Width, node.Layout.Height);
            RectD  bounds = new RectD(node.Layout.X + node.Layout.Width / 2 - size / 2, node.Layout.Y + node.Layout.Height / 2 - size / 2, size, size);

            var path = new GeneralPath();

            path.MoveTo(bounds.X, bounds.CenterY);    // <
            path.LineTo(bounds.CenterX, bounds.Y);    // ^
            path.LineTo(bounds.MaxX, bounds.CenterY); // >
            path.LineTo(bounds.CenterX, bounds.MaxY); // v
            path.Close();
            return(path);
        }
        protected override GeneralPath GetPath(IEdge edge)
        {
            // Create a general path from the locations of the ports and the bends of the edge.
            GeneralPath path = new GeneralPath(edge.Bends.Count + 2);

            path.MoveTo(edge.SourcePort.GetLocation());
            foreach (var bend in edge.Bends)
            {
                path.LineTo(bend.Location);
            }
            path.LineTo(edge.TargetPort.GetLocation());

            return(path);
        }
Example #13
0
        static LogicGateNodeStyle()
        {
            // path for AND nodes
            AndOutlinePath = new GeneralPath();
            AndOutlinePath.MoveTo(0.6, 0);
            AndOutlinePath.LineTo(0.1, 0);
            AndOutlinePath.LineTo(0.1, 1);
            AndOutlinePath.LineTo(0.6, 1);
            AndOutlinePath.QuadTo(0.8, 1.0, 0.8, 0.5);
            AndOutlinePath.QuadTo(0.8, 0.0, 0.6, 0);

            // path for OR nodes
            OrOutlinePath = new GeneralPath();
            OrOutlinePath.MoveTo(0.6, 0);
            OrOutlinePath.LineTo(0.1, 0);
            OrOutlinePath.QuadTo(0.3, 0.5, 0.1, 1);
            OrOutlinePath.LineTo(0.6, 1);
            OrOutlinePath.QuadTo(0.8, 1.0, 0.8, 0.5);
            OrOutlinePath.QuadTo(0.8, 0.0, 0.6, 0);

            // path for NAND nodes
            NandOutlinePath = new GeneralPath();
            NandOutlinePath.MoveTo(0.6, 0);
            NandOutlinePath.LineTo(0.1, 0);
            NandOutlinePath.LineTo(0.1, 1);
            NandOutlinePath.LineTo(0.6, 1);
            NandOutlinePath.QuadTo(0.8, 1.0, 0.8, 0.5);
            NandOutlinePath.QuadTo(0.8, 0.0, 0.6, 0);
            NandOutlinePath.AppendEllipse(new RectD(0.8, 0.4, 0.1, 0.2), false);

            // path for NOR nodes
            NorOutlinePath = new GeneralPath();
            NorOutlinePath.MoveTo(0.6, 0);
            NorOutlinePath.LineTo(0.1, 0);
            NorOutlinePath.QuadTo(0.3, 0.5, 0.1, 1);
            NorOutlinePath.LineTo(0.6, 1);
            NorOutlinePath.QuadTo(0.8, 1.0, 0.8, 0.5);
            NorOutlinePath.QuadTo(0.8, 0.0, 0.6, 0);
            NorOutlinePath.AppendEllipse(new RectD(0.8, 0.4, 0.1, 0.2), false);

            // path for NOT nodes
            NotOutlinePath = new GeneralPath();
            NotOutlinePath.MoveTo(0.8, 0.5);
            NotOutlinePath.LineTo(0.1, 0);
            NotOutlinePath.LineTo(0.1, 1);
            NotOutlinePath.LineTo(0.8, 0.5);
            NotOutlinePath.AppendEllipse(new RectD(0.8, 0.4, 0.1, 0.2), false);
        }
Example #14
0
        private static GeneralPath CreatePath(IOrientedRectangle layout)
        {
            GeneralPath gp   = new GeneralPath(10);
            double      xRad = layout.Width / 4;
            double      yRad = layout.Height / 10;

            gp.MoveTo(0, yRad);
            gp.QuadTo(0, 0, xRad, 0);
            gp.LineTo(layout.Width - xRad, 0);
            gp.QuadTo(layout.Width, 0, layout.Width, yRad);
            gp.LineTo(layout.Width, layout.Height - yRad);
            gp.QuadTo(layout.Width, layout.Height, layout.Width - xRad, layout.Height);
            gp.LineTo(xRad, layout.Height);
            gp.QuadTo(0, layout.Height, 0, layout.Height - yRad);
            gp.Close();
            return(gp);
        }
Example #15
0
        /// <summary>
        /// Creates an <see cref="IVisual"/> which renders the label.
        /// </summary>
        /// <remarks>
        /// Adds separate visuals for background and text in a VisualGroup.
        /// Delegates to method <see cref="LabelStyleBase{TVisual}.GetTransform"/>
        /// to get a valid transform for the label.
        /// </remarks>
        /// <param name="context">The Render Context.</param>
        /// <param name="label">The label to render.</param>
        /// <returns>A visual which renders the label.</returns>
        protected override VisualGroup CreateVisual(IRenderContext context, ILabel label)
        {
            var layout = label.GetLayout();

            // don't render invisible labels
            if (layout.Width < 0 || layout.Height < 0)
            {
                return(null);
            }
            var group = new VisualGroup();

            // convert to convenient coordinate space
            group.Transform = GetTransform(context, layout, true);

            // Draw the label background as a rounded rectangle
            GeneralPath gp   = new GeneralPath(10);
            double      xRad = layout.Width / 4;
            double      yRad = layout.Height / 10;

            gp.MoveTo(0, yRad);
            gp.QuadTo(0, 0, xRad, 0);
            gp.LineTo(layout.Width - xRad, 0);
            gp.QuadTo(layout.Width, 0, layout.Width, yRad);
            gp.LineTo(layout.Width, layout.Height - yRad);
            gp.QuadTo(layout.Width, layout.Height, layout.Width - xRad, layout.Height);
            gp.LineTo(xRad, layout.Height);
            gp.QuadTo(0, layout.Height, 0, layout.Height - yRad);
            gp.Close();
            var pathVisual = new GeneralPathVisual(gp)
            {
                Brush = new SolidBrush(Color.FromArgb(255, 155, 226, 255)), Pen = Pens.SkyBlue
            };

            group.Add(pathVisual);

            // Draw the label's text
            group.Add(new TextVisual {
                Text     = label.Text,
                Font     = Font,
                Brush    = Brushes.Black,
                Location = PointD.Origin
            });
            return(group);
        }
        protected override GeneralPath GetOutline(INode node)
        {
            var cornerSize = Math.Min(node.Layout.Width, node.Layout.Height) * 0.4;

            var path = new GeneralPath();

            path.MoveTo(0, 0);
            path.LineTo(node.Layout.Width - cornerSize, 0);
            path.LineTo(node.Layout.Width, cornerSize);
            path.LineTo(node.Layout.Width, node.Layout.Height);
            path.LineTo(0, node.Layout.Height);
            path.Close();

            var transform = new Matrix2D();

            transform.Translate(node.Layout.GetTopLeft());
            path.Transform(transform);
            return(path);
        }
Example #17
0
        protected override GeneralPath GetOutline(INode node)
        {
            const double halfEllipseHeight = 0.125;
            GeneralPath  path = new GeneralPath();

            path.MoveTo(0, halfEllipseHeight);
            path.LineTo(0, 1 - halfEllipseHeight);
            path.CubicTo(0, 1, 1, 1, 1, 1 - halfEllipseHeight);
            path.LineTo(1, halfEllipseHeight);
            path.CubicTo(1, 0, 0, 0, 0, halfEllipseHeight);
            path.Close();

            var transform = new Matrix2D();

            transform.Translate(node.Layout.GetTopLeft());
            transform.Scale(node.Layout.Width, node.Layout.Height);
            path.Transform(transform);
            return(path);
        }
Example #18
0
        protected override GeneralPath CreatePath(IStripe stripe, IRectangle layout)
        {
            var         row     = (IRow)stripe;
            GeneralPath outline = new GeneralPath();

            outline.MoveTo(0, 0);
            outline.LineTo(0, layout.Height);
            outline.LineTo(layout.Width, layout.Height);
            if (IsFirst(row))
            {
                outline.LineTo(layout.Width, 2 * WedgeHeight);
                outline.LineTo(layout.Width + WedgeWidth, WedgeHeight);
                outline.LineTo(layout.Width, 0);
                outline.Close();
            }
            else
            {
                outline.LineTo(layout.Width, 0);
            }
            return(outline);
        }
Example #19
0
        protected override GeneralPath GetPath(IEdge edge)
        {
            // Create a general path from the locations of the ports and the bends of the edge.
            GeneralPath path = new GeneralPath();

            path.MoveTo(edge.SourcePort.GetLocation());
            foreach (var bend in edge.Bends)
            {
                path.LineTo(bend.Location);
            }
            path.LineTo(edge.TargetPort.GetLocation());

            ////////////////////////////////////////////////////
            //////////////// New in this sample ////////////////
            ////////////////////////////////////////////////////

            // The following lines shorten the path in order to provide room for drawing the arrows.
            path = CropPath(edge, Arrows, Arrows, path);
            ////////////////////////////////////////////////////

            return(path);
        }
Example #20
0
        /// <summary>
        /// Creates a <see cref="GeneralPath"/> that describes the face on the front side of the block.
        /// </summary>
        /// <param name="corners">The coordinates of the corners of the block.</param>
        /// <returns>A <see cref="GeneralPath"/> that describes the face on the front side of the block.</returns>
        static GeneralPath GetFrontFacePath(double[] corners)
        {
            var path = new GeneralPath();

            path.MoveTo(
                corners[LowBottomLeftX],
                corners[LowBottomLeftY]
                );
            path.LineTo(
                corners[UpBottomLeftX],
                corners[UpBottomLeftY]
                );
            path.LineTo(
                corners[UpBottomRightX],
                corners[UpBottomRightY]
                );
            path.LineTo(
                corners[LowBottomRightX],
                corners[LowBottomRightY]
                );
            path.Close();
            return(path);
        }
Example #21
0
        protected override GeneralPath GetOutline(INode node)
        {
            double width  = Math.Min(node.Layout.Width, node.Layout.Height / BpmnConstants.ConversationWidthHeightRatio);
            double height = width * BpmnConstants.ConversationWidthHeightRatio;
            RectD  bounds = new RectD(node.Layout.GetCenter().X - width / 2, node.Layout.GetCenter().Y - height / 2, width, height);

            var path = new GeneralPath();

            path.MoveTo(0, 0.5);
            path.LineTo(0.25, 0);
            path.LineTo(0.75, 0);
            path.LineTo(1, 0.5);
            path.LineTo(0.75, 1);
            path.LineTo(0.25, 1);
            path.Close();

            var transform = new Matrix2D();

            transform.Translate(bounds.GetTopLeft());
            transform.Scale(bounds.Width, bounds.Height);
            path.Transform(transform);
            return(path);
        }
Example #22
0
        /// <summary>
        /// Creates a <see cref="GeneralPath"/> that describes the face on the back side of the block.
        /// </summary>
        /// <param name="corners">The coordinates of the corners of the block.</param>
        /// <returns>A <see cref="GeneralPath"/> that describes the face on the back side of the block.</returns>
        static GeneralPath GetBackFacePath(double[] corners)
        {
            var path = new GeneralPath();

            path.MoveTo(
                corners[LowTopLeftX],
                corners[LowTopLeftY]
                );
            path.LineTo(
                corners[UpTopLeftX],
                corners[UpTopLeftY]
                );
            path.LineTo(
                corners[UpTopRightX],
                corners[UpTopRightY]
                );
            path.LineTo(
                corners[LowTopRightX],
                corners[LowTopRightY]
                );
            path.Close();
            return(path);
        }
        protected override GeneralPath GetOutline(INode node)
        {
            // Create a rounded rectangle path
            var layout = node.Layout.ToRectD();
            var path   = new GeneralPath(12);
            var x      = layout.X;
            var y      = layout.Y;
            var w      = layout.Width;
            var h      = layout.Height;
            var arcX   = Math.Min(w * 0.5, 5);
            var arcY   = Math.Min(h * 0.5, 5);

            path.MoveTo(x, y + arcY);
            path.QuadTo(x, y, x + arcX, y);
            path.LineTo(x + w - arcX, y);
            path.QuadTo(x + w, y, x + w, y + arcY);
            path.LineTo(x + w, y + h - arcY);
            path.QuadTo(x + w, y + h, x + w - arcX, y + h);
            path.LineTo(x + arcX, y + h);
            path.QuadTo(x, y + h, x, y + h - arcY);
            path.Close();
            return(path);
        }
Example #24
0
        public override IVisual CreateVisual(IRenderContext context)
        {
            var bounds = Bounds;
            var width  = bounds.Width;
            var height = bounds.Height;

            var path = new GeneralPath();

            path.MoveTo(0, TopLeftRadius);
            path.QuadTo(0, 0, TopLeftRadius, 0);
            path.LineTo(width - TopRightRadius, 0);
            path.QuadTo(width, 0, width, TopRightRadius);
            path.LineTo(width, height - BottomRightRadius);
            path.QuadTo(width, height, width - BottomRightRadius, height);
            path.LineTo(BottomLeftRadius, height);
            path.QuadTo(0, height, 0, height - BottomRightRadius);
            path.Close();

            return(new GeneralPathVisual(path)
            {
                Brush = Brush, Pen = Pen, Transform = new Matrix(1, 0, 0, 1, (float)Bounds.X, (float)Bounds.Y)
            });
        }
Example #25
0
        /// <summary>
        /// Generates a path for the callout decoration, which is an isosceles triangle from the label's center pointing
        /// to the node.
        /// </summary>
        /// <param name="label">The label for which to create the path.</param>
        /// <returns>A path for the callout triangle.</returns>
        private static GeneralPath GenerateTrianglePath(ILabel label)
        {
            var node   = (INode)label.Owner;
            var layout = label.GetLayout();

            // Find the point where the triangle attaches to the outline shape
            var outlineShape = node.Style.Renderer.GetShapeGeometry(node, node.Style).GetOutline();
            var nodeCenter   = node.Layout.GetCenter();
            var labelCenter  = layout.GetCenter();

            if (outlineShape == null)
            {
                outlineShape = new GeneralPath(4);
                outlineShape.AppendOrientedRectangle(layout, false);
            }
            var intersection      = outlineShape.FindLineIntersection(nodeCenter, labelCenter);
            var intersectionPoint = nodeCenter + intersection * (labelCenter - nodeCenter);

            // Find the vector that is orthogonal to the line connecting the label and node centers
            var triangleVector = labelCenter - intersectionPoint;
            var orthoVector    = OrthoNormal(triangleVector);

            // Construct the other points of the triangle
            var point2 = labelCenter + orthoVector * 20;
            var point3 = labelCenter - orthoVector * 20;

            // Create the path
            var p = new GeneralPath();

            p.MoveTo(intersectionPoint);
            p.LineTo(point2);
            p.LineTo(point3);
            p.Close();

            return(p);
        }
Example #26
0
        /// <summary>
        /// If the existing number of bends is 2 mod 3 (i.e. the bends are consistent with
        /// what the bezier style expects),
        /// this implementation creates a triple of collinear bends and adjust the neighboring bends
        /// in a way that the shape of the curve is not changed initially and returns the middle bend.
        /// If there are no bends at all, it creates a triple plus two initial and final control bends, all of them collinear.
        /// Otherwise, the fallback bend creator is used to create a bend with its default strategy.
        /// </summary>
        /// <returns>The index of middle bend of a control point triple if such a triple was created,
        /// or the index of the newly created single bend.</returns>
        public int CreateBend(IInputModeContext context, IGraph graph, IEdge edge, PointD location)
        {
            switch (edge.Bends.Count)
            {
            case 0:
                var spl = edge.SourcePort.GetLocation();
                var tpl = edge.TargetPort.GetLocation();

                //a single linear segment... we just insert 5 collinear bends adjusted to the angle of the linear segment,
                //approximately evenly spaced
                graph.AddBend(edge, (location - spl) / 4 + spl, 0);
                graph.AddBend(edge, -(location - spl) / 4 + location, 1);
                graph.AddBend(edge, location, 2);
                graph.AddBend(edge, (location - spl) / 4 + location, 3);
                graph.AddBend(edge, location + (tpl - location) * 3 / 4, 4);
                return(2);

            case 1:
                //Use the default strategy to insert a single bend at the correct index
                return(fallBackCreator.CreateBend(context, graph, edge, location));

            default:
                var pathPoints = edge.GetPathPoints();
                if (pathPoints.Count % 3 == 1)
                {
                    //Consistent number of existing points
                    //Try to insert a smooth bend
                    //I.e. a triple of three collinear bends and adjust the neighbor bends

                    //Various quality measures and counters
                    var    segmentIndex    = 0;
                    var    pathCounter     = 0;
                    var    bestDistanceSqr = Double.PositiveInfinity;
                    double bestRatio       = Double.NaN;

                    //The index of the segment where we want to create the bend in the end
                    int bestIndex = -1;

                    //Find the best segment
                    while (pathCounter + 3 < pathPoints.Count)
                    {
                        //Get the control points defining the current segment
                        var cp0 = pathPoints[pathCounter++];
                        var cp1 = pathPoints[pathCounter++];
                        var cp2 = pathPoints[pathCounter++];
                        //Consecutive segments share the last/first control point! So we may not advance the counter here
                        var cp3 = pathPoints[pathCounter];
                        //Shift a cubic segment
                        //
                        //Here we assume that the path is actually composed of cubic segments, only.
                        //Alternatively, we could inspect the actual path created by the edge renderer - this would also
                        //allow to deal with intermediate non cubic segments, but we'd have to associate those
                        //path segments somehow with the correct bends again, so again this would be tied to the actual
                        //renderer implementation.
                        var fragment = new GeneralPath(2);
                        fragment.MoveTo(cp0);
                        fragment.CubicTo(cp1, cp2, cp3);

                        //Try to find the projection onto the fragment
                        var ratio = fragment.GetProjection(location, 0);
                        if (ratio.HasValue)
                        {
                            //Actually found a projection ratio
                            //Determine the point on the curve - the tangent provides this
                            var tangent = fragment.GetTangent(0, ratio.Value);
                            if (tangent.HasValue)
                            {
                                //There actually is a tangent
                                var d = (location - tangent.Value.Point).SquaredVectorLength;
                                //Is this the best distance?
                                if (d < bestDistanceSqr)
                                {
                                    bestDistanceSqr = d;
                                    //Remember ratio (needed to split the curve)
                                    bestRatio = ratio.Value;
                                    //and the index, of course
                                    bestIndex = segmentIndex;
                                }
                            }
                        }
                        ++segmentIndex;
                    }
                    if (bestIndex != -1)
                    {
                        //Actually found a segment
                        //For the drag, we want to move the middle bend
                        return(CreateBends(graph, edge, bestIndex, bestRatio, pathPoints).GetIndex());
                    }
                    //No best segment found (for whatever reason) - we don't want to create a bend so that we don't mess up anything
                    return(-1);
                }
                else
                {
                    //No consistent number of bends - just insert a single bend
                    //We could also see whether we actually would have a cubic segment on the path, and treat that differently
                    //However, why bother - just create the edge with a correct number of points instead
                    return(fallBackCreator.CreateBend(context, graph, edge, location));
                }
            }
        }
Example #27
0
        private static PortConstraint CreatePortConstraintFromSketch(IEdge e, bool source, bool strong)
        {
            //Get connection port and owner
            IPort port      = source ? e.SourcePort : e.TargetPort;
            INode portOwner = port.Owner as INode;

            if (portOwner != null)
            {
                //Einfachste Loesung:
                //Erzeugt einen strong PortConstraint genau an der port location
                //anschluesse in alle richtungen moeglich
                //        return PortConstraint.create(PortConstraint.ANY_SIDE, strong);
                //alternativ: z.B. Kantenpfad bestimmen und einen PortConstraint
                //erzeugen, dessen Richtung durch den Schnittpunkt zwischen Pfad und Knotenrand gegeben ist.
                //hier nur geradlinige Verbindung zwischen Bends
                PointD portLocation = port.GetLocation();
                PointD seg          = new PointD();
                var    bends        = e.Bends;
                if (bends.Count == 0)
                {
                    // no bends, instead take the endpoint
                    seg = source ? e.TargetPort.GetLocation() : e.SourcePort.GetLocation();
                }
                else
                {
                    IPoint p1 = bends[0].Location;
                    IPoint p2 = bends[bends.Count - 1].Location;
                    seg = source ? new PointD(p1) : new PointD(p2);
                }
                // Some offset for ports, which lie exactly on the border
                RectD enlarged = portOwner.Layout.ToRectD().GetEnlarged(5);

                var generalPath = new GeneralPath(2);
                generalPath.MoveTo(portLocation);
                generalPath.LineTo(seg);

                if (generalPath.FindLineIntersection(enlarged.TopLeft, enlarged.TopRight) < 1)
                {
                    //Erstes Segment verlaesst den Knoten auf der Nordseite
                    //Die tatsaechliche Position des Constraints ergibt sich aus dem Startpunkt der Kante, muss
                    //hier also nicht noch mal angegeben werden, dafuer aber, dass es sich wirklich um einen STRONG constraint
                    //handelt.
                    return(PortConstraint.Create(PortSide.North, strong));
                }
                if (generalPath.FindLineIntersection(enlarged.TopLeft, enlarged.BottomLeft) < 1)
                {
                    //first segment leaves at west...
                    return(PortConstraint.Create(PortSide.West, strong));
                }
                if (generalPath.FindLineIntersection(enlarged.TopRight, enlarged.BottomRight) < 1)
                {
                    //first segment leaves at east...
                    return(PortConstraint.Create(PortSide.East, strong));
                }
                if (generalPath.FindLineIntersection(enlarged.BottomLeft, enlarged.BottomRight) < 1)
                {
                    //first segment leaves at south...
                    return(PortConstraint.Create(PortSide.South, strong));
                }
                //keine intersection mit dem ersten segment, hier waehlen wir den einfachen Weg...
                return(PortConstraint.Create(PortSide.Any, strong));
            }
            return(null);
        }
        /// <summary>
        /// Creates a visual representation of the constraint indicator.
        /// </summary>
        public GeneralPath CreateConstraintIndicator()
        {
            IPort port       = sourceEnd ? bend.Owner.SourcePort : bend.Owner.TargetPort;
            var   nodeLayout = ((INode)port.Owner).Layout.ToRectD();

            PointD portLocation = nodeLayout.Center;
            double plX = portLocation.X, plY = portLocation.Y;
            PointD bendLocation = bend.Location.ToPointD();
            PointD delta        = bendLocation - portLocation;

            if (delta.VectorLength > MinDistance && !nodeLayout.Contains(bendLocation))
            {
                PointD direction = delta.Normalized;

                GeneralPath path = new GeneralPath(20);

                path.MoveTo(-15, 0);
                path.LineTo(-5, 10);
                path.LineTo(-2, 7);
                path.LineTo(-5, 4);
                path.LineTo(8, 4);
                path.LineTo(8, -4);
                path.LineTo(-5, -4);
                path.LineTo(-2, -7);
                path.LineTo(-5, -10);
                path.Close();

                // mirror at target end
                if (!sourceEnd)
                {
                    path.Transform(new Matrix2D(-1, 0, 0, 1, 0, 0));
                }

                // rotate and translate arrow
                const int ArrowOffset = 11;
                if (direction.IsHorizontalVector)
                {
                    plY = nodeLayout.CenterY;
                    if (direction.X > 0)
                    {
                        plX = nodeLayout.MaxX + ArrowOffset;
                        path.Transform(new Matrix2D(-1, 0, 0, 1, plX, plY));
                    }
                    else
                    {
                        plX = nodeLayout.X - ArrowOffset;
                        path.Transform(new Matrix2D(1, 0, 0, 1, plX, plY));
                    }
                }
                else
                {
                    plX = nodeLayout.CenterX;
                    if (direction.Y < 0)
                    {
                        plY = nodeLayout.Y - ArrowOffset;
                        path.Transform(new Matrix2D(0, 1, 1, 0, plX, plY));
                    }
                    else
                    {
                        plY = nodeLayout.MaxY + ArrowOffset;
                        path.Transform(new Matrix2D(0, 1, -1, 0, plX, plY));
                    }
                }
                return(path);
            }
            return(null);
        }
Example #29
0
        protected override VisualGroup CreateVisual(IRenderContext context, ILabel label)
        {
            var  group   = new VisualGroup();
            bool enabled = false;

            if (Button != null)
            {
                enabled = Button.CanExecute((INode)label.Owner, context.CanvasControl);
            }

            var labelLayout = label.GetLayout();
            var layout      = new RectD(labelLayout.AnchorX, labelLayout.AnchorY - label.PreferredSize.Height,
                                        label.PreferredSize.Width, label.PreferredSize.Height);
            Brush backgroundBrush;
            Brush foregroundBrush;
            Pen   foregroundPen;

            if (enabled)
            {
                // enabled style
                if (Icon != ButtonIcon.Increase)
                {
                    backgroundBrush = new LinearGradientBrush(layout.TopLeft, layout.BottomLeft,
                                                              BackgroundColor,
                                                              Mix(Color.White, BackgroundColor, 0.5d));
                }
                else
                {
                    backgroundBrush = new LinearGradientBrush(layout.TopLeft, layout.BottomLeft,
                                                              Mix(Color.White, BackgroundColor, 0.5d),
                                                              BackgroundColor);
                }
                foregroundPen   = new Pen(ForegroundColor);
                foregroundBrush = new SolidBrush(ForegroundColor);
            }
            else
            {
                // disabled style
                backgroundBrush = new LinearGradientBrush(layout.TopLeft, layout.BottomLeft,
                                                          Mix(Color.White, BackgroundColor, 0.7),
                                                          Mix(Color.White, BackgroundColor, 0.7));
                foregroundPen   = new Pen(Mix(Color.White, ForegroundColor, 0.7));
                foregroundBrush = new SolidBrush(Mix(Color.White, ForegroundColor, 0.7));
            }
            var backgroundRect = new RectangleVisual(layout)
            {
                Brush = backgroundBrush,
                Pen   = BorderPen
            };

            group.Add(backgroundRect);
            GeneralPath path;
            ShapeVisual pathPaintable;

            switch (Icon)
            {
            case ButtonIcon.Increase: // paint "up"-arrow
                path = new GeneralPath();
                path.MoveTo(layout.TopLeft + new PointD(layout.Width * 0.3, layout.Height * 0.7));
                path.LineTo(layout.TopLeft + new PointD(layout.Width * 0.7, layout.Height * 0.7));
                path.LineTo(layout.TopLeft + new PointD(layout.Width * 0.5, layout.Height * 0.3));
                path.Close();
                pathPaintable = new GeneralPathVisual(path)
                {
                    Brush = foregroundBrush
                };
                group.Add(pathPaintable);
                break;

            case ButtonIcon.Decrease: // paint "down"-arrow
                path = new GeneralPath();
                path.MoveTo(layout.TopLeft + new PointD(layout.Width * 0.3, layout.Height * 0.3));
                path.LineTo(layout.TopLeft + new PointD(layout.Width * 0.7, layout.Height * 0.3));
                path.LineTo(layout.TopLeft + new PointD(layout.Width * 0.5, layout.Height * 0.7));
                path.Close();
                pathPaintable = new GeneralPathVisual(path)
                {
                    Brush = foregroundBrush
                };
                group.Add(pathPaintable);
                break;

            case ButtonIcon.Toggle: // paint "check"
                path = new GeneralPath();
                path.MoveTo(layout.TopLeft + new PointD(layout.Width * 0.3, layout.Height * 0.5));
                path.LineTo(layout.TopLeft + new PointD(layout.Width * 0.5, layout.Height * 0.7));
                path.LineTo(layout.TopLeft + new PointD(layout.Width * 0.7, layout.Height * 0.3));;
                pathPaintable = new GeneralPathVisual(path)
                {
                    Pen = foregroundPen
                };
                group.Add(pathPaintable);
                break;

            case ButtonIcon.None: // paint nothing
                break;

            default: // can't happen
                throw new ArgumentOutOfRangeException();
            }
            return(group);
        }
        protected override VisualGroup CreateVisual(IRenderContext context, INode node)
        {
            Color borderColor, backgroundColor1, backgroundColor2;

            if (((GraphControl)context.CanvasControl).CurrentItem == node)
            {
                borderColor      = Color.Orange;
                backgroundColor1 = Color.White;
                backgroundColor2 = Color.Orange;
            }
            else
            {
                borderColor      = Color.FromArgb(255, 24, 154, 231);
                backgroundColor1 = Color.FromArgb(255, 204, 255, 255);
                backgroundColor2 = Color.FromArgb(255, 24, 154, 231);
            }

            var layout = node.Layout;

            var employee = (Employee)node.Tag;

            var text = new TextVisual {
                Text     = GetShortName(employee.Name),
                Font     = new Font("Arial", 37, FontStyle.Regular, GraphicsUnit.Pixel),
                Brush    = Brushes.Black,
                Location = new PointD(5, 5)
            };
            double locationX = layout.Width / 2 - text.GetBounds(context).Width / 2;
            double locationY = layout.Height / 2 - text.GetBounds(context).Height / 2;
            string s1        = GetShortName(employee.Name);
            Font   font1     = new Font("Arial", 37, FontStyle.Regular, GraphicsUnit.Pixel);
            Brush  brush1    = Brushes.Black;
            IPoint location1 = new PointD(locationX, locationY);

            text = new TextVisual {
                Text = s1, Font = font1, Brush = brush1, Location = location1
            };

            var ribbonColor = Color.Green;

            if (employee.Status == EmployeeStatus.Travel)
            {
                ribbonColor = Color.Purple;
            }
            if (employee.Status == EmployeeStatus.Unavailable)
            {
                ribbonColor = Color.Red;
            }

            var border = new RectangleVisual(0, 0, layout.Width, layout.Height)
            {
                Pen = new Pen(borderColor)
            };
            var background = new RectangleVisual(0, 0, layout.Width, layout.Height)
            {
                Brush = new LinearGradientBrush(new PointF(0, 0), new PointF((float)layout.Width, (float)layout.Height), backgroundColor1, backgroundColor2)
            };
            var ribbonPath = new GeneralPath();

            ribbonPath.MoveTo(0, 20);
            ribbonPath.LineTo(25, 0);
            ribbonPath.LineTo(40, 0);
            ribbonPath.LineTo(0, 35);
            ribbonPath.Close();
            var ribbon = new GeneralPathVisual(ribbonPath)
            {
                Brush = new SolidBrush(ribbonColor)
            };

            // Set a transform on the group, matching the node's location.
            // That way only the transform has to be updated instead of every single child visual.
            var transform = new Matrix();

            transform.Translate((float)layout.X, (float)layout.Y);

            var group = new VisualGroup
            {
                Transform = transform,
                Children  =
                {
                    border, background, text, ribbon
                }
            };

            return(group);
        }