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