Example #1
0
        private void DrawPseudostate(TNode state, D2dGraphics g, bool outline)
        {
            RectangleF bounds       = state.Bounds;
            D2dEllipse ellipse      = (D2dEllipse)bounds;
            D2dEllipse innerEllipse = ellipse;

            innerEllipse.RadiusX = 4;
            innerEllipse.RadiusY = 4;
            PointF c = ellipse.Center;

            g.FillEllipse(ellipse, m_theme.FillBrush);

            switch (state.Type)
            {
            case StateType.Start:
                g.FillEllipse(innerEllipse, m_theme.TextBrush);
                break;

            case StateType.Final:
                g.DrawEllipse(ellipse, m_theme.OutlineBrush, 3.0f);
                g.FillEllipse(innerEllipse, m_theme.TextBrush);
                break;

            case StateType.ShallowHistory:
                g.DrawText("H", m_centerText, bounds, m_theme.TextBrush);
                break;

            case StateType.DeepHistory:
                g.DrawText("H*", m_centerText, bounds, m_theme.TextBrush);
                break;

            case StateType.Conditional:
                g.DrawText("C", m_centerText, bounds, m_theme.TextBrush);
                break;
            }

            if (outline && state.Type != StateType.Final)
            {
                g.DrawEllipse(ellipse, m_theme.OutlineBrush);
            }
        }
Example #2
0
        /// <summary>
        /// Draws a partially defined graph edge</summary>
        /// <param name="fromNode">Source node, or null</param>
        /// <param name="fromRoute">Source route, or null</param>
        /// <param name="toNode">Destination node, or null</param>
        /// <param name="toRoute">Destination route, or null</param>
        /// <param name="label">Edge label</param>
        /// <param name="endPoint">Endpoint to substitute for source or destination, if either is null</param>
        /// <param name="g">Graphics object</param>
        public override void Draw(
            TNode fromNode,
            BoundaryRoute fromRoute,
            TNode toNode,
            BoundaryRoute toRoute,
            string label,
            Point endPoint,
            D2dGraphics g)
        {
            // put endpoint into statechart space
            var inverse = g.Transform;

            inverse.Invert();
            PointF end = Matrix3x2F.TransformPoint(inverse, endPoint);

            PointF p1;
            PointF normal1;

            if (fromNode != null)
            {
                p1 = ParameterToPoint(fromNode.Bounds, fromRoute.Position, out normal1);
            }
            else
            {
                p1      = end;
                normal1 = new Point();
            }

            PointF p4;
            PointF normal2;

            if (toNode != null)
            {
                p4 = ParameterToPoint(toNode.Bounds, toRoute.Position, out normal2);
            }
            else
            {
                p4      = end;
                normal2 = new Point();
            }

            PointF p2, p3;
            float  d = GetTransitionPoints(p1, normal1, p4, normal2, out p2, out p3);

            DrawEdgeSpline(p1, p2, p3, p4, d, m_theme.OutlineBrush, g);

            if (!string.IsNullOrEmpty(label))
            {
                BezierCurve2F curve    = new BezierCurve2F(p1, p2, p3, p4);
                Vec2F         midpoint = curve.Evaluate(0.5f);
                g.DrawText(label, m_centerText, new PointF(midpoint.X, midpoint.Y), m_theme.TextBrush);
            }
        }
Example #3
0
        private void Draw(TNode node, D2dGraphics g)
        {
            RectangleF             boundRect = node.Bounds;
            D2dEllipse             bounds    = (D2dEllipse)boundRect;
            D2dLinearGradientBrush brush
                = m_theme.FillGradientBrush;

            brush.StartPoint = boundRect.Location;
            brush.EndPoint   = new PointF(boundRect.Right, boundRect.Bottom);
            g.FillEllipse(bounds, brush);
            g.DrawEllipse(bounds, m_theme.OutlineBrush);
            g.DrawText(node.TitleText, m_theme.TextFormat, boundRect, m_theme.TextBrush);
        }
