Пример #1
0
        // TODO: Use VisualStyles stuff in .NET 2.0 instead
        /// <summary>
        /// Draws a button in the appropriate system theme (Aero vs. Luna vs. Classic).
        /// </summary>
        /// <remarks>
        /// Note to implementors: This may be implemented as a simple thunk to ControlPaint.DrawButton().
        /// </remarks>
        public static void DrawThemedButton(
            Control hostControl,
            Graphics g,
            int x,
            int y,
            int width,
            int height,
            UI.ButtonState state)
        {
            System.Windows.Forms.ButtonState swfState;

            switch (state)
            {
            case UI.ButtonState.Disabled:
                swfState = System.Windows.Forms.ButtonState.Inactive;
                break;

            default:
            case UI.ButtonState.Hot:
            case UI.ButtonState.Normal:
                swfState = System.Windows.Forms.ButtonState.Normal;
                break;

            case UI.ButtonState.Pressed:
                swfState = System.Windows.Forms.ButtonState.Pushed;
                break;
            }

            ControlPaint.DrawButton(g, x, y, width, height, swfState);


            GC.KeepAlive(hostControl);
        }
Пример #2
0
        protected override void OnPaintButton(Graphics g, UI.ButtonState state, bool drawAsDefault, bool drawFocusCues, bool drawKeyboardCues)
        {
            UI.ButtonState newState;

            if (this.forcedPushed)
            {
                newState = UI.ButtonState.Pressed;
            }
            else
            {
                newState = state;
            }

            OnPaintButtonImpl(g, newState, drawAsDefault, drawFocusCues, drawKeyboardCues);
        }
Пример #3
0
            public void SetPartRenderState(ItemPart itemPart, UI.ButtonState renderState)
            {
                switch (itemPart)
                {
                case ItemPart.None:
                    break;

                case ItemPart.CloseButton:
                    CloseRenderState = renderState;
                    break;

                case ItemPart.Image:
                    ImageRenderState = renderState;
                    break;

                default:
                    throw new InvalidEnumArgumentException();
                }
            }
