/// <summary>
        /// Creates a <see cref="GeneralPath"/> that describes the face on the top 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 top of the block.</returns>
        static GeneralPath GetTopFacePath(double[] corners)
        {
            var path = new GeneralPath();

            path.MoveTo(
                corners[UpTopLeftX],
                corners[UpTopLeftY]
                );
            path.LineTo(
                corners[UpTopRightX],
                corners[UpTopRightY]
                );
            path.LineTo(
                corners[UpBottomRightX],
                corners[UpBottomRightY]
                );
            path.LineTo(
                corners[UpBottomLeftX],
                corners[UpBottomLeftY]
                );
            path.Close();
            return(path);
        }
Пример #2
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)
            });
        }
Пример #3
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);
        }
Пример #4
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);
        }
Пример #5
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);
        }
        /// <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);
        }
Пример #8
0
        ////////////////////////////////////////////////////

        #region Visual

        /// <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);

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

            // 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);
        }