Example #4
0
        private void Draw(TEdge edge, D2dBrush brush, D2dGraphics g)
        {
            PointF p1, p2, p3, p4;
            float  d = GetTransitionPoints(edge, out p1, out p2, out p3, out p4);

            DrawEdgeSpline(p1, p2, p3, p4, d, brush, g);
            GdiUtil.MakeRectangle(p1, p2);

            BezierCurve2F curve    = new BezierCurve2F(p1, p2, p3, p4);
            Vec2F         midpoint = curve.Evaluate(0.5f);

            midpoint.X += 2;
            string label = edge.Label;

            if (!string.IsNullOrEmpty(label))
            {
                g.DrawText(edge.Label, m_theme.TextFormat, new PointF(midpoint.X, midpoint.Y), m_theme.TextBrush);
            }
        }
Example #5
0
        /// <summary>
        /// Draws a partially defined graph edge</summary>
        /// <param name="fromNode">Source node, or null</param>
        /// <param name="fromRoute">Source route, or null</param>
        /// <param name="toNode">Destination node, or null</param>
        /// <param name="toRoute">Destination route, or null</param>
        /// <param name="label">Edge label</param>
        /// <param name="endPoint">Endpoint to substitute for source or destination (in client coords), if either is null</param>
        /// <param name="g">Graphics object</param>
        public override void Draw(
            TNode fromNode,
            NumberedRoute fromRoute,
            TNode toNode,
            NumberedRoute toRoute,
            string label,
            Point endPoint,
            D2dGraphics g)
        {
            var inverse = g.Transform;

            inverse.Invert();
            PointF end = Matrix3x2F.TransformPoint(inverse, endPoint);

            TNode   node     = (fromNode != null) ? fromNode : toNode;
            CircleF boundary = GetBoundary(node);
            Vec2F   proj     = new Vec2F();

            if (CircleF.Project(new Vec2F(end), boundary, ref proj))
            {
                PointF start = new PointF(proj.X, proj.Y);
                g.DrawLine(start, end, m_theme.OutlineBrush);

                if (fromNode == null)
                {
                    PointF temp = end;
                    end   = start;
                    start = temp;
                }
                Vec2F endTangent    = new Vec2F(end.X - start.X, end.Y - start.Y);
                Vec2F arrowPosition = new Vec2F(end);
                DrawArrow(arrowPosition, endTangent, m_theme.OutlineBrush, g);

                if (!string.IsNullOrEmpty(label))
                {
                    PointF     textPoint = new PointF((end.X + start.X) * 0.5f, (end.Y + start.Y) * 0.5f);
                    RectangleF textBox   = new RectangleF(textPoint.X - 512, textPoint.Y, 1024, m_theme.TextFormat.FontHeight);
                    //g.DrawString(label, m_theme.Font, m_theme.TextBrush, textBox, m_theme.CenterStringFormat);
                    g.DrawText(label, m_theme.TextFormat, textBox, m_theme.TextBrush);
                }
            }
        }