Пример #4
0
        private void OnPaintButtonImpl(Graphics g, UI.ButtonState state, bool drawAsDefault, bool drawFocusCues, bool drawKeyboardCues)
        {
            Color backColor;
            Color outlineColor;
            Color arrowFillColor;
            Color arrowOutlineColor;

            switch (state)
            {
            case UI.ButtonState.Disabled:
                backColor         = Color.Transparent;
                outlineColor      = BackColor;
                arrowFillColor    = Color.Gray;
                arrowOutlineColor = Color.Black;
                break;

            case UI.ButtonState.Hot:
                backColor         = Color.FromArgb(64, SystemColors.HotTrack);
                outlineColor      = backColor;
                arrowFillColor    = Color.Blue;
                arrowOutlineColor = Color.White;
                break;

            case UI.ButtonState.Normal:
                backColor         = Color.Transparent;
                outlineColor      = Color.Transparent;
                arrowFillColor    = Color.Black;
                arrowOutlineColor = Color.White;
                break;

            case UI.ButtonState.Pressed:
                backColor         = Color.FromArgb(192, SystemColors.Highlight);
                outlineColor      = Color.FromArgb(192, SystemColors.Highlight);
                arrowFillColor    = Color.Blue;
                arrowOutlineColor = Color.White;
                break;

            default:
                throw new InvalidEnumArgumentException("buttonState");
            }

            // Draw parent background
            IPaintBackground asIpb = Parent as IPaintBackground;

            if (!this.drawWithGradient || asIpb == null)
            {
                if (asIpb != null)
                {
                    Rectangle screenRect = RectangleToScreen(ClientRectangle);
                    Rectangle parentRect = Parent.RectangleToClient(screenRect);

                    g.TranslateTransform(-Left, -Top, MatrixOrder.Append);
                    asIpb.PaintBackground(g, parentRect);
                    g.TranslateTransform(+Left, +Top, MatrixOrder.Append);
                }
                else
                {
                    using (SolidBrush backBrush = new SolidBrush(BackColor))
                    {
                        g.FillRectangle(backBrush, ClientRectangle);
                    }
                }
            }
            else
            {
                if (this.backBufferSurface != null &&
                    (this.backBufferSurface.Width != ClientSize.Width || this.backBufferSurface.Height != ClientSize.Height))
                {
                    this.backBuffer.Dispose();
                    this.backBuffer = null;

                    this.backBufferSurface.Dispose();
                    this.backBufferSurface = null;
                }

                if (this.backBufferSurface == null)
                {
                    this.backBufferSurface = new Surface(ClientSize.Width, ClientSize.Height);
                    this.backBuffer        = new RenderArgs(this.backBufferSurface);
                }

                Rectangle screenRect = RectangleToScreen(ClientRectangle);
                Rectangle parentRect = Parent.RectangleToClient(screenRect);

                using (Graphics bg = Graphics.FromImage(this.backBuffer.Bitmap))
                {
                    bg.TranslateTransform(-Left, -Top, MatrixOrder.Append);
                    asIpb.PaintBackground(bg, parentRect);
                }

                BitmapData bitmapData = this.backBuffer.Bitmap.LockBits(
                    new Rectangle(0, 0, this.backBuffer.Bitmap.Width, this.backBuffer.Bitmap.Height),
                    ImageLockMode.ReadWrite,
                    PixelFormat.Format32bppArgb);

                int startAlpha;
                int finishAlpha;

                if (this.arrowDirection == ArrowDirection.Left || this.arrowDirection == ArrowDirection.Up)
                {
                    startAlpha  = 255;
                    finishAlpha = 0;
                }
                else if (this.arrowDirection == ArrowDirection.Right || this.ArrowDirection == ArrowDirection.Down)
                {
                    startAlpha  = 0;
                    finishAlpha = 255;
                }
                else
                {
                    throw new InvalidEnumArgumentException("this.arrowDirection");
                }

                unsafe
                {
                    if (this.arrowDirection == ArrowDirection.Left || this.arrowDirection == ArrowDirection.Right)
                    {
                        for (int x = 0; x < this.backBuffer.Bitmap.Width; ++x)
                        {
                            float lerp = (float)x / (float)(this.backBuffer.Bitmap.Width - 1);

                            if (this.arrowDirection == ArrowDirection.Left)
                            {
                                lerp = 1.0f - (float)Math.Cos(lerp * (Math.PI / 2.0));
                            }
                            else
                            {
                                lerp = (float)Math.Sin(lerp * (Math.PI / 2.0));
                            }

                            byte  alpha = (byte)(startAlpha + ((int)(lerp * (finishAlpha - startAlpha))));
                            byte *pb    = (byte *)bitmapData.Scan0.ToPointer() + (x * 4) + 3; // *4 because 4-bytes per pixel, +3 to get to alpha channel

                            for (int y = 0; y < this.backBuffer.Bitmap.Height; ++y)
                            {
                                *pb = alpha;
                                pb += bitmapData.Stride;
                            }
                        }
                    }
                    else if (this.arrowDirection == ArrowDirection.Up || this.arrowDirection == ArrowDirection.Down)
                    {
                        for (int y = 0; y < this.backBuffer.Bitmap.Height; ++y)
                        {
                            float lerp = (float)y / (float)(this.backBuffer.Bitmap.Height - 1);
                            lerp = 1.0f - (float)Math.Cos(lerp * (Math.PI / 2.0));

                            byte  alpha = (byte)(startAlpha + ((int)(lerp * (finishAlpha - startAlpha))));
                            byte *pb    = (byte *)bitmapData.Scan0.ToPointer() + (y * bitmapData.Stride) + 3; // *Stride for access to start of row, +3 to get to alpha channel

                            for (int x = 0; x < this.backBuffer.Bitmap.Width; ++x)
                            {
                                *pb = alpha;
                                pb += 4; // 4 for byte size of pixel
                            }
                        }
                    }
                }

                this.backBuffer.Bitmap.UnlockBits(bitmapData);
                bitmapData = null;

                g.DrawImage(this.backBuffer.Bitmap, new Point(0, 0));
            }

            using (SolidBrush fillBrush = new SolidBrush(backColor))
            {
                g.FillRectangle(fillBrush, ClientRectangle);
            }

            // Draw outline
            using (Pen outlinePen = new Pen(outlineColor))
            {
                g.DrawRectangle(outlinePen, new Rectangle(0, 0, ClientSize.Width - 1, ClientSize.Height - 1));
            }

            // Draw button
            g.SmoothingMode = SmoothingMode.AntiAlias;

            const int arrowInset = 3;
            int       arrowSize  = Math.Min(ClientSize.Width - arrowInset * 2, ClientSize.Height - arrowInset * 2) - 1;

            PointF a;
            PointF b;
            PointF c;

            switch (this.arrowDirection)
            {
            case ArrowDirection.Left:
                a = new PointF(arrowInset, ClientSize.Height / 2);
                b = new PointF(ClientSize.Width - arrowInset, (ClientSize.Height - arrowSize) / 2);
                c = new PointF(ClientSize.Width - arrowInset, (ClientSize.Height + arrowSize) / 2);
                break;

            case ArrowDirection.Right:
                a = new PointF(ClientSize.Width - arrowInset, ClientSize.Height / 2);
                b = new PointF(arrowInset, (ClientSize.Height - arrowSize) / 2);
                c = new PointF(arrowInset, (ClientSize.Height + arrowSize) / 2);
                break;

            case ArrowDirection.Up:
                a = new PointF(ClientSize.Width / 2, (ClientSize.Height - arrowSize) / 2);
                b = new PointF((ClientSize.Width - arrowSize) / 2, (ClientSize.Height + arrowSize) / 2);
                c = new PointF((ClientSize.Width + arrowSize) / 2, (ClientSize.Height + arrowSize) / 2);
                break;

            case ArrowDirection.Down:
                a = new PointF(ClientSize.Width / 2, (ClientSize.Height + arrowSize) / 2);
                b = new PointF((ClientSize.Width - arrowSize) / 2, (ClientSize.Height - arrowSize) / 2);
                c = new PointF((ClientSize.Width + arrowSize) / 2, (ClientSize.Height - arrowSize) / 2);
                break;

            default:
                throw new InvalidEnumArgumentException("this.arrowDirection");
            }

            // SPIKE in order to get this rendering correctly right away
            if (this.arrowDirection == ArrowDirection.Down)
            {
                SmoothingMode oldSM = g.SmoothingMode;
                g.SmoothingMode = SmoothingMode.None;

                float top         = b.Y - 2;
                float left        = b.X;
                float right       = c.X;
                int   squareCount = (int)((right - left) / 3);

                Brush outlineBrush  = new SolidBrush(arrowOutlineColor);
                Brush interiorBrush = new SolidBrush(arrowFillColor);

                g.FillRectangle(interiorBrush, left, top, right - left + 1, 3);

                ++left;
                while (left < right)
                {
                    RectangleF rect = new RectangleF(left, top + 1, 1, 1);
                    g.FillRectangle(outlineBrush, rect);
                    left += 2;
                }

                outlineBrush.Dispose();
                outlineBrush = null;

                interiorBrush.Dispose();
                interiorBrush = null;

                a.Y += 2;
                b.Y += 2;
                c.Y += 2;

                g.SmoothingMode = oldSM;
            }

            if (this.reverseArrowColors)
            {
                Utility.Swap(ref arrowFillColor, ref arrowOutlineColor);
            }

            using (Brush buttonBrush = new SolidBrush(arrowFillColor))
            {
                g.FillPolygon(buttonBrush, new PointF[] { a, b, c });
            }

            using (Pen buttonPen = new Pen(arrowOutlineColor, this.arrowOutlineWidth))
            {
                g.DrawPolygon(buttonPen, new PointF[] { a, b, c });
            }
        }
