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