added everything
This commit is contained in:
464
engine/gui/controls/guiColorPicker.cc
Executable file
464
engine/gui/controls/guiColorPicker.cc
Executable file
@@ -0,0 +1,464 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "console/console.h"
|
||||
#include "dgl/dgl.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "platform/platformAudio.h"
|
||||
#include "gui/core/guiCanvas.h"
|
||||
#include "gui/controls/guiButtonCtrl.h"
|
||||
#include "gui/core/guiDefaultControlRender.h"
|
||||
#include "gui/controls/guiColorPicker.h"
|
||||
|
||||
/// @name Common colors we use
|
||||
/// @{
|
||||
ColorF colorWhite(1.,1.,1.);
|
||||
ColorF colorWhiteBlend(1.,1.,1.,.75);
|
||||
ColorF colorBlack(.0,.0,.0);
|
||||
ColorF colorAlpha(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
ColorI GuiColorPickerCtrl::mColorRange[9] = {
|
||||
ColorI(255,255,255), // White
|
||||
ColorI(255,255,255), // White
|
||||
ColorI(255,0,255), // Pink
|
||||
ColorI(0,0,255), // Blue
|
||||
ColorI(0,255,255), // Light blue
|
||||
ColorI(0,255,0), // Green
|
||||
ColorI(255,255,0), // Yellow
|
||||
ColorI(255,0,0), // Red
|
||||
ColorI(0,0,0) // Black
|
||||
};
|
||||
/// @}
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiColorPickerCtrl);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
GuiColorPickerCtrl::GuiColorPickerCtrl()
|
||||
{
|
||||
mBounds.extent.set(140, 30);
|
||||
mDisplayMode = pPallet;
|
||||
mBaseColor = ColorF(1.,.0,1.);
|
||||
mPickColor = ColorF(.0,.0,.0);
|
||||
mSelectorPos = Point2I(0,0);
|
||||
mMouseDown = mMouseOver = false;
|
||||
mActive = true;
|
||||
mPositionChanged = false;
|
||||
mSelectorGap = 1;
|
||||
mActionOnMove = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static EnumTable::Enums gColorPickerModeEnums[] =
|
||||
{
|
||||
{ GuiColorPickerCtrl::pPallet, "Pallet" },
|
||||
{ GuiColorPickerCtrl::pHorizColorRange, "HorizColor"},
|
||||
{ GuiColorPickerCtrl::pVertColorRange, "VertColor" },
|
||||
{ GuiColorPickerCtrl::pHorizColorBrightnessRange, "HorizBrightnessColor"},
|
||||
{ GuiColorPickerCtrl::pVertColorBrightnessRange, "VertBrightnessColor" },
|
||||
{ GuiColorPickerCtrl::pBlendColorRange, "BlendColor"},
|
||||
{ GuiColorPickerCtrl::pHorizAlphaRange, "HorizAlpha"},
|
||||
{ GuiColorPickerCtrl::pVertAlphaRange, "VertAlpha" },
|
||||
{ GuiColorPickerCtrl::pDropperBackground, "Dropper" },
|
||||
};
|
||||
|
||||
static EnumTable gColorPickerModeTable( 9, gColorPickerModeEnums );
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void GuiColorPickerCtrl::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
|
||||
addGroup("ColorPicker");
|
||||
addField("BaseColor", TypeColorF, Offset(mBaseColor, GuiColorPickerCtrl));
|
||||
addField("PickColor", TypeColorF, Offset(mPickColor, GuiColorPickerCtrl));
|
||||
addField("SelectorGap", TypeS32, Offset(mSelectorGap, GuiColorPickerCtrl));
|
||||
addField("DisplayMode", TypeEnum, Offset(mDisplayMode, GuiColorPickerCtrl), 1, &gColorPickerModeTable );
|
||||
addField("ActionOnMove", TypeBool,Offset(mActionOnMove, GuiColorPickerCtrl));
|
||||
endGroup("ColorPicker");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Function to draw a box which can have 4 different colors in each corner blended together
|
||||
void dglDrawBlendBox(RectI &bounds, ColorF &c1, ColorF &c2, ColorF &c3, ColorF &c4)
|
||||
{
|
||||
S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
|
||||
S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
// Make sure the top row of pixels are the right color.
|
||||
glColor4f(c1.red, c1.green, c1.blue, c1.alpha);
|
||||
glVertex2f(l, t);
|
||||
glColor4f(c2.red, c2.green, c2.blue, c2.alpha);
|
||||
glVertex2f(r, t);
|
||||
glColor4f(c2.red, c2.green, c2.blue, c2.alpha);
|
||||
glVertex2f(r, t + 1);
|
||||
glColor4f(c1.red, c1.green, c1.blue, c1.alpha);
|
||||
glVertex2f(l, t + 1);
|
||||
|
||||
// The main blend box.
|
||||
glColor4f(c1.red, c1.green, c1.blue, c1.alpha);
|
||||
glVertex2f(l, t + 1);
|
||||
glColor4f(c2.red, c2.green, c2.blue, c2.alpha);
|
||||
glVertex2f(r, t + 1);
|
||||
glColor4f(c3.red, c3.green, c3.blue, c3.alpha);
|
||||
glVertex2f(r, b - 1);
|
||||
glColor4f(c4.red, c4.green, c4.blue, c4.alpha);
|
||||
glVertex2f(l, b - 1);
|
||||
|
||||
// Make sure the bottom row of pixels are the right color.
|
||||
glColor4f(c4.red, c4.green, c4.blue, c4.alpha);
|
||||
glVertex2f(l, b - 1);
|
||||
glColor4f(c3.red, c3.green, c3.blue, c3.alpha);
|
||||
glVertex2f(r, b - 1);
|
||||
glColor4f(c3.red, c3.green, c3.blue, c3.alpha);
|
||||
glVertex2f(r, b);
|
||||
glColor4f(c4.red, c4.green, c4.blue, c4.alpha);
|
||||
glVertex2f(l, b);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/// Function to draw a set of boxes blending throughout an array of colors
|
||||
void dglDrawBlendRangeBox(RectI &bounds, bool vertical, U8 numColors, ColorI *colors)
|
||||
{
|
||||
S32 l = bounds.point.x, r = bounds.point.x + bounds.extent.x - 1;
|
||||
S32 t = bounds.point.y, b = bounds.point.y + bounds.extent.y - 1;
|
||||
|
||||
// Calculate increment value
|
||||
S32 x_inc = int(mFloor((r - l) / (numColors-1)));
|
||||
S32 y_inc = int(mFloor((b - t) / (numColors-1)));
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
for (U16 i=0;i<numColors-1;i++)
|
||||
{
|
||||
// If we are at the end, x_inc and y_inc need to go to the end (otherwise there is a rendering bug)
|
||||
if (i == numColors-2)
|
||||
{
|
||||
x_inc += r-l-1;
|
||||
y_inc += b-t-1;
|
||||
}
|
||||
if (!vertical) // Horizontal (+x)
|
||||
{
|
||||
// First color
|
||||
glColor4ub(colors[i].red, colors[i].green, colors[i].blue, colors[i].alpha);
|
||||
glVertex2f(l, t);
|
||||
glVertex2f(l, b);
|
||||
// Second color
|
||||
glColor4ub(colors[i+1].red, colors[i+1].green, colors[i+1].blue, colors[i+1].alpha);
|
||||
glVertex2f(l+x_inc, b);
|
||||
glVertex2f(l+x_inc, t);
|
||||
l += x_inc;
|
||||
}
|
||||
else // Vertical (+y)
|
||||
{
|
||||
// First color
|
||||
glColor4ub(colors[i].red, colors[i].green, colors[i].blue, colors[i].alpha);
|
||||
glVertex2f(l, t);
|
||||
glVertex2f(r, t);
|
||||
// Second color
|
||||
glColor4ub(colors[i+1].red, colors[i+1].green, colors[i+1].blue, colors[i+1].alpha);
|
||||
glVertex2f(r, t+y_inc);
|
||||
glVertex2f(l, t+y_inc);
|
||||
t += y_inc;
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void GuiColorPickerCtrl::drawSelector(RectI &bounds, Point2I &selectorPos, SelectorMode mode)
|
||||
{
|
||||
U16 sMax = mSelectorGap*2;
|
||||
switch (mode)
|
||||
{
|
||||
case sVertical:
|
||||
// Now draw the vertical selector
|
||||
// Up -> Pos
|
||||
if (selectorPos.y != bounds.point.y+1)
|
||||
dglDrawLine(selectorPos.x, bounds.point.y, selectorPos.x, selectorPos.y-sMax-1, colorWhiteBlend);
|
||||
// Down -> Pos
|
||||
if (selectorPos.y != bounds.point.y+bounds.extent.y)
|
||||
dglDrawLine(selectorPos.x, selectorPos.y + sMax, selectorPos.x, bounds.point.y + bounds.extent.y, colorWhiteBlend);
|
||||
break;
|
||||
case sHorizontal:
|
||||
// Now draw the horizontal selector
|
||||
// Left -> Pos
|
||||
if (selectorPos.x != bounds.point.x)
|
||||
dglDrawLine(bounds.point.x, selectorPos.y-1, selectorPos.x-sMax, selectorPos.y-1, colorWhiteBlend);
|
||||
// Right -> Pos
|
||||
if (selectorPos.x != bounds.point.x)
|
||||
dglDrawLine(bounds.point.x+mSelectorPos.x+sMax, selectorPos.y-1, bounds.point.x + bounds.extent.x, selectorPos.y-1, colorWhiteBlend);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/// Function to invoke calls to draw the picker box and selector
|
||||
void GuiColorPickerCtrl::renderColorBox(RectI &bounds)
|
||||
{
|
||||
RectI pickerBounds;
|
||||
pickerBounds.point.x = bounds.point.x+1;
|
||||
pickerBounds.point.y = bounds.point.y+1;
|
||||
pickerBounds.extent.x = bounds.extent.x-1;
|
||||
pickerBounds.extent.y = bounds.extent.y-1;
|
||||
|
||||
if (mProfile->mBorder)
|
||||
dglDrawRect(bounds, mProfile->mBorderColor);
|
||||
|
||||
Point2I selectorPos = Point2I(bounds.point.x+mSelectorPos.x+1, bounds.point.y+mSelectorPos.y+1);
|
||||
|
||||
// Draw color box differently depending on mode
|
||||
RectI blendRect;
|
||||
switch (mDisplayMode)
|
||||
{
|
||||
case pHorizColorRange:
|
||||
dglDrawBlendRangeBox( pickerBounds, false, 7, mColorRange + 2);
|
||||
drawSelector( pickerBounds, selectorPos, sVertical );
|
||||
break;
|
||||
case pVertColorRange:
|
||||
dglDrawBlendRangeBox( pickerBounds, true, 7, mColorRange + 2);
|
||||
drawSelector( pickerBounds, selectorPos, sHorizontal );
|
||||
break;
|
||||
case pHorizColorBrightnessRange:
|
||||
blendRect = pickerBounds;
|
||||
blendRect.point.y++;
|
||||
blendRect.extent.y -= 2;
|
||||
dglDrawBlendRangeBox( pickerBounds, false, 9, mColorRange);
|
||||
// This is being drawn slightly offset from the larger rect so as to insure 255 and 0
|
||||
// can both be selected for every color.
|
||||
dglDrawBlendBox( blendRect, colorAlpha, colorAlpha, colorBlack, colorBlack );
|
||||
blendRect.point.y += blendRect.extent.y - 1;
|
||||
blendRect.extent.y = 2;
|
||||
dglDrawRect( blendRect, colorBlack);
|
||||
drawSelector( pickerBounds, selectorPos, sHorizontal );
|
||||
drawSelector( pickerBounds, selectorPos, sVertical );
|
||||
break;
|
||||
case pVertColorBrightnessRange:
|
||||
dglDrawBlendRangeBox( pickerBounds, true, 9, mColorRange);
|
||||
dglDrawBlendBox( pickerBounds, colorAlpha, colorBlack, colorBlack, colorAlpha );
|
||||
drawSelector( pickerBounds, selectorPos, sHorizontal );
|
||||
drawSelector( pickerBounds, selectorPos, sVertical );
|
||||
break;
|
||||
case pHorizAlphaRange:
|
||||
dglDrawBlendBox( pickerBounds, colorBlack, colorWhite, colorWhite, colorBlack );
|
||||
drawSelector( pickerBounds, selectorPos, sVertical );
|
||||
break;
|
||||
case pVertAlphaRange:
|
||||
dglDrawBlendBox( pickerBounds, colorBlack, colorBlack, colorWhite, colorWhite );
|
||||
drawSelector( pickerBounds, selectorPos, sHorizontal );
|
||||
break;
|
||||
case pBlendColorRange:
|
||||
dglDrawBlendBox( pickerBounds, colorWhite, mBaseColor, colorBlack, colorBlack );
|
||||
drawSelector( pickerBounds, selectorPos, sHorizontal );
|
||||
drawSelector( pickerBounds, selectorPos, sVertical );
|
||||
break;
|
||||
case pDropperBackground:
|
||||
break;
|
||||
case pPallet:
|
||||
default:
|
||||
dglDrawRectFill( pickerBounds, mBaseColor );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GuiColorPickerCtrl::onRender(Point2I offset, const RectI& updateRect)
|
||||
{
|
||||
RectI boundsRect(offset, mBounds.extent);
|
||||
renderColorBox(boundsRect);
|
||||
|
||||
if (mPositionChanged)
|
||||
{
|
||||
mPositionChanged = false;
|
||||
Point2I extent = Canvas->getExtent();
|
||||
// If we are anything but a pallete, change the pick color
|
||||
if (mDisplayMode != pPallet)
|
||||
{
|
||||
// To simplify things a bit, just read the color via glReadPixels()
|
||||
GLfloat rBuffer[4];
|
||||
glReadBuffer(GL_BACK);
|
||||
|
||||
U32 buf_x = offset.x+mSelectorPos.x+1;
|
||||
U32 buf_y = extent.y-(offset.y+mSelectorPos.y+1);
|
||||
glReadPixels(buf_x, buf_y, 1, 1, GL_RGBA, GL_FLOAT, rBuffer);
|
||||
|
||||
mPickColor.red = rBuffer[0];
|
||||
mPickColor.green = rBuffer[1];
|
||||
mPickColor.blue = rBuffer[2];
|
||||
mPickColor.alpha = rBuffer[3];
|
||||
|
||||
// Now do onAction() if we are allowed
|
||||
if (mActionOnMove)
|
||||
onAction();
|
||||
}
|
||||
}
|
||||
|
||||
//render the children
|
||||
renderChildControls( offset, updateRect);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void GuiColorPickerCtrl::setSelectorPos(const Point2I &pos)
|
||||
{
|
||||
Point2I extent = mBounds.extent;
|
||||
RectI rect;
|
||||
if (mDisplayMode != pDropperBackground)
|
||||
{
|
||||
extent.x -= 3;
|
||||
extent.y -= 2;
|
||||
rect = RectI(Point2I(1,1), extent);
|
||||
}
|
||||
else
|
||||
{
|
||||
rect = RectI(Point2I(0,0), extent);
|
||||
}
|
||||
|
||||
if (rect.pointInRect(pos))
|
||||
{
|
||||
mSelectorPos = pos;
|
||||
mPositionChanged = true;
|
||||
// We now need to update
|
||||
setUpdate();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if ((pos.x > rect.point.x) && (pos.x < (rect.point.x + rect.extent.x)))
|
||||
mSelectorPos.x = pos.x;
|
||||
else if (pos.x <= rect.point.x)
|
||||
mSelectorPos.x = rect.point.x;
|
||||
else if (pos.x >= (rect.point.x + rect.extent.x))
|
||||
mSelectorPos.x = rect.point.x + rect.extent.x - 1;
|
||||
|
||||
if ((pos.y > rect.point.y) && (pos.y < (rect.point.y + rect.extent.y)))
|
||||
mSelectorPos.y = pos.y;
|
||||
else if (pos.y <= rect.point.y)
|
||||
mSelectorPos.y = rect.point.y;
|
||||
else if (pos.y >= (rect.point.y + rect.extent.y))
|
||||
mSelectorPos.y = rect.point.y + rect.extent.y - 1;
|
||||
|
||||
mPositionChanged = true;
|
||||
setUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void GuiColorPickerCtrl::onMouseDown(const GuiEvent &event)
|
||||
{
|
||||
if (!mActive)
|
||||
return;
|
||||
|
||||
if (mDisplayMode == pDropperBackground)
|
||||
return;
|
||||
|
||||
mouseLock(this);
|
||||
|
||||
if (mProfile->mCanKeyFocus)
|
||||
setFirstResponder();
|
||||
|
||||
// Update the picker cross position
|
||||
if (mDisplayMode != pPallet)
|
||||
setSelectorPos(globalToLocalCoord(event.mousePoint));
|
||||
|
||||
mMouseDown = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void GuiColorPickerCtrl::onMouseDragged(const GuiEvent &event)
|
||||
{
|
||||
if ((mActive && mMouseDown) || (mActive && (mDisplayMode == pDropperBackground)))
|
||||
{
|
||||
// Update the picker cross position
|
||||
if (mDisplayMode != pPallet)
|
||||
setSelectorPos(globalToLocalCoord(event.mousePoint));
|
||||
}
|
||||
|
||||
if (!mActionOnMove && mAltConsoleCommand[0] )
|
||||
Con::evaluate( mAltConsoleCommand, false );
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void GuiColorPickerCtrl::onMouseMove(const GuiEvent &event)
|
||||
{
|
||||
// Only for dropper mode
|
||||
if (mActive && (mDisplayMode == pDropperBackground))
|
||||
setSelectorPos(globalToLocalCoord(event.mousePoint));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void GuiColorPickerCtrl::onMouseEnter(const GuiEvent &event)
|
||||
{
|
||||
mMouseOver = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void GuiColorPickerCtrl::onMouseLeave(const GuiEvent &)
|
||||
{
|
||||
// Reset state
|
||||
mMouseOver = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void GuiColorPickerCtrl::onMouseUp(const GuiEvent &)
|
||||
{
|
||||
//if we released the mouse within this control, perform the action
|
||||
if (mActive && mMouseDown && (mDisplayMode != pDropperBackground))
|
||||
{
|
||||
onAction();
|
||||
mMouseDown = false;
|
||||
}
|
||||
else if (mActive && (mDisplayMode == pDropperBackground))
|
||||
{
|
||||
// In a dropper, the alt command executes the mouse up action (to signal stopping)
|
||||
if ( mAltConsoleCommand[0] )
|
||||
Con::evaluate( mAltConsoleCommand, false );
|
||||
}
|
||||
|
||||
mouseUnlock();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
const char *GuiColorPickerCtrl::getScriptValue()
|
||||
{
|
||||
static char temp[256];
|
||||
ColorF color = getValue();
|
||||
dSprintf(temp,256,"%f %f %f %f",color.red, color.green, color.blue, color.alpha);
|
||||
return temp;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void GuiColorPickerCtrl::setScriptValue(const char *value)
|
||||
{
|
||||
ColorF newValue;
|
||||
dSscanf(value, "%f %f %f %f", &newValue.red, &newValue.green, &newValue.blue, &newValue.alpha);
|
||||
setValue(newValue);
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiColorPickerCtrl, getSelectorPos, const char*, 2, 2, "Gets the current position of the selector")
|
||||
{
|
||||
char *temp = Con::getReturnBuffer(256);
|
||||
Point2I pos;
|
||||
pos = object->getSelectorPos();
|
||||
dSprintf(temp,256,"%d %d",pos.x, pos.y);
|
||||
return temp;
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiColorPickerCtrl, setSelectorPos, void, 3, 3, "Sets the current position of the selector")
|
||||
{
|
||||
Point2I newPos;
|
||||
dSscanf(argv[2], "%d %d", &newPos.x, &newPos.y);
|
||||
object->setSelectorPos(newPos);
|
||||
}
|
||||
|
||||
ConsoleMethod(GuiColorPickerCtrl, updateColor, void, 2, 2, "Forces update of pick color")
|
||||
{
|
||||
object->updateColor();
|
||||
}
|
||||
Reference in New Issue
Block a user