Click here to Skip to main content
15,884,237 members
Articles / Programming Languages / C#

NeoTabControl Library

Rate me:
Please Sign up or sign in to vote.
4.96/5 (110 votes)
28 Sep 2012CPOL16 min read 195.1K   21.3K   163  
A custom .NET tab control for WinForms applications with add-in renderer support.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace NeoTabControlLibrary
{
    public class ProgressBarPainter : IDisposable
    {
        #region Struct

        struct ColorManipulation
        {
            #region Instance Members

            public Color Dark;
            public Color Light;
            public Color Darker;
            public Color Lighter;
            public Color BaseColor;

            #endregion

            #region Constructor

            public ColorManipulation(Color baseColor)
            {
                this.Dark = Shade(0.8f, baseColor);
                this.Light = Smooth(0.6f, baseColor);
                this.Darker = Shade(0.6f, baseColor);
                this.Lighter = Smooth(0.3f, baseColor);
                this.BaseColor = baseColor;
            }

            #endregion

            #region Helper Methods

            private static Color Shade(float ratio, Color baseColor)
            {
                return Manipule(ratio, baseColor, Color.Black);
            }

            private static Color Smooth(float ratio, Color baseColor)
            {
                return Manipule(ratio, baseColor, Color.White);
            }

            private static Color Manipule(float ratio, Color baseColor, Color manipuleColor)
            {
                int r = (int)(manipuleColor.R + ratio * (baseColor.R - manipuleColor.R));// Red
                int g = (int)(manipuleColor.G + ratio * (baseColor.G - manipuleColor.G));// Green
                int b = (int)(manipuleColor.B + ratio * (baseColor.B - manipuleColor.B));// Blue
                return Color.FromArgb(r, g, b);
            }

            #endregion
        };

        #endregion
        
        #region Instance Members

        private Color[] COLORS = new Color[3];
        private ColorManipulation[] progressColors = null;

        #endregion

        #region Constructor

        public ProgressBarPainter(Color borderColor, Color backColorA, Color backColorB,
            Color progColorA, Color progColorB)
        {
            COLORS[0] = borderColor;
            COLORS[1] = backColorA;
            COLORS[2] = backColorB;
            progressColors = new ColorManipulation[] {
                new ColorManipulation(progColorA), new ColorManipulation(progColorB) };
        }

        #endregion

        #region Property

        public int VALUE { get; set; }
        public int MAXVALUE { get; set; }
        public Rectangle BarRectangle { get; set; }

        #endregion

        #region Helper Methods

        private void DrawBorder(Graphics gr)
        {
            Pen pen = new Pen(COLORS[0]);
            gr.DrawRectangle(pen, BarRectangle);
            pen.Dispose();
        }

        private void DrawBackground(Graphics gr)
        {
            Rectangle backgroundRectangle = BarRectangle;
            backgroundRectangle.Inflate(-1, -1);
            if (backgroundRectangle.Width < 2)
                return;
            using (LinearGradientBrush brush = new LinearGradientBrush(Point.Empty, new Point(0, backgroundRectangle.Height),
                COLORS[1], COLORS[2]))
            {
                Blend bl = new Blend(2);
                bl.Factors = new float[] { 0.3F, 1.0F };
                bl.Positions = new float[] { 0.0F, 1.0F };
                brush.Blend = bl;
                gr.FillRectangle(brush, backgroundRectangle);
            }
        }

        private void DrawProgress(Graphics gr)
        {
            Rectangle progressRectangle = BarRectangle;
            progressRectangle.Inflate(-1, -1);
            progressRectangle.Width = VALUE >= MAXVALUE ? progressRectangle.Width : progressRectangle.Width * VALUE / MAXVALUE;
            if (progressRectangle.Width < 2)
                return;
            Point left = new Point(progressRectangle.X, progressRectangle.Y);
            Point right = new Point(progressRectangle.Right, progressRectangle.Y);
            using (LinearGradientBrush brush = new LinearGradientBrush(Point.Empty, new Point(0, progressRectangle.Height),
                progressColors[0].BaseColor, progressColors[1].BaseColor))
            {
                Blend bl = new Blend(2);
                bl.Factors = new float[] { 0.3F, 1.0F };
                bl.Positions = new float[] { 0.0F, 1.0F };
                brush.Blend = bl;
                gr.FillRectangle(brush, progressRectangle);
            }
            LinearGradientBrush topInner = new LinearGradientBrush(left, right,
                progressColors[0].Light, progressColors[1].Light);
            LinearGradientBrush topOuter = new LinearGradientBrush(left, right,
                progressColors[0].Lighter, progressColors[1].Lighter);
            LinearGradientBrush bottomInner = new LinearGradientBrush(left, right,
                progressColors[0].Dark, progressColors[1].Dark);
            LinearGradientBrush bottomOuter = new LinearGradientBrush(left, right,
                progressColors[0].Darker, progressColors[1].Darker);
            // Inner Top
            using (Pen pen = new Pen(topInner))
            {
                gr.DrawLine(pen, progressRectangle.X + 1, progressRectangle.Y + 1, 
                    progressRectangle.Right - 1, progressRectangle.Y + 1);
            }
            // Inner Left
            using (Pen pen = new Pen(progressColors[0].Light))
            {
                gr.DrawLine(pen, progressRectangle.X + 1, progressRectangle.Y + 1, 
                    progressRectangle.X + 1, progressRectangle.Bottom - 1);
            }
            // Outer Top
            using (Pen pen = new Pen(topOuter))
            {
                gr.DrawLine(pen, progressRectangle.X, progressRectangle.Y, 
                    progressRectangle.Right, progressRectangle.Y);
            }
            // Outer Left
            using (Pen pen = new Pen(progressColors[0].Lighter))
            {
                gr.DrawLine(pen, progressRectangle.X, progressRectangle.Y, 
                    progressRectangle.X, progressRectangle.Bottom);
            }
            // Inner Bottom
            using (Pen pen = new Pen(bottomInner))
            {
                gr.DrawLine(pen, progressRectangle.X + 1, progressRectangle.Bottom - 1, 
                    progressRectangle.Right - 1, progressRectangle.Bottom - 1);
            }
            // Inner Right
            using (Pen pen = new Pen(progressColors[1].Dark))
            {
                gr.DrawLine(pen, progressRectangle.Right - 1, progressRectangle.Y + 1, 
                    progressRectangle.Right - 1, progressRectangle.Bottom - 1);
            }
            // Outer Bottom
            using (Pen pen = new Pen(bottomOuter))
            {
                gr.DrawLine(pen, progressRectangle.X, progressRectangle.Bottom, 
                    progressRectangle.Right, progressRectangle.Bottom);
            }
            // Outer Right
            using (Pen pen = new Pen(progressColors[1].Darker))
            {
                gr.DrawLine(pen, progressRectangle.Right, progressRectangle.Y, 
                    progressRectangle.Right, progressRectangle.Bottom);
            }
            topInner.Dispose();
            topOuter.Dispose();
            bottomInner.Dispose();
            bottomOuter.Dispose();
        }

        #endregion

        #region General Methods

        public void PaintProgressBar(Graphics g, Rectangle rct)
        {
            BarRectangle = rct;
            DrawBorder(g);
            DrawBackground(g);
            DrawProgress(g);
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) ARELTEK
Turkey Turkey
Since 1998...

MCPD - Enterprise Application Developer

“Hesaplı hareket ettiğini zanneden ve onunla iftihar eyliyen dar kafalar; kurtulmağa, yükselmeğe elverişli hiç bir eser vücüda getirmezler. Kurtuluş ve yükselişi, ancak varlığına dayanan ve mülkü milletin gizli kapalı hazinelerini verimli hale getirmesini bilen, şahsi menfaatini millet menfaati uğruna feda eden, ruhu idealist, dimağı realist şahsiyetlerde aramalıdır.”

Nuri Demirağ, 1947

Comments and Discussions