Пример #5
0
        private Size MeasureAndDraw(Graphics g, bool enableDrawing, UI.ButtonState state, bool drawAsDefault, bool drawFocusCues, bool drawKeyboardCues)
        {
            if (enableDrawing)
            {
                g.PixelOffsetMode   = PixelOffsetMode.Half;
                g.CompositingMode   = CompositingMode.SourceOver;
                g.InterpolationMode = InterpolationMode.Bilinear;
            }

            int marginX       = UI.ScaleWidth(9);
            int marginYTop    = UI.ScaleHeight(8);
            int marginYBottom = UI.ScaleHeight(9);
            int paddingX      = UI.ScaleWidth(8);
            int paddingY      = UI.ScaleHeight(3);
            int offsetX       = 0;
            int offsetY       = 0;

            if (enableDrawing)
            {
                switch (state)
                {
                case UI.ButtonState.Disabled:
                    UI.DrawThemedButton(this, g, 0, 0, ClientSize.Width, ClientSize.Height, UI.ButtonState.Disabled);
                    break;

                case UI.ButtonState.Pressed:
                    UI.DrawThemedButton(this, g, 0, 0, ClientSize.Width, ClientSize.Height, UI.ButtonState.Pressed);
                    offsetX = 1;
                    offsetY = 1;
                    break;

                case UI.ButtonState.Hot:
                    UI.DrawThemedButton(this, g, 0, 0, ClientSize.Width, ClientSize.Height, UI.ButtonState.Hot);
                    break;

                case UI.ButtonState.Normal:
                    using (Brush backBrush = new SolidBrush(this.BackColor))
                    {
                        g.FillRectangle(backBrush, ClientRectangle);
                    }
                    break;
                }
            }

            Rectangle actionImageRect;

            Brush textBrush = new SolidBrush(SystemColors.WindowText);

            if (this.actionImage == null)
            {
                actionImageRect = new Rectangle(offsetX, offsetY + marginYTop, 0, 0);
            }
            else
            {
                actionImageRect = new Rectangle(offsetX + marginX, offsetY + marginYTop,
                                                UI.ScaleWidth(this.actionImage.Width), UI.ScaleHeight(this.actionImage.Height));

                Rectangle srcRect = new Rectangle(0, 0, this.actionImage.Width, this.actionImage.Height);

                if (enableDrawing)
                {
                    Image drawMe = Enabled ? this.actionImage : this.actionImageDisabled;
                    actionImageRect.Y += 2;
                    g.DrawImage(drawMe, actionImageRect, srcRect, GraphicsUnit.Pixel);
                    actionImageRect.Y -= 2;
                }
            }

            int actionTextX     = actionImageRect.Right + paddingX;
            int actionTextY     = actionImageRect.Top;
            int actionTextWidth = ClientSize.Width - actionTextX - marginX + offsetX;

            StringFormat stringFormat = (StringFormat)StringFormat.GenericTypographic.Clone();

            stringFormat.HotkeyPrefix = drawKeyboardCues ? HotkeyPrefix.Show : HotkeyPrefix.Hide;

            SizeF actionTextSize = g.MeasureString(this.actionText, this.actionTextFont, actionTextWidth, stringFormat);

            Rectangle actionTextRect = new Rectangle(actionTextX, actionTextY,
                                                     actionTextWidth, (int)Math.Ceiling(actionTextSize.Height));

            if (enableDrawing)
            {
                if (state == UI.ButtonState.Disabled)
                {
                    ControlPaint.DrawStringDisabled(g, this.actionText, this.actionTextFont, this.BackColor, actionTextRect, stringFormat);
                }
                else
                {
                    g.DrawString(this.actionText, this.actionTextFont, textBrush, actionTextRect, stringFormat);
                }
            }

            int descriptionTextX     = actionTextX;
            int descriptionTextY     = actionTextRect.Bottom + paddingY;
            int descriptionTextWidth = actionTextWidth;

            SizeF descriptionTextSize = g.MeasureString(this.explanationText, this.explanationTextFont,
                                                        descriptionTextWidth, stringFormat);

            Rectangle descriptionTextRect = new Rectangle(descriptionTextX, descriptionTextY,
                                                          descriptionTextWidth, (int)Math.Ceiling(descriptionTextSize.Height));

            if (enableDrawing)
            {
                if (state == UI.ButtonState.Disabled)
                {
                    ControlPaint.DrawStringDisabled(g, this.explanationText, this.explanationTextFont, this.BackColor, descriptionTextRect, stringFormat);
                }
                else
                {
                    g.DrawString(this.explanationText, this.explanationTextFont, textBrush, descriptionTextRect, stringFormat);
                }
            }

            if (enableDrawing)
            {
                if (drawFocusCues)
                {
                    ControlPaint.DrawFocusRectangle(g, new Rectangle(3, 3, ClientSize.Width - 5, ClientSize.Height - 5));
                }
            }

            if (textBrush != null)
            {
                textBrush.Dispose();
                textBrush = null;
            }

            stringFormat.Dispose();
            stringFormat = null;

            Size layoutSize = new Size(ClientSize.Width, descriptionTextRect.Bottom + marginYBottom);

            return(layoutSize);
        }
