1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/radiobox.cpp
4 // Author: Stefan Csomor
5 // Modified by: JS Lair (99/11/15) first implementation
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
16 #include "wx/radiobox.h"
19 #include "wx/radiobut.h"
20 #include "wx/arrstr.h"
23 #include "wx/osx/private.h"
25 // regarding layout: note that there are differences in inter-control
26 // spacing between InterfaceBuild and the Human Interface Guidelines, we stick
27 // to the latter, as those are also used eg in the System Preferences Dialogs
29 IMPLEMENT_DYNAMIC_CLASS(wxRadioBox
, wxControl
)
32 BEGIN_EVENT_TABLE(wxRadioBox
, wxControl
)
33 EVT_RADIOBUTTON( wxID_ANY
, wxRadioBox::OnRadioButton
)
37 void wxRadioBox::OnRadioButton( wxCommandEvent
&outer
)
39 if ( outer
.IsChecked() )
41 wxCommandEvent
event( wxEVT_COMMAND_RADIOBOX_SELECTED
, m_windowId
);
42 int i
= GetSelection() ;
44 event
.SetString(GetString(i
));
45 event
.SetEventObject( this );
46 ProcessCommand(event
);
50 wxRadioBox::wxRadioBox()
54 m_radioButtonCycle
= NULL
;
57 wxRadioBox::~wxRadioBox()
61 wxRadioButton
*next
, *current
;
63 current
= m_radioButtonCycle
->NextInCycle();
66 while (current
!= m_radioButtonCycle
)
68 next
= current
->NextInCycle();
78 // Create the radiobox for two-step construction
80 bool wxRadioBox::Create( wxWindow
*parent
,
81 wxWindowID id
, const wxString
& label
,
82 const wxPoint
& pos
, const wxSize
& size
,
83 const wxArrayString
& choices
,
84 int majorDim
, long style
,
85 const wxValidator
& val
, const wxString
& name
)
87 wxCArrayString
chs(choices
);
90 parent
, id
, label
, pos
, size
, chs
.GetCount(),
91 chs
.GetStrings(), majorDim
, style
, val
, name
);
94 bool wxRadioBox::Create( wxWindow
*parent
,
95 wxWindowID id
, const wxString
& label
,
96 const wxPoint
& pos
, const wxSize
& size
,
97 int n
, const wxString choices
[],
98 int majorDim
, long style
,
99 const wxValidator
& val
, const wxString
& name
)
101 m_macIsUserPane
= false ;
103 if ( !wxControl::Create( parent
, id
, pos
, size
, style
, val
, name
) )
108 m_noItems
= (unsigned int)n
;
109 m_noRowsOrCols
= majorDim
;
110 m_radioButtonCycle
= NULL
;
112 SetMajorDim( majorDim
== 0 ? n
: majorDim
, style
);
114 m_labelOrig
= m_label
= label
;
116 m_peer
= wxWidgetImpl::CreateGroupBox( this, parent
, id
, label
, pos
, size
, style
, GetExtraStyle() );
118 for (i
= 0; i
< n
; i
++)
120 wxRadioButton
*radBtn
= new wxRadioButton(
123 GetLabelText(choices
[i
]),
124 wxPoint( 5, 20 * i
+ 10 ),
126 i
== 0 ? wxRB_GROUP
: 0 );
129 m_radioButtonCycle
= radBtn
;
130 // m_radioButtonCycle = radBtn->AddInCycle( m_radioButtonCycle );
134 MacPostControlCreate( pos
, size
);
139 // Enables or disables the entire radiobox
141 bool wxRadioBox::Enable(bool enable
)
143 wxRadioButton
*current
;
145 if (!wxControl::Enable( enable
))
148 current
= m_radioButtonCycle
;
149 for (unsigned int i
= 0; i
< m_noItems
; i
++)
151 current
->Enable( enable
);
152 current
= current
->NextInCycle();
158 // Enables or disables an given button
160 bool wxRadioBox::Enable(unsigned int item
, bool enable
)
162 if (!IsValid( item
))
166 wxRadioButton
*current
= m_radioButtonCycle
;
170 current
= current
->NextInCycle();
173 return current
->Enable( enable
);
176 bool wxRadioBox::IsItemEnabled(unsigned int item
) const
178 if (!IsValid( item
))
182 wxRadioButton
*current
= m_radioButtonCycle
;
186 current
= current
->NextInCycle();
189 return current
->IsEnabled();
192 // Returns the radiobox label
194 wxString
wxRadioBox::GetLabel() const
196 return wxControl::GetLabel();
199 // Returns the label for the given button
201 wxString
wxRadioBox::GetString(unsigned int item
) const
203 wxRadioButton
*current
;
205 if (!IsValid( item
))
206 return wxEmptyString
;
209 current
= m_radioButtonCycle
;
213 current
= current
->NextInCycle();
216 return current
->GetLabel();
219 // Returns the zero-based position of the selected button
221 int wxRadioBox::GetSelection() const
224 wxRadioButton
*current
;
227 current
= m_radioButtonCycle
;
228 while (!current
->GetValue())
231 current
= current
->NextInCycle();
237 // Sets the radiobox label
239 void wxRadioBox::SetLabel(const wxString
& label
)
241 return wxControl::SetLabel( label
);
244 // Sets the label of a given button
246 void wxRadioBox::SetString(unsigned int item
,const wxString
& label
)
248 if (!IsValid( item
))
252 wxRadioButton
*current
= m_radioButtonCycle
;
256 current
= current
->NextInCycle();
259 return current
->SetLabel( label
);
262 // Sets a button by passing the desired position. This does not cause
263 // wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted
265 void wxRadioBox::SetSelection(int item
)
268 wxRadioButton
*current
;
270 if (!IsValid( item
))
274 current
= m_radioButtonCycle
;
278 current
= current
->NextInCycle();
281 current
->SetValue( true );
284 // Shows or hides the entire radiobox
286 bool wxRadioBox::Show(bool show
)
288 wxRadioButton
*current
;
290 current
= m_radioButtonCycle
;
291 for (unsigned int i
=0; i
<m_noItems
; i
++)
293 current
->Show( show
);
294 current
= current
->NextInCycle();
297 wxControl::Show( show
);
302 // Shows or hides the given button
304 bool wxRadioBox::Show(unsigned int item
, bool show
)
306 if (!IsValid( item
))
310 wxRadioButton
*current
= m_radioButtonCycle
;
314 current
= current
->NextInCycle();
317 return current
->Show( show
);
320 bool wxRadioBox::IsItemShown(unsigned int item
) const
322 if (!IsValid( item
))
326 wxRadioButton
*current
= m_radioButtonCycle
;
330 current
= current
->NextInCycle();
333 return current
->IsShown();
337 // Simulates the effect of the user issuing a command to the item
339 void wxRadioBox::Command( wxCommandEvent
& event
)
341 SetSelection( event
.GetInt() );
342 ProcessCommand( event
);
345 // Sets the selected button to receive keyboard input
347 void wxRadioBox::SetFocus()
349 wxRadioButton
*current
;
351 current
= m_radioButtonCycle
;
352 while (!current
->GetValue())
354 current
= current
->NextInCycle();
360 // Simulates the effect of the user issuing a command to the item
363 #define RADIO_SIZE 20
365 // Cocoa has an additional border are of about 3 pixels
366 #define RADIO_SIZE 23
369 void wxRadioBox::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
372 wxRadioButton
*current
;
374 // define the position
376 int x_current
, y_current
;
377 int x_offset
, y_offset
;
378 int widthOld
, heightOld
;
380 GetSize( &widthOld
, &heightOld
);
381 GetPosition( &x_current
, &y_current
);
385 if (!(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
387 if (x
== wxDefaultCoord
)
388 x_offset
= x_current
;
389 if (y
== wxDefaultCoord
)
390 y_offset
= y_current
;
394 int charWidth
, charHeight
;
395 int maxWidth
, maxHeight
;
396 int eachWidth
[128], eachHeight
[128];
397 int totWidth
, totHeight
;
400 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
401 &charWidth
, &charHeight
);
407 wxSize bestSizeRadio
;
408 if ( m_radioButtonCycle
)
409 bestSizeRadio
= m_radioButtonCycle
->GetBestSize();
411 for (unsigned int i
= 0 ; i
< m_noItems
; i
++)
413 GetTextExtent(GetString(i
), &eachWidth
[i
], &eachHeight
[i
] );
414 eachWidth
[i
] = eachWidth
[i
] + RADIO_SIZE
;
415 eachHeight
[i
] = wxMax( eachHeight
[i
], bestSizeRadio
.y
);
417 if (maxWidth
< eachWidth
[i
])
418 maxWidth
= eachWidth
[i
];
419 if (maxHeight
< eachHeight
[i
])
420 maxHeight
= eachHeight
[i
];
423 // according to HIG (official space - 3 Pixels Diff between Frame and Layout size)
425 if ( GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
428 totHeight
= GetRowCount() * maxHeight
+ (GetRowCount() - 1) * space
;
429 totWidth
= GetColumnCount() * (maxWidth
+ charWidth
);
431 wxSize sz
= DoGetSizeFromClientSize( wxSize( totWidth
, totHeight
) ) ;
433 // change the width / height only when specified
434 if ( width
== wxDefaultCoord
)
436 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
442 if ( height
== wxDefaultCoord
)
444 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
450 wxControl::DoSetSize( x_offset
, y_offset
, width
, height
, wxSIZE_AUTO
);
452 // arrange radio buttons
453 int x_start
, y_start
;
455 x_start
= ( width
- sz
.x
) / 2;
456 y_start
= ( height
- sz
.y
) / 2;
461 current
= m_radioButtonCycle
;
462 for (i
= 0 ; i
< (int)m_noItems
; i
++)
464 // not to do for the zero button!
465 if ((i
> 0) && ((i
% GetMajorDim()) == 0))
467 if (m_windowStyle
& wxRA_SPECIFY_ROWS
)
469 x_offset
+= maxWidth
+ charWidth
;
475 y_offset
+= maxHeight
+ space
;
479 current
->SetSize( x_offset
, y_offset
, eachWidth
[i
], eachHeight
[i
] );
480 current
= current
->NextInCycle();
482 if (m_windowStyle
& wxRA_SPECIFY_ROWS
)
483 y_offset
+= maxHeight
+ space
;
485 x_offset
+= maxWidth
+ charWidth
;
489 wxSize
wxRadioBox::DoGetBestSize() const
491 int charWidth
, charHeight
;
492 int maxWidth
, maxHeight
;
493 int eachWidth
, eachHeight
;
494 int totWidth
, totHeight
;
496 wxFont font
= GetFont(); // GetParent()->GetFont()
498 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
499 &charWidth
, &charHeight
, NULL
, NULL
, &font
);
506 wxSize bestSizeRadio
;
507 if ( m_radioButtonCycle
)
508 bestSizeRadio
= m_radioButtonCycle
->GetBestSize();
510 for (unsigned int i
= 0 ; i
< m_noItems
; i
++)
512 GetTextExtent(GetString(i
), &eachWidth
, &eachHeight
, NULL
, NULL
, &font
);
513 eachWidth
= (eachWidth
+ RADIO_SIZE
);
514 eachHeight
= wxMax(eachHeight
, bestSizeRadio
.y
);
515 if (maxWidth
< eachWidth
)
516 maxWidth
= eachWidth
;
517 if (maxHeight
< eachHeight
)
518 maxHeight
= eachHeight
;
521 // according to HIG (official space - 3 Pixels Diff between Frame and Layout size)
523 if ( GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
526 totHeight
= GetRowCount() * maxHeight
+ (GetRowCount() - 1) * space
;
527 totWidth
= GetColumnCount() * (maxWidth
+ charWidth
);
529 wxSize sz
= DoGetSizeFromClientSize( wxSize( totWidth
, totHeight
) );
533 // optimum size is an additional 5 pt border to all sides
537 // handle radio box title as well
538 GetTextExtent( GetLabel(), &eachWidth
, NULL
);
539 eachWidth
= (int)(eachWidth
+ RADIO_SIZE
) + 3 * charWidth
;
540 if (totWidth
< eachWidth
)
541 totWidth
= eachWidth
;
543 return wxSize( totWidth
, totHeight
);
546 bool wxRadioBox::SetFont(const wxFont
& font
)
548 bool retval
= wxWindowBase::SetFont( font
);
550 // dont' update the native control, it has its own small font
552 // should we iterate over the children ?
557 #endif // wxUSE_RADIOBOX