Example #6
0
        /// <summary>
        /// Draws the scrubber manipulator and calculates the bounding rectangle on the handle</summary>
        /// <param name="g">The graphics object to draw with</param>
        /// <param name="handleRect">The handle's bounding rectangle for pick tests, in view
        /// coordinates</param>
        protected virtual void DrawManipulator(D2dGraphics g, out RectangleF handleRect)
        {
            Matrix worldToView = Owner.Transform;

            float     viewX         = Sce.Atf.GdiUtil.Transform(worldToView, Position);
            Rectangle clipRectangle = Owner.VisibleClientRectangle;

            // allow only the arrow portion to be selected
            handleRect = new RectangleF(
                viewX - 5,
                clipRectangle.Top,
                10,
                7);

            g.DrawLine(viewX, clipRectangle.Top, viewX, clipRectangle.Bottom, s_color, 1.0f, null);

            Color handle_color = m_isMoving ? Color.Tomato : s_color;
            float pos_x        = viewX;
            float pos_y        = clipRectangle.Top + 5;

            s_arrow[0] = new PointF(pos_x - 4, pos_y - 5);
            s_arrow[1] = new PointF(pos_x - 4, pos_y);
            s_arrow[2] = new PointF(pos_x - 5, pos_y + 1);
            s_arrow[3] = new PointF(pos_x - 5, pos_y + 2);
            s_arrow[4] = new PointF(pos_x, pos_y + 7);
            s_arrow[5] = new PointF(pos_x + 5, pos_y + 2);
            s_arrow[6] = new PointF(pos_x + 5, pos_y + 1);
            s_arrow[7] = new PointF(pos_x + 4, pos_y);
            s_arrow[8] = new PointF(pos_x + 4, pos_y - 5);
            //g.FillPolygon(s_arrow, handle_color);   // Fill arrow
            // Draw arrow border with same gray Photoshop uses
            //g.DrawLines(s_arrow, Color.FromArgb(116, 114, 106), 3.0f);

            g.DrawLines(s_arrow, handle_color, 2.0f);

            string label = Position.ToString(CultureInfo.CurrentCulture);

            g.DrawText(label, Owner.Renderer.TextFormat, new PointF(pos_x + 6, clipRectangle.Top), SystemColors.WindowText);
        }
Example #7
0
        /// <summary>
        /// Draws floating group pin</summary>
        /// <param name="grpPin">Group pin</param>
        /// <param name="inputSide">True for input pin, false for output pin</param>
        /// <param name="style">DiagramDrawingStyle</param>
        /// <param name="g">Graphics object</param>
        public void DrawFloatingGroupPin(ICircuitGroupPin <TElement> grpPin, bool inputSide, DiagramDrawingStyle style, D2dGraphics g)
        {
            SizeF  pinNameSize = g.MeasureText(grpPin.Name, Theme.TextFormat);
            PointF p;

            if (inputSide)
            {
                p = GetGroupPinLocation(grpPin, true);

                RectangleF pinRect = new RectangleF(p.X + CircuitGroupPinInfo.FloatingPinBoxWidth - Theme.PinSize,
                                                    grpPin.Bounds.Location.Y + Theme.PinMargin + Theme.PinOffset,
                                                    Theme.PinSize, Theme.PinSize);
                // draw output pin for input floating pins
                g.DrawRectangle(pinRect, m_subGraphPinPen);
                if (grpPin.Info.Pinned)
                {
                    D2dUtil.DrawPin((int)(p.X + CircuitGroupPinInfo.FloatingPinBoxWidth), (int)p.Y, true, true, m_pinBrush, g);
                }
                else
                {
                    D2dUtil.DrawPin((int)(p.X + CircuitGroupPinInfo.FloatingPinBoxWidth), (int)p.Y + Theme.PinSize / 2, false, true, m_pinBrush, g);
                }

                RectangleF bounds    = new RectangleF(p.X, p.Y, CircuitGroupPinInfo.FloatingPinBoxWidth, CircuitGroupPinInfo.FloatingPinBoxHeight);
                RectangleF alignRect = new RectangleF(
                    bounds.Left, bounds.Bottom + Theme.PinMargin, pinNameSize.Width, Theme.RowSpacing);
                var textAlignment = Theme.TextFormat.TextAlignment;
                Theme.TextFormat.TextAlignment = D2dTextAlignment.Leading;
                g.DrawText(grpPin.Name, Theme.TextFormat, alignRect.Location, Theme.TextBrush);
                Theme.TextFormat.TextAlignment = textAlignment;
            }
            else
            {
                // assume vertical scroll bar width = 16
                p = GetGroupPinLocation(grpPin, false);

                RectangleF pinRect = new RectangleF(p.X + 1, grpPin.Bounds.Location.Y + Theme.PinMargin + Theme.PinOffset,
                                                    Theme.PinSize, Theme.PinSize);
                // draw input pin for output floating pins
                g.DrawRectangle(pinRect, m_subGraphPinPen);
                // draw pin icon
                if (grpPin.Info.Pinned)
                {
                    D2dUtil.DrawPin((int)p.X, (int)p.Y, true, false, m_pinBrush, g);
                }
                else
                {
                    D2dUtil.DrawPin((int)p.X, (int)p.Y + Theme.PinSize / 2, false, false, m_pinBrush, g);
                }

                // draw label
                RectangleF bounds     = new RectangleF(p.X, p.Y, CircuitGroupPinInfo.FloatingPinBoxWidth, CircuitGroupPinInfo.FloatingPinBoxHeight);
                RectangleF alignRectF = new RectangleF(bounds.Right - pinNameSize.Width, bounds.Bottom + Theme.PinMargin,
                                                       pinNameSize.Width, Theme.RowSpacing);

                var textAlignment = Theme.TextFormat.TextAlignment;
                Theme.TextFormat.TextAlignment = D2dTextAlignment.Trailing;
                g.DrawText(grpPin.Name, Theme.TextFormat, alignRectF, Theme.TextBrush);
                Theme.TextFormat.TextAlignment = textAlignment;
            }

            // draw the fake pin node itself
            float savedStrokeWidth = Theme.StrokeWidth;

            Theme.StrokeWidth = 2.0f;
            if (style == DiagramDrawingStyle.Normal)
            {
                g.DrawRectangle(new RectangleF(p.X, p.Y, CircuitGroupPinInfo.FloatingPinBoxWidth, CircuitGroupPinInfo.FloatingPinBoxHeight), m_subGraphPinNodePen);
            }
            else
            {
                g.DrawRectangle(new RectangleF(p.X, p.Y, CircuitGroupPinInfo.FloatingPinBoxWidth, CircuitGroupPinInfo.FloatingPinBoxHeight), Theme.HotBrush);
            }
            Theme.StrokeWidth = savedStrokeWidth;


            if (!grpPin.Info.ExternalConnected)
            {
                RectangleF eyeRect = GetVisibilityCheckRect(grpPin, inputSide);
                g.DrawEyeIcon(eyeRect, grpPin.Info.Visible ? m_visiblePinBrush : m_hiddrenPinBrush, 1.0f);
            }

            // draw fake edge that connects group pin fake node
            DrawGroupPinNodeFakeEdge(grpPin, p, inputSide, style, g);
        }
