]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/radiobox.cpp
clean-up and fix
[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 = (unsigned int)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 (unsigned int 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(unsigned int item, bool enable)
165 {
166 if (!IsValid( item ))
167 return false;
168
169 unsigned int i = 0;
170 wxRadioButton *current = m_radioButtonCycle;
171 while (i != item)
172 {
173 i++;
174 current = current->NextInCycle();
175 }
176
177 return current->Enable( enable );
178 }
179
180 // Returns the radiobox label
181 //
182 wxString wxRadioBox::GetLabel() const
183 {
184 return wxControl::GetLabel();
185 }
186
187 // Returns the label for the given button
188 //
189 wxString wxRadioBox::GetString(unsigned int item) const
190 {
191 wxRadioButton *current;
192
193 if (!IsValid( item ))
194 return wxEmptyString;
195
196 unsigned int i = 0;
197 current = m_radioButtonCycle;
198 while (i != item)
199 {
200 i++;
201 current = current->NextInCycle();
202 }
203
204 return current->GetLabel();
205 }
206
207 // Returns the zero-based position of the selected button
208 //
209 int wxRadioBox::GetSelection() const
210 {
211 int i;
212 wxRadioButton *current;
213
214 i = 0;
215 current = m_radioButtonCycle;
216 while (!current->GetValue())
217 {
218 i++;
219 current = current->NextInCycle();
220 }
221
222 return i;
223 }
224
225 // Sets the radiobox label
226 //
227 void wxRadioBox::SetLabel(const wxString& label)
228 {
229 return wxControl::SetLabel( label );
230 }
231
232 // Sets the label of a given button
233 //
234 void wxRadioBox::SetString(unsigned int item,const wxString& label)
235 {
236 if (!IsValid( item ))
237 return;
238
239 unsigned int i = 0;
240 wxRadioButton *current = m_radioButtonCycle;
241 while (i != item)
242 {
243 i++;
244 current = current->NextInCycle();
245 }
246
247 return current->SetLabel( label );
248 }
249
250 // Sets a button by passing the desired position. This does not cause
251 // wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted
252 //
253 void wxRadioBox::SetSelection(int item)
254 {
255 int i;
256 wxRadioButton *current;
257
258 if (!IsValid( item ))
259 return;
260
261 i = 0;
262 current = m_radioButtonCycle;
263 while (i != item)
264 {
265 i++;
266 current = current->NextInCycle();
267 }
268
269 current->SetValue( true );
270 }
271
272 // Shows or hides the entire radiobox
273 //
274 bool wxRadioBox::Show(bool show)
275 {
276 wxRadioButton *current;
277
278 current = m_radioButtonCycle;
279 for (unsigned int i=0; i<m_noItems; i++)
280 {
281 current->Show( show );
282 current = current->NextInCycle();
283 }
284
285 wxControl::Show( show );
286
287 return true;
288 }
289
290 // Shows or hides the given button
291 //
292 bool wxRadioBox::Show(unsigned int item, bool show)
293 {
294 if (!IsValid( item ))
295 return false;
296
297 unsigned int i = 0;
298 wxRadioButton *current = m_radioButtonCycle;
299 while (i != item)
300 {
301 i++;
302 current = current->NextInCycle();
303 }
304
305 return current->Show( show );
306 }
307
308 // Simulates the effect of the user issuing a command to the item
309 //
310 void wxRadioBox::Command( wxCommandEvent& event )
311 {
312 SetSelection( event.GetInt() );
313 ProcessCommand( event );
314 }
315
316 // Sets the selected button to receive keyboard input
317 //
318 void wxRadioBox::SetFocus()
319 {
320 int i;
321 wxRadioButton *current;
322
323 i = 0;
324 current = m_radioButtonCycle;
325 while (!current->GetValue())
326 {
327 i++;
328 current = current->NextInCycle();
329 }
330
331 current->SetFocus();
332 }
333
334 // Simulates the effect of the user issuing a command to the item
335 //
336 #define RADIO_SIZE 20
337
338 void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
339 {
340 int i;
341 wxRadioButton *current;
342
343 // define the position
344
345 int x_current, y_current;
346 int x_offset, y_offset;
347 int widthOld, heightOld;
348
349 GetSize( &widthOld, &heightOld );
350 GetPosition( &x_current, &y_current );
351
352 x_offset = x;
353 y_offset = y;
354 if (!(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
355 {
356 if (x == wxDefaultCoord)
357 x_offset = x_current;
358 if (y == wxDefaultCoord)
359 y_offset = y_current;
360 }
361
362 // define size
363 int charWidth, charHeight;
364 int maxWidth, maxHeight;
365 int eachWidth[128], eachHeight[128];
366 int totWidth, totHeight;
367
368 GetTextExtent(
369 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
370 &charWidth, &charHeight );
371
372 charWidth /= 52;
373
374 maxWidth = -1;
375 maxHeight = -1;
376 for (unsigned int i = 0 ; i < m_noItems; i++)
377 {
378 GetTextExtent(GetString(i), &eachWidth[i], &eachHeight[i] );
379 eachWidth[i] = (int)(eachWidth[i] + RADIO_SIZE);
380 eachHeight[i] = (int)((3 * eachHeight[i]) / 2);
381
382 if (maxWidth < eachWidth[i])
383 maxWidth = eachWidth[i];
384 if (maxHeight < eachHeight[i])
385 maxHeight = eachHeight[i];
386 }
387
388 totHeight = GetRowCount() * maxHeight;
389 totWidth = GetColumnCount() * (maxWidth + charWidth);
390
391 wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) ) ;
392
393 // change the width / height only when specified
394 if ( width == wxDefaultCoord )
395 {
396 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
397 width = sz.x;
398 else
399 width = widthOld;
400 }
401
402 if ( height == wxDefaultCoord )
403 {
404 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
405 height = sz.y;
406 else
407 height = heightOld;
408 }
409
410 wxControl::DoSetSize( x_offset, y_offset, width, height, wxSIZE_AUTO );
411
412 // arrange radio buttons
413 int x_start, y_start;
414
415 x_start = 0;
416 y_start = 0;
417
418 x_offset = x_start;
419 y_offset = y_start;
420
421 current = m_radioButtonCycle;
422 for (i = 0 ; i < (int)m_noItems; i++)
423 {
424 // not to do for the zero button!
425 if ((i > 0) && ((i % GetMajorDim()) == 0))
426 {
427 if (m_windowStyle & wxRA_SPECIFY_ROWS)
428 {
429 x_offset += maxWidth + charWidth;
430 y_offset = y_start;
431 }
432 else
433 {
434 x_offset = x_start;
435 y_offset += maxHeight ; //+ charHeight / 2
436 }
437 }
438
439 current->SetSize( x_offset, y_offset, eachWidth[i], eachHeight[i]);
440 current = current->NextInCycle();
441
442 if (m_windowStyle & wxRA_SPECIFY_ROWS)
443 y_offset += maxHeight ; // + charHeight / 2
444 else
445 x_offset += maxWidth + charWidth;
446 }
447 }
448
449 wxSize wxRadioBox::DoGetBestSize() const
450 {
451 int charWidth, charHeight;
452 int maxWidth, maxHeight;
453 int eachWidth, eachHeight;
454 int totWidth, totHeight;
455
456 wxFont font = GetFont(); // GetParent()->GetFont()
457 GetTextExtent(
458 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
459 &charWidth, &charHeight, NULL, NULL, &font );
460
461 charWidth /= 52;
462
463 maxWidth = -1;
464 maxHeight = -1;
465
466 for (unsigned int i = 0 ; i < m_noItems; i++)
467 {
468 GetTextExtent(GetString(i), &eachWidth, &eachHeight, NULL, NULL, &font );
469 eachWidth = (int)(eachWidth + RADIO_SIZE);
470 eachHeight = (int)((3 * eachHeight) / 2);
471 if (maxWidth < eachWidth)
472 maxWidth = eachWidth;
473 if (maxHeight < eachHeight)
474 maxHeight = eachHeight;
475 }
476
477 totHeight = GetRowCount() * maxHeight;
478 totWidth = GetColumnCount() * (maxWidth + charWidth);
479
480 wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) );
481 totWidth = sz.x;
482 totHeight = sz.y;
483
484 // handle radio box title as well
485 GetTextExtent( GetLabel(), &eachWidth, NULL );
486 eachWidth = (int)(eachWidth + RADIO_SIZE) + 3 * charWidth;
487 if (totWidth < eachWidth)
488 totWidth = eachWidth;
489
490 return wxSize( totWidth, totHeight );
491 }
492
493 #endif // wxUSE_RADIOBOX