removed hardcoded 48 (number of standard colours) from a few places -- still left...
[wxWidgets.git] / src / generic / colrdlgg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: generic/colrdlgg.cpp
3 // Purpose: Choice dialogs
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "colrdlgg.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #if wxUSE_COLOURDLG
24
25 #ifndef WX_PRECOMP
26 #include "wx/utils.h"
27 #include "wx/intl.h"
28 #include "wx/dialog.h"
29 #include "wx/listbox.h"
30 #include "wx/button.h"
31 #include "wx/stattext.h"
32 #include "wx/layout.h"
33 #include "wx/dcclient.h"
34 #include "wx/slider.h"
35 #include "wx/sizer.h"
36 #endif
37
38 #if wxUSE_STATLINE
39 #include "wx/statline.h"
40 #endif
41
42 #include "wx/generic/colrdlgg.h"
43
44 IMPLEMENT_DYNAMIC_CLASS(wxGenericColourDialog, wxDialog)
45
46 BEGIN_EVENT_TABLE(wxGenericColourDialog, wxDialog)
47 EVT_BUTTON(wxID_ADD_CUSTOM, wxGenericColourDialog::OnAddCustom)
48 EVT_SLIDER(wxID_RED_SLIDER, wxGenericColourDialog::OnRedSlider)
49 EVT_SLIDER(wxID_GREEN_SLIDER, wxGenericColourDialog::OnGreenSlider)
50 EVT_SLIDER(wxID_BLUE_SLIDER, wxGenericColourDialog::OnBlueSlider)
51 EVT_PAINT(wxGenericColourDialog::OnPaint)
52 EVT_MOUSE_EVENTS(wxGenericColourDialog::OnMouseEvent)
53 EVT_CLOSE(wxGenericColourDialog::OnCloseWindow)
54 END_EVENT_TABLE()
55
56
57 /*
58 * Generic wxColourDialog
59 */
60
61 // don't change the number of elements (48) in this array, the code below is
62 // hardcoded to use it
63 static const wxChar *wxColourDialogNames[] =
64 {
65 wxT("ORANGE"),
66 wxT("GOLDENROD"),
67 wxT("WHEAT"),
68 wxT("SPRING GREEN"),
69 wxT("SKY BLUE"),
70 wxT("SLATE BLUE"),
71 wxT("MEDIUM VIOLET RED"),
72 wxT("PURPLE"),
73
74 wxT("RED"),
75 wxT("YELLOW"),
76 wxT("MEDIUM SPRING GREEN"),
77 wxT("PALE GREEN"),
78 wxT("CYAN"),
79 wxT("LIGHT STEEL BLUE"),
80 wxT("ORCHID"),
81 wxT("LIGHT MAGENTA"),
82
83 wxT("BROWN"),
84 wxT("YELLOW"),
85 wxT("GREEN"),
86 wxT("CADET BLUE"),
87 wxT("MEDIUM BLUE"),
88 wxT("MAGENTA"),
89 wxT("MAROON"),
90 wxT("ORANGE RED"),
91
92 wxT("FIREBRICK"),
93 wxT("CORAL"),
94 wxT("FOREST GREEN"),
95 wxT("AQUAMARINE"),
96 wxT("BLUE"),
97 wxT("NAVY"),
98 wxT("THISTLE"),
99 wxT("MEDIUM VIOLET RED"),
100
101 wxT("INDIAN RED"),
102 wxT("GOLD"),
103 wxT("MEDIUM SEA GREEN"),
104 wxT("MEDIUM BLUE"),
105 wxT("MIDNIGHT BLUE"),
106 wxT("GREY"),
107 wxT("PURPLE"),
108 wxT("KHAKI"),
109
110 wxT("BLACK"),
111 wxT("MEDIUM FOREST GREEN"),
112 wxT("KHAKI"),
113 wxT("DARK GREY"),
114 wxT("SEA GREEN"),
115 wxT("LIGHT GREY"),
116 wxT("MEDIUM SLATE BLUE"),
117 wxT("WHITE")
118 };
119
120 wxGenericColourDialog::wxGenericColourDialog()
121 {
122 dialogParent = NULL;
123 whichKind = 1;
124 colourSelection = -1;
125 }
126
127 wxGenericColourDialog::wxGenericColourDialog(wxWindow *parent,
128 wxColourData *data)
129 {
130 whichKind = 1;
131 colourSelection = -1;
132 Create(parent, data);
133 }
134
135 wxGenericColourDialog::~wxGenericColourDialog()
136 {
137 }
138
139 void wxGenericColourDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
140 {
141 EndModal(wxID_CANCEL);
142 }
143
144 bool wxGenericColourDialog::Create(wxWindow *parent, wxColourData *data)
145 {
146 if ( !wxDialog::Create(parent, -1, wxT("Colour"),
147 wxPoint(0, 0), wxSize(900, 900),
148 wxDEFAULT_DIALOG_STYLE | wxDIALOG_MODAL) )
149 return FALSE;
150
151 dialogParent = parent;
152
153 if (data)
154 colourData = *data;
155
156 InitializeColours();
157 CalculateMeasurements();
158 CreateWidgets();
159
160 return TRUE;
161 }
162
163 int wxGenericColourDialog::ShowModal()
164 {
165 return wxDialog::ShowModal();
166 }
167
168
169 // Internal functions
170 void wxGenericColourDialog::OnMouseEvent(wxMouseEvent& event)
171 {
172 if (event.ButtonDown(1))
173 {
174 int x = (int)event.GetX();
175 int y = (int)event.GetY();
176
177 if ((x >= standardColoursRect.x && x <= (standardColoursRect.x + standardColoursRect.width)) &&
178 (y >= standardColoursRect.y && y <= (standardColoursRect.y + standardColoursRect.height)))
179 {
180 int selX = (int)(x - standardColoursRect.x)/(smallRectangleSize.x + gridSpacing);
181 int selY = (int)(y - standardColoursRect.y)/(smallRectangleSize.y + gridSpacing);
182 int ptr = (int)(selX + selY*8);
183 OnBasicColourClick(ptr);
184 }
185 else if ((x >= customColoursRect.x && x <= (customColoursRect.x + customColoursRect.width)) &&
186 (y >= customColoursRect.y && y <= (customColoursRect.y + customColoursRect.height)))
187 {
188 int selX = (int)(x - customColoursRect.x)/(smallRectangleSize.x + gridSpacing);
189 int selY = (int)(y - customColoursRect.y)/(smallRectangleSize.y + gridSpacing);
190 int ptr = (int)(selX + selY*8);
191 OnCustomColourClick(ptr);
192 }
193 else
194 event.Skip();
195 }
196 else
197 event.Skip();
198 }
199
200 void wxGenericColourDialog::OnPaint(wxPaintEvent& event)
201 {
202 #if !defined(__WXMOTIF__) && !defined(__WXMAC__) && !defined(__WXPM__)
203 wxDialog::OnPaint(event);
204 #endif
205
206 wxPaintDC dc(this);
207
208 PaintBasicColours(dc);
209 PaintCustomColours(dc);
210 PaintCustomColour(dc);
211 PaintHighlight(dc, TRUE);
212 }
213
214 void wxGenericColourDialog::CalculateMeasurements()
215 {
216 smallRectangleSize.x = 18;
217 smallRectangleSize.y = 14;
218 customRectangleSize.x = 40;
219 customRectangleSize.y = 40;
220
221 gridSpacing = 6;
222 sectionSpacing = 15;
223
224 standardColoursRect.x = 10;
225 standardColoursRect.y = 15;
226 standardColoursRect.width = (8*smallRectangleSize.x) + (7*gridSpacing);
227 standardColoursRect.height = (6*smallRectangleSize.y) + (5*gridSpacing);
228
229 customColoursRect.x = standardColoursRect.x;
230 customColoursRect.y = standardColoursRect.y + standardColoursRect.height + 20;
231 customColoursRect.width = (8*smallRectangleSize.x) + (7*gridSpacing);
232 customColoursRect.height = (2*smallRectangleSize.y) + (1*gridSpacing);
233
234 singleCustomColourRect.x = customColoursRect.width + customColoursRect.x + sectionSpacing;
235 singleCustomColourRect.y = 80;
236 singleCustomColourRect.width = customRectangleSize.x;
237 singleCustomColourRect.height = customRectangleSize.y;
238
239 okButtonX = 10;
240 customButtonX = singleCustomColourRect.x ;
241 buttonY = customColoursRect.y + customColoursRect.height + 10;
242 }
243
244 void wxGenericColourDialog::CreateWidgets()
245 {
246 wxBeginBusyCursor();
247
248 int sliderX = singleCustomColourRect.x + singleCustomColourRect.width + sectionSpacing;
249 #if defined(__WXMOTIF__)
250 int sliderSpacing = 65;
251 int sliderHeight = 160;
252 #else
253 int sliderSpacing = 45;
254 int sliderHeight = 160;
255 #endif
256
257 redSlider = new wxSlider(this, wxID_RED_SLIDER, singleCustomColour.Red(), 0, 255,
258 wxPoint(sliderX, 10), wxSize(-1, sliderHeight), wxVERTICAL|wxSL_LABELS);
259 greenSlider = new wxSlider(this, wxID_GREEN_SLIDER, singleCustomColour.Green(), 0, 255,
260 wxPoint(sliderX + sliderSpacing, 10), wxSize(-1, sliderHeight), wxVERTICAL|wxSL_LABELS);
261 blueSlider = new wxSlider(this, wxID_BLUE_SLIDER, singleCustomColour.Blue(), 0, 255,
262 wxPoint(sliderX + 2*sliderSpacing, 10), wxSize(-1, sliderHeight), wxVERTICAL|wxSL_LABELS);
263
264 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
265
266 // 1) space for explicitly layouted controls
267 topsizer->Add( sliderX + 3*sliderSpacing, sliderHeight+25 );
268
269 #if wxUSE_STATLINE
270 // 2) static line
271 topsizer->Add( new wxStaticLine( this, -1 ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 );
272 #endif
273
274 // 3) buttons
275 wxSizer *buttonsizer = CreateButtonSizer( wxOK|wxCANCEL );
276 buttonsizer->Add( new wxButton(this, wxID_ADD_CUSTOM, _("Add to custom colours") ), 0, wxLEFT|wxRIGHT, 10 );
277 topsizer->Add( buttonsizer, 0, wxCENTRE | wxALL, 10 );
278
279 SetAutoLayout( TRUE );
280 SetSizer( topsizer );
281
282 topsizer->SetSizeHints( this );
283 topsizer->Fit( this );
284
285 Centre( wxBOTH );
286
287 wxEndBusyCursor();
288 }
289
290 void wxGenericColourDialog::InitializeColours(void)
291 {
292 int i;
293
294 for (i = 0; i < WXSIZEOF(wxColourDialogNames); i++)
295 {
296 wxColour *col = wxTheColourDatabase->FindColour(wxColourDialogNames[i]);
297 if (col)
298 standardColours[i].Set(col->Red(), col->Green(), col->Blue());
299 else
300 standardColours[i].Set(0, 0, 0);
301 }
302
303 for (i = 0; i < 16; i++)
304 {
305 customColours[i] = colourData.GetCustomColour(i);
306 }
307
308 wxColour curr = colourData.GetColour();
309 if ( curr.Ok() )
310 {
311 bool initColourFound = FALSE;
312
313 for (i = 0; i < WXSIZEOF(wxColourDialogNames); i++)
314 {
315 if ( standardColours[i] == curr && !initColourFound )
316 {
317 whichKind = 1;
318 colourSelection = i;
319 initColourFound = TRUE;
320 break;
321 }
322 }
323 if ( !initColourFound )
324 {
325 for ( i = 0; i < 16; i++ )
326 {
327 if ( customColours[i] == curr )
328 {
329 whichKind = 2;
330 colourSelection = i;
331 initColourFound = TRUE;
332 break;
333 }
334 }
335 }
336 singleCustomColour.Set( curr.Red(), curr.Green(), curr.Blue() );
337 }
338 else
339 {
340 whichKind = 1;
341 colourSelection = 0;
342 singleCustomColour.Set( 0, 0, 0 );
343 }
344 }
345
346 void wxGenericColourDialog::PaintBasicColours(wxDC& dc)
347 {
348 dc.BeginDrawing();
349
350 int i;
351 for (i = 0; i < 6; i++)
352 {
353 int j;
354 for (j = 0; j < 8; j++)
355 {
356 int ptr = i*8 + j;
357
358 int x = (j*(smallRectangleSize.x+gridSpacing) + standardColoursRect.x);
359 int y = (i*(smallRectangleSize.y+gridSpacing) + standardColoursRect.y);
360
361 dc.SetPen(*wxBLACK_PEN);
362 wxBrush brush(standardColours[ptr], wxSOLID);
363 dc.SetBrush(brush);
364
365 dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
366 }
367 }
368 dc.EndDrawing();
369 }
370
371 void wxGenericColourDialog::PaintCustomColours(wxDC& dc)
372 {
373 dc.BeginDrawing();
374
375 int i;
376 for (i = 0; i < 2; i++)
377 {
378 int j;
379 for (j = 0; j < 8; j++)
380 {
381 int ptr = i*8 + j;
382
383 int x = (j*(smallRectangleSize.x+gridSpacing)) + customColoursRect.x;
384 int y = (i*(smallRectangleSize.y+gridSpacing)) + customColoursRect.y;
385
386 dc.SetPen(*wxBLACK_PEN);
387
388 wxBrush brush(customColours[ptr], wxSOLID);
389 dc.SetBrush(brush);
390
391 dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
392 }
393 }
394 dc.EndDrawing();
395 }
396
397 void wxGenericColourDialog::PaintHighlight(wxDC& dc, bool draw)
398 {
399 if ( colourSelection < 0 )
400 return;
401
402 dc.BeginDrawing();
403
404 // Number of pixels bigger than the standard rectangle size
405 // for drawing a highlight
406 int deltaX = 2;
407 int deltaY = 2;
408
409 if (whichKind == 1)
410 {
411 // Standard colours
412 int y = (int)(colourSelection / 8);
413 int x = (int)(colourSelection - (y*8));
414
415 x = (x*(smallRectangleSize.x + gridSpacing) + standardColoursRect.x) - deltaX;
416 y = (y*(smallRectangleSize.y + gridSpacing) + standardColoursRect.y) - deltaY;
417
418 if (draw)
419 dc.SetPen(*wxBLACK_PEN);
420 else
421 dc.SetPen(*wxLIGHT_GREY_PEN);
422
423 dc.SetBrush(*wxTRANSPARENT_BRUSH);
424 dc.DrawRectangle( x, y, (smallRectangleSize.x + (2*deltaX)), (smallRectangleSize.y + (2*deltaY)));
425 }
426 else
427 {
428 // User-defined colours
429 int y = (int)(colourSelection / 8);
430 int x = (int)(colourSelection - (y*8));
431
432 x = (x*(smallRectangleSize.x + gridSpacing) + customColoursRect.x) - deltaX;
433 y = (y*(smallRectangleSize.y + gridSpacing) + customColoursRect.y) - deltaY;
434
435 if (draw)
436 dc.SetPen(*wxBLACK_PEN);
437 else
438 dc.SetPen(*wxLIGHT_GREY_PEN);
439
440 dc.SetBrush(*wxTRANSPARENT_BRUSH);
441 dc.DrawRectangle( x, y, (smallRectangleSize.x + (2*deltaX)), (smallRectangleSize.y + (2*deltaY)));
442 }
443
444 dc.EndDrawing();
445 }
446
447 void wxGenericColourDialog::PaintCustomColour(wxDC& dc)
448 {
449 dc.BeginDrawing();
450
451 dc.SetPen(*wxBLACK_PEN);
452
453 wxBrush *brush = new wxBrush(singleCustomColour, wxSOLID);
454 dc.SetBrush(*brush);
455
456 dc.DrawRectangle( singleCustomColourRect.x, singleCustomColourRect.y,
457 customRectangleSize.x, customRectangleSize.y);
458
459 dc.SetBrush(wxNullBrush);
460 delete brush;
461
462 dc.EndDrawing();
463 }
464
465 void wxGenericColourDialog::OnBasicColourClick(int which)
466 {
467 wxClientDC dc(this);
468
469 PaintHighlight(dc, FALSE);
470 whichKind = 1;
471 colourSelection = which;
472 colourData.SetColour(standardColours[colourSelection]);
473 redSlider->SetValue( standardColours[colourSelection].Red() );
474 greenSlider->SetValue( standardColours[colourSelection].Green() );
475 blueSlider->SetValue( standardColours[colourSelection].Blue() );
476 singleCustomColour.Set(standardColours[colourSelection].Red(), standardColours[colourSelection].Green(), standardColours[colourSelection].Blue());
477
478 PaintCustomColour(dc);
479 PaintHighlight(dc, TRUE);
480 }
481
482 void wxGenericColourDialog::OnCustomColourClick(int which)
483 {
484 wxClientDC dc(this);
485 PaintHighlight(dc, FALSE);
486 whichKind = 2;
487 colourSelection = which;
488 colourData.SetColour(customColours[colourSelection]);
489 redSlider->SetValue( customColours[colourSelection].Red() );
490 greenSlider->SetValue( customColours[colourSelection].Green() );
491 blueSlider->SetValue( customColours[colourSelection].Blue() );
492 singleCustomColour.Set(customColours[colourSelection].Red(), customColours[colourSelection].Green(), customColours[colourSelection].Blue());
493 PaintCustomColour(dc);
494 PaintHighlight(dc, TRUE);
495 }
496
497 /*
498 void wxGenericColourDialog::OnOk(void)
499 {
500 Show(FALSE);
501 }
502
503 void wxGenericColourDialog::OnCancel(void)
504 {
505 colourDialogCancelled = TRUE;
506 Show(FALSE);
507 }
508 */
509
510 void wxGenericColourDialog::OnAddCustom(wxCommandEvent& WXUNUSED(event))
511 {
512 wxClientDC dc(this);
513 if (whichKind != 2)
514 {
515 PaintHighlight(dc, FALSE);
516 whichKind = 2;
517 colourSelection = 0;
518 PaintHighlight(dc, TRUE);
519 }
520
521 customColours[colourSelection].Set(singleCustomColour.Red(), singleCustomColour.Green(), singleCustomColour.Blue());
522 colourData.SetColour(customColours[colourSelection]);
523 colourData.SetCustomColour(colourSelection, customColours[colourSelection]);
524
525 PaintCustomColours(dc);
526 }
527
528 void wxGenericColourDialog::OnRedSlider(wxCommandEvent& WXUNUSED(event))
529 {
530 if (!redSlider)
531 return;
532
533 wxClientDC dc(this);
534 singleCustomColour.Set(redSlider->GetValue(), singleCustomColour.Green(), singleCustomColour.Blue());
535 PaintCustomColour(dc);
536 }
537
538 void wxGenericColourDialog::OnGreenSlider(wxCommandEvent& WXUNUSED(event))
539 {
540 if (!greenSlider)
541 return;
542
543 wxClientDC dc(this);
544 singleCustomColour.Set(singleCustomColour.Red(), greenSlider->GetValue(), singleCustomColour.Blue());
545 PaintCustomColour(dc);
546 }
547
548 void wxGenericColourDialog::OnBlueSlider(wxCommandEvent& WXUNUSED(event))
549 {
550 if (!blueSlider)
551 return;
552
553 wxClientDC dc(this);
554 singleCustomColour.Set(singleCustomColour.Red(), singleCustomColour.Green(), blueSlider->GetValue());
555 PaintCustomColour(dc);
556 }
557
558 #endif // wxUSE_COLOURDLG
559