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: colrdlgg.cpp 41838 2006-10-09 21:08:45Z VZ $
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 
wxGenericColourDialog()118 wxGenericColourDialog::wxGenericColourDialog()
119 {
120     dialogParent = NULL;
121     whichKind = 1;
122     colourSelection = -1;
123 }
124 
wxGenericColourDialog(wxWindow * parent,wxColourData * data)125 wxGenericColourDialog::wxGenericColourDialog(wxWindow *parent,
126                                              wxColourData *data)
127 {
128     whichKind = 1;
129     colourSelection = -1;
130     Create(parent, data);
131 }
132 
~wxGenericColourDialog()133 wxGenericColourDialog::~wxGenericColourDialog()
134 {
135 }
136 
OnCloseWindow(wxCloseEvent & WXUNUSED (event))137 void wxGenericColourDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
138 {
139     EndModal(wxID_CANCEL);
140 }
141 
Create(wxWindow * parent,wxColourData * data)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 
ShowModal()160 int wxGenericColourDialog::ShowModal()
161 {
162     return wxDialog::ShowModal();
163 }
164 
165 
166 // Internal functions
OnMouseEvent(wxMouseEvent & event)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 
OnPaint(wxPaintEvent & event)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 
CalculateMeasurements()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 
CreateWidgets()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 
InitializeColours(void)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 
PaintBasicColours(wxDC & dc)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 
PaintCustomColours(wxDC & dc)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 
PaintHighlight(wxDC & dc,bool draw)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 
PaintCustomColour(wxDC & dc)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 
OnBasicColourClick(int which)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 
OnCustomColourClick(int which)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 
OnAddCustom(wxCommandEvent & WXUNUSED (event))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 
OnRedSlider(wxCommandEvent & WXUNUSED (event))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 
OnGreenSlider(wxCommandEvent & WXUNUSED (event))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 
OnBlueSlider(wxCommandEvent & WXUNUSED (event))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__)
587