Example #8
0
        private void Draw(TEdge edge, D2dBrush brush, D2dGraphics g)
        {
            Vec2F   startPoint  = new Vec2F();
            Vec2F   endPoint    = new Vec2F();
            CircleF c           = new CircleF();
            bool    moreThan180 = false;
            Vec2F   endTangent;
            Vec2F   textPoint;
            int     route = edge.FromRoute.Index;

            if (GetEdgeGeometry(edge, route, ref startPoint, ref endPoint, ref c, ref moreThan180))
            {
                g.DrawLine(new PointF(startPoint.X, startPoint.Y),
                           new PointF(endPoint.X, endPoint.Y),
                           brush,
                           m_theme.StrokeWidth);

                endTangent = endPoint - startPoint;
                textPoint  = (endPoint + startPoint) * 0.5f;
            }
            else
            {
                // prepare to draw arc
                RectangleF rect = new RectangleF(c.Center.X - c.Radius, c.Center.Y - c.Radius, 2 * c.Radius, 2 * c.Radius);

                double       angle1 = Math.Atan2(startPoint.Y - c.Center.Y, startPoint.X - c.Center.X);
                double       angle2 = Math.Atan2(endPoint.Y - c.Center.Y, endPoint.X - c.Center.X);
                const double twoPi  = 2 * Math.PI;

                // swap so we always go clockwise
                if (angle1 > angle2)
                {
                    double temp = angle1;
                    angle1 = angle2;
                    angle2 = temp;
                }

                double startAngle = angle1;
                double sweepAngle = angle2 - angle1;

                if (moreThan180)
                {
                    if (sweepAngle < Math.PI)
                    {
                        sweepAngle = -(twoPi - sweepAngle);
                    }
                }
                else
                {
                    if (sweepAngle > Math.PI)
                    {
                        sweepAngle = -(twoPi - sweepAngle);
                    }
                }

                const double RadiansToDegrees = 360 / twoPi;
                startAngle *= RadiansToDegrees;
                sweepAngle *= RadiansToDegrees;

                g.DrawArc((D2dEllipse)rect,
                          brush,
                          (float)startAngle,
                          (float)sweepAngle,
                          m_theme.StrokeWidth);

                endTangent = endPoint - c.Center; endTangent = endTangent.Perp;
                textPoint  = (endPoint + startPoint) * 0.5f;
                CircleF.Project(textPoint, c, ref textPoint);
                if (moreThan180)
                {
                    textPoint -= 2 * (textPoint - c.Center);
                }
            }

            DrawArrow(endPoint, endTangent, brush, g);

            string label = edge.Label;

            if (!string.IsNullOrEmpty(label))
            {
                RectangleF textBox = new RectangleF(textPoint.X - 512, textPoint.Y, 1024, m_theme.TextFormat.FontHeight);
                g.DrawText(label, m_theme.TextFormat, textBox, m_theme.TextBrush);
            }
        }