Пример #6
0
 protected override void OnPaintButton(Graphics g, UI.ButtonState state, bool drawAsDefault, bool drawFocusCues, bool drawKeyboardCues)
 {
     MeasureAndDraw(g, true, state, drawAsDefault, drawFocusCues, drawKeyboardCues);
 }
Пример #7
0
        // TODO: Use VisualStyles stuff in .NET 2.0 instead
        /// <summary>
        /// Draws a button in the appropriate system theme (Aero vs. Luna vs. Classic).
        /// </summary>
        /// <remarks>
        /// Note to implementors: This may be implemented as a simple thunk to ControlPaint.DrawButton().
        /// </remarks>
        public static void DrawThemedButton(
            Control hostControl,
            Graphics g,
            int x,
            int y,
            int width,
            int height,
            UI.ButtonState state)
        {
            IntPtr hTheme = OpenTheme(hostControl);

            if (hTheme != IntPtr.Zero)
            {
                NativeStructs.RECT rect = new NativeStructs.RECT();
                rect.left   = x;
                rect.top    = y;
                rect.right  = x + width;
                rect.bottom = y + height;

                int iState;
                switch (state)
                {
                case UI.ButtonState.Disabled:
                    iState = NativeConstants.PBS_DISABLED;
                    break;

                case UI.ButtonState.Hot:
                    iState = NativeConstants.PBS_HOT;
                    break;

                default:
                case UI.ButtonState.Normal:
                    iState = NativeConstants.PBS_NORMAL;
                    break;

                case UI.ButtonState.Pressed:
                    iState = NativeConstants.PBS_PRESSED;
                    break;
                }

                IntPtr hdc = g.GetHdc();

                SafeNativeMethods.DrawThemeBackground(
                    hTheme,
                    hdc,
                    NativeConstants.BP_PUSHBUTTON,
                    iState,
                    ref rect,
                    ref rect);

                g.ReleaseHdc(hdc);

                SafeNativeMethods.CloseThemeData(hTheme);
                hTheme = IntPtr.Zero;
            }
            else
            {
                System.Windows.Forms.ButtonState swfState;

                switch (state)
                {
                case UI.ButtonState.Disabled:
                    swfState = System.Windows.Forms.ButtonState.Inactive;
                    break;

                default:
                case UI.ButtonState.Hot:
                case UI.ButtonState.Normal:
                    swfState = System.Windows.Forms.ButtonState.Normal;
                    break;

                case UI.ButtonState.Pressed:
                    swfState = System.Windows.Forms.ButtonState.Pushed;
                    break;
                }

                ControlPaint.DrawButton(g, x, y, width, height, swfState);
            }

            GC.KeepAlive(hostControl);
        }
Пример #8
0
 protected abstract void OnPaintButton(
     Graphics g,
     UI.ButtonState state,
     bool drawAsDefault,
     bool drawFocusCues,
     bool drawKeyboardCues);