/// <summary>
        /// Helper method to create the tail of the bubble, so we can also calculate the bounds
        /// </summary>
        /// <returns></returns>
        private GraphicsPath CreateTail()
        {
            Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);

            int tailLength = GeometryHelper.Distance2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Left, TargetGripper.Top);
            int tailWidth  = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20;

            // This should fix a problem with the tail being to wide
            tailWidth = Math.Min(Math.Abs(rect.Width) / 2, tailWidth);
            tailWidth = Math.Min(Math.Abs(rect.Height) / 2, tailWidth);

            GraphicsPath tail = new GraphicsPath();

            tail.AddLine(-tailWidth, 0, tailWidth, 0);
            tail.AddLine(tailWidth, 0, 0, -tailLength);
            tail.CloseFigure();

            int tailAngle = 90 + (int)GeometryHelper.Angle2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Left, TargetGripper.Top);

            using (Matrix tailMatrix = new Matrix())
            {
                tailMatrix.Translate(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2));
                tailMatrix.Rotate(tailAngle);
                tail.Transform(tailMatrix);
            }

            return(tail);
        }
Esempio n. 2
0
        /// <summary>
        ///     Helper method to create the tail of the bubble, so we can also calculate the bounds
        /// </summary>
        /// <returns></returns>
        private GraphicsPath CreateTail()
        {
            var rect = new NativeRect(Left, Top, Width, Height).Normalize();

            var tailLength = GeometryHelper.Distance2D(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2, TargetAdorner.Location.X, TargetAdorner.Location.Y);
            var tailWidth  = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20;

            // This should fix a problem with the tail being to wide
            tailWidth = Math.Min(Math.Abs(rect.Width) / 2, tailWidth);
            tailWidth = Math.Min(Math.Abs(rect.Height) / 2, tailWidth);

            var tail = new GraphicsPath();

            tail.AddLine(-tailWidth, 0, tailWidth, 0);
            tail.AddLine(tailWidth, 0, 0, -tailLength);
            tail.CloseFigure();

            var tailAngle = 90 + (int)GeometryHelper.Angle2D(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2, TargetAdorner.Location.X, TargetAdorner.Location.Y);

            using (var tailMatrix = new Matrix())
            {
                tailMatrix.Translate(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2);
                tailMatrix.Rotate(tailAngle);
                tail.Transform(tailMatrix);
            }

            return(tail);
        }
Esempio n. 3
0
        public override void Draw(Graphics graphics, RenderMode renderMode)
        {
            if (TargetGripper == null)
            {
                return;
            }
            graphics.SmoothingMode      = SmoothingMode.HighQuality;
            graphics.InterpolationMode  = InterpolationMode.HighQualityBicubic;
            graphics.CompositingQuality = CompositingQuality.HighQuality;
            graphics.PixelOffsetMode    = PixelOffsetMode.None;
            graphics.TextRenderingHint  = TextRenderingHint.AntiAliasGridFit;

            Color lineColor     = GetFieldValueAsColor(FieldType.LINE_COLOR);
            Color fillColor     = GetFieldValueAsColor(FieldType.FILL_COLOR);
            int   lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);

            bool      lineVisible = (lineThickness > 0 && Colors.IsVisible(lineColor));
            Rectangle rect        = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);

            if (Selected && renderMode == RenderMode.EDIT)
            {
                DrawSelectionBorder(graphics, rect);
            }

            int tailAngle  = 90 + (int)GeometryHelper.Angle2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Left, TargetGripper.Top);
            int tailLength = GeometryHelper.Distance2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Left, TargetGripper.Top);
            int tailWidth  = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20;

            GraphicsPath bubble = new GraphicsPath();
            // adapt corner radius to small rectangle dimensions
            int smallerSideLength = Math.Min(rect.Width, rect.Height);
            int cornerRadius      = smallerSideLength > 60 ? 30 : smallerSideLength / 2;

            if (cornerRadius > 5)
            {
                Rectangle bubbleRect = GuiRectangle.GetGuiRectangle(0, 0, rect.Width, rect.Height);
                bubbleRect = Rectangle.Inflate(bubbleRect, -lineThickness, -lineThickness);
                bubble.AddArc(bubbleRect.X, bubbleRect.Y, cornerRadius, cornerRadius, 180, 90);
                bubble.AddArc(bubbleRect.X + bubbleRect.Width - cornerRadius, bubbleRect.Y, cornerRadius, cornerRadius, 270, 90);
                bubble.AddArc(bubbleRect.X + bubbleRect.Width - cornerRadius, bubbleRect.Y + bubbleRect.Height - cornerRadius, cornerRadius, cornerRadius, 0, 90);
                bubble.AddArc(bubbleRect.X, bubbleRect.Y + bubbleRect.Height - cornerRadius, cornerRadius, cornerRadius, 90, 90);
            }

            //bubble.AddRectangle(GuiRectangle.GetGuiRectangle(0, 0, rect.Width, rect.Height));
            //bubble.AddEllipse(0, 0, Math.Abs(rect.Width), Math.Abs(rect.Height));
            bubble.CloseAllFigures();

            GraphicsPath tail = new GraphicsPath();

            tail.AddLine(-tailWidth, 0, tailWidth, 0);
            tail.AddLine(tailWidth, 0, 0, -tailLength);
            tail.CloseFigure();

            GraphicsState state = graphics.Save();

            // draw the tail border where the bubble is not visible
            using (Region clipRegion = new Region(bubble))
            {
                clipRegion.Translate(rect.Left, rect.Top);
                graphics.SetClip(clipRegion, CombineMode.Exclude);
                graphics.TranslateTransform(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2));
                graphics.RotateTransform(tailAngle);
                using (Pen pen = new Pen(lineColor, lineThickness))
                {
                    graphics.DrawPath(pen, tail);
                }
            }
            graphics.Restore(state);

            if (Colors.IsVisible(fillColor))
            {
                //draw the bubbleshape
                state = graphics.Save();
                graphics.TranslateTransform(rect.Left, rect.Top);
                using (Brush brush = new SolidBrush(fillColor))
                {
                    graphics.FillPath(brush, bubble);
                }
                graphics.Restore(state);
            }

            if (lineVisible)
            {
                //draw the bubble border
                state = graphics.Save();
                // Draw bubble where the Tail is not visible.
                using (Region clipRegion = new Region(tail))
                {
                    using (Matrix transformMatrix = new Matrix())
                    {
                        transformMatrix.Rotate(tailAngle);
                        clipRegion.Transform(transformMatrix);
                    }
                    clipRegion.Translate(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2));
                    graphics.SetClip(clipRegion, CombineMode.Exclude);
                    graphics.TranslateTransform(rect.Left, rect.Top);
                    using (Pen pen = new Pen(lineColor, lineThickness))
                    {
                        //pen.EndCap = pen.StartCap = LineCap.Round;
                        graphics.DrawPath(pen, bubble);
                    }
                }
                graphics.Restore(state);
            }

            if (Colors.IsVisible(fillColor))
            {
                // Draw the tail border
                state = graphics.Save();
                graphics.TranslateTransform(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2));
                graphics.RotateTransform(tailAngle);
                using (Brush brush = new SolidBrush(fillColor))
                {
                    graphics.FillPath(brush, tail);
                }
                graphics.Restore(state);
            }

            // cleanup the paths
            bubble.Dispose();
            tail.Dispose();

            // Draw the text
            UpdateFormat();
            DrawText(graphics, rect, lineThickness, ControlPaint.Dark(lineColor, 0.25f), false, StringFormat, Text, Font);
        }