1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/radiobox_osx.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
)
103 if ( !wxControl::Create( parent
, id
, pos
, size
, style
, val
, name
) )
106 // during construction we must keep this at 0, otherwise GetBestSize fails
108 m_noRowsOrCols
= majorDim
;
109 m_radioButtonCycle
= NULL
;
111 SetMajorDim( majorDim
== 0 ? n
: majorDim
, style
);
113 m_labelOrig
= m_label
= label
;
115 SetPeer(wxWidgetImpl::CreateGroupBox( this, parent
, id
, label
, pos
, size
, style
, GetExtraStyle() ));
117 for (int i
= 0; i
< n
; i
++)
119 wxRadioButton
*radBtn
= new wxRadioButton(
122 GetLabelText(choices
[i
]),
123 wxPoint( 5, 20 * i
+ 10 ),
125 i
== 0 ? wxRB_GROUP
: 0 );
128 m_radioButtonCycle
= radBtn
;
129 // m_radioButtonCycle = radBtn->AddInCycle( m_radioButtonCycle );
132 // as all radiobuttons have been set-up, set the correct dimensions
133 m_noItems
= (unsigned int)n
;
134 SetMajorDim( majorDim
== 0 ? n
: majorDim
, style
);
137 InvalidateBestSize();
138 SetInitialSize( size
);
139 MacPostControlCreate( pos
, size
);
144 // Enables or disables the entire radiobox
146 bool wxRadioBox::Enable(bool enable
)
148 wxRadioButton
*current
;
150 if (!wxControl::Enable( enable
))
153 current
= m_radioButtonCycle
;
154 for (unsigned int i
= 0; i
< m_noItems
; i
++)
156 current
->Enable( enable
);
157 current
= current
->NextInCycle();
163 // Enables or disables an given button
165 bool wxRadioBox::Enable(unsigned int item
, bool enable
)
167 if (!IsValid( item
))
171 wxRadioButton
*current
= m_radioButtonCycle
;
175 current
= current
->NextInCycle();
178 return current
->Enable( enable
);
181 bool wxRadioBox::IsItemEnabled(unsigned int item
) const
183 if (!IsValid( item
))
187 wxRadioButton
*current
= m_radioButtonCycle
;
191 current
= current
->NextInCycle();
194 return current
->IsEnabled();
197 // Returns the radiobox label
199 wxString
wxRadioBox::GetLabel() const
201 return wxControl::GetLabel();
204 // Returns the label for the given button
206 wxString
wxRadioBox::GetString(unsigned int item
) const
208 wxRadioButton
*current
;
210 if (!IsValid( item
))
211 return wxEmptyString
;
214 current
= m_radioButtonCycle
;
218 current
= current
->NextInCycle();
221 return current
->GetLabel();
224 // Returns the zero-based position of the selected button
226 int wxRadioBox::GetSelection() const
229 wxRadioButton
*current
;
232 current
= m_radioButtonCycle
;
233 while (!current
->GetValue())
236 current
= current
->NextInCycle();
242 // Sets the radiobox label
244 void wxRadioBox::SetLabel(const wxString
& label
)
246 return wxControl::SetLabel( label
);
249 // Sets the label of a given button
251 void wxRadioBox::SetString(unsigned int item
,const wxString
& label
)
253 if (!IsValid( item
))
257 wxRadioButton
*current
= m_radioButtonCycle
;
261 current
= current
->NextInCycle();
264 return current
->SetLabel( label
);
267 // Sets a button by passing the desired position. This does not cause
268 // wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted
270 void wxRadioBox::SetSelection(int item
)
273 wxRadioButton
*current
;
275 if (!IsValid( item
))
279 current
= m_radioButtonCycle
;
283 current
= current
->NextInCycle();
286 current
->SetValue( true );
289 // Shows or hides the entire radiobox
291 bool wxRadioBox::Show(bool show
)
293 wxRadioButton
*current
;
295 current
= m_radioButtonCycle
;
296 for (unsigned int i
=0; i
<m_noItems
; i
++)
298 current
->Show( show
);
299 current
= current
->NextInCycle();
302 wxControl::Show( show
);
307 // Shows or hides the given button
309 bool wxRadioBox::Show(unsigned int item
, bool show
)
311 if (!IsValid( item
))
315 wxRadioButton
*current
= m_radioButtonCycle
;
319 current
= current
->NextInCycle();
322 return current
->Show( show
);
325 bool wxRadioBox::IsItemShown(unsigned int item
) const
327 if (!IsValid( item
))
331 wxRadioButton
*current
= m_radioButtonCycle
;
335 current
= current
->NextInCycle();
338 return current
->IsShown();
342 // Simulates the effect of the user issuing a command to the item
344 void wxRadioBox::Command( wxCommandEvent
& event
)
346 SetSelection( event
.GetInt() );
347 ProcessCommand( event
);
350 // Sets the selected button to receive keyboard input
352 void wxRadioBox::SetFocus()
354 wxRadioButton
*current
;
356 current
= m_radioButtonCycle
;
357 while (!current
->GetValue())
359 current
= current
->NextInCycle();
365 // Simulates the effect of the user issuing a command to the item
368 #define RADIO_SIZE 20
370 // Cocoa has an additional border are of about 3 pixels
371 #define RADIO_SIZE 23
374 void wxRadioBox::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
377 wxRadioButton
*current
;
379 // define the position
381 int x_current
, y_current
;
382 int x_offset
, y_offset
;
383 int widthOld
, heightOld
;
385 GetSize( &widthOld
, &heightOld
);
386 GetPosition( &x_current
, &y_current
);
390 if (!(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
392 if (x
== wxDefaultCoord
)
393 x_offset
= x_current
;
394 if (y
== wxDefaultCoord
)
395 y_offset
= y_current
;
399 int charWidth
, charHeight
;
400 int maxWidth
, maxHeight
;
401 int eachWidth
[128], eachHeight
[128];
402 int totWidth
, totHeight
;
405 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
406 &charWidth
, &charHeight
);
412 wxSize bestSizeRadio
;
413 if ( m_radioButtonCycle
)
414 bestSizeRadio
= m_radioButtonCycle
->GetBestSize();
416 for (unsigned int i
= 0 ; i
< m_noItems
; i
++)
418 GetTextExtent(GetString(i
), &eachWidth
[i
], &eachHeight
[i
] );
419 eachWidth
[i
] = eachWidth
[i
] + RADIO_SIZE
;
420 eachHeight
[i
] = wxMax( eachHeight
[i
], bestSizeRadio
.y
);
422 if (maxWidth
< eachWidth
[i
])
423 maxWidth
= eachWidth
[i
];
424 if (maxHeight
< eachHeight
[i
])
425 maxHeight
= eachHeight
[i
];
428 // according to HIG (official space - 3 Pixels Diff between Frame and Layout size)
430 if ( GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
433 totHeight
= GetRowCount() * maxHeight
+ (GetRowCount() - 1) * space
;
434 totWidth
= GetColumnCount() * (maxWidth
+ charWidth
);
436 wxSize sz
= DoGetSizeFromClientSize( wxSize( totWidth
, totHeight
) ) ;
438 // change the width / height only when specified
439 if ( width
== wxDefaultCoord
)
441 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
447 if ( height
== wxDefaultCoord
)
449 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
455 wxControl::DoSetSize( x_offset
, y_offset
, width
, height
, wxSIZE_AUTO
);
457 // arrange radio buttons
458 int x_start
, y_start
;
460 x_start
= ( width
- sz
.x
) / 2;
461 y_start
= ( height
- sz
.y
) / 2;
466 current
= m_radioButtonCycle
;
467 for (i
= 0 ; i
< (int)m_noItems
; i
++)
469 // not to do for the zero button!
470 if ((i
> 0) && ((i
% GetMajorDim()) == 0))
472 if (m_windowStyle
& wxRA_SPECIFY_ROWS
)
474 x_offset
+= maxWidth
+ charWidth
;
480 y_offset
+= maxHeight
+ space
;
484 current
->SetSize( x_offset
, y_offset
, eachWidth
[i
], eachHeight
[i
] );
485 current
= current
->NextInCycle();
487 if (m_windowStyle
& wxRA_SPECIFY_ROWS
)
488 y_offset
+= maxHeight
+ space
;
490 x_offset
+= maxWidth
+ charWidth
;
494 wxSize
wxRadioBox::DoGetBestSize() const
496 int charWidth
, charHeight
;
497 int maxWidth
, maxHeight
;
498 int eachWidth
, eachHeight
;
499 int totWidth
, totHeight
;
501 wxFont font
= GetFont(); // GetParent()->GetFont()
503 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
504 &charWidth
, &charHeight
, NULL
, NULL
, &font
);
511 wxSize bestSizeRadio
;
512 if ( m_radioButtonCycle
)
513 bestSizeRadio
= m_radioButtonCycle
->GetBestSize();
515 for (unsigned int i
= 0 ; i
< m_noItems
; i
++)
517 GetTextExtent(GetString(i
), &eachWidth
, &eachHeight
, NULL
, NULL
, &font
);
518 eachWidth
= (eachWidth
+ RADIO_SIZE
);
519 eachHeight
= wxMax(eachHeight
, bestSizeRadio
.y
);
520 if (maxWidth
< eachWidth
)
521 maxWidth
= eachWidth
;
522 if (maxHeight
< eachHeight
)
523 maxHeight
= eachHeight
;
526 // according to HIG (official space - 3 Pixels Diff between Frame and Layout size)
528 if ( GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
531 totHeight
= GetRowCount() * maxHeight
+ (GetRowCount() - 1) * space
;
532 totWidth
= GetColumnCount() * (maxWidth
+ charWidth
);
534 wxSize sz
= DoGetSizeFromClientSize( wxSize( totWidth
, totHeight
) );
538 // optimum size is an additional 5 pt border to all sides
542 // handle radio box title as well
543 GetTextExtent( GetLabel(), &eachWidth
, NULL
);
544 eachWidth
= (int)(eachWidth
+ RADIO_SIZE
) + 3 * charWidth
;
545 if (totWidth
< eachWidth
)
546 totWidth
= eachWidth
;
548 return wxSize( totWidth
, totHeight
);
551 bool wxRadioBox::SetFont(const wxFont
& font
)
553 bool retval
= wxWindowBase::SetFont( font
);
555 // dont' update the native control, it has its own small font
557 // should we iterate over the children ?
562 #endif // wxUSE_RADIOBOX