use wxSizerFlags and updated CreateButtonSizer() in all generic dialogs
[wxWidgets.git] / src / generic / colrdlgg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/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 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if wxUSE_COLOURDLG && (!defined(__WXGTK20__) || defined(__WXUNIVERSAL__))
20
21 #ifndef WX_PRECOMP
22 #include "wx/utils.h"
23 #include "wx/intl.h"
24 #include "wx/dialog.h"
25 #include "wx/listbox.h"
26 #include "wx/button.h"
27 #include "wx/stattext.h"
28 #include "wx/layout.h"
29 #include "wx/dcclient.h"
30 #include "wx/sizer.h"
31 #include "wx/slider.h"
32 #endif
33
34 #if wxUSE_STATLINE
35 #include "wx/statline.h"
36 #endif
37
38 #include "wx/generic/colrdlgg.h"
39
40 IMPLEMENT_DYNAMIC_CLASS(wxGenericColourDialog, wxDialog)
41
42 BEGIN_EVENT_TABLE(wxGenericColourDialog, wxDialog)
43 EVT_BUTTON(wxID_ADD_CUSTOM, wxGenericColourDialog::OnAddCustom)
44 #if wxUSE_SLIDER
45 EVT_SLIDER(wxID_RED_SLIDER, wxGenericColourDialog::OnRedSlider)
46 EVT_SLIDER(wxID_GREEN_SLIDER, wxGenericColourDialog::OnGreenSlider)
47 EVT_SLIDER(wxID_BLUE_SLIDER, wxGenericColourDialog::OnBlueSlider)
48 #endif
49 EVT_PAINT(wxGenericColourDialog::OnPaint)
50 EVT_MOUSE_EVENTS(wxGenericColourDialog::OnMouseEvent)
51 EVT_CLOSE(wxGenericColourDialog::OnCloseWindow)
52 END_EVENT_TABLE()
53
54
55 /*
56 * Generic wxColourDialog
57 */
58
59 // don't change the number of elements (48) in this array, the code below is
60 // hardcoded to use it
61 static const wxChar *wxColourDialogNames[] =
62 {
63 wxT("ORANGE"),
64 wxT("GOLDENROD"),
65 wxT("WHEAT"),
66 wxT("SPRING GREEN"),
67 wxT("SKY BLUE"),
68 wxT("SLATE BLUE"),
69 wxT("MEDIUM VIOLET RED"),
70 wxT("PURPLE"),
71
72 wxT("RED"),
73 wxT("YELLOW"),
74 wxT("MEDIUM SPRING GREEN"),
75 wxT("PALE GREEN"),
76 wxT("CYAN"),
77 wxT("LIGHT STEEL BLUE"),
78 wxT("ORCHID"),
79 wxT("LIGHT MAGENTA"),
80
81 wxT("BROWN"),
82 wxT("YELLOW"),
83 wxT("GREEN"),
84 wxT("CADET BLUE"),
85 wxT("MEDIUM BLUE"),
86 wxT("MAGENTA"),
87 wxT("MAROON"),
88 wxT("ORANGE RED"),
89
90 wxT("FIREBRICK"),
91 wxT("CORAL"),
92 wxT("FOREST GREEN"),
93 wxT("AQUAMARINE"),
94 wxT("BLUE"),
95 wxT("NAVY"),
96 wxT("THISTLE"),
97 wxT("MEDIUM VIOLET RED"),
98
99 wxT("INDIAN RED"),
100 wxT("GOLD"),
101 wxT("MEDIUM SEA GREEN"),
102 wxT("MEDIUM BLUE"),
103 wxT("MIDNIGHT BLUE"),
104 wxT("GREY"),
105 wxT("PURPLE"),
106 wxT("KHAKI"),
107
108 wxT("BLACK"),
109 wxT("MEDIUM FOREST GREEN"),
110 wxT("KHAKI"),
111 wxT("DARK GREY"),
112 wxT("SEA GREEN"),
113 wxT("LIGHT GREY"),
114 wxT("MEDIUM SLATE BLUE"),
115 wxT("WHITE")
116 };
117
118 wxGenericColourDialog::wxGenericColourDialog()
119 {
120 dialogParent = NULL;
121 whichKind = 1;
122 colourSelection = -1;
123 }
124
125 wxGenericColourDialog::wxGenericColourDialog(wxWindow *parent,
126 wxColourData *data)
127 {
128 whichKind = 1;
129 colourSelection = -1;
130 Create(parent, data);
131 }
132
133 wxGenericColourDialog::~wxGenericColourDialog()
134 {
135 }
136
137 void wxGenericColourDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
138 {
139 EndModal(wxID_CANCEL);
140 }
141
142 bool wxGenericColourDialog::Create(wxWindow *parent, wxColourData *data)
143 {
144 if ( !wxDialog::Create(parent, wxID_ANY, _("Choose colour"),
145 wxPoint(0,0), wxSize(900, 900)) )
146 return false;
147
148 dialogParent = parent;
149
150 if (data)
151 colourData = *data;
152
153 InitializeColours();
154 CalculateMeasurements();
155 CreateWidgets();
156
157 return true;
158 }
159
160 int wxGenericColourDialog::ShowModal()
161 {
162 return wxDialog::ShowModal();
163 }
164
165
166 // Internal functions
167 void wxGenericColourDialog::OnMouseEvent(wxMouseEvent& event)
168 {
169 if (event.ButtonDown(1))
170 {
171 int x = (int)event.GetX();
172 int y = (int)event.GetY();
173
174 #ifdef __WXPM__
175 // Handle OS/2's reverse coordinate system and account for the dialog title
176 int nClientHeight;
177
178 GetClientSize(NULL, &nClientHeight);
179 y = (nClientHeight - y) + 20;
180 #endif
181 if ((x >= standardColoursRect.x && x <= (standardColoursRect.x + standardColoursRect.width)) &&
182 (y >= standardColoursRect.y && y <= (standardColoursRect.y + standardColoursRect.height)))
183 {
184 int selX = (int)(x - standardColoursRect.x)/(smallRectangleSize.x + gridSpacing);
185 int selY = (int)(y - standardColoursRect.y)/(smallRectangleSize.y + gridSpacing);
186 int ptr = (int)(selX + selY*8);
187 OnBasicColourClick(ptr);
188 }
189 else if ((x >= customColoursRect.x && x <= (customColoursRect.x + customColoursRect.width)) &&
190 (y >= customColoursRect.y && y <= (customColoursRect.y + customColoursRect.height)))
191 {
192 int selX = (int)(x - customColoursRect.x)/(smallRectangleSize.x + gridSpacing);
193 int selY = (int)(y - customColoursRect.y)/(smallRectangleSize.y + gridSpacing);
194 int ptr = (int)(selX + selY*8);
195 OnCustomColourClick(ptr);
196 }
197 else
198 event.Skip();
199 }
200 else
201 event.Skip();
202 }
203
204 void wxGenericColourDialog::OnPaint(wxPaintEvent& event)
205 {
206 #if !defined(__WXMOTIF__) && !defined(__WXPM__) && !defined(__WXCOCOA__)
207 wxDialog::OnPaint(event);
208 #else
209 wxUnusedVar(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 wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
259
260 const int sliderHeight = 160;
261
262 // first sliders
263 #if wxUSE_SLIDER
264 const int sliderX = singleCustomColourRect.x + singleCustomColourRect.width + sectionSpacing;
265
266 redSlider = new wxSlider(this, wxID_RED_SLIDER, colourData.m_dataColour.Red(), 0, 255,
267 wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE);
268 greenSlider = new wxSlider(this, wxID_GREEN_SLIDER, colourData.m_dataColour.Green(), 0, 255,
269 wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE);
270 blueSlider = new wxSlider(this, wxID_BLUE_SLIDER, colourData.m_dataColour.Blue(), 0, 255,
271 wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE);
272
273 wxBoxSizer *sliderSizer = new wxBoxSizer( wxHORIZONTAL );
274
275 sliderSizer->Add(sliderX, sliderHeight );
276
277 wxSizerFlags flagsRight;
278 flagsRight.Align(wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL).DoubleBorder();
279
280 sliderSizer->Add(redSlider, flagsRight);
281 sliderSizer->Add(greenSlider,flagsRight);
282 sliderSizer->Add(blueSlider,flagsRight);
283
284 topSizer->Add(sliderSizer, wxSizerFlags().Centre().DoubleBorder());
285 #else
286 topSizer->Add(1, sliderHeight, wxSizerFlags(1).Centre().TripleBorder());
287 #endif // wxUSE_SLIDER
288
289 // then the custom button
290 topSizer->Add(new wxButton(this, wxID_ADD_CUSTOM,
291 _("Add to custom colours") ),
292 wxSizerFlags().DoubleHorzBorder());
293
294 // then the standard buttons
295 wxSizer *buttonsizer = CreateSeparatedButtonSizer(wxOK | wxCANCEL);
296 if ( buttonsizer )
297 {
298 topSizer->Add(buttonsizer, wxSizerFlags().Expand().DoubleBorder());
299 }
300
301 SetAutoLayout( true );
302 SetSizer( topSizer );
303
304 topSizer->SetSizeHints( this );
305 topSizer->Fit( this );
306
307 Centre( wxBOTH );
308
309 wxEndBusyCursor();
310 }
311
312 void wxGenericColourDialog::InitializeColours(void)
313 {
314 size_t i;
315
316 for (i = 0; i < WXSIZEOF(wxColourDialogNames); i++)
317 {
318 wxColour col = wxTheColourDatabase->Find(wxColourDialogNames[i]);
319 if (col.Ok())
320 standardColours[i].Set(col.Red(), col.Green(), col.Blue());
321 else
322 standardColours[i].Set(0, 0, 0);
323 }
324
325 for (i = 0; i < WXSIZEOF(customColours); i++)
326 {
327 wxColour c = colourData.GetCustomColour(i);
328 if (c.Ok())
329 customColours[i] = colourData.GetCustomColour(i);
330 else
331 customColours[i] = wxColour(255, 255, 255);
332 }
333
334 wxColour curr = colourData.GetColour();
335 if ( curr.Ok() )
336 {
337 bool initColourFound = false;
338
339 for (i = 0; i < WXSIZEOF(wxColourDialogNames); i++)
340 {
341 if ( standardColours[i] == curr && !initColourFound )
342 {
343 whichKind = 1;
344 colourSelection = i;
345 initColourFound = true;
346 break;
347 }
348 }
349 if ( !initColourFound )
350 {
351 for ( i = 0; i < WXSIZEOF(customColours); i++ )
352 {
353 if ( customColours[i] == curr )
354 {
355 whichKind = 2;
356 colourSelection = i;
357 break;
358 }
359 }
360 }
361 colourData.m_dataColour.Set( curr.Red(), curr.Green(), curr.Blue() );
362 }
363 else
364 {
365 whichKind = 1;
366 colourSelection = 0;
367 colourData.m_dataColour.Set( 0, 0, 0 );
368 }
369 }
370
371 void wxGenericColourDialog::PaintBasicColours(wxDC& dc)
372 {
373 int i;
374 for (i = 0; i < 6; i++)
375 {
376 int j;
377 for (j = 0; j < 8; j++)
378 {
379 int ptr = i*8 + j;
380
381 int x = (j*(smallRectangleSize.x+gridSpacing) + standardColoursRect.x);
382 int y = (i*(smallRectangleSize.y+gridSpacing) + standardColoursRect.y);
383
384 dc.SetPen(*wxBLACK_PEN);
385 wxBrush brush(standardColours[ptr], wxSOLID);
386 dc.SetBrush(brush);
387
388 dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
389 }
390 }
391 }
392
393 void wxGenericColourDialog::PaintCustomColours(wxDC& dc)
394 {
395 int i;
396 for (i = 0; i < 2; i++)
397 {
398 int j;
399 for (j = 0; j < 8; j++)
400 {
401 int ptr = i*8 + j;
402
403 int x = (j*(smallRectangleSize.x+gridSpacing)) + customColoursRect.x;
404 int y = (i*(smallRectangleSize.y+gridSpacing)) + customColoursRect.y;
405
406 dc.SetPen(*wxBLACK_PEN);
407
408 wxBrush brush(customColours[ptr], wxSOLID);
409 dc.SetBrush(brush);
410
411 dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
412 }
413 }
414 }
415
416 void wxGenericColourDialog::PaintHighlight(wxDC& dc, bool draw)
417 {
418 if ( colourSelection < 0 )
419 return;
420
421 // Number of pixels bigger than the standard rectangle size
422 // for drawing a highlight
423 int deltaX = 2;
424 int deltaY = 2;
425
426 if (whichKind == 1)
427 {
428 // Standard colours
429 int y = (int)(colourSelection / 8);
430 int x = (int)(colourSelection - (y*8));
431
432 x = (x*(smallRectangleSize.x + gridSpacing) + standardColoursRect.x) - deltaX;
433 y = (y*(smallRectangleSize.y + gridSpacing) + standardColoursRect.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 else
444 {
445 // User-defined colours
446 int y = (int)(colourSelection / 8);
447 int x = (int)(colourSelection - (y*8));
448
449 x = (x*(smallRectangleSize.x + gridSpacing) + customColoursRect.x) - deltaX;
450 y = (y*(smallRectangleSize.y + gridSpacing) + customColoursRect.y) - deltaY;
451
452 if (draw)
453 dc.SetPen(*wxBLACK_PEN);
454 else
455 dc.SetPen(*wxLIGHT_GREY_PEN);
456
457 dc.SetBrush(*wxTRANSPARENT_BRUSH);
458 dc.DrawRectangle( x, y, (smallRectangleSize.x + (2*deltaX)), (smallRectangleSize.y + (2*deltaY)));
459 }
460 }
461
462 void wxGenericColourDialog::PaintCustomColour(wxDC& dc)
463 {
464 dc.SetPen(*wxBLACK_PEN);
465
466 wxBrush *brush = new wxBrush(colourData.m_dataColour, wxSOLID);
467 dc.SetBrush(*brush);
468
469 dc.DrawRectangle( singleCustomColourRect.x, singleCustomColourRect.y,
470 customRectangleSize.x, customRectangleSize.y);
471
472 dc.SetBrush(wxNullBrush);
473 delete brush;
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
484 #if wxUSE_SLIDER
485 redSlider->SetValue( standardColours[colourSelection].Red() );
486 greenSlider->SetValue( standardColours[colourSelection].Green() );
487 blueSlider->SetValue( standardColours[colourSelection].Blue() );
488 #endif // wxUSE_SLIDER
489
490 colourData.m_dataColour.Set(standardColours[colourSelection].Red(),
491 standardColours[colourSelection].Green(),
492 standardColours[colourSelection].Blue());
493
494 PaintCustomColour(dc);
495 PaintHighlight(dc, true);
496 }
497
498 void wxGenericColourDialog::OnCustomColourClick(int which)
499 {
500 wxClientDC dc(this);
501 PaintHighlight(dc, false);
502 whichKind = 2;
503 colourSelection = which;
504
505 #if wxUSE_SLIDER
506 redSlider->SetValue( customColours[colourSelection].Red() );
507 greenSlider->SetValue( customColours[colourSelection].Green() );
508 blueSlider->SetValue( customColours[colourSelection].Blue() );
509 #endif // wxUSE_SLIDER
510
511 colourData.m_dataColour.Set(customColours[colourSelection].Red(),
512 customColours[colourSelection].Green(),
513 customColours[colourSelection].Blue());
514
515 PaintCustomColour(dc);
516 PaintHighlight(dc, true);
517 }
518
519 /*
520 void wxGenericColourDialog::OnOk(void)
521 {
522 Show(false);
523 }
524
525 void wxGenericColourDialog::OnCancel(void)
526 {
527 colourDialogCancelled = true;
528 Show(false);
529 }
530 */
531
532 void wxGenericColourDialog::OnAddCustom(wxCommandEvent& WXUNUSED(event))
533 {
534 wxClientDC dc(this);
535 if (whichKind != 2)
536 {
537 PaintHighlight(dc, false);
538 whichKind = 2;
539 colourSelection = 0;
540 PaintHighlight(dc, true);
541 }
542
543 customColours[colourSelection].Set(colourData.m_dataColour.Red(),
544 colourData.m_dataColour.Green(),
545 colourData.m_dataColour.Blue());
546
547 colourData.SetCustomColour(colourSelection, customColours[colourSelection]);
548
549 PaintCustomColours(dc);
550 }
551
552 #if wxUSE_SLIDER
553
554 void wxGenericColourDialog::OnRedSlider(wxCommandEvent& WXUNUSED(event))
555 {
556 if (!redSlider)
557 return;
558
559 wxClientDC dc(this);
560 colourData.m_dataColour.Set((unsigned char)redSlider->GetValue(), colourData.m_dataColour.Green(), colourData.m_dataColour.Blue());
561 PaintCustomColour(dc);
562 }
563
564 void wxGenericColourDialog::OnGreenSlider(wxCommandEvent& WXUNUSED(event))
565 {
566 if (!greenSlider)
567 return;
568
569 wxClientDC dc(this);
570 colourData.m_dataColour.Set(colourData.m_dataColour.Red(), (unsigned char)greenSlider->GetValue(), colourData.m_dataColour.Blue());
571 PaintCustomColour(dc);
572 }
573
574 void wxGenericColourDialog::OnBlueSlider(wxCommandEvent& WXUNUSED(event))
575 {
576 if (!blueSlider)
577 return;
578
579 wxClientDC dc(this);
580 colourData.m_dataColour.Set(colourData.m_dataColour.Red(), colourData.m_dataColour.Green(), (unsigned char)blueSlider->GetValue());
581 PaintCustomColour(dc);
582 }
583
584 #endif // wxUSE_SLIDER
585
586 #endif // wxUSE_COLOURDLG && !defined(__WXGTK20__)