Example #9
0
        /// <summary>
        /// Draws a horizontal chart scale</summary>
        /// <param name="g">The Direct2D graphics object</param>
        /// <param name="transform">Graph (world) to window's client (screen) transform</param>
        /// <param name="graphRect">Graph rectangle</param>
        /// <param name="top">Whether or not the scale should be aligned along the top of the rectangle</param>
        /// <param name="majorSpacing">Spacing, in pixels, between major tick marks</param>
        /// <param name="minimumGraphStep">Minimum spacing, in graph (world) space, between ticks.
        /// For example, 1.0 would limit ticks to being drawn on whole integers.</param>
        /// <param name="lineBrush">Scale line pen</param>
        /// <param name="textFormat">Text format</param>
        /// <param name="textBrush">Text brush</param>
        public static void DrawHorizontalScale(
            this D2dGraphics g,
            Matrix transform,
            RectangleF graphRect,
            bool top,
            int majorSpacing,
            float minimumGraphStep,
            D2dBrush lineBrush,
            D2dTextFormat textFormat,
            D2dBrush textBrush)
        {
            double     xScale     = transform.Elements[0];
            RectangleF clientRect = Transform(transform, graphRect);

            double tickEnd, majorTickStart, minorTickStart, textStart;

            if (top)
            {
                tickEnd        = clientRect.Top + 1;
                majorTickStart = tickEnd + 12;
                minorTickStart = tickEnd + 6;
                textStart      = tickEnd + 8;
            }
            else
            {
                tickEnd        = clientRect.Bottom - 1;
                majorTickStart = tickEnd - 12;
                minorTickStart = tickEnd - 6;
                textStart      = tickEnd - 19;
            }

            double min = Math.Min(graphRect.Left, graphRect.Right);
            double max = Math.Max(graphRect.Left, graphRect.Right);

            double tickAnchor     = CalculateTickAnchor(min, max);
            double majorGraphStep = CalculateStep(
                min, max, Math.Abs(clientRect.Right - clientRect.Left), majorSpacing, minimumGraphStep);
            int    numMinorTicks = CalculateNumMinorTicks(majorGraphStep, minimumGraphStep, 5);
            double cMinorStep    = (majorGraphStep / numMinorTicks) * xScale;

            if (majorGraphStep > 0)
            {
                double offset = tickAnchor - min;
                offset = offset - MathUtil.Remainder(offset, majorGraphStep);

                // draw leading minor ticks
                double cmx;
                cmx = ((tickAnchor - (offset + majorGraphStep)) - min) * xScale + clientRect.Left + cMinorStep;
                for (int i = 0; i < numMinorTicks - 1 && cmx < clientRect.Right; i++)
                {
                    // cull minor ticks outside of the view
                    if (cmx > clientRect.Left)
                    {
                        g.DrawLine((float)cmx, (float)minorTickStart, (float)cmx, (float)tickEnd, lineBrush);
                    }
                    cmx += cMinorStep;
                }

                for (double x = tickAnchor - offset; x < max; x += majorGraphStep)
                {
                    double cx = (x - min) * xScale + clientRect.Left;
                    g.DrawLine((float)cx, (float)majorTickStart, (float)cx, (float)tickEnd, lineBrush);
                    string xString  = String.Format("{0:G8}", Math.Round(x, 6));
                    SizeF  textSize = g.MeasureText(xString, textFormat);
                    var    textRect = new RectangleF(new PointF((float)cx + 1, (float)textStart), textSize);
                    g.DrawText(xString, textFormat, textRect, textBrush);

                    // draw minor ticks
                    cmx = cx + cMinorStep;
                    for (int i = 0; i < numMinorTicks - 1 && cmx < clientRect.Right; i++)
                    {
                        g.DrawLine((float)cmx, (float)minorTickStart, (float)cmx, (float)tickEnd, lineBrush);
                        cmx += cMinorStep;
                    }
                }
            }
        }
