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