]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/radiobox.cpp
support themed foreground brushes
[wxWidgets.git] / src / mac / carbon / radiobox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/radiobox.cpp
3 // Purpose: wxRadioBox
4 // Author: Stefan Csomor
5 // Modified by: JS Lair (99/11/15) first implementation
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 //-------------------------------------------------------------------------------------
13 // headers
14 //-------------------------------------------------------------------------------------
15
16 #include "wx/wxprec.h"
17
18 #if wxUSE_RADIOBOX
19
20 #include "wx/arrstr.h"
21 #include "wx/radiobox.h"
22 #include "wx/radiobut.h"
23 #include "wx/mac/uma.h"
24
25 IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
26
27
28 BEGIN_EVENT_TABLE(wxRadioBox, wxControl)
29 EVT_RADIOBUTTON( wxID_ANY , wxRadioBox::OnRadioButton )
30 END_EVENT_TABLE()
31
32
33 void wxRadioBox::OnRadioButton( wxCommandEvent &outer )
34 {
35 if ( outer.IsChecked() )
36 {
37 wxCommandEvent event( wxEVT_COMMAND_RADIOBOX_SELECTED, m_windowId );
38 int i = GetSelection() ;
39 event.SetInt( i );
40 event.SetString( GetString( i ) );
41 event.SetEventObject( this );
42 ProcessCommand( event );
43 }
44 }
45
46 wxRadioBox::wxRadioBox()
47 {
48 m_noItems = 0;
49 m_noRowsOrCols = 0;
50 m_radioButtonCycle = NULL;
51 }
52
53 wxRadioBox::~wxRadioBox()
54 {
55 m_isBeingDeleted = true;
56
57 wxRadioButton *next, *current;
58
59 current = m_radioButtonCycle->NextInCycle();
60 if (current != NULL)
61 {
62 while (current != m_radioButtonCycle)
63 {
64 next = current->NextInCycle();
65 delete current;
66
67 current = next;
68 }
69
70 delete current;
71 }
72 }
73
74 // Create the radiobox for two-step construction
75
76 bool wxRadioBox::Create( wxWindow *parent,
77 wxWindowID id, const wxString& label,
78 const wxPoint& pos, const wxSize& size,
79 const wxArrayString& choices,
80 int majorDim, long style,
81 const wxValidator& val, const wxString& name )
82 {
83 wxCArrayString chs(choices);
84
85 return Create(
86 parent, id, label, pos, size, chs.GetCount(),
87 chs.GetStrings(), majorDim, style, val, name);
88 }
89
90 bool wxRadioBox::Create( wxWindow *parent,
91 wxWindowID id, const wxString& label,
92 const wxPoint& pos, const wxSize& size,
93 int n, const wxString choices[],
94 int majorDim, long style,
95 const wxValidator& val, const wxString& name )
96 {
97 m_macIsUserPane = false ;
98
99 if ( !wxControl::Create( parent, id, pos, size, style, val, name ) )
100 return false;
101
102 int i;
103
104 m_noItems = n;
105 m_noRowsOrCols = majorDim;
106 m_radioButtonCycle = NULL;
107
108 SetMajorDim( majorDim == 0 ? n : majorDim, style );
109
110 m_label = label ;
111
112 Rect bounds = wxMacGetBoundsForControl( this, pos, size );
113 if ( bounds.right <= bounds.left )
114 bounds.right = bounds.left + 100;
115 if ( bounds.bottom <= bounds.top )
116 bounds.bottom = bounds.top + 100;
117
118 m_peer = new wxMacControl( this );
119
120 OSStatus err = CreateGroupBoxControl(
121 MAC_WXHWND(parent->MacGetTopLevelWindowRef()),
122 &bounds, CFSTR("") , true /*primary*/,
123 m_peer->GetControlRefAddr() );
124 verify_noerr( err );
125
126 for (i = 0; i < n; i++)
127 {
128 wxRadioButton *radBtn = new wxRadioButton(
129 this,
130 wxID_ANY,
131 wxStripMenuCodes(choices[i]),
132 wxPoint( 5, 20 * i + 10 ),
133 wxDefaultSize,
134 i == 0 ? wxRB_GROUP : 0 );
135
136 if ( i == 0 )
137 m_radioButtonCycle = radBtn;
138 // m_radioButtonCycle = radBtn->AddInCycle( m_radioButtonCycle );
139 }
140
141 SetSelection( 0 );
142 MacPostControlCreate( pos, size );
143
144 return true;
145 }
146
147 // Enables or disables the entire radiobox
148 //
149 bool wxRadioBox::Enable(bool enable)
150 {
151 int i;
152 wxRadioButton *current;
153
154 if (!wxControl::Enable( enable ))
155 return false;
156
157 current = m_radioButtonCycle;
158 for (i = 0; i < m_noItems; i++)
159 {
160 current->Enable( enable );
161 current = current->NextInCycle();
162 }
163
164 return true;
165 }
166
167 // Enables or disables an given button
168 //
169 bool wxRadioBox::Enable(int item, bool enable)
170 {
171 int i;
172 wxRadioButton *current;
173
174 if (!IsValid( item ))
175 return false;
176
177 i = 0;
178 current = m_radioButtonCycle;
179 while (i != item)
180 {
181 i++;
182 current = current->NextInCycle();
183 }
184
185 return current->Enable( enable );
186 }
187
188 // Returns the radiobox label
189 //
190 wxString wxRadioBox::GetLabel() const
191 {
192 return wxControl::GetLabel();
193 }
194
195 // Returns the label for the given button
196 //
197 wxString wxRadioBox::GetString(int item) const
198 {
199 int i;
200 wxRadioButton *current;
201
202 if (!IsValid( item ))
203 return wxEmptyString;
204
205 i = 0;
206 current = m_radioButtonCycle;
207 while (i != item)
208 {
209 i++;
210 current = current->NextInCycle();
211 }
212
213 return current->GetLabel();
214 }
215
216 // Returns the zero-based position of the selected button
217 //
218 int wxRadioBox::GetSelection() const
219 {
220 int i;
221 wxRadioButton *current;
222
223 i = 0;
224 current = m_radioButtonCycle;
225 while (!current->GetValue())
226 {
227 i++;
228 current = current->NextInCycle();
229 }
230
231 return i;
232 }
233
234 // Sets the radiobox label
235 //
236 void wxRadioBox::SetLabel(const wxString& label)
237 {
238 return wxControl::SetLabel( label );
239 }
240
241 // Sets the label of a given button
242 //
243 void wxRadioBox::SetString(int item,const wxString& label)
244 {
245 int i;
246 wxRadioButton *current;
247
248 if (!IsValid( item ))
249 return;
250
251 i = 0;
252 current = m_radioButtonCycle;
253 while (i != item)
254 {
255 i++;
256 current = current->NextInCycle();
257 }
258
259 return current->SetLabel( label );
260 }
261
262 // Sets a button by passing the desired position. This does not cause
263 // wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted
264 //
265 void wxRadioBox::SetSelection(int item)
266 {
267 int i;
268 wxRadioButton *current;
269
270 if (!IsValid( item ))
271 return;
272
273 i = 0;
274 current = m_radioButtonCycle;
275 while (i != item)
276 {
277 i++;
278 current = current->NextInCycle();
279 }
280
281 current->SetValue( true );
282 }
283
284 // Shows or hides the entire radiobox
285 //
286 bool wxRadioBox::Show(bool show)
287 {
288 int i;
289 wxRadioButton *current;
290
291 current = m_radioButtonCycle;
292 for (i=0; i<m_noItems; i++)
293 {
294 current->Show( show );
295 current = current->NextInCycle();
296 }
297
298 wxControl::Show( show );
299
300 return true;
301 }
302
303 // Shows or hides the given button
304 //
305 bool wxRadioBox::Show(int item, bool show)
306 {
307 int i;
308 wxRadioButton *current;
309
310 if (!IsValid( item ))
311 return false;
312
313 i = 0;
314 current = m_radioButtonCycle;
315 while (i != item)
316 {
317 i++;
318 current = current->NextInCycle();
319 }
320
321 return current->Show( show );
322 }
323
324 // Simulates the effect of the user issuing a command to the item
325 //
326 void wxRadioBox::Command( wxCommandEvent& event )
327 {
328 SetSelection( event.GetInt() );
329 ProcessCommand( event );
330 }
331
332 // Sets the selected button to receive keyboard input
333 //
334 void wxRadioBox::SetFocus()
335 {
336 int i;
337 wxRadioButton *current;
338
339 i = 0;
340 current = m_radioButtonCycle;
341 while (!current->GetValue())
342 {
343 i++;
344 current = current->NextInCycle();
345 }
346
347 current->SetFocus();
348 }
349
350 // Simulates the effect of the user issuing a command to the item
351 //
352 #define RADIO_SIZE 20
353
354 void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
355 {
356 int i;
357 wxRadioButton *current;
358
359 // define the position
360
361 int x_current, y_current;
362 int x_offset, y_offset;
363 int widthOld, heightOld;
364
365 GetSize( &widthOld, &heightOld );
366 GetPosition( &x_current, &y_current );
367
368 x_offset = x;
369 y_offset = y;
370 if (!(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
371 {
372 if (x == wxDefaultCoord)
373 x_offset = x_current;
374 if (y == wxDefaultCoord)
375 y_offset = y_current;
376 }
377
378 // define size
379 int charWidth, charHeight;
380 int maxWidth, maxHeight;
381 int eachWidth[128], eachHeight[128];
382 int totWidth, totHeight;
383
384 GetTextExtent(
385 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
386 &charWidth, &charHeight );
387
388 charWidth /= 52;
389
390 maxWidth = -1;
391 maxHeight = -1;
392 for (i = 0 ; i < m_noItems; i++)
393 {
394 GetTextExtent( GetString( i ), &eachWidth[i], &eachHeight[i] );
395 eachWidth[i] = (int)(eachWidth[i] + RADIO_SIZE);
396 eachHeight[i] = (int)((3 * eachHeight[i]) / 2);
397
398 if (maxWidth < eachWidth[i])
399 maxWidth = eachWidth[i];
400 if (maxHeight < eachHeight[i])
401 maxHeight = eachHeight[i];
402 }
403
404 totHeight = GetRowCount() * maxHeight;
405 totWidth = GetColumnCount() * (maxWidth + charWidth);
406
407 wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) ) ;
408
409 // change the width / height only when specified
410 if ( width == wxDefaultCoord )
411 {
412 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
413 width = sz.x;
414 else
415 width = widthOld;
416 }
417
418 if ( height == wxDefaultCoord )
419 {
420 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
421 height = sz.y;
422 else
423 height = heightOld;
424 }
425
426 wxControl::DoSetSize( x_offset, y_offset, width, height, wxSIZE_AUTO );
427
428 // arrange radio buttons
429 int x_start, y_start;
430
431 x_start = 0;
432 y_start = 0;
433
434 x_offset = x_start;
435 y_offset = y_start;
436
437 current = m_radioButtonCycle;
438 for ( i = 0 ; i < m_noItems; i++)
439 {
440 // not to do for the zero button!
441 if ((i > 0) && ((i % GetMajorDim()) == 0))
442 {
443 if (m_windowStyle & wxRA_SPECIFY_ROWS)
444 {
445 x_offset += maxWidth + charWidth;
446 y_offset = y_start;
447 }
448 else
449 {
450 x_offset = x_start;
451 y_offset += maxHeight ; //+ charHeight / 2
452 }
453 }
454
455 current->SetSize( x_offset, y_offset, eachWidth[i], eachHeight[i]);
456 current = current->NextInCycle();
457
458 if (m_windowStyle & wxRA_SPECIFY_ROWS)
459 y_offset += maxHeight ; // + charHeight / 2
460 else
461 x_offset += maxWidth + charWidth;
462 }
463 }
464
465 wxSize wxRadioBox::DoGetBestSize() const
466 {
467 int charWidth, charHeight;
468 int maxWidth, maxHeight;
469 int eachWidth, eachHeight;
470 int totWidth, totHeight;
471
472 wxFont font = GetFont(); // GetParent()->GetFont()
473 GetTextExtent(
474 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
475 &charWidth, &charHeight, NULL, NULL, &font );
476
477 charWidth /= 52;
478
479 maxWidth = -1;
480 maxHeight = -1;
481
482 for (int i = 0 ; i < m_noItems; i++)
483 {
484 GetTextExtent( GetString( i ), &eachWidth, &eachHeight, NULL, NULL, &font );
485 eachWidth = (int)(eachWidth + RADIO_SIZE);
486 eachHeight = (int)((3 * eachHeight) / 2);
487 if (maxWidth < eachWidth)
488 maxWidth = eachWidth;
489 if (maxHeight < eachHeight)
490 maxHeight = eachHeight;
491 }
492
493 totHeight = GetRowCount() * maxHeight;
494 totWidth = GetColumnCount() * (maxWidth + charWidth);
495
496 wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) );
497 totWidth = sz.x;
498 totHeight = sz.y;
499
500 // handle radio box title as well
501 GetTextExtent( GetLabel(), &eachWidth, NULL );
502 eachWidth = (int)(eachWidth + RADIO_SIZE) + 3 * charWidth;
503 if (totWidth < eachWidth)
504 totWidth = eachWidth;
505
506 return wxSize( totWidth, totHeight );
507 }
508
509 #endif