]> git.saurik.com Git - wxWidgets.git/blob - src/generic/colrdlgg.cpp
[ 1509599 ] 'Split pickers page in widgets sample' with more icons and rebaking.
[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 #if wxUSE_SLIDER
263 const int sliderX = singleCustomColourRect.x + singleCustomColourRect.width + sectionSpacing;
264
265 redSlider = new wxSlider(this, wxID_RED_SLIDER, colourData.m_dataColour.Red(), 0, 255,
266 wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE);
267 greenSlider = new wxSlider(this, wxID_GREEN_SLIDER, colourData.m_dataColour.Green(), 0, 255,
268 wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE);
269 blueSlider = new wxSlider(this, wxID_BLUE_SLIDER, colourData.m_dataColour.Blue(), 0, 255,
270 wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE);
271
272 wxBoxSizer *sliderSizer = new wxBoxSizer( wxHORIZONTAL );
273
274 // 1) space for sliders
275 sliderSizer->Add( sliderX, sliderHeight );
276 sliderSizer->Add( redSlider, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 10 );
277 sliderSizer->Add( greenSlider, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 10 );
278 sliderSizer->Add( blueSlider, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 10 );
279
280 topSizer->Add( sliderSizer, 0, wxCENTRE | wxALL, 10 );
281 #else
282 topSizer->Add( 1, sliderHeight, 0, wxCENTRE | wxALL, 15 );
283 #endif // wxUSE_SLIDER
284
285 #if wxUSE_STATLINE
286 // 2) static line
287 topSizer->Add( new wxStaticLine( this, wxID_ANY ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 );
288 #endif
289
290 // 3) buttons
291 wxSizer *buttonsizer = CreateButtonSizer( wxOK|wxCANCEL );
292 buttonsizer->Add( new wxButton(this, wxID_ADD_CUSTOM, _("Add to custom colours") ), 0, wxLEFT|wxRIGHT, 10 );
293 topSizer->Add( buttonsizer, 0, wxEXPAND | wxALL, 10 );
294
295 SetAutoLayout( true );
296 SetSizer( topSizer );
297
298 topSizer->SetSizeHints( this );
299 topSizer->Fit( this );
300
301 Centre( wxBOTH );
302
303 wxEndBusyCursor();
304 }
305
306 void wxGenericColourDialog::InitializeColours(void)
307 {
308 size_t i;
309
310 for (i = 0; i < WXSIZEOF(wxColourDialogNames); i++)
311 {
312 wxColour col = wxTheColourDatabase->Find(wxColourDialogNames[i]);
313 if (col.Ok())
314 standardColours[i].Set(col.Red(), col.Green(), col.Blue());
315 else
316 standardColours[i].Set(0, 0, 0);
317 }
318
319 for (i = 0; i < WXSIZEOF(customColours); i++)
320 {
321 wxColour c = colourData.GetCustomColour(i);
322 if (c.Ok())
323 customColours[i] = colourData.GetCustomColour(i);
324 else
325 customColours[i] = wxColour(255, 255, 255);
326 }
327
328 wxColour curr = colourData.GetColour();
329 if ( curr.Ok() )
330 {
331 bool initColourFound = false;
332
333 for (i = 0; i < WXSIZEOF(wxColourDialogNames); i++)
334 {
335 if ( standardColours[i] == curr && !initColourFound )
336 {
337 whichKind = 1;
338 colourSelection = i;
339 initColourFound = true;
340 break;
341 }
342 }
343 if ( !initColourFound )
344 {
345 for ( i = 0; i < WXSIZEOF(customColours); i++ )
346 {
347 if ( customColours[i] == curr )
348 {
349 whichKind = 2;
350 colourSelection = i;
351 break;
352 }
353 }
354 }
355 colourData.m_dataColour.Set( curr.Red(), curr.Green(), curr.Blue() );
356 }
357 else
358 {
359 whichKind = 1;
360 colourSelection = 0;
361 colourData.m_dataColour.Set( 0, 0, 0 );
362 }
363 }
364
365 void wxGenericColourDialog::PaintBasicColours(wxDC& dc)
366 {
367 int i;
368 for (i = 0; i < 6; i++)
369 {
370 int j;
371 for (j = 0; j < 8; j++)
372 {
373 int ptr = i*8 + j;
374
375 int x = (j*(smallRectangleSize.x+gridSpacing) + standardColoursRect.x);
376 int y = (i*(smallRectangleSize.y+gridSpacing) + standardColoursRect.y);
377
378 dc.SetPen(*wxBLACK_PEN);
379 wxBrush brush(standardColours[ptr], wxSOLID);
380 dc.SetBrush(brush);
381
382 dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
383 }
384 }
385 }
386
387 void wxGenericColourDialog::PaintCustomColours(wxDC& dc)
388 {
389 int i;
390 for (i = 0; i < 2; i++)
391 {
392 int j;
393 for (j = 0; j < 8; j++)
394 {
395 int ptr = i*8 + j;
396
397 int x = (j*(smallRectangleSize.x+gridSpacing)) + customColoursRect.x;
398 int y = (i*(smallRectangleSize.y+gridSpacing)) + customColoursRect.y;
399
400 dc.SetPen(*wxBLACK_PEN);
401
402 wxBrush brush(customColours[ptr], wxSOLID);
403 dc.SetBrush(brush);
404
405 dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
406 }
407 }
408 }
409
410 void wxGenericColourDialog::PaintHighlight(wxDC& dc, bool draw)
411 {
412 if ( colourSelection < 0 )
413 return;
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
456 void wxGenericColourDialog::PaintCustomColour(wxDC& dc)
457 {
458 dc.SetPen(*wxBLACK_PEN);
459
460 wxBrush *brush = new wxBrush(colourData.m_dataColour, wxSOLID);
461 dc.SetBrush(*brush);
462
463 dc.DrawRectangle( singleCustomColourRect.x, singleCustomColourRect.y,
464 customRectangleSize.x, customRectangleSize.y);
465
466 dc.SetBrush(wxNullBrush);
467 delete brush;
468 }
469
470 void wxGenericColourDialog::OnBasicColourClick(int which)
471 {
472 wxClientDC dc(this);
473
474 PaintHighlight(dc, false);
475 whichKind = 1;
476 colourSelection = which;
477
478 #if wxUSE_SLIDER
479 redSlider->SetValue( standardColours[colourSelection].Red() );
480 greenSlider->SetValue( standardColours[colourSelection].Green() );
481 blueSlider->SetValue( standardColours[colourSelection].Blue() );
482 #endif // wxUSE_SLIDER
483
484 colourData.m_dataColour.Set(standardColours[colourSelection].Red(),
485 standardColours[colourSelection].Green(),
486 standardColours[colourSelection].Blue());
487
488 PaintCustomColour(dc);
489 PaintHighlight(dc, true);
490 }
491
492 void wxGenericColourDialog::OnCustomColourClick(int which)
493 {
494 wxClientDC dc(this);
495 PaintHighlight(dc, false);
496 whichKind = 2;
497 colourSelection = which;
498
499 #if wxUSE_SLIDER
500 redSlider->SetValue( customColours[colourSelection].Red() );
501 greenSlider->SetValue( customColours[colourSelection].Green() );
502 blueSlider->SetValue( customColours[colourSelection].Blue() );
503 #endif // wxUSE_SLIDER
504
505 colourData.m_dataColour.Set(customColours[colourSelection].Red(),
506 customColours[colourSelection].Green(),
507 customColours[colourSelection].Blue());
508
509 PaintCustomColour(dc);
510 PaintHighlight(dc, true);
511 }
512
513 /*
514 void wxGenericColourDialog::OnOk(void)
515 {
516 Show(false);
517 }
518
519 void wxGenericColourDialog::OnCancel(void)
520 {
521 colourDialogCancelled = true;
522 Show(false);
523 }
524 */
525
526 void wxGenericColourDialog::OnAddCustom(wxCommandEvent& WXUNUSED(event))
527 {
528 wxClientDC dc(this);
529 if (whichKind != 2)
530 {
531 PaintHighlight(dc, false);
532 whichKind = 2;
533 colourSelection = 0;
534 PaintHighlight(dc, true);
535 }
536
537 customColours[colourSelection].Set(colourData.m_dataColour.Red(),
538 colourData.m_dataColour.Green(),
539 colourData.m_dataColour.Blue());
540
541 colourData.SetCustomColour(colourSelection, customColours[colourSelection]);
542
543 PaintCustomColours(dc);
544 }
545
546 #if wxUSE_SLIDER
547
548 void wxGenericColourDialog::OnRedSlider(wxCommandEvent& WXUNUSED(event))
549 {
550 if (!redSlider)
551 return;
552
553 wxClientDC dc(this);
554 colourData.m_dataColour.Set((unsigned char)redSlider->GetValue(), colourData.m_dataColour.Green(), colourData.m_dataColour.Blue());
555 PaintCustomColour(dc);
556 }
557
558 void wxGenericColourDialog::OnGreenSlider(wxCommandEvent& WXUNUSED(event))
559 {
560 if (!greenSlider)
561 return;
562
563 wxClientDC dc(this);
564 colourData.m_dataColour.Set(colourData.m_dataColour.Red(), (unsigned char)greenSlider->GetValue(), colourData.m_dataColour.Blue());
565 PaintCustomColour(dc);
566 }
567
568 void wxGenericColourDialog::OnBlueSlider(wxCommandEvent& WXUNUSED(event))
569 {
570 if (!blueSlider)
571 return;
572
573 wxClientDC dc(this);
574 colourData.m_dataColour.Set(colourData.m_dataColour.Red(), colourData.m_dataColour.Green(), (unsigned char)blueSlider->GetValue());
575 PaintCustomColour(dc);
576 }
577
578 #endif // wxUSE_SLIDER
579
580 #endif // wxUSE_COLOURDLG && !defined(__WXGTK20__)