|
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace CommonTools
{
public class ColorWheel : Control
{
public event EventHandler SelectedColorChanged;
Color m_frameColor = Color.CadetBlue;
HSLColor m_selectedColor = new HSLColor(Color.BlanchedAlmond);
PathGradientBrush m_brush = null;
List<PointF> m_path = new List<PointF>();
List<Color> m_colors = new List<Color>();
double m_wheelLightness = 0.5;
public HSLColor SelectedHSLColor
{
get { return m_selectedColor; }
set
{
if (m_selectedColor == value)
return;
Invalidate(Util.Rect(ColorSelectorRectangle));
m_selectedColor = value;
if (SelectedColorChanged != null)
SelectedColorChanged(this, null);
Refresh();//Invalidate(Util.Rect(ColorSelectorRectangle));
}
}
public ColorWheel()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
DoubleBuffered = true;
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
}
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
Invalidate();
}
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
using (SolidBrush b = new SolidBrush(BackColor))
{
e.Graphics.FillRectangle(b, ClientRectangle);
}
RectangleF wheelrect = WheelRectangle;
Util.DrawFrame(e.Graphics, wheelrect, 6, m_frameColor);
wheelrect = ColorWheelRectangle;
PointF center = Util.Center(wheelrect);
e.Graphics.SmoothingMode = SmoothingMode.HighSpeed;
if (m_brush == null)
{
m_brush = new PathGradientBrush(m_path.ToArray(), WrapMode.Clamp);
m_brush.CenterPoint = center;
m_brush.CenterColor = Color.White;
m_brush.SurroundColors = m_colors.ToArray();
}
e.Graphics.FillPie(m_brush, Util.Rect(wheelrect), 0, 360);
DrawColorSelector(e.Graphics);
if (Focused)
{
RectangleF r = WheelRectangle;
r.Inflate(-2,-2);
ControlPaint.DrawFocusRectangle(e.Graphics, Util.Rect(r));
}
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (m_brush != null)
m_brush.Dispose();
m_brush = null;
RecalcWheelPoints();
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
PointF mousepoint = new PointF(e.X, e.Y);
if (e.Button == MouseButtons.Left)
SetColor(mousepoint);
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
Focus();
PointF mousepoint = new PointF(e.X, e.Y);
if (e.Button == MouseButtons.Left)
SetColor(mousepoint);
}
protected override bool ProcessDialogKey(Keys keyData)
{
HSLColor c = SelectedHSLColor;
double hue = c.Hue;
int step = 1;
if ((keyData & Keys.Control) == Keys.Control)
step = 5;
if ((keyData & Keys.Up) == Keys.Up)
hue += step;
if ((keyData & Keys.Down) == Keys.Down)
hue -= step;
if (hue >= 360)
hue = 0;
if (hue < 0)
hue = 359;
if (hue != c.Hue)
{
c.Hue = hue;
SelectedHSLColor = c;
return true;
}
return base.ProcessDialogKey(keyData);
}
RectangleF ColorSelectorRectangle
{
get
{
HSLColor color = m_selectedColor;
double angleR = color.Hue * Math.PI / 180;
PointF center = Util.Center(ColorWheelRectangle);
double radius = Radius(ColorWheelRectangle);
radius *= color.Saturation;
double x = center.X + Math.Cos(angleR) * radius;
double y = center.Y - Math.Sin(angleR) * radius;
Rectangle colrect = new Rectangle(new Point((int)x, (int)y), new Size(0, 0));
colrect.Inflate(12, 12);
return colrect;
}
}
void DrawColorSelector(Graphics dc)
{
Rectangle r = Util.Rect(ColorSelectorRectangle);
PointF center = Util.Center(r);
Image image = SelectorImages.Image(SelectorImages.eIndexes.Donut);
dc.DrawImageUnscaled(image, (int)(center.X-image.Width/2), (int)(center.Y-image.Height/2));
}
RectangleF WheelRectangle
{
get
{
Rectangle r = ClientRectangle;
r.Width -= 1;
r.Height -= 1;
return r;
}
}
RectangleF ColorWheelRectangle
{
get
{
RectangleF r = WheelRectangle;
r.Inflate(-5, -5);
return r;
}
}
float Radius(RectangleF r)
{
PointF center = Util.Center(r);
float radius = Math.Min((r.Width / 2), (r.Height / 2));
return radius;
}
void RecalcWheelPoints()
{
m_path.Clear();
m_colors.Clear();
PointF center = Util.Center(ColorWheelRectangle);
float radius = Radius(ColorWheelRectangle);
double angle = 0;
double fullcircle = 360;
double step = 5;
while (angle < fullcircle)
{
double angleR = angle * (Math.PI/180);
double x = center.X + Math.Cos(angleR) * radius;
double y = center.Y - Math.Sin(angleR) * radius;
m_path.Add(new PointF((float)x,(float)y));
m_colors.Add(new HSLColor(angle, 1, m_wheelLightness).Color);
angle += step;
}
}
void SetColor(PointF mousepoint)
{
if (WheelRectangle.Contains(mousepoint) == false)
return;
PointF center = Util.Center(ColorWheelRectangle);
double radius = Radius(ColorWheelRectangle);
double dx = Math.Abs(mousepoint.X - center.X);
double dy = Math.Abs(mousepoint.Y - center.Y);
double angle = Math.Atan(dy / dx) / Math.PI * 180;
double dist = Math.Pow((Math.Pow(dx, 2) + (Math.Pow(dy, 2))), 0.5);
double saturation = dist/radius;
//if (dist > radius + 5) // give 5 pixels slack
// return;
if (dist < 6)
saturation = 0; // snap to center
if (mousepoint.X < center.X)
angle = 180 - angle;
if (mousepoint.Y > center.Y)
angle = 360 - angle;
SelectedHSLColor = new HSLColor(angle, saturation, SelectedHSLColor.Lightness);
}
}
}
|
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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.