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