applied patch #935127: "wxDIALOG_MODAL and wxDIALOG_MODELESS cleaning"; some cosmetic...
[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
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
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 return FALSE;
149
150 dialogParent = parent;
151
152 if (data)
153 colourData = *data;
154
155 InitializeColours();
156 CalculateMeasurements();
157 CreateWidgets();
158
159 return TRUE;
160 }
161
162 int wxGenericColourDialog::ShowModal()
163 {
164 return wxDialog::ShowModal();
165 }
166
167
168 // Internal functions
169 void wxGenericColourDialog::OnMouseEvent(wxMouseEvent& event)
170 {
171 if (event.ButtonDown(1))
172 {
173 int x = (int)event.GetX();
174 int y = (int)event.GetY();
175
176 #ifdef __WXPM__
177 // Handle OS/2's reverse coordinate system and account for the dialog title
178 int nClientHeight;
179
180 GetClientSize(NULL, &nClientHeight);
181 y = (nClientHeight - y) + 20;
182 #endif
183 if ((x >= standardColoursRect.x && x <= (standardColoursRect.x + standardColoursRect.width)) &&
184 (y >= standardColoursRect.y && y <= (standardColoursRect.y + standardColoursRect.height)))
185 {
186 int selX = (int)(x - standardColoursRect.x)/(smallRectangleSize.x + gridSpacing);
187 int selY = (int)(y - standardColoursRect.y)/(smallRectangleSize.y + gridSpacing);
188 int ptr = (int)(selX + selY*8);
189 OnBasicColourClick(ptr);
190 }
191 else if ((x >= customColoursRect.x && x <= (customColoursRect.x + customColoursRect.width)) &&
192 (y >= customColoursRect.y && y <= (customColoursRect.y + customColoursRect.height)))
193 {
194 int selX = (int)(x - customColoursRect.x)/(smallRectangleSize.x + gridSpacing);
195 int selY = (int)(y - customColoursRect.y)/(smallRectangleSize.y + gridSpacing);
196 int ptr = (int)(selX + selY*8);
197 OnCustomColourClick(ptr);
198 }
199 else
200 event.Skip();
201 }
202 else
203 event.Skip();
204 }
205
206 void wxGenericColourDialog::OnPaint(wxPaintEvent& event)
207 {
208 #if !defined(__WXMOTIF__) && !defined(__WXMAC__) && !defined(__WXPM__) && !defined(__WXCOCOA__)
209 wxDialog::OnPaint(event);
210 #endif
211
212 wxPaintDC dc(this);
213
214 PaintBasicColours(dc);
215 PaintCustomColours(dc);
216 PaintCustomColour(dc);
217 PaintHighlight(dc, TRUE);
218 }
219
220 void wxGenericColourDialog::CalculateMeasurements()
221 {
222 smallRectangleSize.x = 18;
223 smallRectangleSize.y = 14;
224 customRectangleSize.x = 40;
225 customRectangleSize.y = 40;
226
227 gridSpacing = 6;
228 sectionSpacing = 15;
229
230 standardColoursRect.x = 10;
231 #ifdef __WXPM__
232 standardColoursRect.y = 15 + 20; /* OS/2 needs to account for dialog titlebar */
233 #else
234 standardColoursRect.y = 15;
235 #endif
236 standardColoursRect.width = (8*smallRectangleSize.x) + (7*gridSpacing);
237 standardColoursRect.height = (6*smallRectangleSize.y) + (5*gridSpacing);
238
239 customColoursRect.x = standardColoursRect.x;
240 customColoursRect.y = standardColoursRect.y + standardColoursRect.height + 20;
241 customColoursRect.width = (8*smallRectangleSize.x) + (7*gridSpacing);
242 customColoursRect.height = (2*smallRectangleSize.y) + (1*gridSpacing);
243
244 singleCustomColourRect.x = customColoursRect.width + customColoursRect.x + sectionSpacing;
245 singleCustomColourRect.y = 80;
246 singleCustomColourRect.width = customRectangleSize.x;
247 singleCustomColourRect.height = customRectangleSize.y;
248
249 okButtonX = 10;
250 customButtonX = singleCustomColourRect.x ;
251 buttonY = customColoursRect.y + customColoursRect.height + 10;
252 }
253
254 void wxGenericColourDialog::CreateWidgets()
255 {
256 wxBeginBusyCursor();
257
258 int sliderX = singleCustomColourRect.x + singleCustomColourRect.width + sectionSpacing;
259 #if defined(__WXMOTIF__)
260 int sliderSpacing = 65;
261 int sliderHeight = 160;
262 #else
263 int sliderSpacing = 45;
264 int sliderHeight = 160;
265 #endif
266
267 redSlider = new wxSlider(this, wxID_RED_SLIDER, singleCustomColour.Red(), 0, 255,
268 wxPoint(sliderX, 10), wxSize(-1, sliderHeight), wxVERTICAL|wxSL_LABELS);
269 greenSlider = new wxSlider(this, wxID_GREEN_SLIDER, singleCustomColour.Green(), 0, 255,
270 wxPoint(sliderX + sliderSpacing, 10), wxSize(-1, sliderHeight), wxVERTICAL|wxSL_LABELS);
271 blueSlider = new wxSlider(this, wxID_BLUE_SLIDER, singleCustomColour.Blue(), 0, 255,
272 wxPoint(sliderX + 2*sliderSpacing, 10), wxSize(-1, sliderHeight), wxVERTICAL|wxSL_LABELS);
273
274 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
275
276 // 1) space for explicitly layouted controls
277 topsizer->Add( sliderX + 3*sliderSpacing, sliderHeight+25 );
278
279 #if wxUSE_STATLINE
280 // 2) static line
281 topsizer->Add( new wxStaticLine( this, -1 ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 );
282 #endif
283
284 // 3) buttons
285 wxSizer *buttonsizer = CreateButtonSizer( wxOK|wxCANCEL );
286 buttonsizer->Add( new wxButton(this, wxID_ADD_CUSTOM, _("Add to custom colours") ), 0, wxLEFT|wxRIGHT, 10 );
287 topsizer->Add( buttonsizer, 0, wxCENTRE | wxALL, 10 );
288
289 SetAutoLayout( TRUE );
290 SetSizer( topsizer );
291
292 topsizer->SetSizeHints( this );
293 topsizer->Fit( this );
294
295 Centre( wxBOTH );
296
297 wxEndBusyCursor();
298 }
299
300 void wxGenericColourDialog::InitializeColours(void)
301 {
302 size_t i;
303
304 for (i = 0; i < WXSIZEOF(wxColourDialogNames); i++)
305 {
306 wxColour col = wxTheColourDatabase->Find(wxColourDialogNames[i]);
307 if (col.Ok())
308 standardColours[i].Set(col.Red(), col.Green(), col.Blue());
309 else
310 standardColours[i].Set(0, 0, 0);
311 }
312
313 for (i = 0; i < WXSIZEOF(customColours); i++)
314 {
315 customColours[i] = colourData.GetCustomColour(i);
316 }
317
318 wxColour curr = colourData.GetColour();
319 if ( curr.Ok() )
320 {
321 bool initColourFound = FALSE;
322
323 for (i = 0; i < WXSIZEOF(wxColourDialogNames); i++)
324 {
325 if ( standardColours[i] == curr && !initColourFound )
326 {
327 whichKind = 1;
328 colourSelection = i;
329 initColourFound = TRUE;
330 break;
331 }
332 }
333 if ( !initColourFound )
334 {
335 for ( i = 0; i < WXSIZEOF(customColours); i++ )
336 {
337 if ( customColours[i] == curr )
338 {
339 whichKind = 2;
340 colourSelection = i;
341 break;
342 }
343 }
344 }
345 singleCustomColour.Set( curr.Red(), curr.Green(), curr.Blue() );
346 }
347 else
348 {
349 whichKind = 1;
350 colourSelection = 0;
351 singleCustomColour.Set( 0, 0, 0 );
352 }
353 }
354
355 void wxGenericColourDialog::PaintBasicColours(wxDC& dc)
356 {
357 dc.BeginDrawing();
358
359 int i;
360 for (i = 0; i < 6; i++)
361 {
362 int j;
363 for (j = 0; j < 8; j++)
364 {
365 int ptr = i*8 + j;
366
367 int x = (j*(smallRectangleSize.x+gridSpacing) + standardColoursRect.x);
368 int y = (i*(smallRectangleSize.y+gridSpacing) + standardColoursRect.y);
369
370 dc.SetPen(*wxBLACK_PEN);
371 wxBrush brush(standardColours[ptr], wxSOLID);
372 dc.SetBrush(brush);
373
374 dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
375 }
376 }
377 dc.EndDrawing();
378 }
379
380 void wxGenericColourDialog::PaintCustomColours(wxDC& dc)
381 {
382 dc.BeginDrawing();
383
384 int i;
385 for (i = 0; i < 2; i++)
386 {
387 int j;
388 for (j = 0; j < 8; j++)
389 {
390 int ptr = i*8 + j;
391
392 int x = (j*(smallRectangleSize.x+gridSpacing)) + customColoursRect.x;
393 int y = (i*(smallRectangleSize.y+gridSpacing)) + customColoursRect.y;
394
395 dc.SetPen(*wxBLACK_PEN);
396
397 wxBrush brush(customColours[ptr], wxSOLID);
398 dc.SetBrush(brush);
399
400 dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
401 }
402 }
403 dc.EndDrawing();
404 }
405
406 void wxGenericColourDialog::PaintHighlight(wxDC& dc, bool draw)
407 {
408 if ( colourSelection < 0 )
409 return;
410
411 dc.BeginDrawing();
412
413 // Number of pixels bigger than the standard rectangle size
414 // for drawing a highlight
415 int deltaX = 2;
416 int deltaY = 2;
417
418 if (whichKind == 1)
419 {
420 // Standard colours
421 int y = (int)(colourSelection / 8);
422 int x = (int)(colourSelection - (y*8));
423
424 x = (x*(smallRectangleSize.x + gridSpacing) + standardColoursRect.x) - deltaX;
425 y = (y*(smallRectangleSize.y + gridSpacing) + standardColoursRect.y) - deltaY;
426
427 if (draw)
428 dc.SetPen(*wxBLACK_PEN);
429 else
430 dc.SetPen(*wxLIGHT_GREY_PEN);
431
432 dc.SetBrush(*wxTRANSPARENT_BRUSH);
433 dc.DrawRectangle( x, y, (smallRectangleSize.x + (2*deltaX)), (smallRectangleSize.y + (2*deltaY)));
434 }
435 else
436 {
437 // User-defined colours
438 int y = (int)(colourSelection / 8);
439 int x = (int)(colourSelection - (y*8));
440
441 x = (x*(smallRectangleSize.x + gridSpacing) + customColoursRect.x) - deltaX;
442 y = (y*(smallRectangleSize.y + gridSpacing) + customColoursRect.y) - deltaY;
443
444 if (draw)
445 dc.SetPen(*wxBLACK_PEN);
446 else
447 dc.SetPen(*wxLIGHT_GREY_PEN);
448
449 dc.SetBrush(*wxTRANSPARENT_BRUSH);
450 dc.DrawRectangle( x, y, (smallRectangleSize.x + (2*deltaX)), (smallRectangleSize.y + (2*deltaY)));
451 }
452
453 dc.EndDrawing();
454 }
455
456 void wxGenericColourDialog::PaintCustomColour(wxDC& dc)
457 {
458 dc.BeginDrawing();
459
460 dc.SetPen(*wxBLACK_PEN);
461
462 wxBrush *brush = new wxBrush(singleCustomColour, wxSOLID);
463 dc.SetBrush(*brush);
464
465 dc.DrawRectangle( singleCustomColourRect.x, singleCustomColourRect.y,
466 customRectangleSize.x, customRectangleSize.y);
467
468 dc.SetBrush(wxNullBrush);
469 delete brush;
470
471 dc.EndDrawing();
472 }
473
474 void wxGenericColourDialog::OnBasicColourClick(int which)
475 {
476 wxClientDC dc(this);
477
478 PaintHighlight(dc, FALSE);
479 whichKind = 1;
480 colourSelection = which;
481 colourData.SetColour(standardColours[colourSelection]);
482 redSlider->SetValue( standardColours[colourSelection].Red() );
483 greenSlider->SetValue( standardColours[colourSelection].Green() );
484 blueSlider->SetValue( standardColours[colourSelection].Blue() );
485 singleCustomColour.Set(standardColours[colourSelection].Red(), standardColours[colourSelection].Green(), standardColours[colourSelection].Blue());
486
487 PaintCustomColour(dc);
488 PaintHighlight(dc, TRUE);
489 }
490
491 void wxGenericColourDialog::OnCustomColourClick(int which)
492 {
493 wxClientDC dc(this);
494 PaintHighlight(dc, FALSE);
495 whichKind = 2;
496 colourSelection = which;
497 colourData.SetColour(customColours[colourSelection]);
498 redSlider->SetValue( customColours[colourSelection].Red() );
499 greenSlider->SetValue( customColours[colourSelection].Green() );
500 blueSlider->SetValue( customColours[colourSelection].Blue() );
501 singleCustomColour.Set(customColours[colourSelection].Red(), customColours[colourSelection].Green(), customColours[colourSelection].Blue());
502 PaintCustomColour(dc);
503 PaintHighlight(dc, TRUE);
504 }
505
506 /*
507 void wxGenericColourDialog::OnOk(void)
508 {
509 Show(FALSE);
510 }
511
512 void wxGenericColourDialog::OnCancel(void)
513 {
514 colourDialogCancelled = TRUE;
515 Show(FALSE);
516 }
517 */
518
519 void wxGenericColourDialog::OnAddCustom(wxCommandEvent& WXUNUSED(event))
520 {
521 wxClientDC dc(this);
522 if (whichKind != 2)
523 {
524 PaintHighlight(dc, FALSE);
525 whichKind = 2;
526 colourSelection = 0;
527 PaintHighlight(dc, TRUE);
528 }
529
530 customColours[colourSelection].Set(singleCustomColour.Red(), singleCustomColour.Green(), singleCustomColour.Blue());
531 colourData.SetColour(customColours[colourSelection]);
532 colourData.SetCustomColour(colourSelection, customColours[colourSelection]);
533
534 PaintCustomColours(dc);
535 }
536
537 void wxGenericColourDialog::OnRedSlider(wxCommandEvent& WXUNUSED(event))
538 {
539 if (!redSlider)
540 return;
541
542 wxClientDC dc(this);
543 singleCustomColour.Set(redSlider->GetValue(), singleCustomColour.Green(), singleCustomColour.Blue());
544 PaintCustomColour(dc);
545 }
546
547 void wxGenericColourDialog::OnGreenSlider(wxCommandEvent& WXUNUSED(event))
548 {
549 if (!greenSlider)
550 return;
551
552 wxClientDC dc(this);
553 singleCustomColour.Set(singleCustomColour.Red(), greenSlider->GetValue(), singleCustomColour.Blue());
554 PaintCustomColour(dc);
555 }
556
557 void wxGenericColourDialog::OnBlueSlider(wxCommandEvent& WXUNUSED(event))
558 {
559 if (!blueSlider)
560 return;
561
562 wxClientDC dc(this);
563 singleCustomColour.Set(singleCustomColour.Red(), singleCustomColour.Green(), blueSlider->GetValue());
564 PaintCustomColour(dc);
565 }
566
567 #endif // wxUSE_COLOURDLG
568