The rounded corners look really dumb at this size.
[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 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #if wxUSE_COLOURDLG
19
20 #ifndef WX_PRECOMP
21 #include "wx/utils.h"
22 #include "wx/intl.h"
23 #include "wx/dialog.h"
24 #include "wx/listbox.h"
25 #include "wx/button.h"
26 #include "wx/stattext.h"
27 #include "wx/layout.h"
28 #include "wx/dcclient.h"
29 #include "wx/sizer.h"
30 #include "wx/slider.h"
31 #endif
32
33 #if wxUSE_STATLINE
34 #include "wx/statline.h"
35 #endif
36
37 #include "wx/colourdata.h"
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 *const 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 m_whichKind = 1;
121 m_colourSelection = -1;
122 }
123
124 wxGenericColourDialog::wxGenericColourDialog(wxWindow *parent,
125 wxColourData *data)
126 {
127 m_whichKind = 1;
128 m_colourSelection = -1;
129 Create(parent, data);
130 }
131
132 wxGenericColourDialog::~wxGenericColourDialog()
133 {
134 }
135
136 void wxGenericColourDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
137 {
138 EndModal(wxID_CANCEL);
139 }
140
141 bool wxGenericColourDialog::Create(wxWindow *parent, wxColourData *data)
142 {
143 if ( !wxDialog::Create(GetParentForModalDialog(parent, 0), wxID_ANY,
144 _("Choose colour"),
145 wxPoint(0, 0), wxSize(900, 900)) )
146 return false;
147
148 if (data)
149 m_colourData = *data;
150
151 InitializeColours();
152 CalculateMeasurements();
153 CreateWidgets();
154
155 return true;
156 }
157
158 int wxGenericColourDialog::ShowModal()
159 {
160 return wxDialog::ShowModal();
161 }
162
163
164 // Internal functions
165 void wxGenericColourDialog::OnMouseEvent(wxMouseEvent& event)
166 {
167 if (event.ButtonDown(1))
168 {
169 int x = (int)event.GetX();
170 int y = (int)event.GetY();
171
172 #ifdef __WXPM__
173 // Handle OS/2's reverse coordinate system and account for the dialog title
174 int nClientHeight;
175
176 GetClientSize(NULL, &nClientHeight);
177 y = (nClientHeight - y) + 20;
178 #endif
179 if ((x >= m_standardColoursRect.x && x <= (m_standardColoursRect.x + m_standardColoursRect.width)) &&
180 (y >= m_standardColoursRect.y && y <= (m_standardColoursRect.y + m_standardColoursRect.height)))
181 {
182 int selX = (int)(x - m_standardColoursRect.x)/(m_smallRectangleSize.x + m_gridSpacing);
183 int selY = (int)(y - m_standardColoursRect.y)/(m_smallRectangleSize.y + m_gridSpacing);
184 int ptr = (int)(selX + selY*8);
185 OnBasicColourClick(ptr);
186 }
187 else if ((x >= m_customColoursRect.x && x <= (m_customColoursRect.x + m_customColoursRect.width)) &&
188 (y >= m_customColoursRect.y && y <= (m_customColoursRect.y + m_customColoursRect.height)))
189 {
190 int selX = (int)(x - m_customColoursRect.x)/(m_smallRectangleSize.x + m_gridSpacing);
191 int selY = (int)(y - m_customColoursRect.y)/(m_smallRectangleSize.y + m_gridSpacing);
192 int ptr = (int)(selX + selY*8);
193 OnCustomColourClick(ptr);
194 }
195 else
196 event.Skip();
197 }
198 else
199 event.Skip();
200 }
201
202 void wxGenericColourDialog::OnPaint(wxPaintEvent& WXUNUSED(event))
203 {
204 wxPaintDC dc(this);
205
206 PaintBasicColours(dc);
207 PaintCustomColours(dc);
208 PaintCustomColour(dc);
209 PaintHighlight(dc, true);
210 }
211
212 void wxGenericColourDialog::CalculateMeasurements()
213 {
214 m_smallRectangleSize.x = 18;
215 m_smallRectangleSize.y = 14;
216 m_customRectangleSize.x = 40;
217 m_customRectangleSize.y = 40;
218
219 m_gridSpacing = 6;
220 m_sectionSpacing = 15;
221
222 m_standardColoursRect.x = 10;
223 #ifdef __WXPM__
224 m_standardColoursRect.y = 15 + 20; /* OS/2 needs to account for dialog titlebar */
225 #else
226 m_standardColoursRect.y = 15;
227 #endif
228 m_standardColoursRect.width = (8*m_smallRectangleSize.x) + (7*m_gridSpacing);
229 m_standardColoursRect.height = (6*m_smallRectangleSize.y) + (5*m_gridSpacing);
230
231 m_customColoursRect.x = m_standardColoursRect.x;
232 m_customColoursRect.y = m_standardColoursRect.y + m_standardColoursRect.height + 20;
233 m_customColoursRect.width = (8*m_smallRectangleSize.x) + (7*m_gridSpacing);
234 m_customColoursRect.height = (2*m_smallRectangleSize.y) + (1*m_gridSpacing);
235
236 m_singleCustomColourRect.x = m_customColoursRect.width + m_customColoursRect.x + m_sectionSpacing;
237 m_singleCustomColourRect.y = 80;
238 m_singleCustomColourRect.width = m_customRectangleSize.x;
239 m_singleCustomColourRect.height = m_customRectangleSize.y;
240
241 m_okButtonX = 10;
242 m_customButtonX = m_singleCustomColourRect.x ;
243 m_buttonY = m_customColoursRect.y + m_customColoursRect.height + 10;
244 }
245
246 void wxGenericColourDialog::CreateWidgets()
247 {
248 wxBeginBusyCursor();
249
250 wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
251
252 const int sliderHeight = 160;
253
254 // first sliders
255 #if wxUSE_SLIDER
256 const int sliderX = m_singleCustomColourRect.x + m_singleCustomColourRect.width + m_sectionSpacing;
257
258 m_redSlider = new wxSlider(this, wxID_RED_SLIDER, m_colourData.m_dataColour.Red(), 0, 255,
259 wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE);
260 m_greenSlider = new wxSlider(this, wxID_GREEN_SLIDER, m_colourData.m_dataColour.Green(), 0, 255,
261 wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE);
262 m_blueSlider = new wxSlider(this, wxID_BLUE_SLIDER, m_colourData.m_dataColour.Blue(), 0, 255,
263 wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE);
264
265 wxBoxSizer *sliderSizer = new wxBoxSizer( wxHORIZONTAL );
266
267 sliderSizer->Add(sliderX, sliderHeight );
268
269 wxSizerFlags flagsRight;
270 flagsRight.Align(wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL).DoubleBorder();
271
272 sliderSizer->Add(m_redSlider, flagsRight);
273 sliderSizer->Add(m_greenSlider,flagsRight);
274 sliderSizer->Add(m_blueSlider,flagsRight);
275
276 topSizer->Add(sliderSizer, wxSizerFlags().Centre().DoubleBorder());
277 #else
278 topSizer->Add(1, sliderHeight, wxSizerFlags(1).Centre().TripleBorder());
279 #endif // wxUSE_SLIDER
280
281 // then the custom button
282 topSizer->Add(new wxButton(this, wxID_ADD_CUSTOM,
283 _("Add to custom colours") ),
284 wxSizerFlags().DoubleHorzBorder());
285
286 // then the standard buttons
287 wxSizer *buttonsizer = CreateSeparatedButtonSizer(wxOK | wxCANCEL);
288 if ( buttonsizer )
289 {
290 topSizer->Add(buttonsizer, wxSizerFlags().Expand().DoubleBorder());
291 }
292
293 SetAutoLayout( true );
294 SetSizer( topSizer );
295
296 topSizer->SetSizeHints( this );
297 topSizer->Fit( this );
298
299 Centre( wxBOTH );
300
301 wxEndBusyCursor();
302 }
303
304 void wxGenericColourDialog::InitializeColours(void)
305 {
306 size_t i;
307
308 for (i = 0; i < WXSIZEOF(wxColourDialogNames); i++)
309 {
310 wxColour col = wxTheColourDatabase->Find(wxColourDialogNames[i]);
311 if (col.IsOk())
312 m_standardColours[i].Set(col.Red(), col.Green(), col.Blue());
313 else
314 m_standardColours[i].Set(0, 0, 0);
315 }
316
317 for (i = 0; i < WXSIZEOF(m_customColours); i++)
318 {
319 wxColour c = m_colourData.GetCustomColour(i);
320 if (c.IsOk())
321 m_customColours[i] = m_colourData.GetCustomColour(i);
322 else
323 m_customColours[i] = wxColour(255, 255, 255);
324 }
325
326 wxColour curr = m_colourData.GetColour();
327 if ( curr.IsOk() )
328 {
329 bool m_initColourFound = false;
330
331 for (i = 0; i < WXSIZEOF(wxColourDialogNames); i++)
332 {
333 if ( m_standardColours[i] == curr && !m_initColourFound )
334 {
335 m_whichKind = 1;
336 m_colourSelection = i;
337 m_initColourFound = true;
338 break;
339 }
340 }
341 if ( !m_initColourFound )
342 {
343 for ( i = 0; i < WXSIZEOF(m_customColours); i++ )
344 {
345 if ( m_customColours[i] == curr )
346 {
347 m_whichKind = 2;
348 m_colourSelection = i;
349 break;
350 }
351 }
352 }
353 m_colourData.m_dataColour.Set( curr.Red(), curr.Green(), curr.Blue() );
354 }
355 else
356 {
357 m_whichKind = 1;
358 m_colourSelection = 0;
359 m_colourData.m_dataColour.Set( 0, 0, 0 );
360 }
361 }
362
363 void wxGenericColourDialog::PaintBasicColours(wxDC& dc)
364 {
365 int i;
366 for (i = 0; i < 6; i++)
367 {
368 int j;
369 for (j = 0; j < 8; j++)
370 {
371 int ptr = i*8 + j;
372
373 int x = (j*(m_smallRectangleSize.x+m_gridSpacing) + m_standardColoursRect.x);
374 int y = (i*(m_smallRectangleSize.y+m_gridSpacing) + m_standardColoursRect.y);
375
376 dc.SetPen(*wxBLACK_PEN);
377 wxBrush brush(m_standardColours[ptr]);
378 dc.SetBrush(brush);
379
380 dc.DrawRectangle( x, y, m_smallRectangleSize.x, m_smallRectangleSize.y);
381 }
382 }
383 }
384
385 void wxGenericColourDialog::PaintCustomColours(wxDC& dc)
386 {
387 int i;
388 for (i = 0; i < 2; i++)
389 {
390 int j;
391 for (j = 0; j < 8; j++)
392 {
393 int ptr = i*8 + j;
394
395 int x = (j*(m_smallRectangleSize.x+m_gridSpacing)) + m_customColoursRect.x;
396 int y = (i*(m_smallRectangleSize.y+m_gridSpacing)) + m_customColoursRect.y;
397
398 dc.SetPen(*wxBLACK_PEN);
399
400 wxBrush brush(m_customColours[ptr]);
401 dc.SetBrush(brush);
402
403 dc.DrawRectangle( x, y, m_smallRectangleSize.x, m_smallRectangleSize.y);
404 }
405 }
406 }
407
408 void wxGenericColourDialog::PaintHighlight(wxDC& dc, bool draw)
409 {
410 if ( m_colourSelection < 0 )
411 return;
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 (m_whichKind == 1)
419 {
420 // Standard colours
421 int y = (int)(m_colourSelection / 8);
422 int x = (int)(m_colourSelection - (y*8));
423
424 x = (x*(m_smallRectangleSize.x + m_gridSpacing) + m_standardColoursRect.x) - deltaX;
425 y = (y*(m_smallRectangleSize.y + m_gridSpacing) + m_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, (m_smallRectangleSize.x + (2*deltaX)), (m_smallRectangleSize.y + (2*deltaY)));
434 }
435 else
436 {
437 // User-defined colours
438 int y = (int)(m_colourSelection / 8);
439 int x = (int)(m_colourSelection - (y*8));
440
441 x = (x*(m_smallRectangleSize.x + m_gridSpacing) + m_customColoursRect.x) - deltaX;
442 y = (y*(m_smallRectangleSize.y + m_gridSpacing) + m_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, (m_smallRectangleSize.x + (2*deltaX)), (m_smallRectangleSize.y + (2*deltaY)));
451 }
452 }
453
454 void wxGenericColourDialog::PaintCustomColour(wxDC& dc)
455 {
456 dc.SetPen(*wxBLACK_PEN);
457
458 wxBrush *brush = new wxBrush(m_colourData.m_dataColour);
459 dc.SetBrush(*brush);
460
461 dc.DrawRectangle( m_singleCustomColourRect.x, m_singleCustomColourRect.y,
462 m_customRectangleSize.x, m_customRectangleSize.y);
463
464 dc.SetBrush(wxNullBrush);
465 delete brush;
466 }
467
468 void wxGenericColourDialog::OnBasicColourClick(int which)
469 {
470 wxClientDC dc(this);
471
472 PaintHighlight(dc, false);
473 m_whichKind = 1;
474 m_colourSelection = which;
475
476 #if wxUSE_SLIDER
477 m_redSlider->SetValue( m_standardColours[m_colourSelection].Red() );
478 m_greenSlider->SetValue( m_standardColours[m_colourSelection].Green() );
479 m_blueSlider->SetValue( m_standardColours[m_colourSelection].Blue() );
480 #endif // wxUSE_SLIDER
481
482 m_colourData.m_dataColour.Set(m_standardColours[m_colourSelection].Red(),
483 m_standardColours[m_colourSelection].Green(),
484 m_standardColours[m_colourSelection].Blue());
485
486 PaintCustomColour(dc);
487 PaintHighlight(dc, true);
488 }
489
490 void wxGenericColourDialog::OnCustomColourClick(int which)
491 {
492 wxClientDC dc(this);
493 PaintHighlight(dc, false);
494 m_whichKind = 2;
495 m_colourSelection = which;
496
497 #if wxUSE_SLIDER
498 m_redSlider->SetValue( m_customColours[m_colourSelection].Red() );
499 m_greenSlider->SetValue( m_customColours[m_colourSelection].Green() );
500 m_blueSlider->SetValue( m_customColours[m_colourSelection].Blue() );
501 #endif // wxUSE_SLIDER
502
503 m_colourData.m_dataColour.Set(m_customColours[m_colourSelection].Red(),
504 m_customColours[m_colourSelection].Green(),
505 m_customColours[m_colourSelection].Blue());
506
507 PaintCustomColour(dc);
508 PaintHighlight(dc, true);
509 }
510
511 /*
512 void wxGenericColourDialog::OnOk(void)
513 {
514 Show(false);
515 }
516
517 void wxGenericColourDialog::OnCancel(void)
518 {
519 colourDialogCancelled = true;
520 Show(false);
521 }
522 */
523
524 void wxGenericColourDialog::OnAddCustom(wxCommandEvent& WXUNUSED(event))
525 {
526 wxClientDC dc(this);
527 if (m_whichKind != 2)
528 {
529 PaintHighlight(dc, false);
530 m_whichKind = 2;
531 m_colourSelection = 0;
532 PaintHighlight(dc, true);
533 }
534
535 m_customColours[m_colourSelection].Set(m_colourData.m_dataColour.Red(),
536 m_colourData.m_dataColour.Green(),
537 m_colourData.m_dataColour.Blue());
538
539 m_colourData.SetCustomColour(m_colourSelection, m_customColours[m_colourSelection]);
540
541 PaintCustomColours(dc);
542 }
543
544 #if wxUSE_SLIDER
545
546 void wxGenericColourDialog::OnRedSlider(wxCommandEvent& WXUNUSED(event))
547 {
548 if (!m_redSlider)
549 return;
550
551 wxClientDC dc(this);
552 m_colourData.m_dataColour.Set((unsigned char)m_redSlider->GetValue(), m_colourData.m_dataColour.Green(), m_colourData.m_dataColour.Blue());
553 PaintCustomColour(dc);
554 }
555
556 void wxGenericColourDialog::OnGreenSlider(wxCommandEvent& WXUNUSED(event))
557 {
558 if (!m_greenSlider)
559 return;
560
561 wxClientDC dc(this);
562 m_colourData.m_dataColour.Set(m_colourData.m_dataColour.Red(), (unsigned char)m_greenSlider->GetValue(), m_colourData.m_dataColour.Blue());
563 PaintCustomColour(dc);
564 }
565
566 void wxGenericColourDialog::OnBlueSlider(wxCommandEvent& WXUNUSED(event))
567 {
568 if (!m_blueSlider)
569 return;
570
571 wxClientDC dc(this);
572 m_colourData.m_dataColour.Set(m_colourData.m_dataColour.Red(), m_colourData.m_dataColour.Green(), (unsigned char)m_blueSlider->GetValue());
573 PaintCustomColour(dc);
574 }
575
576 #endif // wxUSE_SLIDER
577
578 #endif // wxUSE_COLOURDLG