//  ToolTip _tt; looks like tool-tips messes with mouse events.


        public ColorCursor(ColorFunction colorFunction, PictureBox bitmap, TextBox textbox, ColorCursorChangeCallBack callback, YColor initialColor)
        {
            _bitmap        = bitmap;
            _textbox       = textbox;
            _colorFunction = colorFunction;
            _callback      = callback;
            //_tt = new ToolTip();

            HueBackground = new Bitmap(255, 10);
            Graphics g = Graphics.FromImage(HueBackground);

            for (int i = 0; i < 256; i++)
            {
                YColor c = YColor.FromAhsl(255, (byte)i, 255, 127);
                Pen    p = new Pen(c.toColor(), 1);
                g.DrawLine(p, i, 0, i, 11);
                p.Dispose();
            }
            g.Dispose();



            _bitmap.MouseDown    += MouseAction;
            _bitmap.MouseMove    += MouseAction;
            _textbox.Text         = _value.ToString();
            _textbox.TextChanged += textBox_TextChanged;
            _textbox.MaxLength    = 3;
            setNewColor(initialColor);
        }
 public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
 {
     if (value is String)
     {
         return(YColor.fromString((string)value));
     }
     return(base.ConvertFrom(context, culture, value));
 }
 static public void  AddColorToHistory(YColor c)
 {
     _colorHistory.Insert(0, c);
     while (_colorHistory.Count > maxHistoryLength)
     {
         _colorHistory.RemoveAt(_colorHistory.Count - 1);
     }
 }
 public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture,
                                  object value, System.Type destinationType)
 {
     if (destinationType == typeof(YColor) && value is String)
     {
         YColor.fromString((string)value);
     }
     return(base.ConvertTo(context, culture, value, destinationType));
 }
        public void  Init(YColor initialValue)
        {
            _ok    = false;
            _value = initialValue;
            autoSelectTab();


            computeSpacing();

            DrawHistory();
            PreviewColor();
            DrawPredefinedColors();
        }
        public static YColor FromAhsl(byte A, byte H, byte S, byte L)
        {
            YColor it = new YColor();

            it._fromHSL = true;
            it._A       = A;
            it._H       = H;
            it._S       = S;
            it._L       = L;

            if (S == 0)
            {
                it._R = L;
                it._G = L;
                it._B = L;
            }
            else
            {
                double Hue        = (6 * (double)H) / 255;
                double Saturation = ((double)S / 255);
                double Luminosity = ((double)L / 255);



                double t1, t2;
                double th = Hue / 6.0d;

                if (Luminosity < 0.5d)
                {
                    t2 = Luminosity * (1d + Saturation);
                }
                else
                {
                    t2 = (Luminosity + Saturation) - (Luminosity * Saturation);
                }
                t1 = 2d * Luminosity - t2;

                double tr, tg, tb;
                tr = th + (1.0d / 3.0d);
                tg = th;
                tb = th - (1.0d / 3.0d);

                tr    = ColorCalc(tr, t1, t2);
                tg    = ColorCalc(tg, t1, t2);
                tb    = ColorCalc(tb, t1, t2);
                it._R = (byte)Math.Round(tr * 255d);
                it._G = (byte)Math.Round(tg * 255d);
                it._B = (byte)Math.Round(tb * 255d);
            }
            return(it);
        }
        public static YColor FromArgb(byte A, byte R, byte G, byte B)
        {
            YColor it = new YColor();

            it._fromHSL = false;
            it._A       = A; it._R = R; it._G = G; it._B = B;

            float _fR = (R / 255f);
            float _fG = (G / 255f);
            float _fB = (B / 255f);

            float _Min   = Math.Min(Math.Min(_fR, _fG), _fB);
            float _Max   = Math.Max(Math.Max(_fR, _fG), _fB);
            float _Delta = _Max - _Min;

            float fH = 0;
            float fS = 0;
            float fL = (float)((_Max + _Min) / 2.0f);

            if (_Delta != 0)
            {
                if (fL < 0.5f)
                {
                    fS = (float)(_Delta / (_Max + _Min));
                }
                else
                {
                    fS = (float)(_Delta / (2.0f - _Max - _Min));
                }


                if (_fR == _Max)
                {
                    fH = (_fG - _fB) / _Delta;
                }
                else if (_fG == _Max)
                {
                    fH = 2f + (_fB - _fR) / _Delta;
                }
                else if (_fB == _Max)
                {
                    fH = 4f + (_fR - _fG) / _Delta;
                }
            }

            it._H = (byte)(255 * fH / 6);
            it._S = (byte)(255 * fS);
            it._L = (byte)(255 * fL);
            return(it);
        }
        void ValueChanged(ColorCursor source, byte value)
        {
            if ((source == C1HSL))
            {
                _value = YColor.FromAhsl(C4HSL.value, value, C2HSL.value, C3HSL.value);
            }
            if ((source == C1RGB))
            {
                _value = YColor.FromArgb(C4RGB.value, value, C2RGB.value, C3RGB.value);
            }
            if ((source == C2HSL))
            {
                _value = YColor.FromAhsl(C4HSL.value, C1HSL.value, value, C3HSL.value);
            }
            if ((source == C2RGB))
            {
                _value = YColor.FromArgb(C4RGB.value, C1RGB.value, value, C3RGB.value);
            }
            if ((source == C3HSL))
            {
                _value = YColor.FromAhsl(C4HSL.value, C1HSL.value, C2HSL.value, value);
            }
            if ((source == C3RGB))
            {
                _value = YColor.FromArgb(C4RGB.value, C1RGB.value, C2RGB.value, value);
            }
            if ((source == C4HSL))
            {
                _value = YColor.FromAhsl(value, C1HSL.value, C2HSL.value, C3HSL.value);
            }
            if ((source == C4RGB))
            {
                _value = YColor.FromArgb(value, C1RGB.value, C2RGB.value, C3RGB.value);
            }


            updateCursors();
            PreviewColor();
            if (OnColorChanged != null)
            {
                OnColorChanged(this, new ColorChangeEventArgs(_value));
            }
        }
        private void PredefinedMouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
            {
                return;
            }
            int n = findPredefinedIndex(e.X, e.Y);

            if (n < 0)
            {
                return;
            }


            _value = YColor.fromColor(predefinedColors[n]);
            DrawPredefinedColors();
            ValueChanged(null, 0);
            PreviewColor();
            if (OnColorChanged != null)
            {
                OnColorChanged(this, new ColorChangeEventArgs(_value));
            }
        }
        public void setNewColor(YColor color)
        {
            _color = color;

            if ((_colorFunction == ColorFunction.COLOR_H) || (_colorFunction == ColorFunction.COLOR_R))
            {
                _colorFunction = _color.isHSL ? ColorFunction.COLOR_H : ColorFunction.COLOR_R;
            }

            if ((_colorFunction == ColorFunction.COLOR_S) || (_colorFunction == ColorFunction.COLOR_G))
            {
                _colorFunction = _color.isHSL ? ColorFunction.COLOR_S : ColorFunction.COLOR_G;
            }

            if ((_colorFunction == ColorFunction.COLOR_L) || (_colorFunction == ColorFunction.COLOR_B))
            {
                _colorFunction = _color.isHSL ? ColorFunction.COLOR_L : ColorFunction.COLOR_B;
            }

            switch (_colorFunction)
            {
            case ColorFunction.COLOR_H: /*_tt.SetToolTip(_bitmap, "Hue");*/ _value = _color.H; updateTextBox(); break;

            case ColorFunction.COLOR_R: /*_tt.SetToolTip(_bitmap, "Red"); */ _value = _color.R; updateTextBox(); break;

            case ColorFunction.COLOR_G: /*_tt.SetToolTip(_bitmap, "Green");*/ _value = _color.G; updateTextBox(); break;

            case ColorFunction.COLOR_B: /*_tt.SetToolTip(_bitmap, "Blue"); */ _value = _color.B; updateTextBox(); break;

            case ColorFunction.COLOR_S: /*_tt.SetToolTip(_bitmap, "Saturation");*/ _value = _color.S; updateTextBox(); break;

            case ColorFunction.COLOR_L: /*_tt.SetToolTip(_bitmap, "Luminosity"); */ _value = _color.L; updateTextBox(); break;

            case ColorFunction.COLOR_A: /*_tt.SetToolTip(_bitmap, "Alpha-transparency"); */ _value = _color.A; updateTextBox(); break;
            }
            redraw();
        }
        public static YColor fromString(string s, out bool matchFound)
        {
            matchFound = false;
            s          = s.Replace(" ", "");

            if (s.StartsWith("#"))
            {
                s = "RGB:" + s.Substring(1);
            }
            if (s.ToUpper() == "LIGHTGREY")
            {
                s = "RGB:FFD3D3D3";                        // sometimes it's LightGrey, sometimes it's LightGray,
            }
            if (s.ToUpper() == "TRANSPARENT")
            {
                s = "RGB:00000000";                          //
            }
            foreach (var colorProperty in knownColorProperties)
            {
                var colorPropertyValue = (Color)colorProperty.GetValue(null, null);
                if (String.Equals(colorProperty.Name, s, StringComparison.OrdinalIgnoreCase))
                {
                    matchFound = true;
                    return(YColor.FromArgb(255, colorPropertyValue.R, colorPropertyValue.G, colorPropertyValue.B));
                }
            }



            bool fromHSL = false;

            if ((s.Length > 4))
            {
                if (s.Substring(0, 4).ToUpper() == "HSL:")
                {
                    fromHSL = true; s = s.Substring(4);
                }
                else if (s.Substring(0, 4).ToUpper() == "RGB:")
                {
                    s = s.Substring(4);
                }
            }

            long value;

            if ((s.Length >= 6) && (long.TryParse(s, System.Globalization.NumberStyles.HexNumber, null, out value)))
            {
                byte a;
                if (s.Length < 7)
                {
                    a = 255;
                }
                else
                {
                    a = (byte)(value >> 24);
                }
                if (fromHSL)
                {
                    matchFound = true; return(YColor.FromAhsl(a, (byte)((value >> 16) & 0xFF), (byte)((value >> 8) & 0xFF), (byte)((value) & 0xFF)));
                }
                else
                {
                    matchFound = true; return(FromArgb(a, (byte)((value >> 16) & 0xFF), (byte)((value >> 8) & 0xFF), (byte)((value) & 0xFF)));
                }
            }


            return(YColor.FromArgb(255, 0, 0, 0));
        }
        private void redraw()
        {
            int w = _bitmap.Size.Width;
            int h = _bitmap.Size.Height;


            Bitmap DrawArea = new Bitmap(w, h);

            _bitmap.Image = DrawArea;


            Graphics g = Graphics.FromImage(DrawArea);

            Rectangle contentsRectangle = new Rectangle(1, 1, _bitmap.Width - 2, _bitmap.Height - 2);
            Rectangle outsideRectangle  = new Rectangle(0, 0, _bitmap.Width - 1, _bitmap.Height - 1);

            switch (_colorFunction)
            {
            case ColorFunction.COLOR_H: g.DrawImage(HueBackground, contentsRectangle); break;

            case ColorFunction.COLOR_S:
                for (int i = 0; i < _bitmap.Width - 2; i++)
                {
                    byte b = (byte)Math.Round(255 * (double)i / (_bitmap.Width - 2));
                    Pen  p = new Pen(YColor.FromAhsl(255, _color.H, b, _color.L).toColor());
                    g.DrawLine(p, i + 1, 0, i + 1, _bitmap.Height);
                    p.Dispose();
                }
                break;

            case ColorFunction.COLOR_L:
                for (int i = 0; i < _bitmap.Width - 2; i++)
                {
                    byte b = (byte)Math.Round(255 * (double)i / (_bitmap.Width - 2));
                    Pen  p = new Pen(YColor.FromAhsl(255, _color.H, _color.S, b).toColor());
                    g.DrawLine(p, i + 1, 0, i + 1, _bitmap.Height);
                    p.Dispose();
                }
                break;


            case ColorFunction.COLOR_R:
                for (int i = 0; i < _bitmap.Width - 2; i++)
                {
                    byte b = (byte)Math.Round(255 * (double)i / (_bitmap.Width - 2));
                    Pen  p = new Pen(YColor.FromArgb(255, b, _color.G, _color.B).toColor());
                    g.DrawLine(p, i + 1, 0, i + 1, _bitmap.Height);
                    p.Dispose();
                }
                break;

            case ColorFunction.COLOR_G:
                for (int i = 0; i < _bitmap.Width - 2; i++)
                {
                    byte b = (byte)Math.Round(255 * (double)i / (_bitmap.Width - 2));
                    Pen  p = new Pen(YColor.FromArgb(255, _color.R, b, _color.B).toColor());
                    g.DrawLine(p, i + 1, 0, i + 1, _bitmap.Height);
                    p.Dispose();
                }
                break;

            case ColorFunction.COLOR_B:
                for (int i = 0; i < _bitmap.Width - 2; i++)
                {
                    byte b = (byte)Math.Round(255 * (double)i / (_bitmap.Width - 2));
                    Pen  p = new Pen(YColor.FromArgb(255, _color.R, _color.G, b).toColor());
                    g.DrawLine(p, i + 1, 0, i + 1, _bitmap.Height);
                    p.Dispose();
                }
                break;


            case ColorFunction.COLOR_A:
                g.FillRectangle(Brushes.White, 0, 0, _bitmap.Width, _bitmap.Height);
                for (int i = 0; i < 16; i++)
                {
                    g.FillRectangle(Brushes.Black, i * _bitmap.Width / 16, i % 2 == 0 ? 0 : (_bitmap.Height - 2) / 2, 1 + (_bitmap.Width - 2) / 16, 1 + (_bitmap.Height - 2) / 2);
                }

                if (_color.isHSL)
                {
                    for (int i = 0; i < _bitmap.Width - 2; i++)
                    {
                        byte b = (byte)Math.Round(255 * (double)i / (_bitmap.Width - 2));
                        Pen  p = new Pen(YColor.FromAhsl(b, _color.H, _color.S, _color.L).toColor());
                        g.DrawLine(p, i + 1, 0, i + 1, _bitmap.Height);
                        p.Dispose();
                    }
                }
                else
                {
                    for (int i = 0; i < _bitmap.Width - 2; i++)
                    {
                        byte b = (byte)Math.Round(255 * (double)i / (_bitmap.Width - 2));
                        Pen  p = new Pen(YColor.FromArgb(b, _color.R, _color.G, _color.B).toColor());
                        g.DrawLine(p, i + 1, 0, i + 1, _bitmap.Height);
                        p.Dispose();
                    }
                }


                break;
            }

            g.DrawRectangle(Pens.Black, outsideRectangle);


            int x = (int)Math.Round((_bitmap.Width - 2) * (double)this._value / 255.0);

            Point[] TopPolygon = new Point[3];
            TopPolygon[0] = new Point {
                X = 1 + x - 5, Y = 0
            };
            TopPolygon[1] = new Point {
                X = 1 + x, Y = 5
            };
            TopPolygon[2] = new Point {
                X = 1 + x + 5, Y = 0
            };

            Point[] BottomPolygon = new Point[3];
            BottomPolygon[0] = new Point {
                X = +1 + x - 5, Y = _bitmap.Height
            };
            BottomPolygon[1] = new Point {
                X = +1 + x, Y = _bitmap.Height - 5
            };
            BottomPolygon[2] = new Point {
                X = 1 + x + 5, Y = _bitmap.Height
            };

            g.FillPolygon(Brushes.Black, TopPolygon);
            g.DrawPolygon(Pens.White, TopPolygon);

            g.FillPolygon(Brushes.Black, BottomPolygon);
            g.DrawPolygon(Pens.White, BottomPolygon);

            g.Dispose();
        }
 public ColorChangeEventArgs(YColor color)
 {
     _color = color;
 }
        public ColorEdit(YColor initialValue)
        {
            TabStop = true;



            // WTF???   System.Drawing.Color predefined values contains duplicates
            for (int i = 0; i < predefinedColorProperties.Count; i++)
            {
                Color c = (Color)predefinedColorProperties[i].GetValue(null, null);
                if ((c.A == 255) && (c.Name != "Transparent"))
                {
                    bool found = false;
                    for (int j = 0; j < predefinedColors.Count; j++)
                    {
                        if ((c.R == predefinedColors[j].R) && (c.G == predefinedColors[j].G) && (c.B == predefinedColors[j].B))
                        {
                            found = true;
                        }
                    }


                    if (!found)
                    {
                        predefinedColors.Add(c);
                    }
                }

                predefinedColors.Sort(new ColorComparer());
            }



            if (_colorHistory.Count <= 0)
            {
                _colorHistory.Add(YColor.FromAhsl(100, 0, 0, 0));
                _colorHistory.Add(YColor.FromAhsl(100, 0, 0, 51));
                _colorHistory.Add(YColor.FromAhsl(100, 0, 0, 102));
                _colorHistory.Add(YColor.FromAhsl(100, 0, 0, 153));
                _colorHistory.Add(YColor.FromAhsl(100, 0, 0, 204));
                _colorHistory.Add(YColor.FromAhsl(100, 0, 0, 255));


                _colorHistory.Add(YColor.FromAhsl(100, 0, 255, 127));
                _colorHistory.Add(YColor.FromAhsl(100, 42, 255, 127));
                _colorHistory.Add(YColor.FromAhsl(100, 85, 255, 127));
                _colorHistory.Add(YColor.FromAhsl(100, 96, 255, 127));
                _colorHistory.Add(YColor.FromAhsl(100, 127, 255, 127));
                _colorHistory.Add(YColor.FromAhsl(100, 170, 255, 127));
                _colorHistory.Add(YColor.FromAhsl(100, 192, 255, 127));
                _colorHistory.Add(YColor.FromAhsl(100, 212, 255, 127));
                _colorHistory.Add(YColor.FromAhsl(255, 226, 217, 214));
            }

            _value = initialValue;
            this.InitializeComponent();

            BackColor = SystemColors.Control;
            ToolTip tt = new ToolTip();

            tt.SetToolTip(pictureBoxHistory, "Color history");

            tt = new ToolTip();
            tt.SetToolTip(PredefinedPanel, "Predefined colors palette");

            tt = new ToolTip();
            tt.SetToolTip(pictureBoxPreview, "Color Preview");



            C1RGB = new ColorCursor(ColorCursor.ColorFunction.COLOR_R, C1RGB_pictureBox, C1RGB_textBox, ValueChanged, _value);
            C2RGB = new ColorCursor(ColorCursor.ColorFunction.COLOR_G, C2RGB_pictureBox, C2RGB_textBox, ValueChanged, _value);
            C3RGB = new ColorCursor(ColorCursor.ColorFunction.COLOR_B, C3RGB_pictureBox, C3RGB_textBox, ValueChanged, _value);
            C4RGB = new ColorCursor(ColorCursor.ColorFunction.COLOR_A, C4RGB_pictureBox, C4RGB_textBox, ValueChanged, _value);

            C1HSL = new ColorCursor(ColorCursor.ColorFunction.COLOR_H, C1HSL_pictureBox, C1HSL_textBox, ValueChanged, _value);
            C2HSL = new ColorCursor(ColorCursor.ColorFunction.COLOR_S, C2HSL_pictureBox, C2HSL_textBox, ValueChanged, _value);
            C3HSL = new ColorCursor(ColorCursor.ColorFunction.COLOR_L, C3HSL_pictureBox, C3HSL_textBox, ValueChanged, _value);
            C4HSL = new ColorCursor(ColorCursor.ColorFunction.COLOR_A, C4HSL_pictureBox, C4HSL_textBox, ValueChanged, _value);


            autoSelectTab();



            pictureBoxHistory.MouseMove        += HistoryMouseMove;
            pictureBoxHistory.MouseUp          += HistoryMouseUp;
            pictureBoxHistory.MouseDoubleClick += HistoryMouseDoubleClick;

            PredefinedPanel.MouseMove        += PredefinedMouseMove;
            PredefinedPanel.MouseUp          += PredefinedMouseUp;
            PredefinedPanel.MouseDoubleClick += PredefinedMouseDoubleClick;



            computeSpacing();

            DrawHistory();
            PreviewColor();
            DrawPredefinedColors();
        }
 public ColorEdit() : this(YColor.fromColor(Color.Red))
 {
 }