using System;
using System.Drawing;
using Gwen.Input;
namespace Gwen.Control
{
///
/// Linear-interpolated HSV color box.
///
public class ColorLerpBox : Base
{
private Point m_CursorPos;
private bool m_Depressed;
private float m_Hue;
private Texture m_Texture;
///
/// Invoked when the selected color has been changed.
///
public event GwenEventHandler ColorChanged;
///
/// Initializes a new instance of the class.
///
/// Parent control.
public ColorLerpBox(Base parent) : base(parent)
{
SetColor(Color.FromArgb(255, 255, 128, 0));
SetSize(128, 128);
MouseInputEnabled = true;
m_Depressed = false;
// texture is initialized in Render() if null
}
///
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
///
public override void Dispose()
{
if (m_Texture != null)
m_Texture.Dispose();
base.Dispose();
}
///
/// Linear color interpolation.
///
public static Color Lerp(Color toColor, Color fromColor, float amount)
{
Color delta = toColor.Subtract(fromColor);
delta = delta.Multiply(amount);
return fromColor.Add(delta);
}
///
/// Selected color.
///
public Color SelectedColor
{
get { return GetColorAt(m_CursorPos.X, m_CursorPos.Y); }
}
///
/// Sets the selected color.
///
/// Value to set.
/// Deetrmines whether to only set H value (not SV).
public void SetColor(Color value, bool onlyHue = true)
{
HSV hsv = value.ToHSV();
m_Hue = hsv.h;
if (!onlyHue)
{
m_CursorPos.X = (int)(hsv.s * Width);
m_CursorPos.Y = (int)((1 - hsv.v) * Height);
}
Invalidate();
if (ColorChanged != null)
ColorChanged.Invoke(this);
}
///
/// Handler invoked on mouse moved event.
///
/// X coordinate.
/// Y coordinate.
/// X change.
/// Y change.
protected override void OnMouseMoved(int x, int y, int dx, int dy)
{
if (m_Depressed)
{
m_CursorPos = CanvasPosToLocal(new Point(x, y));
//Do we have clamp?
if (m_CursorPos.X < 0)
m_CursorPos.X = 0;
if (m_CursorPos.X > Width)
m_CursorPos.X = Width;
if (m_CursorPos.Y < 0)
m_CursorPos.Y = 0;
if (m_CursorPos.Y > Height)
m_CursorPos.Y = Height;
if (ColorChanged != null)
ColorChanged.Invoke(this);
}
}
///
/// Handler invoked on mouse click (left) event.
///
/// X coordinate.
/// Y coordinate.
/// If set to true mouse button is down.
protected override void OnMouseClickedLeft(int x, int y, bool down)
{
m_Depressed = down;
if (down)
InputHandler.MouseFocus = this;
else
InputHandler.MouseFocus = null;
OnMouseMoved(x, y, 0, 0);
}
///
/// Gets the color from specified coordinates.
///
/// X
/// Y
/// Color value.
private Color GetColorAt(int x, int y)
{
float xPercent = (x / (float)Width);
float yPercent = 1 - (y / (float)Height);
Color result = Util.HSVToColor(m_Hue, xPercent, yPercent);
return result;
}
///
/// Invalidates the control.
///
public override void Invalidate()
{
if (m_Texture != null)
{
m_Texture.Dispose();
m_Texture = null;
}
base.Invalidate();
}
///
/// Renders the control using specified skin.
///
/// Skin to use.
protected override void Render(Skin.Base skin)
{
if (m_Texture == null)
{
byte[] pixelData = new byte[Width*Height*4];
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
Color c = GetColorAt(x, y);
pixelData[4*(x + y*Width)] = c.R;
pixelData[4*(x + y*Width) + 1] = c.G;
pixelData[4*(x + y*Width) + 2] = c.B;
pixelData[4*(x + y*Width) + 3] = c.A;
}
}
m_Texture = new Texture(skin.Renderer);
m_Texture.Width = Width;
m_Texture.Height = Height;
m_Texture.LoadRaw(Width, Height, pixelData);
}
skin.Renderer.DrawColor = Color.White;
skin.Renderer.DrawTexturedRect(m_Texture, RenderBounds);
skin.Renderer.DrawColor = Color.Black;
skin.Renderer.DrawLinedRect(RenderBounds);
Color selected = SelectedColor;
if ((selected.R + selected.G + selected.B)/3 < 170)
skin.Renderer.DrawColor = Color.White;
else
skin.Renderer.DrawColor = Color.Black;
Rectangle testRect = new Rectangle(m_CursorPos.X - 3, m_CursorPos.Y - 3, 6, 6);
skin.Renderer.DrawShavedCornerRect(testRect);
base.Render(skin);
}
}
}