Example #10
0
        private void Draw(TNode state, D2dGraphics g, bool outline)
        {
            RectangleF bounds = state.Bounds;

            if (state.Type != StateType.Normal)
            {
                DrawPseudostate(state, g, outline);
            }
            else
            {
                float scaleX     = g.Transform.M11; // assume no rotation.
                float radInPixel = scaleX * CornerRadius;

                IComplexState <TNode, TEdge> complexState = state as IComplexState <TNode, TEdge>;

                StateIndicators indicators = state.Indicators;
                if ((indicators & StateIndicators.Active) != 0)
                {
                    if (radInPixel > MinRadiusInPixel)
                    {
                        D2dEllipse ellipse = new D2dEllipse();
                        ellipse.RadiusX = CornerRadius;
                        ellipse.RadiusY = CornerRadius;
                        ellipse.Center  = bounds.Location;
                        g.FillEllipse(ellipse, Color.SpringGreen);
                    }
                }


                if (radInPixel > MinRadiusInPixel)
                {
                    m_stateRect.Rect = bounds;
                    D2dLinearGradientBrush gradbrush = m_theme.FillGradientBrush;
                    gradbrush.StartPoint = bounds.Location;
                    gradbrush.EndPoint   = new PointF(bounds.Right, bounds.Bottom);

                    g.FillRoundedRectangle(m_stateRect, gradbrush);
                    if (outline)
                    {
                        g.DrawRoundedRectangle(m_stateRect, m_theme.OutlineBrush);
                    }
                }
                else
                {
                    g.FillRectangle(bounds, m_theme.FillBrush);
                    if (outline)
                    {
                        g.DrawRectangle(bounds, m_theme.OutlineBrush);
                    }
                }
                g.DrawLine(bounds.Left, bounds.Top + m_fontHeight + Margin,
                           bounds.Right, bounds.Top + m_fontHeight + Margin, m_theme.OutlineBrush);

                if ((scaleX * m_fontHeight) > MinFontHeightInPixel)
                {
                    g.DrawText(complexState.TitleText, m_theme.TextFormat,
                               new PointF(bounds.X + CornerRadius, bounds.Y + Margin), m_theme.TextBrush);
                }



                //RectangleF textBounds = new RectangleF(
                //    (float)(bounds.Left + 4),
                //    (float)(bounds.Top + m_fontHeight + 2),
                //    (float)(bounds.Width - 5),
                //    (float)(bounds.Height - m_fontHeight - 4));

                //g.DrawString(complexState.Text, m_theme.Font, m_theme.TextBrush, textBounds, s_stateTextFormat);

                //IList<int> partitionWidths = complexState.PartitionSizes;
                //if (partitionWidths.Count > 0)
                //{
                //    // draw AND-state dividers
                //    int lastDivider = bounds.Left;
                //    foreach (int width in partitionWidths)
                //    {
                //        g.DrawLine(
                //            m_dividerPen,
                //            lastDivider, bounds.Y + m_fontHeight + Margin,
                //            lastDivider, bounds.Y + bounds.Height);

                //        lastDivider += width;
                //    }
                //}
            }
        }