| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704 | using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing;using System.Drawing.Drawing2D;using System.Windows.Forms;namespace Optimizer.Controls{    [DefaultProperty("Color")]    [DefaultEvent("ColorChanged")]    public partial class ColorPicker : Control    {        #region Fields        private Brush _brush;        private PointF _centerPoint;        private Color _color;        private int _colorStep;        private bool _dragStartedWithinWheel;        private HslColor _hslColor;        private int _largeChange;        private float _radius;        private int _selectionSize;        private int _smallChange;        private int _updateCount;        #endregion        #region Constructors        public ColorPicker()        {            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.Selectable | ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, true);            this.Color = Color.Black;            this.ColorStep = 4;            this.SelectionSize = 10;            this.SmallChange = 1;            this.LargeChange = 5;            this.SelectionGlyph = this.CreateSelectionGlyph();        }        #endregion        #region Events        [Category("Property Changed")]        public event EventHandler ColorChanged;        [Category("Property Changed")]        public event EventHandler ColorStepChanged;        [Category("Property Changed")]        public event EventHandler HslColorChanged;        [Category("Property Changed")]        public event EventHandler LargeChangeChanged;        [Category("Property Changed")]        public event EventHandler SelectionSizeChanged;        [Category("Property Changed")]        public event EventHandler SmallChangeChanged;        #endregion        #region Overridden Methods        protected override void Dispose(bool disposing)        {            if (disposing)            {                if (_brush != null)                {                    _brush.Dispose();                }                if (this.SelectionGlyph != null)                {                    this.SelectionGlyph.Dispose();                }            }            base.Dispose(disposing);        }        protected override bool IsInputKey(Keys keyData)        {            bool result;            if ((keyData & Keys.Left) == Keys.Left || (keyData & Keys.Up) == Keys.Up || (keyData & Keys.Down) == Keys.Down || (keyData & Keys.Right) == Keys.Right || (keyData & Keys.PageUp) == Keys.PageUp || (keyData & Keys.PageDown) == Keys.PageDown)            {                result = true;            }            else            {                result = base.IsInputKey(keyData);            }            return result;        }        protected override void OnGotFocus(EventArgs e)        {            base.OnGotFocus(e);            this.Invalidate();        }        protected override void OnKeyDown(KeyEventArgs e)        {            HslColor color;            double hue;            int step;            color = this.HslColor;            hue = color.H;            step = e.Shift ? this.LargeChange : this.SmallChange;            switch (e.KeyCode)            {                case Keys.Right:                case Keys.Up:                    hue += step;                    break;                case Keys.Left:                case Keys.Down:                    hue -= step;                    break;                case Keys.PageUp:                    hue += this.LargeChange;                    break;                case Keys.PageDown:                    hue -= this.LargeChange;                    break;            }            if (hue >= 360)            {                hue = 0;            }            if (hue < 0)            {                hue = 359;            }            if (hue != color.H)            {                color.H = hue;                this.LockUpdates = true;                this.Color = color.ToRgbColor();                this.HslColor = color;                this.LockUpdates = false;                e.Handled = true;            }            base.OnKeyDown(e);        }        protected override void OnLostFocus(EventArgs e)        {            base.OnLostFocus(e);            this.Invalidate();        }        protected override void OnMouseDown(MouseEventArgs e)        {            base.OnMouseDown(e);            if (!this.Focused && this.TabStop)            {                this.Focus();            }            if (e.Button == MouseButtons.Left && this.IsPointInWheel(e.Location))            {                _dragStartedWithinWheel = true;                this.SetColor(e.Location);            }        }        protected override void OnMouseMove(MouseEventArgs e)        {            base.OnMouseMove(e);            if (e.Button == MouseButtons.Left && _dragStartedWithinWheel)            {                this.SetColor(e.Location);            }        }        protected override void OnMouseUp(MouseEventArgs e)        {            base.OnMouseUp(e);            _dragStartedWithinWheel = false;        }        protected override void OnPaddingChanged(EventArgs e)        {            base.OnPaddingChanged(e);            this.RefreshWheel();        }        protected override void OnPaint(PaintEventArgs e)        {            base.OnPaint(e);            if (this.AllowPainting)            {                base.OnPaintBackground(e);                if (this.BackgroundImage == null && this.Parent != null && (this.BackColor == this.Parent.BackColor || this.Parent.BackColor.A != 255))                {                    ButtonRenderer.DrawParentBackground(e.Graphics, this.DisplayRectangle, this);                }                if (_brush != null)                {                    e.Graphics.FillPie(_brush, this.ClientRectangle, 0, 360);                }                e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;                using (Pen pen = new Pen(this.BackColor, 2))                {                    e.Graphics.DrawEllipse(pen, new RectangleF(_centerPoint.X - _radius, _centerPoint.Y - _radius, _radius * 2, _radius * 2));                }                if (!this.Color.IsEmpty)                {                    this.PaintCurrentColor(e);                }            }        }        protected override void OnResize(EventArgs e)        {            base.OnResize(e);            this.RefreshWheel();        }        #endregion        #region Public Properties        [Category("Appearance")]        [DefaultValue(typeof(Color), "Black")]        public virtual Color Color        {            get { return _color; }            set            {                if (this.Color != value)                {                    _color = value;                    this.OnColorChanged(EventArgs.Empty);                }            }        }        [Category("Appearance")]        [DefaultValue(4)]        public virtual int ColorStep        {            get { return _colorStep; }            set            {                if (value < 1 || value > 359)                {                    throw new ArgumentOutOfRangeException("value", value, "Value must be between 1 and 359");                }                if (this.ColorStep != value)                {                    _colorStep = value;                    this.OnColorStepChanged(EventArgs.Empty);                }            }        }        [Category("Appearance")]        [DefaultValue(typeof(HslColor), "0, 0, 0")]        [Browsable(false)]        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]        public virtual HslColor HslColor        {            get { return _hslColor; }            set            {                if (this.HslColor != value)                {                    _hslColor = value;                    this.OnHslColorChanged(EventArgs.Empty);                }            }        }        [Category("Behavior")]        [DefaultValue(5)]        public virtual int LargeChange        {            get { return _largeChange; }            set            {                if (this.LargeChange != value)                {                    _largeChange = value;                    this.OnLargeChangeChanged(EventArgs.Empty);                }            }        }        [Category("Appearance")]        [DefaultValue(10)]        public virtual int SelectionSize        {            get { return _selectionSize; }            set            {                if (this.SelectionSize != value)                {                    _selectionSize = value;                    this.OnSelectionSizeChanged(EventArgs.Empty);                }            }        }        [Category("Behavior")]        [DefaultValue(1)]        public virtual int SmallChange        {            get { return _smallChange; }            set            {                if (this.SmallChange != value)                {                    _smallChange = value;                    this.OnSmallChangeChanged(EventArgs.Empty);                }            }        }        #endregion        #region Protected Properties        protected virtual bool AllowPainting        {            get { return _updateCount == 0; }        }        protected Color[] Colors { get; set; }        protected bool LockUpdates { get; set; }        protected PointF[] Points { get; set; }        protected Image SelectionGlyph { get; set; }        #endregion        #region Public Members        public virtual void BeginUpdate()        {            _updateCount++;        }        public virtual void EndUpdate()        {            if (_updateCount > 0)            {                _updateCount--;            }            if (this.AllowPainting)            {                this.Invalidate();            }        }        #endregion        #region Protected Members        protected virtual void CalculateWheel()        {            List<PointF> points;            List<Color> colors;            points = new List<PointF>();            colors = new List<Color>();            if (this.ClientSize.Width > 16 && this.ClientSize.Height > 16)            {                int w;                int h;                w = this.ClientSize.Width;                h = this.ClientSize.Height;                _centerPoint = new PointF(w / 2.0F, h / 2.0F);                _radius = this.GetRadius(_centerPoint);                for (double angle = 0; angle < 360; angle += this.ColorStep)                {                    double angleR;                    PointF location;                    angleR = angle * (Math.PI / 180);                    location = this.GetColorLocation(angleR, _radius);                    points.Add(location);                    colors.Add(new HslColor(angle, 1, 0.5).ToRgbColor());                }            }            this.Points = points.ToArray();            this.Colors = colors.ToArray();        }        protected virtual Brush CreateGradientBrush()        {            Brush result;            if (this.Points.Length != 0 && this.Points.Length == this.Colors.Length)            {                result = new PathGradientBrush(this.Points, WrapMode.Clamp)                {                    CenterPoint = _centerPoint,                    CenterColor = Color.White,                    SurroundColors = this.Colors                };            }            else            {                result = null;            }            return result;        }                protected virtual Color GetContrastColor(Color c)        {            double brightness = c.R * 0.299 + c.G * 0.587 + c.B * 0.114;            return brightness > 149 ? Color.Black : Color.White;        }        protected virtual Image CreateSelectionGlyph()        {            Image image;            int halfSize;            halfSize = this.SelectionSize / 2;            image = new Bitmap(this.SelectionSize + 1, this.SelectionSize + 1);            using (Graphics g = Graphics.FromImage(image))            {                g.SmoothingMode = SmoothingMode.AntiAlias;                g.PixelOffsetMode = PixelOffsetMode.HighQuality;                g.InterpolationMode = InterpolationMode.High;                g.DrawEllipse(new Pen(GetContrastColor(Color)), halfSize - 4.5f, halfSize - 4.5f, 4.5f + 4.5f, 4.5f + 4.5f);                g.FillEllipse(new SolidBrush(this.Color), halfSize - 4, halfSize - 4, 4 + 4, 4 + 4);            }            return image;        }        protected PointF GetColorLocation(Color color)        {            return this.GetColorLocation(new HslColor(color));        }        protected virtual PointF GetColorLocation(HslColor color)        {            double angle;            double radius;            angle = color.H * Math.PI / 180;            radius = _radius * color.S;            return this.GetColorLocation(angle, radius);        }        protected PointF GetColorLocation(double angleR, double radius)        {            double x;            double y;            x = this.Padding.Left + _centerPoint.X + Math.Cos(angleR) * radius;            y = this.Padding.Top + _centerPoint.Y - Math.Sin(angleR) * radius;            return new PointF((float)x, (float)y);        }        protected float GetRadius(PointF centerPoint)        {            return Math.Min(centerPoint.X, centerPoint.Y) - (Math.Max(this.Padding.Horizontal, this.Padding.Vertical) + (this.SelectionSize / 2));        }        protected bool IsPointInWheel(Point point)        {            PointF normalized;            normalized = new PointF(point.X - _centerPoint.X, point.Y - _centerPoint.Y);            return (normalized.X * normalized.X + normalized.Y * normalized.Y) <= (_radius * _radius);        }        protected virtual void OnColorChanged(EventArgs e)        {            EventHandler handler;            if (!this.LockUpdates)            {                this.HslColor = new HslColor(this.Color);            }                        this.SelectionGlyph = this.CreateSelectionGlyph();            this.Refresh();            handler = this.ColorChanged;            if (handler != null)            {                handler(this, e);            }        }        protected virtual void OnColorStepChanged(EventArgs e)        {            EventHandler handler;            this.RefreshWheel();            handler = this.ColorStepChanged;            if (handler != null)            {                handler(this, e);            }        }        protected virtual void OnHslColorChanged(EventArgs e)        {            EventHandler handler;            if (!this.LockUpdates)            {                this.Color = this.HslColor.ToRgbColor();            }            this.Invalidate();            handler = this.HslColorChanged;            if (handler != null)            {                handler(this, e);            }        }        protected virtual void OnLargeChangeChanged(EventArgs e)        {            EventHandler handler;            handler = this.LargeChangeChanged;            if (handler != null)            {                handler(this, e);            }        }        protected virtual void OnSelectionSizeChanged(EventArgs e)        {            EventHandler handler;            if (this.SelectionGlyph != null)            {                this.SelectionGlyph.Dispose();            }            this.SelectionGlyph = this.CreateSelectionGlyph();            this.RefreshWheel();            handler = this.SelectionSizeChanged;            if (handler != null)            {                handler(this, e);            }        }        protected virtual void OnSmallChangeChanged(EventArgs e)        {            EventHandler handler;            handler = this.SmallChangeChanged;            if (handler != null)            {                handler(this, e);            }        }        protected void PaintColor(PaintEventArgs e, HslColor color)        {            this.PaintColor(e, color, false);        }        protected virtual void PaintColor(PaintEventArgs e, HslColor color, bool includeFocus)        {            PointF location;            location = this.GetColorLocation(color);            if (!float.IsNaN(location.X) && !float.IsNaN(location.Y))            {                int x;                int y;                x = (int)location.X - (this.SelectionSize / 2);                y = (int)location.Y - (this.SelectionSize / 2);                if (this.SelectionGlyph == null)                {                    e.Graphics.DrawRectangle(Pens.Black, x, y, this.SelectionSize, this.SelectionSize);                }                else                {                    e.Graphics.DrawImage(this.SelectionGlyph, x, y);                }            }        }        protected virtual void PaintCurrentColor(PaintEventArgs e)        {            this.PaintColor(e, this.HslColor, true);        }        protected virtual void SetColor(Point point)        {            double dx;            double dy;            double angle;            double distance;            double saturation;            dx = Math.Abs(point.X - _centerPoint.X - this.Padding.Left);            dy = Math.Abs(point.Y - _centerPoint.Y - this.Padding.Top);            angle = Math.Atan(dy / dx) / Math.PI * 180;            distance = Math.Pow((Math.Pow(dx, 2) + (Math.Pow(dy, 2))), 0.5);            saturation = distance / _radius;            if (distance < 6)            {                saturation = 0;            }            if (point.X < _centerPoint.X)            {                angle = 180 - angle;            }            if (point.Y > _centerPoint.Y)            {                angle = 360 - angle;            }            this.LockUpdates = true;            this.HslColor = new HslColor(angle, saturation, 0.5);            this.Color = this.HslColor.ToRgbColor();            this.LockUpdates = false;        }        #endregion        #region Private Members        private void RefreshWheel()        {            if (_brush != null)            {                _brush.Dispose();            }            this.CalculateWheel();            _brush = this.CreateGradientBrush();            this.Invalidate();        }        #endregion    }}
 |