Files
bullet3/btgui/Gwen/Controls/ColorControls.cpp
2013-03-12 23:52:31 -07:00

327 lines
6.5 KiB
C++

/*
GWEN
Copyright (c) 2010 Facepunch Studios
See license in Gwen.h
*/
#include "Gwen/Utility.h"
#include "Gwen/Controls/ColorControls.h"
using namespace Gwen;
using namespace Gwen::Controls;
//Find a place to put these...
Color HSVToColor( float h, float s, float v )
{
if (h < 0.0f) h += 360.0f;
if (h > 360.0f) h -= 360.0f;
s *= 255.0f;
v *= 255.0f;
float r, g, b;
if (!h && !s)
{
r = g = b = v;
}
double min,max,delta,hue;
max = v;
delta = (max * s)/255.0;
min = max - delta;
hue = h;
if (h > 300 || h <= 60)
{
r = (int)max;
if (h > 300)
{
g = (int)min;
hue = (hue - 360.0)/60.0;
b = (int)((hue * delta - min) * -1);
}
else
{
b = (int)min;
hue = hue / 60.0;
g = (int)(hue * delta + min);
}
}
else if (h > 60 && h < 180)
{
g = (int)max;
if (h < 120)
{
b = (int)min;
hue = (hue/60.0 - 2.0 ) * delta;
r = (int)(min - hue);
}
else
{
r = (int)min;
hue = (hue/60 - 2.0) * delta;
b = (int)(min + hue);
}
}
else
{
b = (int)max;
if (h < 240)
{
r = (int)min;
hue = (hue/60.0 - 4.0 ) * delta;
g = (int)(min - hue);
}
else
{
g = (int)min;
hue = (hue/60 - 4.0) * delta;
r = (int)(min + hue);
}
}
return Color( r, g, b, 255);
}
HSV RGBtoHSV( int r, int g, int b )
{
double min,max,delta,temp;
min = GwenUtil_Min(r,GwenUtil_Min(g,b));
max = GwenUtil_Max(r,GwenUtil_Max(g,b));
delta = max - min;
HSV hsv;
hsv.v = (int)max;
if (!delta)
{
hsv.h = hsv.s = 0;
}
else
{
temp = delta/max;
hsv.s = (int)(temp*255);
if (r == (int)max)
{
temp = (double)(g-b)/delta;
}
else
if (g == (int)max)
{
temp = 2.0 + ((double)(b-r)/delta);
}
else
{
temp = 4.0 + ((double)(r-g)/delta);
}
temp *= 60;
if (temp < 0)
{
temp+=360;
}
if (temp == 360)
{
temp = 0;
}
hsv.h = (int)temp;
}
hsv.s /= 255.0f;
hsv.v /= 255.0f;
return hsv;
}
GWEN_CONTROL_CONSTRUCTOR( ColorLerpBox )
{
SetColor( Gwen::Color(255, 128, 0, 255) );
SetSize( 128, 128 );
SetMouseInputEnabled( true );
m_bDepressed = false;
}
//Find a place to put this? color member?
Gwen::Color LerpColor( Gwen::Color &toColor, Gwen::Color &fromColor, float amount )
{
Gwen::Color colorDelta = toColor - fromColor;
colorDelta.r *= amount;
colorDelta.g *= amount;
colorDelta.b *= amount;
Gwen::Color newColor = fromColor + colorDelta;
return newColor;
}
Gwen::Color ColorLerpBox::GetSelectedColor()
{
return GetColorAtPos( cursorPos.x, cursorPos.y );
}
void ColorLerpBox::SetColor( Gwen::Color color, bool onlyHue )
{
HSV hsv = RGBtoHSV(color.r, color.g, color.b);
m_Hue = hsv.h;
if ( !onlyHue )
{
cursorPos.x = hsv.s * Width();
cursorPos.y = (1 - hsv.v) * Height();
}
onSelectionChanged.Call( this );
}
void ColorLerpBox::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
{
if ( m_bDepressed )
{
cursorPos = CanvasPosToLocal( Gwen::Point( x, y ) );
//Do we have clamp?
if ( cursorPos.x < 0)
cursorPos.x = 0;
if (cursorPos.x > Width())
cursorPos.x = Width();
if (cursorPos.y < 0)
cursorPos.y = 0;
if (cursorPos.y > Height())
cursorPos.y = Height();
onSelectionChanged.Call( this );
}
}
void ColorLerpBox::OnMouseClickLeft( int x, int y, bool bDown )
{
m_bDepressed = bDown;
if ( bDown )
Gwen::MouseFocus = this;
else
Gwen::MouseFocus = NULL;
OnMouseMoved( x, y, 0, 0);
}
Gwen::Color ColorLerpBox::GetColorAtPos( int x, int y )
{
float xPercent = ( (float)x / (float)Width() );
float yPercent = 1 - ( (float)y / (float)Height() );
Gwen::Color result = HSVToColor( m_Hue, xPercent, yPercent );
result.a = 255;
return result;
}
void ColorLerpBox::Render( Gwen::Skin::Base* skin )
{
//Is there any way to move this into skin? Not for now, no idea how we'll "actually" render these
BaseClass::Render( skin );
for ( int x = 0; x<Width(); x++)
{
for ( int y = 0; y<Height(); y++)
{
skin->GetRender()->SetDrawColor( GetColorAtPos( x, y ) );
skin->GetRender()->DrawPixel( x, y );
}
}
skin->GetRender()->SetDrawColor( Gwen::Color( 0, 0, 0, 255 ) );
skin->GetRender()->DrawLinedRect( GetRenderBounds() );
Gwen::Color selected = GetSelectedColor();
if ( (selected.r + selected.g + selected.b) / 3 < 170 )
skin->GetRender()->SetDrawColor( Gwen::Color( 255, 255, 255, 255 ) );
else
skin->GetRender()->SetDrawColor( Gwen::Color( 0, 0, 0, 255 ) );
Gwen::Rect testRect = Gwen::Rect( cursorPos.x -3, cursorPos.y -3, 6, 6);
skin->GetRender()->DrawShavedCornerRect( testRect );
}
GWEN_CONTROL_CONSTRUCTOR( ColorSlider )
{
SetSize( 32, 128 );
SetMouseInputEnabled( true );
m_bDepressed = false;
}
void ColorSlider::Render( Gwen::Skin::Base* skin )
{
//Is there any way to move this into skin? Not for now, no idea how we'll "actually" render these
int y = 0;
for ( y = 0; y < Height(); y++)
{
float yPercent = (float)y / (float)Height();
skin->GetRender()->SetDrawColor( HSVToColor( yPercent * 360, 1, 1 ) );
skin->GetRender()->DrawFilledRect( Gwen::Rect( 5, y, Width() - 10, 1 ) );
}
int drawHeight = m_iSelectedDist - 3;
//Draw our selectors
skin->GetRender()->SetDrawColor( Gwen::Color( 0, 0, 0, 255 ));
skin->GetRender()->DrawFilledRect( Gwen::Rect( 0, drawHeight + 2, Width(), 1));
skin->GetRender()->DrawFilledRect( Gwen::Rect( 0, drawHeight, 5, 5) );
skin->GetRender()->DrawFilledRect( Gwen::Rect( Width() - 5, drawHeight, 5, 5) );
skin->GetRender()->SetDrawColor( Gwen::Color( 255, 255, 255, 255 ) );
skin->GetRender()->DrawFilledRect( Gwen::Rect( 1, drawHeight + 1, 3, 3 ) );
skin->GetRender()->DrawFilledRect( Gwen::Rect( Width() - 4, drawHeight + 1, 3, 3 ) );
}
void ColorSlider::OnMouseClickLeft( int x, int y, bool bDown )
{
m_bDepressed = bDown;
if ( bDown)
Gwen::MouseFocus = this;
else
Gwen::MouseFocus = NULL;
OnMouseMoved(x, y, 0, 0);
}
Gwen::Color ColorSlider::GetColorAtHeight( int y )
{
float yPercent = (float)y / (float)Height();
return HSVToColor( yPercent * 360, 1, 1);
}
void ColorSlider::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
{
if ( m_bDepressed )
{
Gwen::Point cursorPos = CanvasPosToLocal( Gwen::Point( x, y ) );
if (cursorPos.y < 0)
cursorPos.y = 0;
if (cursorPos.y > Height())
cursorPos.y = Height();
m_iSelectedDist = cursorPos.y;
onSelectionChanged.Call( this );
}
}
void ColorSlider::SetColor( Gwen::Color color)
{
HSV hsv = RGBtoHSV( color.r, color.g, color.b );
m_iSelectedDist = hsv.h / 360 * Height();
onSelectionChanged.Call( this );
}
Gwen::Color ColorSlider::GetSelectedColor()
{
return GetColorAtHeight( m_iSelectedDist );
}