]> git.saurik.com Git - wxWidgets.git/blob - src/generic/colrdlgg.cpp
implementing pure carbon event behaviour, getting rid of doubly executed events
[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 // 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 #endif
32
33 #if wxUSE_STATLINE
34 #include "wx/statline.h"
35 #endif
36
37 #if wxUSE_SLIDER
38 #include "wx/slider.h"
39 #endif
40
41 #include "wx/generic/colrdlgg.h"
42
43 IMPLEMENT_DYNAMIC_CLASS(wxGenericColourDialog, wxDialog)
44
45 BEGIN_EVENT_TABLE(wxGenericColourDialog, wxDialog)
46 EVT_BUTTON(wxID_ADD_CUSTOM, wxGenericColourDialog::OnAddCustom)
47 #if wxUSE_SLIDER
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 #endif
52 EVT_PAINT(wxGenericColourDialog::OnPaint)
53 EVT_MOUSE_EVENTS(wxGenericColourDialog::OnMouseEvent)
54 EVT_CLOSE(wxGenericColourDialog::OnCloseWindow)
55 END_EVENT_TABLE()
56
57
58 /*
59 * Generic wxColourDialog
60 */
61
62 // don't change the number of elements (48) in this array, the code below is
63 // hardcoded to use it
64 static const wxChar *wxColourDialogNames[] =
65 {
66 wxT("ORANGE"),
67 wxT("GOLDENROD"),
68 wxT("WHEAT"),
69 wxT("SPRING GREEN"),
70 wxT("SKY BLUE"),
71 wxT("SLATE BLUE"),
72 wxT("MEDIUM VIOLET RED"),
73 wxT("PURPLE"),
74
75 wxT("RED"),
76 wxT("YELLOW"),
77 wxT("MEDIUM SPRING GREEN"),
78 wxT("PALE GREEN"),
79 wxT("CYAN"),
80 wxT("LIGHT STEEL BLUE"),
81 wxT("ORCHID"),
82 wxT("LIGHT MAGENTA"),
83
84 wxT("BROWN"),
85 wxT("YELLOW"),
86 wxT("GREEN"),
87 wxT("CADET BLUE"),
88 wxT("MEDIUM BLUE"),
89 wxT("MAGENTA"),
90 wxT("MAROON"),
91 wxT("ORANGE RED"),
92
93 wxT("FIREBRICK"),
94 wxT("CORAL"),
95 wxT("FOREST GREEN"),
96 wxT("AQUAMARINE"),
97 wxT("BLUE"),
98 wxT("NAVY"),
99 wxT("THISTLE"),
100 wxT("MEDIUM VIOLET RED"),
101
102 wxT("INDIAN RED"),
103 wxT("GOLD"),
104 wxT("MEDIUM SEA GREEN"),
105 wxT("MEDIUM BLUE"),
106 wxT("MIDNIGHT BLUE"),
107 wxT("GREY"),
108 wxT("PURPLE"),
109 wxT("KHAKI"),
110
111 wxT("BLACK"),
112 wxT("MEDIUM FOREST GREEN"),
113 wxT("KHAKI"),
114 wxT("DARK GREY"),
115 wxT("SEA GREEN"),
116 wxT("LIGHT GREY"),
117 wxT("MEDIUM SLATE BLUE"),
118 wxT("WHITE")
119 };
120
121 wxGenericColourDialog::wxGenericColourDialog()
122 {
123 dialogParent = NULL;
124 whichKind = 1;
125 colourSelection = -1;
126 }
127
128 wxGenericColourDialog::wxGenericColourDialog(wxWindow *parent,
129 wxColourData *data)
130 {
131 whichKind = 1;
132 colourSelection = -1;
133 Create(parent, data);
134 }
135
136 wxGenericColourDialog::~wxGenericColourDialog()
137 {
138 }
139
140 void wxGenericColourDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
141 {
142 EndModal(wxID_CANCEL);
143 }
144
145 bool wxGenericColourDialog::Create(wxWindow *parent, wxColourData *data)
146 {
147 if ( !wxDialog::Create(parent, wxID_ANY, _("Choose colour"),
148 wxPoint(0,0), wxSize(900, 900)) )
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(__WXPM__) && !defined(__WXCOCOA__)
210 wxDialog::OnPaint(event);
211 #else
212 wxUnusedVar(event);
213 #endif
214
215 wxPaintDC dc(this);
216
217 PaintBasicColours(dc);
218 PaintCustomColours(dc);
219 PaintCustomColour(dc);
220 PaintHighlight(dc, true);
221 }
222
223 void wxGenericColourDialog::CalculateMeasurements()
224 {
225 smallRectangleSize.x = 18;
226 smallRectangleSize.y = 14;
227 customRectangleSize.x = 40;
228 customRectangleSize.y = 40;
229
230 gridSpacing = 6;
231 sectionSpacing = 15;
232
233 standardColoursRect.x = 10;
234 #ifdef __WXPM__
235 standardColoursRect.y = 15 + 20; /* OS/2 needs to account for dialog titlebar */
236 #else
237 standardColoursRect.y = 15;
238 #endif
239 standardColoursRect.width = (8*smallRectangleSize.x) + (7*gridSpacing);
240 standardColoursRect.height = (6*smallRectangleSize.y) + (5*gridSpacing);
241
242 customColoursRect.x = standardColoursRect.x;
243 customColoursRect.y = standardColoursRect.y + standardColoursRect.height + 20;
244 customColoursRect.width = (8*smallRectangleSize.x) + (7*gridSpacing);
245 customColoursRect.height = (2*smallRectangleSize.y) + (1*gridSpacing);
246
247 singleCustomColourRect.x = customColoursRect.width + customColoursRect.x + sectionSpacing;
248 singleCustomColourRect.y = 80;
249 singleCustomColourRect.width = customRectangleSize.x;
250 singleCustomColourRect.height = customRectangleSize.y;
251
252 okButtonX = 10;
253 customButtonX = singleCustomColourRect.x ;
254 buttonY = customColoursRect.y + customColoursRect.height + 10;
255 }
256
257 void wxGenericColourDialog::CreateWidgets()
258 {
259 wxBeginBusyCursor();
260
261 wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
262
263 const int sliderHeight = 160;
264
265 #if wxUSE_SLIDER
266 const int sliderX = singleCustomColourRect.x + singleCustomColourRect.width + sectionSpacing;
267
268 redSlider = new wxSlider(this, wxID_RED_SLIDER, colourData.m_dataColour.Red(), 0, 255,
269 wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE);
270 greenSlider = new wxSlider(this, wxID_GREEN_SLIDER, colourData.m_dataColour.Green(), 0, 255,
271 wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE);
272 blueSlider = new wxSlider(this, wxID_BLUE_SLIDER, colourData.m_dataColour.Blue(), 0, 255,
273 wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE);
274
275 wxBoxSizer *sliderSizer = new wxBoxSizer( wxHORIZONTAL );
276
277 // 1) space for sliders
278 sliderSizer->Add( sliderX, sliderHeight );
279 sliderSizer->Add( redSlider, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 10 );
280 sliderSizer->Add( greenSlider, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 10 );
281 sliderSizer->Add( blueSlider, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 10 );
282
283 topSizer->Add( sliderSizer, 0, wxCENTRE | wxALL, 10 );
284 #else
285 topSizer->Add( 1, sliderHeight, 0, wxCENTRE | wxALL, 15 );
286 #endif // wxUSE_SLIDER
287
288 #if wxUSE_STATLINE
289 // 2) static line
290 topSizer->Add( new wxStaticLine( this, wxID_ANY ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 );
291 #endif
292
293 // 3) buttons
294 wxSizer *buttonsizer = CreateButtonSizer( wxOK|wxCANCEL );
295 buttonsizer->Add( new wxButton(this, wxID_ADD_CUSTOM, _("Add to custom colours") ), 0, wxLEFT|wxRIGHT, 10 );
296 topSizer->Add( buttonsizer, 0, wxEXPAND | wxALL, 10 );
297
298 SetAutoLayout( true );
299 SetSizer( topSizer );
300
301 topSizer->SetSizeHints( this );
302 topSizer->Fit( this );
303
304 Centre( wxBOTH );
305
306 wxEndBusyCursor();
307 }
308
309 void wxGenericColourDialog::InitializeColours(void)
310 {
311 size_t i;
312
313 for (i = 0; i < WXSIZEOF(wxColourDialogNames); i++)
314 {
315 wxColour col = wxTheColourDatabase->Find(wxColourDialogNames[i]);
316 if (col.Ok())
317 standardColours[i].Set(col.Red(), col.Green(), col.Blue());
318 else
319 standardColours[i].Set(0, 0, 0);
320 }
321
322 for (i = 0; i < WXSIZEOF(customColours); i++)
323 {
324 wxColour c = colourData.GetCustomColour(i);
325 if (c.Ok())
326 customColours[i] = colourData.GetCustomColour(i);
327 else
328 customColours[i] = wxColour(255, 255, 255);
329 }
330
331 wxColour curr = colourData.GetColour();
332 if ( curr.Ok() )
333 {
334 bool initColourFound = false;
335
336 for (i = 0; i < WXSIZEOF(wxColourDialogNames); i++)
337 {
338 if ( standardColours[i] == curr && !initColourFound )
339 {
340 whichKind = 1;
341 colourSelection = i;
342 initColourFound = true;
343 break;
344 }
345 }
346 if ( !initColourFound )
347 {
348 for ( i = 0; i < WXSIZEOF(customColours); i++ )
349 {
350 if ( customColours[i] == curr )
351 {
352 whichKind = 2;
353 colourSelection = i;
354 break;
355 }
356 }
357 }
358 colourData.m_dataColour.Set( curr.Red(), curr.Green(), curr.Blue() );
359 }
360 else
361 {
362 whichKind = 1;
363 colourSelection = 0;
364 colourData.m_dataColour.Set( 0, 0, 0 );
365 }
366 }
367
368 void wxGenericColourDialog::PaintBasicColours(wxDC& dc)
369 {
370 dc.BeginDrawing();
371
372 int i;
373 for (i = 0; i < 6; i++)
374 {
375 int j;
376 for (j = 0; j < 8; j++)
377 {
378 int ptr = i*8 + j;
379
380 int x = (j*(smallRectangleSize.x+gridSpacing) + standardColoursRect.x);
381 int y = (i*(smallRectangleSize.y+gridSpacing) + standardColoursRect.y);
382
383 dc.SetPen(*wxBLACK_PEN);
384 wxBrush brush(standardColours[ptr], wxSOLID);
385 dc.SetBrush(brush);
386
387 dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
388 }
389 }
390 dc.EndDrawing();
391 }
392
393 void wxGenericColourDialog::PaintCustomColours(wxDC& dc)
394 {
395 dc.BeginDrawing();
396
397 int i;
398 for (i = 0; i < 2; i++)
399 {
400 int j;
401 for (j = 0; j < 8; j++)
402 {
403 int ptr = i*8 + j;
404
405 int x = (j*(smallRectangleSize.x+gridSpacing)) + customColoursRect.x;
406 int y = (i*(smallRectangleSize.y+gridSpacing)) + customColoursRect.y;
407
408 dc.SetPen(*wxBLACK_PEN);
409
410 wxBrush brush(customColours[ptr], wxSOLID);
411 dc.SetBrush(brush);
412
413 dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
414 }
415 }
416 dc.EndDrawing();
417 }
418
419 void wxGenericColourDialog::PaintHighlight(wxDC& dc, bool draw)
420 {
421 if ( colourSelection < 0 )
422 return;
423
424 dc.BeginDrawing();
425
426 // Number of pixels bigger than the standard rectangle size
427 // for drawing a highlight
428 int deltaX = 2;
429 int deltaY = 2;
430
431 if (whichKind == 1)
432 {
433 // Standard colours
434 int y = (int)(colourSelection / 8);
435 int x = (int)(colourSelection - (y*8));
436
437 x = (x*(smallRectangleSize.x + gridSpacing) + standardColoursRect.x) - deltaX;
438 y = (y*(smallRectangleSize.y + gridSpacing) + standardColoursRect.y) - deltaY;
439
440 if (draw)
441 dc.SetPen(*wxBLACK_PEN);
442 else
443 dc.SetPen(*wxLIGHT_GREY_PEN);
444
445 dc.SetBrush(*wxTRANSPARENT_BRUSH);
446 dc.DrawRectangle( x, y, (smallRectangleSize.x + (2*deltaX)), (smallRectangleSize.y + (2*deltaY)));
447 }
448 else
449 {
450 // User-defined colours
451 int y = (int)(colourSelection / 8);
452 int x = (int)(colourSelection - (y*8));
453
454 x = (x*(smallRectangleSize.x + gridSpacing) + customColoursRect.x) - deltaX;
455 y = (y*(smallRectangleSize.y + gridSpacing) + customColoursRect.y) - deltaY;
456
457 if (draw)
458 dc.SetPen(*wxBLACK_PEN);
459 else
460 dc.SetPen(*wxLIGHT_GREY_PEN);
461
462 dc.SetBrush(*wxTRANSPARENT_BRUSH);
463 dc.DrawRectangle( x, y, (smallRectangleSize.x + (2*deltaX)), (smallRectangleSize.y + (2*deltaY)));
464 }
465
466 dc.EndDrawing();
467 }
468
469 void wxGenericColourDialog::PaintCustomColour(wxDC& dc)
470 {
471 dc.BeginDrawing();
472
473 dc.SetPen(*wxBLACK_PEN);
474
475 wxBrush *brush = new wxBrush(colourData.m_dataColour, wxSOLID);
476 dc.SetBrush(*brush);
477
478 dc.DrawRectangle( singleCustomColourRect.x, singleCustomColourRect.y,
479 customRectangleSize.x, customRectangleSize.y);
480
481 dc.SetBrush(wxNullBrush);
482 delete brush;
483
484 dc.EndDrawing();
485 }
486
487 void wxGenericColourDialog::OnBasicColourClick(int which)
488 {
489 wxClientDC dc(this);
490
491 PaintHighlight(dc, false);
492 whichKind = 1;
493 colourSelection = which;
494
495 #if wxUSE_SLIDER
496 redSlider->SetValue( standardColours[colourSelection].Red() );
497 greenSlider->SetValue( standardColours[colourSelection].Green() );
498 blueSlider->SetValue( standardColours[colourSelection].Blue() );
499 #endif // wxUSE_SLIDER
500
501 colourData.m_dataColour.Set(standardColours[colourSelection].Red(),
502 standardColours[colourSelection].Green(),
503 standardColours[colourSelection].Blue());
504
505 PaintCustomColour(dc);
506 PaintHighlight(dc, true);
507 }
508
509 void wxGenericColourDialog::OnCustomColourClick(int which)
510 {
511 wxClientDC dc(this);
512 PaintHighlight(dc, false);
513 whichKind = 2;
514 colourSelection = which;
515
516 #if wxUSE_SLIDER
517 redSlider->SetValue( customColours[colourSelection].Red() );
518 greenSlider->SetValue( customColours[colourSelection].Green() );
519 blueSlider->SetValue( customColours[colourSelection].Blue() );
520 #endif // wxUSE_SLIDER
521
522 colourData.m_dataColour.Set(customColours[colourSelection].Red(),
523 customColours[colourSelection].Green(),
524 customColours[colourSelection].Blue());
525
526 PaintCustomColour(dc);
527 PaintHighlight(dc, true);
528 }
529
530 /*
531 void wxGenericColourDialog::OnOk(void)
532 {
533 Show(false);
534 }
535
536 void wxGenericColourDialog::OnCancel(void)
537 {
538 colourDialogCancelled = true;
539 Show(false);
540 }
541 */
542
543 void wxGenericColourDialog::OnAddCustom(wxCommandEvent& WXUNUSED(event))
544 {
545 wxClientDC dc(this);
546 if (whichKind != 2)
547 {
548 PaintHighlight(dc, false);
549 whichKind = 2;
550 colourSelection = 0;
551 PaintHighlight(dc, true);
552 }
553
554 customColours[colourSelection].Set(colourData.m_dataColour.Red(),
555 colourData.m_dataColour.Green(),
556 colourData.m_dataColour.Blue());
557
558 colourData.SetCustomColour(colourSelection, customColours[colourSelection]);
559
560 PaintCustomColours(dc);
561 }
562
563 #if wxUSE_SLIDER
564
565 void wxGenericColourDialog::OnRedSlider(wxCommandEvent& WXUNUSED(event))
566 {
567 if (!redSlider)
568 return;
569
570 wxClientDC dc(this);
571 colourData.m_dataColour.Set((unsigned char)redSlider->GetValue(), colourData.m_dataColour.Green(), colourData.m_dataColour.Blue());
572 PaintCustomColour(dc);
573 }
574
575 void wxGenericColourDialog::OnGreenSlider(wxCommandEvent& WXUNUSED(event))
576 {
577 if (!greenSlider)
578 return;
579
580 wxClientDC dc(this);
581 colourData.m_dataColour.Set(colourData.m_dataColour.Red(), (unsigned char)greenSlider->GetValue(), colourData.m_dataColour.Blue());
582 PaintCustomColour(dc);
583 }
584
585 void wxGenericColourDialog::OnBlueSlider(wxCommandEvent& WXUNUSED(event))
586 {
587 if (!blueSlider)
588 return;
589
590 wxClientDC dc(this);
591 colourData.m_dataColour.Set(colourData.m_dataColour.Red(), colourData.m_dataColour.Green(), (unsigned char)blueSlider->GetValue());
592 PaintCustomColour(dc);
593 }
594
595 #endif // wxUSE_SLIDER
596
597 #endif // wxUSE_COLOURDLG && !defined(__WXGTK20__)