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 
wxGenericColourDialog()118 wxGenericColourDialog::wxGenericColourDialog()
119 {
120     m_whichKind = 1;
121     m_colourSelection = -1;
122 }
123 
wxGenericColourDialog(wxWindow * parent,wxColourData * data)124 wxGenericColourDialog::wxGenericColourDialog(wxWindow *parent,
125                                              wxColourData *data)
126 {
127     m_whichKind = 1;
128     m_colourSelection = -1;
129     Create(parent, data);
130 }
131 
~wxGenericColourDialog()132 wxGenericColourDialog::~wxGenericColourDialog()
133 {
134 }
135 
OnCloseWindow(wxCloseEvent & WXUNUSED (event))136 void wxGenericColourDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
137 {
138     EndModal(wxID_CANCEL);
139 }
140 
Create(wxWindow * parent,wxColourData * data)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 
ShowModal()158 int wxGenericColourDialog::ShowModal()
159 {
160     return wxDialog::ShowModal();
161 }
162 
163 
164 // Internal functions
OnMouseEvent(wxMouseEvent & event)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 
OnPaint(wxPaintEvent & WXUNUSED (event))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 
CalculateMeasurements()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 
CreateWidgets()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 
InitializeColours(void)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 
PaintBasicColours(wxDC & dc)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 
PaintCustomColours(wxDC & dc)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 
PaintHighlight(wxDC & dc,bool draw)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 
PaintCustomColour(wxDC & dc)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 
OnBasicColourClick(int which)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 
OnCustomColourClick(int which)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 
OnAddCustom(wxCommandEvent & WXUNUSED (event))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 
OnRedSlider(wxCommandEvent & WXUNUSED (event))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 
OnGreenSlider(wxCommandEvent & WXUNUSED (event))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 
OnBlueSlider(wxCommandEvent & WXUNUSED (event))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
579