kicad/common/widgets/color4Dpickerdlg.cpp

729 lines
22 KiB
C++

/**
* @file color4Dpickerdlg.cpp :
*/
#include "math.h"
#include "color4Dpickerdlg.h"
#define ALPHA_MAX 100 // the max value returned by the alpha (opacity) slider
COLOR4D_PICKER_DLG::COLOR4D_PICKER_DLG( wxWindow* aParent, KIGFX::COLOR4D& aCurrentColor,
bool aAllowOpacityControl )
: COLOR4D_PICKER_DLG_BASE( aParent )
{
m_allowMouseEvents = false;
m_allowOpacityCtrl = aAllowOpacityControl;
m_previousColor4D = aCurrentColor;
m_newColor4D = aCurrentColor;
m_cursorsSize = 8; // Size of square cursors drawn on color bitmaps
m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
m_bitmapRGB = nullptr;
m_bitmapHSV = nullptr;
m_selectedCursor = nullptr;
if( !m_allowOpacityCtrl )
{
m_SizerTransparency->Show( false );
m_previousColor4D.a = 1.0;
m_newColor4D.a = 1.0;
}
if( m_ActivePage >= 0 )
m_notebook->SetSelection( (unsigned) m_ActivePage );
// Build the defined colors panel:
initDefinedColors();
m_sdbSizerOK->SetDefault();
}
int COLOR4D_PICKER_DLG::m_ActivePage = 0; // the active notebook page, stored during a session
COLOR4D_PICKER_DLG::~COLOR4D_PICKER_DLG()
{
delete m_bitmapRGB;
delete m_bitmapHSV;
m_ActivePage = m_notebook->GetSelection();
for( auto button : m_buttonsColor )
button->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COLOR4D_PICKER_DLG::buttColorClick ), NULL, this );
}
void COLOR4D_PICKER_DLG::setIconColor( wxStaticBitmap* aStaticBitmap, KIGFX::COLOR4D& aColor4D )
{
// Draw the icon that shows the aColor4D,
// with colors according to the color 4D rgb and alpha
// for alpha = 1 (no tranparency, the icon is a full rgb color rect
// for alpha = 0 (100% tranparency, the icon is a grid of rgb color
// and background color small sub rect
wxMemoryDC bitmapDC;
wxSize size = aStaticBitmap->GetSize();
wxBitmap newBm( size );
bitmapDC.SelectObject( newBm );
wxPen pen( aColor4D.ToColour() );
wxBrush brush( aColor4D.ToColour() );
// clear background (set bg color to aColor4D )
bitmapDC.SetBackground( brush );
bitmapDC.Clear();
// Draw the alpha subrect
int stepx = size.x/8;
int stepy = size.y/8;
// build the alpha color for icon:
// the alpha color is the initial color modified to be
// the initial color for transparency = 0 ( alpha = 1 )
// and white color for transparency = 1( alpha = 0 )
KIGFX::COLOR4D bgcolor( GetBackgroundColour() );
KIGFX::COLOR4D alphacolor = aColor4D;
alphacolor.r = ( alphacolor.r * aColor4D.a ) + ( bgcolor.r * (1-aColor4D.a) );
alphacolor.g = ( alphacolor.g * aColor4D.a ) + ( bgcolor.g * (1-aColor4D.a) );
alphacolor.b = ( alphacolor.b * aColor4D.a ) + ( bgcolor.b * (1-aColor4D.a) );
pen.SetColour( alphacolor.ToColour() );
brush.SetColour( alphacolor.ToColour() );
bitmapDC.SetPen( pen );
bitmapDC.SetBrush( brush );
for( int ii = 0; ii < size.x/stepx; ii+=2 )
{
for( int jj = 0; jj < size.y/stepy; jj+= 2 )
{
wxPoint pos( stepx*ii + stepx/2, stepy*jj + stepy/2 );
bitmapDC.DrawRectangle( pos, wxSize( stepx, stepy ) );
}
}
aStaticBitmap->SetBitmap( newBm );
// Deselect the Tool Bitmap from DC, in order to delete the MemoryDC
// safely without deleting the bitmap
bitmapDC.SelectObject( wxNullBitmap );
}
bool COLOR4D_PICKER_DLG::TransferDataToWindow()
{
// Draw all bitmaps, with colors according to the color 4D
setIconColor( m_OldColorRect, m_previousColor4D );
SetEditVals( ALL_CHANGED );
drawAll();
m_notebook->GetPage( 0 )->Layout();
m_notebook->GetPage( 1 )->Layout();
FinishDialogSettings();
return true;
}
void COLOR4D_PICKER_DLG::initDefinedColors()
{
#define ID_COLOR_BLACK 2000 // colors_id = ID_COLOR_BLACK a ID_COLOR_BLACK + NBCOLORS-1
// Size of color swatches
const int w = 32, h = 32;
// Colors are built from the g_ColorRefs table (size NBCOLORS).
// The look is better when g_ColorRefs order is displayed in a grid matrix
// of 6 row and 5 columns, first filling a row, and after the next column.
// But the wxFlexGrid used here must be filled by columns, then next row
// the best interval g_ColorRefs from a matrix row to the next row is 6
// So when have to reorder the index used to explore g_ColorRefs
int grid_col = 0;
int grid_row = 0;
int table_row_count = 6;
for( int jj = 0; jj < NBCOLORS; ++jj, grid_col++ )
{
if( grid_col*table_row_count >= NBCOLORS )
{ // the current grid row is filled, and we must fill the next grid row
grid_col = 0;
grid_row++;
}
int ii = grid_row + (grid_col*table_row_count); // The index in g_ColorRefs
int butt_ID = ID_COLOR_BLACK + ii;
wxMemoryDC iconDC;
wxBitmap ButtBitmap( w, h );
wxBrush brush;
iconDC.SelectObject( ButtBitmap );
KIGFX::COLOR4D buttcolor = KIGFX::COLOR4D( g_ColorRefs[ii].m_Numcolor );
iconDC.SetPen( *wxBLACK_PEN );
brush.SetColour( buttcolor.ToColour() );
brush.SetStyle( wxBRUSHSTYLE_SOLID );
iconDC.SetBrush( brush );
iconDC.SetBackground( *wxGREY_BRUSH );
iconDC.Clear();
iconDC.DrawRoundedRectangle( 0, 0, w, h, (double) h / 3 );
wxBitmapButton* bitmapButton = new wxBitmapButton( m_panelDefinedColors, butt_ID, ButtBitmap,
wxDefaultPosition, wxSize( w+8, h+6 ) );
m_fgridColor->Add( bitmapButton, 0,
wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
wxLEFT | wxBOTTOM, 5 );
wxStaticText* label = new wxStaticText( m_panelDefinedColors, -1,
wxGetTranslation( g_ColorRefs[ii].m_ColorName ),
wxDefaultPosition, wxDefaultSize, 0 );
m_fgridColor->Add( label, 1,
wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
wxLEFT | wxRIGHT | wxBOTTOM, 5 );
m_buttonsColor.push_back( bitmapButton );
bitmapButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COLOR4D_PICKER_DLG::buttColorClick ), NULL, this );
}
}
void COLOR4D_PICKER_DLG::createRGBBitmap()
{
wxMemoryDC bitmapDC;
wxSize bmsize = m_RgbBitmap->GetSize();
int half_size = std::min( bmsize.x, bmsize.y )/2;
m_bitmapRGB = new wxBitmap( bmsize );
bitmapDC.SelectObject( *m_bitmapRGB );
wxPen pen;
// clear background (set the window bg color)
wxBrush bgbrush( GetBackgroundColour() );
bitmapDC.SetBackground( bgbrush );
bitmapDC.Clear();
// Use Y axis from bottom to top and origin to center
bitmapDC.SetAxisOrientation( true, true );
bitmapDC.SetDeviceOrigin( half_size, half_size );
// Reserve room to draw cursors inside the bitmap
half_size -= m_cursorsSize/2;
KIGFX::COLOR4D color;
// Red blue area in X Z 3d axis
double inc = 1.0 / half_size;
#define SLOPE_AXIS 50.0
double slope = SLOPE_AXIS/half_size;
color.g = 0.0;
for( int xx = 0; xx < half_size; xx++ ) // blue axis
{
color.b = inc * xx;
for( int yy = 0; yy < half_size; yy++ ) // Red axis
{
color.r = inc * yy;
pen.SetColour( color.ToColour() );
bitmapDC.SetPen( pen );
bitmapDC.DrawPoint( xx, yy - (slope*xx) );
}
}
// Red green area in y Z 3d axis
color.b = 0.0;
for( int xx = 0; xx < half_size; xx++ ) // green axis
{
color.g = inc * xx;
for( int yy = 0; yy < half_size; yy++ ) // Red axis
{
color.r = inc * yy;
pen.SetColour( color.ToColour() );
bitmapDC.SetPen( pen );
bitmapDC.DrawPoint( -xx, yy - (slope*xx) );
}
}
// Blue green area in x y 3d axis
color.r = 0.0;
for( int xx = 0; xx < half_size; xx++ ) // green axis
{
color.g = inc * xx;
for( int yy = 0; yy < half_size; yy++ ) // blue axis
{
color.b = inc * yy;
pen.SetColour( color.ToColour() );
bitmapDC.SetPen( pen );
// Mapping the xx, yy color axis to draw coordinates is more tricky than previously
// in DC coordinates:
// the blue axis is the (0, 0) to half_size, (-yy - SLOPE_AXIS)
// the green axis is the (0, 0) to - half_size, (-yy - SLOPE_AXIS)
int drawX = -xx + yy;
int drawY = - std::min( xx,yy ) * 0.9;
bitmapDC.DrawPoint( drawX, drawY - std::abs( slope*drawX ) );
}
}
}
void COLOR4D_PICKER_DLG::createHSVBitmap()
{
wxMemoryDC bitmapDC;
wxSize bmsize = m_HsvBitmap->GetSize();
int half_size = std::min( bmsize.x, bmsize.y )/2;
delete m_bitmapHSV;
m_bitmapHSV = new wxBitmap( bmsize );
bitmapDC.SelectObject( *m_bitmapHSV );
wxPen pen;
// clear background (set the window bd color)
wxBrush bgbrush( GetBackgroundColour() );
bitmapDC.SetBackground( bgbrush );
bitmapDC.Clear();
// Use Y axis from bottom to top and origin to center
bitmapDC.SetAxisOrientation( true, true );
bitmapDC.SetDeviceOrigin( half_size, half_size );
// Reserve room to draw cursors inside the bitmap
half_size -= m_cursorsSize/2;
double hue, sat;
KIGFX::COLOR4D color;
int sq_radius = half_size*half_size;
for( int xx = -half_size; xx < half_size; xx++ )
{
for( int yy = -half_size; yy < half_size; yy++ )
{
sat = double(xx*xx + yy*yy) / sq_radius;
// sat is <= 1.0
// any value > 1.0 is not a valid HSB color:
if( sat > 1.0 )
continue;
// sat is the distance from center
sat = sqrt( sat );
hue = atan2( (double)yy, (double)xx ) * 180 / M_PI;
if( hue < 0.0 )
hue += 360.0;
color.FromHSV( hue, sat, 1.0 );
pen.SetColour( color.ToColour() );
bitmapDC.SetPen( pen );
bitmapDC.DrawPoint( xx, yy );
}
}
/* Deselect the Tool Bitmap from DC,
* in order to delete the MemoryDC safely without deleting the bitmap
*/
bitmapDC.SelectObject( wxNullBitmap );
}
void COLOR4D_PICKER_DLG::drawRGBPalette()
{
if( !m_bitmapRGB || m_bitmapRGB->GetSize() != m_RgbBitmap->GetSize() )
createRGBBitmap();
wxMemoryDC bitmapDC;
wxSize bmsize = m_bitmapRGB->GetSize();
int half_size = std::min( bmsize.x, bmsize.y )/2;
wxBitmap newBm( *m_bitmapRGB );
bitmapDC.SelectObject( newBm );
// Use Y axis from bottom to top and origin to center
bitmapDC.SetAxisOrientation( true, true );
bitmapDC.SetDeviceOrigin( half_size, half_size );
// Reserve room to draw cursors inside the bitmap
half_size -= m_cursorsSize/2;
// Draw the 3 RGB cursors, usiing white color to make them always visible:
wxPen pen( wxColor( 255, 255, 255 ) );
wxBrush brush( wxColor( 0, 0, 0 ), wxBRUSHSTYLE_TRANSPARENT );
bitmapDC.SetPen( pen );
bitmapDC.SetBrush( brush );
int half_csize = m_cursorsSize/2;
#define SLOPE_AXIS 50.0
double slope = SLOPE_AXIS/half_size;
// Red axis cursor (Z 3Daxis):
m_cursorBitmapRed.x = 0;
m_cursorBitmapRed.y = m_newColor4D.r * half_size;
bitmapDC.DrawRectangle( m_cursorBitmapRed.x - half_csize,
m_cursorBitmapRed.y - half_csize,
m_cursorsSize, m_cursorsSize );
// Blue axis cursor (X 3Daxis):
m_cursorBitmapBlue.x = m_newColor4D.b * half_size;
m_cursorBitmapBlue.y = - slope*m_cursorBitmapBlue.x;
bitmapDC.DrawRectangle( m_cursorBitmapBlue.x - half_csize,
m_cursorBitmapBlue.y - half_csize,
m_cursorsSize, m_cursorsSize );
// Green axis cursor (Y 3Daxis):
m_cursorBitmapGreen.x = m_newColor4D.g * half_size;
m_cursorBitmapGreen.y = - slope * m_cursorBitmapGreen.x;
m_cursorBitmapGreen.x = -m_cursorBitmapGreen.x;
bitmapDC.DrawRectangle( m_cursorBitmapGreen.x - half_csize,
m_cursorBitmapGreen.y - half_csize,
m_cursorsSize, m_cursorsSize );
// Draw the 3 RGB axis:
half_size += half_size/5;
bitmapDC.DrawLine( 0, 0, 0, half_size ); // Red axis (Z 3D axis)
bitmapDC.DrawLine( 0, 0, half_size, - half_size*slope ); // Blue axis (X 3D axis)
bitmapDC.DrawLine( 0, 0, -half_size, - half_size*slope ); // green axis (Y 3D axis)
m_RgbBitmap->SetBitmap( newBm );
/* Deselect the Tool Bitmap from DC,
* in order to delete the MemoryDC safely without deleting the bitmap */
bitmapDC.SelectObject( wxNullBitmap );
}
void COLOR4D_PICKER_DLG::drawHSVPalette()
{
if( !m_bitmapHSV || m_bitmapHSV->GetSize() != m_HsvBitmap->GetSize() )
createHSVBitmap();
wxMemoryDC bitmapDC;
wxSize bmsize = m_bitmapHSV->GetSize();
int half_size = std::min( bmsize.x, bmsize.y )/2;
wxBitmap newBm( *m_bitmapHSV );
bitmapDC.SelectObject( newBm );
// Use Y axis from bottom to top and origin to center
bitmapDC.SetAxisOrientation( true, true );
bitmapDC.SetDeviceOrigin( half_size, half_size );
// Reserve room to draw cursors inside the bitmap
half_size -= m_cursorsSize/2;
// Draw the HSB cursor:
m_cursorBitmapHSV.x = cos( m_hue * M_PI / 180.0 ) * half_size * m_sat;
m_cursorBitmapHSV.y = sin( m_hue * M_PI / 180.0 ) * half_size * m_sat;
wxPen pen( wxColor( 0, 0, 0 ) );
wxBrush brush( wxColor( 0, 0, 0 ), wxBRUSHSTYLE_TRANSPARENT );
bitmapDC.SetPen( pen );
bitmapDC.SetBrush( brush );
int half_csize = m_cursorsSize/2;
bitmapDC.DrawRectangle( m_cursorBitmapHSV.x- half_csize,
m_cursorBitmapHSV.y-half_csize,
m_cursorsSize, m_cursorsSize );
m_HsvBitmap->SetBitmap( newBm );
/* Deselect the Tool Bitmap from DC,
* in order to delete the MemoryDC safely without deleting the bitmap
*/
bitmapDC.SelectObject( wxNullBitmap );
}
void COLOR4D_PICKER_DLG::SetEditVals( CHANGED_COLOR aChanged )
{
m_sliderTransparency->SetValue( normalizeToInt( m_newColor4D.a, ALPHA_MAX ) );
if( aChanged == RED_CHANGED || aChanged == GREEN_CHANGED || aChanged == BLUE_CHANGED )
m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
if( aChanged != RED_CHANGED )
m_spinCtrlRed->SetValue( normalizeToInt( m_newColor4D.r ) );
if( aChanged != GREEN_CHANGED )
m_spinCtrlGreen->SetValue( normalizeToInt( m_newColor4D.g ) );
if( aChanged != BLUE_CHANGED )
m_spinCtrlBlue->SetValue( normalizeToInt( m_newColor4D.b ) );
if( aChanged != HUE_CHANGED )
m_spinCtrlHue->SetValue( (int)m_hue );
if( aChanged != SAT_CHANGED )
m_spinCtrlSaturation->SetValue( m_sat * 255 );
if( aChanged != VAL_CHANGED )
{
m_sliderBrightness->SetValue(normalizeToInt( m_val ) );
}
}
void COLOR4D_PICKER_DLG::drawAll()
{
m_NewColorRect->Freeze(); // Avoid flicker
m_HsvBitmap->Freeze();
m_RgbBitmap->Freeze();
setIconColor( m_NewColorRect, m_newColor4D );
drawHSVPalette();
drawRGBPalette();
m_NewColorRect->Thaw();
m_HsvBitmap->Thaw();
m_RgbBitmap->Thaw();
m_NewColorRect->Refresh();
m_HsvBitmap->Refresh();
m_RgbBitmap->Refresh();
}
void COLOR4D_PICKER_DLG::buttColorClick( wxCommandEvent& event )
{
int id = event.GetId();
KIGFX::COLOR4D color( EDA_COLOR_T( id - ID_COLOR_BLACK ) );
m_newColor4D.r = color.r;
m_newColor4D.g = color.g;
m_newColor4D.b = color.b;
m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
SetEditVals( ALL_CHANGED );
drawAll();
event.Skip();
}
void COLOR4D_PICKER_DLG::onRGBMouseClick( wxMouseEvent& event )
{
m_allowMouseEvents = true;
wxPoint mousePos = event.GetPosition();
// The cursor position is relative to the m_bitmapHSV wxBitmap center
wxSize bmsize = m_bitmapRGB->GetSize();
int half_size = std::min( bmsize.x, bmsize.y )/2;
mousePos.x -= half_size;
mousePos.y -= half_size;
mousePos.y = -mousePos.y; // Use the bottom to top vertical axis
wxPoint dist = m_cursorBitmapRed - mousePos;
if( std::abs( dist.x ) <= m_cursorsSize/2 && std::abs( dist.y ) <= m_cursorsSize/2 )
{
m_selectedCursor = &m_cursorBitmapRed;
return;
}
dist = m_cursorBitmapGreen - mousePos;
if( std::abs( dist.x ) <= m_cursorsSize/2 && std::abs( dist.y ) <= m_cursorsSize/2 )
{
m_selectedCursor = &m_cursorBitmapGreen;
return;
}
dist = m_cursorBitmapBlue - mousePos;
if( std::abs( dist.x ) <= m_cursorsSize/2 && std::abs( dist.y ) <= m_cursorsSize/2 )
{
m_selectedCursor = &m_cursorBitmapBlue;
return;
}
m_selectedCursor = nullptr;
}
void COLOR4D_PICKER_DLG::onRGBMouseDrag( wxMouseEvent& event )
{
if( !event.Dragging() || !m_allowMouseEvents )
{
m_selectedCursor = nullptr;
return;
}
if( m_selectedCursor != &m_cursorBitmapRed &&
m_selectedCursor != &m_cursorBitmapGreen &&
m_selectedCursor != &m_cursorBitmapBlue )
return;
// Adjust the HSV cursor position to follow the mouse cursor
// The cursor position is relative to the m_bitmapHSV wxBitmap center
wxPoint mousePos = event.GetPosition();
wxSize bmsize = m_bitmapRGB->GetSize();
int half_size = std::min( bmsize.x, bmsize.y )/2;
mousePos.x -= half_size;
mousePos.y -= half_size;
mousePos.y = -mousePos.y; // Use the bottom to top vertical axis
half_size -= m_cursorsSize/2; // the actual half_size of the palette area
// Change colors according to the selected cursor:
if( m_selectedCursor == &m_cursorBitmapRed )
{
if( mousePos.y >= 0 && mousePos.y <= half_size )
m_newColor4D.r = (double)mousePos.y / half_size;
else
return;
}
if( m_selectedCursor == &m_cursorBitmapGreen )
{
mousePos.x = -mousePos.x;
if( mousePos.x >= 0 && mousePos.x <= half_size )
m_newColor4D.g = (double)mousePos.x / half_size;
else
return;
}
if( m_selectedCursor == &m_cursorBitmapBlue )
{
if( mousePos.x >= 0 && mousePos.x <= half_size )
m_newColor4D.b = (double)mousePos.x / half_size;
else
return;
}
m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
SetEditVals( ALL_CHANGED );
drawAll();
}
void COLOR4D_PICKER_DLG::onHSVMouseClick( wxMouseEvent& event )
{
m_allowMouseEvents = true;
if( setHSvaluesFromCursor( event.GetPosition() ) )
drawAll();
}
void COLOR4D_PICKER_DLG::onHSVMouseDrag( wxMouseEvent& event )
{
if( !event.Dragging() || !m_allowMouseEvents )
return;
if( setHSvaluesFromCursor( event.GetPosition() ) )
drawAll();
}
bool COLOR4D_PICKER_DLG::setHSvaluesFromCursor( wxPoint aMouseCursor )
{
wxPoint mousePos = aMouseCursor;
wxSize bmsize = m_bitmapHSV->GetSize();
int half_size = std::min( bmsize.x, bmsize.y )/2;
// Make the cursor position relative to the m_bitmapHSV wxBitmap center
mousePos.x -= half_size;
mousePos.y -= half_size;
mousePos.y = -mousePos.y; // Use the bottom to top vertical axis
// The HS cursor position is restricted to a circle of radius half_size
double dist_from_centre = hypot( (double)mousePos.x, (double)mousePos.y );
if( dist_from_centre > half_size )
// Saturation cannot be calculated:
return false;
m_cursorBitmapHSV = mousePos;
// Set saturation and hue from new cursor position:
half_size -= m_cursorsSize/2; // the actual half_size of the palette area
m_sat = dist_from_centre / half_size;
if( m_sat > 1.0 )
m_sat = 1.0;
m_hue = atan2( mousePos.y, mousePos.x ) / M_PI * 180.0;
if( m_hue < 0 )
m_hue += 360.0;
m_newColor4D.FromHSV( m_hue, m_sat, m_val );
SetEditVals( ALL_CHANGED );
return true;
}
void COLOR4D_PICKER_DLG::OnChangeAlpha( wxScrollEvent& event )
{
double alpha = (double)event.GetPosition() / ALPHA_MAX;
m_newColor4D.a = alpha;
m_NewColorRect->Freeze(); // Avoid flicker
setIconColor( m_NewColorRect, m_newColor4D );
m_NewColorRect->Thaw();
m_NewColorRect->Refresh();
}
void COLOR4D_PICKER_DLG::OnChangeEditRed( wxSpinEvent& event )
{
double val = (double)event.GetPosition() / 255.0;
m_newColor4D.r = val;
SetEditVals( RED_CHANGED );
drawAll();
}
void COLOR4D_PICKER_DLG::OnChangeEditGreen( wxSpinEvent& event )
{
double val = (double)event.GetPosition() / 255.0;
m_newColor4D.g = val;
SetEditVals( GREEN_CHANGED );
drawAll();
}
void COLOR4D_PICKER_DLG::OnChangeEditBlue( wxSpinEvent& event )
{
double val = (double)event.GetPosition() / 255.0;
m_newColor4D.b = val;
SetEditVals( BLUE_CHANGED );
drawAll();
}
void COLOR4D_PICKER_DLG::OnChangeEditHue( wxSpinEvent& event )
{
m_hue = (double)event.GetPosition();
m_newColor4D.FromHSV( m_hue, m_sat, m_val );
SetEditVals( HUE_CHANGED );
drawAll();
}
void COLOR4D_PICKER_DLG::OnChangeEditSat( wxSpinEvent& event )
{
m_sat = (double)event.GetPosition() / 255.0;
m_newColor4D.FromHSV( m_hue, m_sat, m_val );
SetEditVals( SAT_CHANGED );
drawAll();
}
void COLOR4D_PICKER_DLG::OnChangeBrightness( wxScrollEvent& event )
{
m_val = (double)event.GetPosition() / 255.0;
m_newColor4D.FromHSV( m_hue, m_sat, m_val );
SetEditVals( VAL_CHANGED );
drawAll();
}