wxUniv fixes for generic wxColourDialog
[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 and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "colrdlgg.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #if wxUSE_COLOURDLG
24
25 #ifndef WX_PRECOMP
26 #include "wx/utils.h"
27 #include "wx/intl.h"
28 #include "wx/dialog.h"
29 #include "wx/listbox.h"
30 #include "wx/button.h"
31 #include "wx/stattext.h"
32 #include "wx/layout.h"
33 #include "wx/dcclient.h"
34 #include "wx/slider.h"
35 #include "wx/sizer.h"
36 #endif
37
38 #if wxUSE_STATLINE
39 #include "wx/statline.h"
40 #endif
41
42 #include "wx/generic/colrdlgg.h"
43
44 IMPLEMENT_DYNAMIC_CLASS(wxGenericColourDialog, wxDialog)
45
46 BEGIN_EVENT_TABLE(wxGenericColourDialog, wxDialog)
47 EVT_BUTTON(wxID_ADD_CUSTOM, wxGenericColourDialog::OnAddCustom)
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 EVT_PAINT(wxGenericColourDialog::OnPaint)
52 EVT_MOUSE_EVENTS(wxGenericColourDialog::OnMouseEvent)
53 EVT_CLOSE(wxGenericColourDialog::OnCloseWindow)
54 END_EVENT_TABLE()
55
56
57 /*
58 * Generic wxColourDialog
59 */
60
61 #define NUM_COLS 48
62 static wxString wxColourDialogNames[NUM_COLS]={wxT("ORANGE"),
63 wxT("GOLDENROD"),
64 wxT("WHEAT"),
65 wxT("SPRING GREEN"),
66 wxT("SKY BLUE"),
67 wxT("SLATE BLUE"),
68 wxT("MEDIUM VIOLET RED"),
69 wxT("PURPLE"),
70
71 wxT("RED"),
72 wxT("YELLOW"),
73 wxT("MEDIUM SPRING GREEN"),
74 wxT("PALE GREEN"),
75 wxT("CYAN"),
76 wxT("LIGHT STEEL BLUE"),
77 wxT("ORCHID"),
78 wxT("LIGHT MAGENTA"),
79
80 wxT("BROWN"),
81 wxT("YELLOW"),
82 wxT("GREEN"),
83 wxT("CADET BLUE"),
84 wxT("MEDIUM BLUE"),
85 wxT("MAGENTA"),
86 wxT("MAROON"),
87 wxT("ORANGE RED"),
88
89 wxT("FIREBRICK"),
90 wxT("CORAL"),
91 wxT("FOREST GREEN"),
92 wxT("AQUAMARINE"),
93 wxT("BLUE"),
94 wxT("NAVY"),
95 wxT("THISTLE"),
96 wxT("MEDIUM VIOLET RED"),
97
98 wxT("INDIAN RED"),
99 wxT("GOLD"),
100 wxT("MEDIUM SEA GREEN"),
101 wxT("MEDIUM BLUE"),
102 wxT("MIDNIGHT BLUE"),
103 wxT("GREY"),
104 wxT("PURPLE"),
105 wxT("KHAKI"),
106
107 wxT("BLACK"),
108 wxT("MEDIUM FOREST GREEN"),
109 wxT("KHAKI"),
110 wxT("DARK GREY"),
111 wxT("SEA GREEN"),
112 wxT("LIGHT GREY"),
113 wxT("MEDIUM SLATE BLUE"),
114 wxT("WHITE")
115 };
116
117 wxGenericColourDialog::wxGenericColourDialog()
118 {
119 dialogParent = NULL;
120 whichKind = 1;
121 colourSelection = 0;
122 }
123
124 wxGenericColourDialog::wxGenericColourDialog(wxWindow *parent,
125 wxColourData *data)
126 {
127 whichKind = 1;
128 colourSelection = 0;
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(parent, -1, wxT("Colour"),
144 wxPoint(0, 0), wxSize(900, 900),
145 wxDEFAULT_DIALOG_STYLE | wxDIALOG_MODAL) )
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 if ((x >= standardColoursRect.x && x <= (standardColoursRect.x + standardColoursRect.width)) &&
175 (y >= standardColoursRect.y && y <= (standardColoursRect.y + standardColoursRect.height)))
176 {
177 int selX = (int)(x - standardColoursRect.x)/(smallRectangleSize.x + gridSpacing);
178 int selY = (int)(y - standardColoursRect.y)/(smallRectangleSize.y + gridSpacing);
179 int ptr = (int)(selX + selY*8);
180 OnBasicColourClick(ptr);
181 }
182 else if ((x >= customColoursRect.x && x <= (customColoursRect.x + customColoursRect.width)) &&
183 (y >= customColoursRect.y && y <= (customColoursRect.y + customColoursRect.height)))
184 {
185 int selX = (int)(x - customColoursRect.x)/(smallRectangleSize.x + gridSpacing);
186 int selY = (int)(y - customColoursRect.y)/(smallRectangleSize.y + gridSpacing);
187 int ptr = (int)(selX + selY*8);
188 OnCustomColourClick(ptr);
189 }
190 else
191 event.Skip();
192 }
193 else
194 event.Skip();
195 }
196
197 void wxGenericColourDialog::OnPaint(wxPaintEvent& event)
198 {
199 #if !defined(__WXMOTIF__) && !defined(__WXMAC__) && !defined(__WXPM__)
200 wxDialog::OnPaint(event);
201 #endif
202
203 wxPaintDC dc(this);
204
205 PaintBasicColours(dc);
206 PaintCustomColours(dc);
207 PaintCustomColour(dc);
208 PaintHighlight(dc, TRUE);
209 }
210
211 void wxGenericColourDialog::CalculateMeasurements()
212 {
213 smallRectangleSize.x = 18;
214 smallRectangleSize.y = 14;
215 customRectangleSize.x = 40;
216 customRectangleSize.y = 40;
217
218 gridSpacing = 6;
219 sectionSpacing = 15;
220
221 standardColoursRect.x = 10;
222 standardColoursRect.y = 15;
223 standardColoursRect.width = (8*smallRectangleSize.x) + (7*gridSpacing);
224 standardColoursRect.height = (6*smallRectangleSize.y) + (5*gridSpacing);
225
226 customColoursRect.x = standardColoursRect.x;
227 customColoursRect.y = standardColoursRect.y + standardColoursRect.height + 20;
228 customColoursRect.width = (8*smallRectangleSize.x) + (7*gridSpacing);
229 customColoursRect.height = (2*smallRectangleSize.y) + (1*gridSpacing);
230
231 singleCustomColourRect.x = customColoursRect.width + customColoursRect.x + sectionSpacing;
232 singleCustomColourRect.y = 80;
233 singleCustomColourRect.width = customRectangleSize.x;
234 singleCustomColourRect.height = customRectangleSize.y;
235
236 okButtonX = 10;
237 customButtonX = singleCustomColourRect.x ;
238 buttonY = customColoursRect.y + customColoursRect.height + 10;
239 }
240
241 void wxGenericColourDialog::CreateWidgets()
242 {
243 wxBeginBusyCursor();
244
245 int sliderX = singleCustomColourRect.x + singleCustomColourRect.width + sectionSpacing;
246 #if defined(__WXMOTIF__)
247 int sliderSpacing = 65;
248 int sliderHeight = 160;
249 #else
250 int sliderSpacing = 45;
251 int sliderHeight = 160;
252 #endif
253
254 redSlider = new wxSlider(this, wxID_RED_SLIDER, 0, 0, 255,
255 wxPoint(sliderX, 10), wxSize(-1, sliderHeight), wxVERTICAL|wxSL_LABELS);
256 greenSlider = new wxSlider(this, wxID_GREEN_SLIDER, 0, 0, 255,
257 wxPoint(sliderX + sliderSpacing, 10), wxSize(-1, sliderHeight), wxVERTICAL|wxSL_LABELS);
258 blueSlider = new wxSlider(this, wxID_BLUE_SLIDER, 0, 0, 255,
259 wxPoint(sliderX + 2*sliderSpacing, 10), wxSize(-1, sliderHeight), wxVERTICAL|wxSL_LABELS);
260
261 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
262
263 // 1) space for explicitly layouted controls
264 topsizer->Add( sliderX + 3*sliderSpacing, sliderHeight+25 );
265
266 #if wxUSE_STATLINE
267 // 2) static line
268 topsizer->Add( new wxStaticLine( this, -1 ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 );
269 #endif
270
271 // 3) buttons
272 wxSizer *buttonsizer = CreateButtonSizer( wxOK|wxCANCEL );
273 buttonsizer->Add( new wxButton(this, wxID_ADD_CUSTOM, _("Add to custom colours") ), 0, wxLEFT|wxRIGHT, 10 );
274 topsizer->Add( buttonsizer, 0, wxCENTRE | wxALL, 10 );
275
276 SetAutoLayout( TRUE );
277 SetSizer( topsizer );
278
279 topsizer->SetSizeHints( this );
280 topsizer->Fit( this );
281
282 Centre( wxBOTH );
283
284 wxEndBusyCursor();
285 }
286
287 void wxGenericColourDialog::InitializeColours(void)
288 {
289 int i;
290 for (i = 0; i < 48; i++)
291 {
292 wxColour *col = wxTheColourDatabase->FindColour(wxColourDialogNames[i]);
293 if (col)
294 standardColours[i].Set(col->Red(), col->Green(), col->Blue());
295 else
296 standardColours[i].Set(0, 0, 0);
297 }
298
299 for (i = 0; i < 16; i++)
300 customColours[i] =
301 colourData.GetCustomColour(i);
302
303 singleCustomColour.Set(0, 0, 0);
304 }
305
306 void wxGenericColourDialog::PaintBasicColours(wxDC& dc)
307 {
308 dc.BeginDrawing();
309
310 int i;
311 for (i = 0; i < 6; i++)
312 {
313 int j;
314 for (j = 0; j < 8; j++)
315 {
316 int ptr = i*8 + j;
317
318 int x = (j*(smallRectangleSize.x+gridSpacing) + standardColoursRect.x);
319 int y = (i*(smallRectangleSize.y+gridSpacing) + standardColoursRect.y);
320
321 dc.SetPen(*wxBLACK_PEN);
322 wxBrush brush(standardColours[ptr], wxSOLID);
323 dc.SetBrush(brush);
324
325 dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
326 }
327 }
328 dc.EndDrawing();
329 }
330
331 void wxGenericColourDialog::PaintCustomColours(wxDC& dc)
332 {
333 dc.BeginDrawing();
334
335 int i;
336 for (i = 0; i < 2; i++)
337 {
338 int j;
339 for (j = 0; j < 8; j++)
340 {
341 int ptr = i*8 + j;
342
343 int x = (j*(smallRectangleSize.x+gridSpacing)) + customColoursRect.x;
344 int y = (i*(smallRectangleSize.y+gridSpacing)) + customColoursRect.y;
345
346 dc.SetPen(*wxBLACK_PEN);
347
348 wxBrush brush(customColours[ptr], wxSOLID);
349 dc.SetBrush(brush);
350
351 dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
352 }
353 }
354 dc.EndDrawing();
355 }
356
357 void wxGenericColourDialog::PaintHighlight(wxDC& dc, bool draw)
358 {
359 dc.BeginDrawing();
360
361 // Number of pixels bigger than the standard rectangle size
362 // for drawing a highlight
363 int deltaX = 2;
364 int deltaY = 2;
365
366 if (whichKind == 1)
367 {
368 // Standard colours
369 int y = (int)(colourSelection / 8);
370 int x = (int)(colourSelection - (y*8));
371
372 x = (x*(smallRectangleSize.x + gridSpacing) + standardColoursRect.x) - deltaX;
373 y = (y*(smallRectangleSize.y + gridSpacing) + standardColoursRect.y) - deltaY;
374
375 if (draw)
376 dc.SetPen(*wxBLACK_PEN);
377 else
378 dc.SetPen(*wxLIGHT_GREY_PEN);
379
380 dc.SetBrush(*wxTRANSPARENT_BRUSH);
381 dc.DrawRectangle( x, y, (smallRectangleSize.x + (2*deltaX)), (smallRectangleSize.y + (2*deltaY)));
382 }
383 else
384 {
385 // User-defined colours
386 int y = (int)(colourSelection / 8);
387 int x = (int)(colourSelection - (y*8));
388
389 x = (x*(smallRectangleSize.x + gridSpacing) + customColoursRect.x) - deltaX;
390 y = (y*(smallRectangleSize.y + gridSpacing) + customColoursRect.y) - deltaY;
391
392 if (draw)
393 dc.SetPen(*wxBLACK_PEN);
394 else
395 dc.SetPen(*wxLIGHT_GREY_PEN);
396
397 dc.SetBrush(*wxTRANSPARENT_BRUSH);
398 dc.DrawRectangle( x, y, (smallRectangleSize.x + (2*deltaX)), (smallRectangleSize.y + (2*deltaY)));
399 }
400
401 dc.EndDrawing();
402 }
403
404 void wxGenericColourDialog::PaintCustomColour(wxDC& dc)
405 {
406 dc.BeginDrawing();
407
408 dc.SetPen(*wxBLACK_PEN);
409
410 wxBrush *brush = new wxBrush(singleCustomColour, wxSOLID);
411 dc.SetBrush(*brush);
412
413 dc.DrawRectangle( singleCustomColourRect.x, singleCustomColourRect.y,
414 customRectangleSize.x, customRectangleSize.y);
415
416 dc.SetBrush(wxNullBrush);
417 delete brush;
418
419 dc.EndDrawing();
420 }
421
422 void wxGenericColourDialog::OnBasicColourClick(int which)
423 {
424 wxClientDC dc(this);
425
426 PaintHighlight(dc, FALSE);
427 whichKind = 1;
428 colourSelection = which;
429 colourData.SetColour(standardColours[colourSelection]);
430
431 PaintHighlight(dc, TRUE);
432 }
433
434 void wxGenericColourDialog::OnCustomColourClick(int which)
435 {
436 wxClientDC dc(this);
437 PaintHighlight(dc, FALSE);
438 whichKind = 2;
439 colourSelection = which;
440 colourData.SetColour(customColours[colourSelection]);
441
442 PaintHighlight(dc, TRUE);
443 }
444
445 /*
446 void wxGenericColourDialog::OnOk(void)
447 {
448 Show(FALSE);
449 }
450
451 void wxGenericColourDialog::OnCancel(void)
452 {
453 colourDialogCancelled = TRUE;
454 Show(FALSE);
455 }
456 */
457
458 void wxGenericColourDialog::OnAddCustom(wxCommandEvent& WXUNUSED(event))
459 {
460 wxClientDC dc(this);
461 if (whichKind != 2)
462 {
463 PaintHighlight(dc, FALSE);
464 whichKind = 2;
465 colourSelection = 0;
466 PaintHighlight(dc, TRUE);
467 }
468
469 customColours[colourSelection].Set(singleCustomColour.Red(), singleCustomColour.Green(), singleCustomColour.Blue());
470 colourData.SetColour(customColours[colourSelection]);
471 colourData.SetCustomColour(colourSelection, customColours[colourSelection]);
472
473 PaintCustomColours(dc);
474 }
475
476 void wxGenericColourDialog::OnRedSlider(wxCommandEvent& WXUNUSED(event))
477 {
478 if (!redSlider)
479 return;
480
481 wxClientDC dc(this);
482 singleCustomColour.Set(redSlider->GetValue(), singleCustomColour.Green(), singleCustomColour.Blue());
483 PaintCustomColour(dc);
484 }
485
486 void wxGenericColourDialog::OnGreenSlider(wxCommandEvent& WXUNUSED(event))
487 {
488 if (!greenSlider)
489 return;
490
491 wxClientDC dc(this);
492 singleCustomColour.Set(singleCustomColour.Red(), greenSlider->GetValue(), singleCustomColour.Blue());
493 PaintCustomColour(dc);
494 }
495
496 void wxGenericColourDialog::OnBlueSlider(wxCommandEvent& WXUNUSED(event))
497 {
498 if (!blueSlider)
499 return;
500
501 wxClientDC dc(this);
502 singleCustomColour.Set(singleCustomColour.Red(), singleCustomColour.Green(), blueSlider->GetValue());
503 PaintCustomColour(dc);
504 }
505
506 #endif // wxUSE_COLOURDLG
507