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));
            }
        }
        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();
        }