Exemplo n.º 1
0
        /// <summary>
        /// Paints tooltip for a single control.
        /// </summary>
        private void doPaintTooltip(Graphics g, Font f, TooltipToPaint ttp)
        {
            int width = AbsRect.Width;
            int height = AbsRect.Height;
            // Painting children will have set all sorts of clip and transform
            g.ResetClip();
            g.ResetTransform();

            // This will be bubble's rectangle, and the polygon representing the needle.
            Rectangle brect;
            Point[] points;
            // This, the text's inside the bubble
            Rectangle trect;
            // Measure tooltip text as if we had all the width in the world (well, within canvas at least)
            g.TextRenderingHint = TextRenderingHint.AntiAlias;
            StringFormat sf = StringFormat.GenericDefault;
            SizeF szF = g.MeasureString(ttp.TTI.Tooltip.Text, f, width - 2 * tooltipPadding);
            Size sz = new Size((int)Math.Ceiling(szF.Width), (int)Math.Ceiling(szF.Height));

            // Tooltip is at the north
            if (ttp.TTI.Tooltip.TooltipLocation == TooltipLocation.North)
            {
                // Look at tooltip's left and right bounds: what control wishes, and how much space we have in window.
                // We assume control's smart enough to request a bubble that fits vertically. We control for breadth.
                int left, right;
                // Center aligned over needle
                if (ttp.TTI.Tooltip.TopOrSide == int.MinValue)
                {
                    left = ttp.TTI.Tooltip.NeedlePos + ttp.Ctrl.AbsLeft - sz.Width / 2 - tooltipPadding;
                    right = left + sz.Width + 2 * tooltipPadding;
                }
                // Right aligned
                else if (ttp.TTI.Tooltip.TopOrSide < 0)
                {
                    int x = -ttp.TTI.Tooltip.TopOrSide;
                    right = ttp.Ctrl.AbsLeft + x;
                    left = right - sz.Width - 2 * tooltipPadding;
                }
                // Left aligned
                else
                {
                    left = ttp.Ctrl.AbsLeft + ttp.TTI.Tooltip.TopOrSide;
                    right = left + sz.Width + 2 * tooltipPadding;
                }
                // Fix left and right so they're never outside canvas
                if (right > width) { left -= (right - width); right = width; }
                if (left < 0) { right += -left; left = 0; }
                // If this is less space than text's desired width, re-measure
                // May need more lines
                if (right - left - 2 * tooltipPadding < sz.Width)
                {
                    szF = g.MeasureString(ttp.TTI.Tooltip.Text, f, right - left);
                    sz = new Size((int)Math.Ceiling(szF.Width), (int)Math.Ceiling(szF.Height));
                }
                // So, we got our rectangles
                brect = new Rectangle(
                    left,
                    ttp.Ctrl.AbsTop - ttp.TTI.Tooltip.NeedleHeight - sz.Height - tooltipPadding,
                    sz.Width + 2 * tooltipPadding, sz.Height + tooltipPadding);
                trect = brect;
                trect.X += tooltipPadding;
                trect.Y += tooltipPadding / 2;
                trect.Width -= 2 * tooltipPadding;
                trect.Height -= tooltipPadding / 2;
                // Bubble with needle
                int npos = ttp.TTI.Tooltip.NeedlePos;
                int nheight = ttp.TTI.Tooltip.NeedleHeight;
                points = new Point[]
                {
                    new Point(ttp.Ctrl.AbsLeft + npos, ttp.Ctrl.AbsTop),
                    new Point(ttp.Ctrl.AbsLeft + npos + nheight, ttp.Ctrl.AbsTop - nheight),
                    new Point(brect.Right, brect.Bottom),
                    new Point(brect.Right, brect.Top),
                    new Point(brect.Left, brect.Top),
                    new Point(brect.Left, brect.Bottom),
                    new Point(ttp.Ctrl.AbsLeft + npos - nheight, ttp.Ctrl.AbsTop - nheight),
                    new Point(ttp.Ctrl.AbsLeft + npos, ttp.Ctrl.AbsTop),
                };
            }
            // Tooltip is at the west
            else if (ttp.TTI.Tooltip.TooltipLocation == TooltipLocation.West)
            {
                // Look at tooltip's top and bottom bounds: what control wishes, and how much space we have in window.
                // We assume control's smart enough to request a bubble that fits horizontally. We control for height.
                int top = 0;
                int bottom = 0;
                // Center aligned next to needle
                if (ttp.TTI.Tooltip.TopOrSide == int.MinValue)
                {
                    top = ttp.TTI.Tooltip.NeedlePos + ttp.Ctrl.AbsTop - sz.Height / 2 - tooltipPadding / 2;
                    bottom = top + sz.Height + tooltipPadding;
                }
                // Top aligned
                else if (ttp.TTI.Tooltip.TopOrSide > 0)
                {
                    int y = ttp.TTI.Tooltip.TopOrSide;
                    top = ttp.Ctrl.AbsTop + y;
                    bottom = top + sz.Height + tooltipPadding;
                }
                // Fix top and bottom so they're never outside canvas
                if (bottom > height) { bottom = height; top = bottom - sz.Height; }
                if (top < 0) { top = 0; bottom = top + height; }
                // So, we got our rectangles
                brect = new Rectangle(
                    ttp.Ctrl.AbsLeft - ttp.TTI.Tooltip.NeedleHeight - sz.Width - 2 * tooltipPadding, top,
                    sz.Width + 2 * tooltipPadding, sz.Height + tooltipPadding);
                trect = brect;
                trect.X += tooltipPadding;
                trect.Y += tooltipPadding / 2;
                trect.Width -= 2 * tooltipPadding;
                trect.Height -= tooltipPadding / 2;
                // Bubble with needle
                int npos = ttp.TTI.Tooltip.NeedlePos;
                int nwidth = ttp.TTI.Tooltip.NeedleHeight;
                points = new Point[]
                {
                    new Point(ttp.Ctrl.AbsLeft, ttp.Ctrl.AbsTop + npos),
                    new Point(ttp.Ctrl.AbsLeft - nwidth, ttp.Ctrl.AbsTop + npos - nwidth),
                    new Point(brect.Right, brect.Top),
                    new Point(brect.Left, brect.Top),
                    new Point(brect.Left, brect.Bottom),
                    new Point(brect.Right, brect.Bottom),
                    new Point(brect.Right, ttp.Ctrl.AbsTop + npos + nwidth),
                    new Point(ttp.Ctrl.AbsLeft, ttp.Ctrl.AbsTop + npos),
                };
            }
            // TO-DO: tooltip at east. Will do when needed.
            else
            {
                // These rectangles will crash FillPolygon below. Goed zo.
                brect = new Rectangle(0, 0, 0, 0);
                trect = new Rectangle(0, 0, 0, 0);
                points = new Point[0];
            }

            // Draw bubble
            g.SmoothingMode = SmoothingMode.HighQuality;
            float alfa = ((float)ZenParams.TooltipMaxAlfa) * ttp.Strength;
            using (Brush b = new SolidBrush(Color.FromArgb((int)alfa, ZenParams.TooltipBackColor)))
            {
                g.FillPolygon(b, points);
            }
            // Write text
            alfa = 255F * ttp.Strength;
            using (Brush b = new SolidBrush(Color.FromArgb((int)alfa, ZenParams.TooltipTextColor)))
            {
                g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                g.DrawString(ttp.TTI.Tooltip.Text, f, b, trect);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Paints tooltip for a single control.
        /// </summary>
        private void doPaintTooltip(Graphics g, Font f, TooltipToPaint ttp)
        {
            int width  = AbsRect.Width;
            int height = AbsRect.Height;

            // Painting children will have set all sorts of clip and transform
            g.ResetClip();
            g.ResetTransform();

            // This will be bubble's rectangle, and the polygon representing the needle.
            Rectangle brect;

            Point[] points;
            // This, the text's inside the bubble
            Rectangle trect;

            // Measure tooltip text as if we had all the width in the world (well, within canvas at least)
            g.TextRenderingHint = TextRenderingHint.AntiAlias;
            StringFormat sf  = StringFormat.GenericDefault;
            SizeF        szF = g.MeasureString(ttp.TTI.Tooltip.Text, f, width - 2 * tooltipPadding);
            Size         sz  = new Size((int)Math.Ceiling(szF.Width), (int)Math.Ceiling(szF.Height));

            // Tooltip is at the north
            if (ttp.TTI.Tooltip.TooltipLocation == TooltipLocation.North)
            {
                // Look at tooltip's left and right bounds: what control wishes, and how much space we have in window.
                // We assume control's smart enough to request a bubble that fits vertically. We control for breadth.
                int left, right;
                // Center aligned over needle
                if (ttp.TTI.Tooltip.TopOrSide == int.MinValue)
                {
                    left  = ttp.TTI.Tooltip.NeedlePos + ttp.Ctrl.AbsLeft - sz.Width / 2 - tooltipPadding;
                    right = left + sz.Width + 2 * tooltipPadding;
                }
                // Right aligned
                else if (ttp.TTI.Tooltip.TopOrSide < 0)
                {
                    int x = -ttp.TTI.Tooltip.TopOrSide;
                    right = ttp.Ctrl.AbsLeft + x;
                    left  = right - sz.Width - 2 * tooltipPadding;
                }
                // Left aligned
                else
                {
                    left  = ttp.Ctrl.AbsLeft + ttp.TTI.Tooltip.TopOrSide;
                    right = left + sz.Width + 2 * tooltipPadding;
                }
                // Fix left and right so they're never outside canvas
                if (right > width)
                {
                    left -= (right - width); right = width;
                }
                if (left < 0)
                {
                    right += -left; left = 0;
                }
                // If this is less space than text's desired width, re-measure
                // May need more lines
                if (right - left - 2 * tooltipPadding < sz.Width)
                {
                    szF = g.MeasureString(ttp.TTI.Tooltip.Text, f, right - left);
                    sz  = new Size((int)Math.Ceiling(szF.Width), (int)Math.Ceiling(szF.Height));
                }
                // So, we got our rectangles
                brect = new Rectangle(
                    left,
                    ttp.Ctrl.AbsTop - ttp.TTI.Tooltip.NeedleHeight - sz.Height - tooltipPadding,
                    sz.Width + 2 * tooltipPadding, sz.Height + tooltipPadding);
                trect         = brect;
                trect.X      += tooltipPadding;
                trect.Y      += tooltipPadding / 2;
                trect.Width  -= 2 * tooltipPadding;
                trect.Height -= tooltipPadding / 2;
                // Bubble with needle
                int npos    = ttp.TTI.Tooltip.NeedlePos;
                int nheight = ttp.TTI.Tooltip.NeedleHeight;
                points = new Point[]
                {
                    new Point(ttp.Ctrl.AbsLeft + npos, ttp.Ctrl.AbsTop),
                    new Point(ttp.Ctrl.AbsLeft + npos + nheight, ttp.Ctrl.AbsTop - nheight),
                    new Point(brect.Right, brect.Bottom),
                    new Point(brect.Right, brect.Top),
                    new Point(brect.Left, brect.Top),
                    new Point(brect.Left, brect.Bottom),
                    new Point(ttp.Ctrl.AbsLeft + npos - nheight, ttp.Ctrl.AbsTop - nheight),
                    new Point(ttp.Ctrl.AbsLeft + npos, ttp.Ctrl.AbsTop),
                };
            }
            // Tooltip is at the west
            else if (ttp.TTI.Tooltip.TooltipLocation == TooltipLocation.West)
            {
                // Look at tooltip's top and bottom bounds: what control wishes, and how much space we have in window.
                // We assume control's smart enough to request a bubble that fits horizontally. We control for height.
                int top    = 0;
                int bottom = 0;
                // Center aligned next to needle
                if (ttp.TTI.Tooltip.TopOrSide == int.MinValue)
                {
                    top    = ttp.TTI.Tooltip.NeedlePos + ttp.Ctrl.AbsTop - sz.Height / 2 - tooltipPadding / 2;
                    bottom = top + sz.Height + tooltipPadding;
                }
                // Top aligned
                else if (ttp.TTI.Tooltip.TopOrSide > 0)
                {
                    int y = ttp.TTI.Tooltip.TopOrSide;
                    top    = ttp.Ctrl.AbsTop + y;
                    bottom = top + sz.Height + tooltipPadding;
                }
                // Fix top and bottom so they're never outside canvas
                if (bottom > height)
                {
                    bottom = height; top = bottom - sz.Height;
                }
                if (top < 0)
                {
                    top = 0; bottom = top + height;
                }
                // So, we got our rectangles
                brect = new Rectangle(
                    ttp.Ctrl.AbsLeft - ttp.TTI.Tooltip.NeedleHeight - sz.Width - 2 * tooltipPadding, top,
                    sz.Width + 2 * tooltipPadding, sz.Height + tooltipPadding);
                trect         = brect;
                trect.X      += tooltipPadding;
                trect.Y      += tooltipPadding / 2;
                trect.Width  -= 2 * tooltipPadding;
                trect.Height -= tooltipPadding / 2;
                // Bubble with needle
                int npos   = ttp.TTI.Tooltip.NeedlePos;
                int nwidth = ttp.TTI.Tooltip.NeedleHeight;
                points = new Point[]
                {
                    new Point(ttp.Ctrl.AbsLeft, ttp.Ctrl.AbsTop + npos),
                    new Point(ttp.Ctrl.AbsLeft - nwidth, ttp.Ctrl.AbsTop + npos - nwidth),
                    new Point(brect.Right, brect.Top),
                    new Point(brect.Left, brect.Top),
                    new Point(brect.Left, brect.Bottom),
                    new Point(brect.Right, brect.Bottom),
                    new Point(brect.Right, ttp.Ctrl.AbsTop + npos + nwidth),
                    new Point(ttp.Ctrl.AbsLeft, ttp.Ctrl.AbsTop + npos),
                };
            }
            // TO-DO: tooltip at east. Will do when needed.
            else
            {
                // These rectangles will crash FillPolygon below. Goed zo.
                brect  = new Rectangle(0, 0, 0, 0);
                trect  = new Rectangle(0, 0, 0, 0);
                points = new Point[0];
            }

            // Draw bubble
            g.SmoothingMode = SmoothingMode.HighQuality;
            float alfa = ((float)ZenParams.TooltipMaxAlfa) * ttp.Strength;

            using (Brush b = new SolidBrush(Color.FromArgb((int)alfa, ZenParams.TooltipBackColor)))
            {
                g.FillPolygon(b, points);
            }
            // Write text
            alfa = 255F * ttp.Strength;
            using (Brush b = new SolidBrush(Color.FromArgb((int)alfa, ZenParams.TooltipTextColor)))
            {
                g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                g.DrawString(ttp.TTI.Tooltip.Text, f, b, trect);
            }
        }