KiCad PCB EDA Suite
dialog_color_picker.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 
21 #include "dialog_color_picker.h"
22 #include <cmath>
23 #include <algorithm>
24 #include <kiface_i.h>
25 #include <settings/app_settings.h>
26 #include <widgets/color_swatch.h>
27 
28 #define ALPHA_MAX 100 // the max value returned by the alpha (opacity) slider
29 
30 using KIGFX::COLOR4D;
31 
32 // Configure the spin controls contained inside the dialog
33 void configureSpinCtrl( wxSpinCtrl* aCtrl )
34 {
35  wxSize textLength = aCtrl->GetTextExtent( "999" );
36  wxSize ctrlSize = aCtrl->GetSizeFromTextSize( textLength );
37 
38  aCtrl->SetMinSize( ctrlSize );
39  aCtrl->SetSize( ctrlSize );
40 }
41 
42 
43 DIALOG_COLOR_PICKER::DIALOG_COLOR_PICKER( wxWindow* aParent, const COLOR4D& aCurrentColor,
44  bool aAllowOpacityControl,
45  CUSTOM_COLORS_LIST* aUserColors,
46  const COLOR4D& aDefaultColor ) :
47  DIALOG_COLOR_PICKER_BASE( aParent )
48 {
49  m_allowMouseEvents = false;
50  m_allowOpacityCtrl = aAllowOpacityControl;
51  m_previousColor4D = aCurrentColor;
52  m_newColor4D = aCurrentColor;
53  m_cursorsSize = 8; // Size of square cursors drawn on color bitmaps
54  m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
55  m_bitmapRGB = nullptr;
56  m_bitmapHSV = nullptr;
57  m_selectedCursor = nullptr;
58  m_defaultColor = aDefaultColor;
59 
60  if( !m_allowOpacityCtrl )
61  {
62  m_SizerTransparency->Show( false );
63  m_previousColor4D.a = 1.0;
64  m_newColor4D.a = 1.0;
65  }
66 
68  wxASSERT( cfg );
69 
70  m_notebook->SetSelection( cfg->m_ColorPicker.default_tab );
71 
72  // Build the defined colors panel:
73  initDefinedColors( aUserColors );
74 
82  if( aDefaultColor == COLOR4D::UNSPECIFIED )
83  m_resetToDefault->SetLabel( _( "Clear Color" ) );
84 
85  m_sdbSizerOK->SetDefault();
86 }
87 
88 
90 {
92  wxASSERT( cfg );
93 
94  cfg->m_ColorPicker.default_tab = m_notebook->GetSelection();
95 
96  delete m_bitmapRGB;
97  delete m_bitmapHSV;
98 
99  for( wxStaticBitmap* swatch : m_colorSwatches )
100  {
101  swatch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED,
102  wxMouseEventHandler( DIALOG_COLOR_PICKER::buttColorClick ),
103  NULL, this );
104  }
105 }
106 
107 
108 void DIALOG_COLOR_PICKER::updatePreview( wxStaticBitmap* aStaticBitmap, COLOR4D& aColor4D )
109 {
110  wxBitmap newBm = COLOR_SWATCH::MakeBitmap( aColor4D, COLOR4D::WHITE, aStaticBitmap->GetSize(),
111  ConvertDialogToPixels( CHECKERBOARD_SIZE_DU ),
112  aStaticBitmap->GetParent()->GetBackgroundColour() );
113  aStaticBitmap->SetBitmap( newBm );
114 }
115 
116 
118 {
119  // Draw all bitmaps, with colors according to the color 4D
121  SetEditVals( ALL_CHANGED, false );
122  drawAll();
123 
124  // Configure the spin control sizes
130 
131  m_notebook->GetPage( 0 )->Layout();
132  m_notebook->GetPage( 1 )->Layout();
133 
135 
136  return true;
137 }
138 
139 
141 {
142  #define ID_COLOR_BLACK 2000 // colors_id = ID_COLOR_BLACK a ID_COLOR_BLACK + NBCOLORS-1
143 
144  // Colors are built from the colorRefs() table (size NBCOLORS).
145  // The look is better when colorRefs() order is displayed in a grid matrix
146  // of 6 row and 5 columns, first filling a row, and after the next column.
147  // But the wxFlexGrid used here must be filled by columns, then next row
148  // the best interval colorRefs() from a matrix row to the next row is 6
149  // So when have to reorder the index used to explore colorRefs()
150  int grid_col = 0;
151  int grid_row = 0;
152  int table_row_count = 6;
153 
154  wxSize swatchSize = ConvertDialogToPixels( SWATCH_SIZE_LARGE_DU );
155  wxSize checkerboardSize = ConvertDialogToPixels( CHECKERBOARD_SIZE_DU );
156  COLOR4D checkboardBackground = m_OldColorRect->GetParent()->GetBackgroundColour();
157 
158  auto addSwatch =
159  [&]( int aId, COLOR4D aColor, const wxString& aColorName )
160  {
161  wxBitmap bm = COLOR_SWATCH::MakeBitmap( aColor, COLOR4D::WHITE, swatchSize,
162  checkerboardSize, checkboardBackground );
163  wxStaticBitmap* swatch = new wxStaticBitmap( m_panelDefinedColors, aId, bm );
164 
165  m_fgridColor->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 5 );
166 
167  wxStaticText* label = new wxStaticText( m_panelDefinedColors, wxID_ANY, aColorName,
168  wxDefaultPosition, wxDefaultSize, 0 );
169  m_fgridColor->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, 15 );
170 
171  m_colorSwatches.push_back( swatch );
172 
173  swatch->Connect( wxEVT_LEFT_DOWN,
174  wxMouseEventHandler( DIALOG_COLOR_PICKER::buttColorClick ),
175  NULL, this );
176  };
177 
178  // If no predefined list is given, build the default predefined colors:
179  if( aPredefinedColors )
180  {
181  for( unsigned jj = 0; jj < aPredefinedColors->size() && jj < NBCOLORS; ++jj )
182  {
183  CUSTOM_COLOR_ITEM* item = & *aPredefinedColors->begin() + jj;
184  int butt_ID = ID_COLOR_BLACK + jj;
185 
186  addSwatch( butt_ID, item->m_Color, item->m_ColorName );
187  m_Color4DList.push_back( item->m_Color );
188  }
189  }
190  else
191  {
192  m_Color4DList.assign( NBCOLORS, COLOR4D( 0.0, 0.0, 0.0, 1.0 ) );
193 
194  for( int jj = 0; jj < NBCOLORS; ++jj, grid_col++ )
195  {
196  if( grid_col*table_row_count >= NBCOLORS )
197  { // the current grid row is filled, and we must fill the next grid row
198  grid_col = 0;
199  grid_row++;
200  }
201 
202  int ii = grid_row + (grid_col*table_row_count); // The index in colorRefs()
203  int butt_ID = ID_COLOR_BLACK + ii;
204  COLOR4D buttcolor = COLOR4D( colorRefs()[ii].m_Numcolor );
205 
206  addSwatch( butt_ID, buttcolor, wxGetTranslation( colorRefs()[ii].m_ColorName ) );
207  m_Color4DList[ butt_ID - ID_COLOR_BLACK ] = buttcolor;
208  }
209  }
210 }
211 
212 
214 {
215  wxMemoryDC bitmapDC;
216  wxSize bmsize = m_RgbBitmap->GetSize();
217  int half_size = std::min( bmsize.x, bmsize.y )/2;
218  m_bitmapRGB = new wxBitmap( bmsize );
219  bitmapDC.SelectObject( *m_bitmapRGB );
220  wxPen pen;
221 
222  // clear background (set the window bg color)
223  wxBrush bgbrush( GetBackgroundColour() );
224  bitmapDC.SetBackground( bgbrush );
225  bitmapDC.Clear();
226 
227  // Use Y axis from bottom to top and origin to center
228  bitmapDC.SetAxisOrientation( true, true );
229  bitmapDC.SetDeviceOrigin( half_size, half_size );
230 
231  // Reserve room to draw cursors inside the bitmap
232  half_size -= m_cursorsSize/2;
233 
234  COLOR4D color;
235 
236  // Red blue area in X Z 3d axis
237  double inc = 1.0 / half_size;
238  #define SLOPE_AXIS 50.0
239  double slope = SLOPE_AXIS/half_size;
240  color.g = 0.0;
241 
242  for( int xx = 0; xx < half_size; xx++ ) // blue axis
243  {
244  color.b = inc * xx;
245 
246  for( int yy = 0; yy < half_size; yy++ ) // Red axis
247  {
248  color.r = inc * yy;
249 
250  pen.SetColour( color.ToColour() );
251  bitmapDC.SetPen( pen );
252  bitmapDC.DrawPoint( xx, yy - (slope*xx) );
253  }
254  }
255 
256  // Red green area in y Z 3d axis
257  color.b = 0.0;
258  for( int xx = 0; xx < half_size; xx++ ) // green axis
259  {
260  color.g = inc * xx;
261 
262  for( int yy = 0; yy < half_size; yy++ ) // Red axis
263  {
264  color.r = inc * yy;
265 
266  pen.SetColour( color.ToColour() );
267  bitmapDC.SetPen( pen );
268  bitmapDC.DrawPoint( -xx, yy - (slope*xx) );
269  }
270  }
271 
272  // Blue green area in x y 3d axis
273  color.r = 0.0;
274  for( int xx = 0; xx < half_size; xx++ ) // green axis
275  {
276  color.g = inc * xx;
277 
278  for( int yy = 0; yy < half_size; yy++ ) // blue axis
279  {
280  color.b = inc * yy;
281 
282  pen.SetColour( color.ToColour() );
283  bitmapDC.SetPen( pen );
284 
285  // Mapping the xx, yy color axis to draw coordinates is more tricky than previously
286  // in DC coordinates:
287  // the blue axis is the (0, 0) to half_size, (-yy - SLOPE_AXIS)
288  // the green axis is the (0, 0) to - half_size, (-yy - SLOPE_AXIS)
289  int drawX = -xx + yy;
290  int drawY = - std::min( xx,yy ) * 0.9;
291  bitmapDC.DrawPoint( drawX, drawY - std::abs( slope*drawX ) );
292  }
293  }
294 }
295 
296 
298 {
299  wxMemoryDC bitmapDC;
300  wxSize bmsize = m_HsvBitmap->GetSize();
301  int half_size = std::min( bmsize.x, bmsize.y )/2;
302  delete m_bitmapHSV;
303  m_bitmapHSV = new wxBitmap( bmsize );
304  bitmapDC.SelectObject( *m_bitmapHSV );
305  wxPen pen;
306 
307  // clear background (set the window bd color)
308  wxBrush bgbrush( GetBackgroundColour() );
309  bitmapDC.SetBackground( bgbrush );
310  bitmapDC.Clear();
311 
312  // Use Y axis from bottom to top and origin to center
313  bitmapDC.SetAxisOrientation( true, true );
314  bitmapDC.SetDeviceOrigin( half_size, half_size );
315 
316  // Reserve room to draw cursors inside the bitmap
317  half_size -= m_cursorsSize/2;
318 
319  double hue, sat;
320  COLOR4D color;
321  int sq_radius = half_size*half_size;
322 
323  for( int xx = -half_size; xx < half_size; xx++ )
324  {
325  for( int yy = -half_size; yy < half_size; yy++ )
326  {
327  sat = double(xx*xx + yy*yy) / sq_radius;
328 
329  // sat is <= 1.0
330  // any value > 1.0 is not a valid HSB color:
331  if( sat > 1.0 )
332  continue;
333 
334  // sat is the distance from center
335  sat = sqrt( sat );
336  hue = atan2( (double)yy, (double)xx ) * 180 / M_PI;
337 
338  if( hue < 0.0 )
339  hue += 360.0;
340 
341  color.FromHSV( hue, sat, 1.0 );
342 
343  pen.SetColour( color.ToColour() );
344  bitmapDC.SetPen( pen );
345  bitmapDC.DrawPoint( xx, yy );
346  }
347  }
348 
349  /* Deselect the Tool Bitmap from DC,
350  * in order to delete the MemoryDC safely without deleting the bitmap
351  */
352  bitmapDC.SelectObject( wxNullBitmap );
353 }
354 
355 
357 {
358  if( !m_bitmapRGB || m_bitmapRGB->GetSize() != m_RgbBitmap->GetSize() )
359  createRGBBitmap();
360 
361  wxMemoryDC bitmapDC;
362  wxSize bmsize = m_bitmapRGB->GetSize();
363  int half_size = std::min( bmsize.x, bmsize.y )/2;
364  wxBitmap newBm( *m_bitmapRGB );
365  bitmapDC.SelectObject( newBm );
366 
367  // Use Y axis from bottom to top and origin to center
368  bitmapDC.SetAxisOrientation( true, true );
369  bitmapDC.SetDeviceOrigin( half_size, half_size );
370 
371  // Reserve room to draw cursors inside the bitmap
372  half_size -= m_cursorsSize/2;
373 
374  // Draw the 3 RGB cursors, usiing white color to make them always visible:
375  wxPen pen( wxColor( 255, 255, 255 ) );
376  wxBrush brush( wxColor( 0, 0, 0 ), wxBRUSHSTYLE_TRANSPARENT );
377  bitmapDC.SetPen( pen );
378  bitmapDC.SetBrush( brush );
379  int half_csize = m_cursorsSize/2;
380 
381  #define SLOPE_AXIS 50.0
382  double slope = SLOPE_AXIS/half_size;
383 
384  // Red axis cursor (Z 3Daxis):
385  m_cursorBitmapRed.x = 0;
386  m_cursorBitmapRed.y = m_newColor4D.r * half_size;
387  bitmapDC.DrawRectangle( m_cursorBitmapRed.x - half_csize,
388  m_cursorBitmapRed.y - half_csize,
390 
391  // Blue axis cursor (X 3Daxis):
392  m_cursorBitmapBlue.x = m_newColor4D.b * half_size;
394  bitmapDC.DrawRectangle( m_cursorBitmapBlue.x - half_csize,
395  m_cursorBitmapBlue.y - half_csize,
397 
398  // Green axis cursor (Y 3Daxis):
399  m_cursorBitmapGreen.x = m_newColor4D.g * half_size;
402 
403  bitmapDC.DrawRectangle( m_cursorBitmapGreen.x - half_csize,
404  m_cursorBitmapGreen.y - half_csize,
406 
407  // Draw the 3 RGB axis:
408  half_size += half_size/5;
409  bitmapDC.DrawLine( 0, 0, 0, half_size ); // Red axis (Z 3D axis)
410  bitmapDC.DrawLine( 0, 0, half_size, - half_size*slope ); // Blue axis (X 3D axis)
411  bitmapDC.DrawLine( 0, 0, -half_size, - half_size*slope ); // green axis (Y 3D axis)
412 
413  m_RgbBitmap->SetBitmap( newBm );
414  /* Deselect the Tool Bitmap from DC,
415  * in order to delete the MemoryDC safely without deleting the bitmap */
416  bitmapDC.SelectObject( wxNullBitmap );
417 }
418 
419 
421 {
422  if( !m_bitmapHSV || m_bitmapHSV->GetSize() != m_HsvBitmap->GetSize() )
423  createHSVBitmap();
424 
425  wxMemoryDC bitmapDC;
426  wxSize bmsize = m_bitmapHSV->GetSize();
427  int half_size = std::min( bmsize.x, bmsize.y )/2;
428  wxBitmap newBm( *m_bitmapHSV );
429  bitmapDC.SelectObject( newBm );
430 
431  // Use Y axis from bottom to top and origin to center
432  bitmapDC.SetAxisOrientation( true, true );
433  bitmapDC.SetDeviceOrigin( half_size, half_size );
434 
435  // Reserve room to draw cursors inside the bitmap
436  half_size -= m_cursorsSize/2;
437 
438  // Draw the HSB cursor:
439  m_cursorBitmapHSV.x = cos( m_hue * M_PI / 180.0 ) * half_size * m_sat;
440  m_cursorBitmapHSV.y = sin( m_hue * M_PI / 180.0 ) * half_size * m_sat;
441 
442  wxPen pen( wxColor( 0, 0, 0 ) );
443  wxBrush brush( wxColor( 0, 0, 0 ), wxBRUSHSTYLE_TRANSPARENT );
444  bitmapDC.SetPen( pen );
445  bitmapDC.SetBrush( brush );
446 
447  int half_csize = m_cursorsSize/2;
448  bitmapDC.DrawRectangle( m_cursorBitmapHSV.x- half_csize,
449  m_cursorBitmapHSV.y-half_csize,
451 
452  m_HsvBitmap->SetBitmap( newBm );
453  /* Deselect the Tool Bitmap from DC,
454  * in order to delete the MemoryDC safely without deleting the bitmap
455  */
456  bitmapDC.SelectObject( wxNullBitmap );
457 }
458 
459 
460 void DIALOG_COLOR_PICKER::SetEditVals( CHANGED_COLOR aChanged, bool aCheckTransparency )
461 {
462  if( aCheckTransparency )
463  {
464  // If they've changed the color, they probably don't want it to remain 100% transparent,
465  // and it looks like a bug when changing the color has no effect.
466  if( m_newColor4D.a == 0.0 )
467  m_newColor4D.a = 1.0;
468  }
469 
471 
472  if( aChanged == RED_CHANGED || aChanged == GREEN_CHANGED || aChanged == BLUE_CHANGED )
473  m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
474 
475  if( aChanged != RED_CHANGED )
476  m_spinCtrlRed->SetValue( normalizeToInt( m_newColor4D.r ) );
477 
478  if( aChanged != GREEN_CHANGED )
480 
481  if( aChanged != BLUE_CHANGED )
483 
484  if( aChanged != HUE_CHANGED )
485  m_spinCtrlHue->SetValue( (int)m_hue );
486 
487  if( aChanged != SAT_CHANGED )
488  m_spinCtrlSaturation->SetValue( m_sat * 255 );
489 
490  if( aChanged != VAL_CHANGED )
491  m_sliderBrightness->SetValue(normalizeToInt( m_val ) );
492 
493  if( aChanged != HEX_CHANGED )
494  m_colorValue->ChangeValue( m_newColor4D.ToWxString( wxC2S_CSS_SYNTAX ) );
495 }
496 
497 
499 {
500  m_NewColorRect->Freeze(); // Avoid flicker
501  m_HsvBitmap->Freeze();
502  m_RgbBitmap->Freeze();
504  drawHSVPalette();
505  drawRGBPalette();
506  m_NewColorRect->Thaw();
507  m_HsvBitmap->Thaw();
508  m_RgbBitmap->Thaw();
509  m_NewColorRect->Refresh();
510  m_HsvBitmap->Refresh();
511  m_RgbBitmap->Refresh();
512 }
513 
514 
515 void DIALOG_COLOR_PICKER::buttColorClick( wxMouseEvent& event )
516 {
517  int id = event.GetId();
519  m_newColor4D.r = color.r;
520  m_newColor4D.g = color.g;
521  m_newColor4D.b = color.b;
522  m_newColor4D.a = color.a;
523 
524  m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
525  SetEditVals( ALL_CHANGED, false );
526 
527  drawAll();
528 
529  event.Skip();
530 }
531 
532 
533 void DIALOG_COLOR_PICKER::onRGBMouseClick( wxMouseEvent& event )
534 {
535  m_allowMouseEvents = true;
536  wxPoint mousePos = event.GetPosition();
537 
538  // The cursor position is relative to the m_bitmapHSV wxBitmap center
539  wxSize bmsize = m_bitmapRGB->GetSize();
540  int half_size = std::min( bmsize.x, bmsize.y )/2;
541  mousePos.x -= half_size;
542  mousePos.y -= half_size;
543  mousePos.y = -mousePos.y; // Use the bottom to top vertical axis
544 
545  wxPoint dist = m_cursorBitmapRed - mousePos;
546 
547  if( std::abs( dist.x ) <= m_cursorsSize/2 && std::abs( dist.y ) <= m_cursorsSize/2 )
548  {
550  return;
551  }
552 
553  dist = m_cursorBitmapGreen - mousePos;
554 
555  if( std::abs( dist.x ) <= m_cursorsSize/2 && std::abs( dist.y ) <= m_cursorsSize/2 )
556  {
558  return;
559  }
560 
561  dist = m_cursorBitmapBlue - mousePos;
562 
563  if( std::abs( dist.x ) <= m_cursorsSize/2 && std::abs( dist.y ) <= m_cursorsSize/2 )
564  {
566  return;
567  }
568 
569  m_selectedCursor = nullptr;
570 }
571 
572 
573 void DIALOG_COLOR_PICKER::onRGBMouseDrag( wxMouseEvent& event )
574 {
575  if( !event.Dragging() || !m_allowMouseEvents )
576  {
577  m_selectedCursor = nullptr;
578  return;
579  }
580 
584  return;
585 
586  // Adjust the HSV cursor position to follow the mouse cursor
587  // The cursor position is relative to the m_bitmapHSV wxBitmap center
588  wxPoint mousePos = event.GetPosition();
589  wxSize bmsize = m_bitmapRGB->GetSize();
590  int half_size = std::min( bmsize.x, bmsize.y )/2;
591  mousePos.x -= half_size;
592  mousePos.y -= half_size;
593  mousePos.y = -mousePos.y; // Use the bottom to top vertical axis
594 
595  half_size -= m_cursorsSize/2; // the actual half_size of the palette area
596 
597  // Change colors according to the selected cursor:
599  {
600  if( mousePos.y >= 0 && mousePos.y <= half_size )
601  m_newColor4D.r = (double)mousePos.y / half_size;
602  else
603  return;
604  }
605 
607  {
608  mousePos.x = -mousePos.x;
609 
610  if( mousePos.x >= 0 && mousePos.x <= half_size )
611  m_newColor4D.g = (double)mousePos.x / half_size;
612  else
613  return;
614  }
615 
617  {
618  if( mousePos.x >= 0 && mousePos.x <= half_size )
619  m_newColor4D.b = (double)mousePos.x / half_size;
620  else
621  return;
622  }
623 
624  m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
625  SetEditVals( ALL_CHANGED, true );
626 
627  drawAll();
628 }
629 
630 
631 void DIALOG_COLOR_PICKER::onHSVMouseClick( wxMouseEvent& event )
632 {
633  m_allowMouseEvents = true;
634 
635  if( setHSvaluesFromCursor( event.GetPosition() ) )
636  drawAll();
637 }
638 
639 
640 void DIALOG_COLOR_PICKER::onHSVMouseDrag( wxMouseEvent& event )
641 {
642  if( !event.Dragging() || !m_allowMouseEvents )
643  return;
644 
645  if( setHSvaluesFromCursor( event.GetPosition() ) )
646  drawAll();
647 }
648 
649 
650 void DIALOG_COLOR_PICKER::OnColorValueText( wxCommandEvent& event )
651 {
652  m_newColor4D.SetFromWxString( m_colorValue->GetValue() );
653  m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
654 
655  SetEditVals( HEX_CHANGED, true );
656  drawAll();
657 }
658 
659 
661 {
662  wxPoint mousePos = aMouseCursor;
663  wxSize bmsize = m_bitmapHSV->GetSize();
664  int half_size = std::min( bmsize.x, bmsize.y )/2;
665  // Make the cursor position relative to the m_bitmapHSV wxBitmap center
666  mousePos.x -= half_size;
667  mousePos.y -= half_size;
668  mousePos.y = -mousePos.y; // Use the bottom to top vertical axis
669 
670  // The HS cursor position is restricted to a circle of radius half_size
671  double dist_from_centre = hypot( (double)mousePos.x, (double)mousePos.y );
672 
673  if( dist_from_centre > half_size )
674  // Saturation cannot be calculated:
675  return false;
676 
677  m_cursorBitmapHSV = mousePos;
678 
679  // Set saturation and hue from new cursor position:
680  half_size -= m_cursorsSize/2; // the actual half_size of the palette area
681  m_sat = dist_from_centre / half_size;
682 
683  if( m_sat > 1.0 )
684  m_sat = 1.0;
685 
686  m_hue = atan2( mousePos.y, mousePos.x ) / M_PI * 180.0;
687 
688  if( m_hue < 0 )
689  m_hue += 360.0;
690 
692  SetEditVals( ALL_CHANGED, true );
693 
694  return true;
695 }
696 
697 
698 void DIALOG_COLOR_PICKER::OnChangeAlpha( wxScrollEvent& event )
699 {
700  double alpha = (double)event.GetPosition() / ALPHA_MAX;
701  m_newColor4D.a = alpha;
702  m_NewColorRect->Freeze(); // Avoid flicker
704  m_NewColorRect->Thaw();
705  m_NewColorRect->Refresh();
706 }
707 
708 
709 void DIALOG_COLOR_PICKER::OnChangeEditRed( wxSpinEvent& event )
710 {
711  double val = (double)event.GetPosition() / 255.0;
712  m_newColor4D.r = val;
713  SetEditVals( RED_CHANGED, true );
714 
715  drawAll();
716 }
717 
718 
719 void DIALOG_COLOR_PICKER::OnChangeEditGreen( wxSpinEvent& event )
720 {
721  double val = (double)event.GetPosition() / 255.0;
722  m_newColor4D.g = val;
723  SetEditVals( GREEN_CHANGED, true );
724 
725  drawAll();
726 }
727 
728 
729 void DIALOG_COLOR_PICKER::OnChangeEditBlue( wxSpinEvent& event )
730 {
731  double val = (double)event.GetPosition() / 255.0;
732  m_newColor4D.b = val;
733  SetEditVals( BLUE_CHANGED, true );
734 
735  drawAll();
736 }
737 
738 
739 void DIALOG_COLOR_PICKER::OnChangeEditHue( wxSpinEvent& event )
740 {
741  m_hue = (double)event.GetPosition();
742 
744 
745  SetEditVals( HUE_CHANGED, true );
746 
747  drawAll();
748 }
749 
750 
751 void DIALOG_COLOR_PICKER::OnChangeEditSat( wxSpinEvent& event )
752 {
753  m_sat = (double)event.GetPosition() / 255.0;
754 
756 
757  SetEditVals( SAT_CHANGED, true );
758 
759  drawAll();
760 }
761 
762 
763 void DIALOG_COLOR_PICKER::OnChangeBrightness( wxScrollEvent& event )
764 {
765  m_val = (double)event.GetPosition() / 255.0;
766 
768 
769  SetEditVals( VAL_CHANGED, true );
770 
771  drawAll();
772 }
773 
774 
775 void DIALOG_COLOR_PICKER::OnResetButton( wxCommandEvent& aEvent )
776 {
781 
782  m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
783  SetEditVals( ALL_CHANGED, false );
784 
785  drawAll();
786 }
double m_hue
the current hue, in degrees (0 ... 360)
bool m_allowOpacityCtrl
true to show the widget, false to keep alpha channel = 1.0
double m_sat
the current saturation (0 ... 1.0)
void ToHSV(double &aOutHue, double &aOutSaturation, double &aOutValue, bool aAlwaysDefineHue=false) const
Function ToHSV() Converts current color (stored in RGB) to HSV format.
Definition: color4d.cpp:293
void drawRGBPalette()
draws the RVB color space
void configureSpinCtrl(wxSpinCtrl *aCtrl)
void OnChangeEditGreen(wxSpinEvent &event) override
std::vector< KIGFX::COLOR4D > m_Color4DList
the list of color4d ordered by button ID, for predefined colors
CHANGED_COLOR
int color
Definition: DXF_plotter.cpp:61
void OnChangeAlpha(wxScrollEvent &event) override
Event handlers from wxSpinControl.
static wxBitmap MakeBitmap(KIGFX::COLOR4D aColor, KIGFX::COLOR4D aBackground, wxSize aSize, wxSize aCheckerboardSize, KIGFX::COLOR4D aCheckerboardBackground)
Make a simple color swatch bitmap.
int normalizeToInt(double aValue, int aValMax=255)
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
static const wxSize SWATCH_SIZE_LARGE_DU(24, 16)
void onHSVMouseDrag(wxMouseEvent &event) override
APP_SETTINGS_BASE * KifaceSettings() const
Definition: kiface_i.h:103
void OnColorValueText(wxCommandEvent &event) override
Event handler for the reset button press.
double g
Green component.
Definition: color4d.h:367
void drawHSVPalette()
draws the HSV color circle
a class to handle a custom color (predefined color) for the color picker dialog
std::vector< CUSTOM_COLOR_ITEM > CUSTOM_COLORS_LIST
void createHSVBitmap()
generate the bitmap that shows the HSV color circle
bool setHSvaluesFromCursor(wxPoint aMouseCursor)
manage the Hue and Saturation settings when the mouse cursor is at aMouseCursor.
void OnChangeBrightness(wxScrollEvent &event) override
Event handler from wxSlider: alpha (transparency) control.
KIGFX::COLOR4D m_newColor4D
the current color4d
void onHSVMouseClick(wxMouseEvent &event) override
wxPoint m_cursorBitmapHSV
the cursor on the HSV bitmap palette.
double b
Blue component.
Definition: color4d.h:368
Number of colors.
Definition: color4d.h:74
void SetEditVals(CHANGED_COLOR aChanged, bool aCheckTransparency)
double a
Alpha component.
Definition: color4d.h:369
void onRGBMouseClick(wxMouseEvent &event) override
mouse handlers, when clicking on a palette bitmap
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Definition: app_settings.h:99
#define NULL
KIGFX::COLOR4D m_previousColor4D
the inital color4d
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
void createRGBBitmap()
generate the bitmap that shows the RVB color space
#define ALPHA_MAX
wxBitmap * m_bitmapHSV
the basic HUV palette
void OnChangeEditHue(wxSpinEvent &event) override
Class DIALOG_COLOR_PICKER_BASE.
std::vector< wxStaticBitmap * > m_colorSwatches
list of defined colors buttons
const StructColors * colorRefs()
Global list of legacy color names, still used all over the place for constructing COLOR4D's.
Definition: color4d.cpp:37
void buttColorClick(wxMouseEvent &event)
Event handler for defined color buttons
void onRGBMouseDrag(wxMouseEvent &event) override
void OnResetButton(wxCommandEvent &aEvent) override
void FromHSV(double aInH, double aInS, double aInV)
Function FromHSV() Changes currently used color to the one given by hue, saturation and value paramet...
Definition: color4d.cpp:346
double m_val
the current value (0 ... 1.0)
KIGFX::COLOR4D m_defaultColor
The default color4d.
Definition: color4d.h:48
wxPoint m_cursorBitmapRed
the red cursor on the RGB bitmap palette.
wxPoint m_cursorBitmapBlue
the blue cursor on the RGB bitmap palette.
void OnChangeEditBlue(wxSpinEvent &event) override
#define _(s)
Definition: 3d_actions.cpp:33
bool TransferDataToWindow() override
called when creating the dialog
void initDefinedColors(CUSTOM_COLORS_LIST *aPredefinedColors)
creates the bitmap buttons for each defined colors if aPredefinedColors is nullptr,...
static const wxSize CHECKERBOARD_SIZE_DU(3, 3)
void updatePreview(wxStaticBitmap *aStaticBitmap, KIGFX::COLOR4D &aColor4D)
repaint a static bitmap with the aColor4D color
KIGFX::COLOR4D m_Color
void OnChangeEditRed(wxSpinEvent &event) override
wxBitmap * m_bitmapRGB
the basic RGB palette
DIALOG_COLOR_PICKER(wxWindow *aParent, const KIGFX::COLOR4D &aCurrentColor, bool aAllowOpacityControl, CUSTOM_COLORS_LIST *aUserColors=nullptr, const KIGFX::COLOR4D &aDefaultColor=KIGFX::COLOR4D::UNSPECIFIED)
Dialog constructor.
double r
Red component.
Definition: color4d.h:366
COLOR_PICKER m_ColorPicker
Definition: app_settings.h:163
#define SLOPE_AXIS
#define ID_COLOR_BLACK
void OnChangeEditSat(wxSpinEvent &event) override
wxPoint m_cursorBitmapGreen
the green cursor on the RGB bitmap palette.
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:99
wxPoint * m_selectedCursor
the ref cursor to the selected curor, if any, or null.