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