1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/carbon/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/mac/uma.h" 
  25 IMPLEMENT_DYNAMIC_CLASS(wxRadioBox
, wxControl
) 
  28 BEGIN_EVENT_TABLE(wxRadioBox
, wxControl
) 
  29     EVT_RADIOBUTTON( wxID_ANY 
, wxRadioBox::OnRadioButton 
) 
  33 void wxRadioBox::OnRadioButton( wxCommandEvent 
&outer 
) 
  35     if ( outer
.IsChecked() ) 
  37         wxCommandEvent 
event( wxEVT_COMMAND_RADIOBOX_SELECTED
, m_windowId 
); 
  38         int i 
= GetSelection() ; 
  40         event
.SetString(GetString(i
)); 
  41         event
.SetEventObject( this ); 
  42         ProcessCommand(event
); 
  46 wxRadioBox::wxRadioBox() 
  50     m_radioButtonCycle 
= NULL
; 
  53 wxRadioBox::~wxRadioBox() 
  55     m_isBeingDeleted 
= true; 
  57     wxRadioButton 
*next
, *current
; 
  59     current 
= m_radioButtonCycle
->NextInCycle(); 
  62         while (current 
!= m_radioButtonCycle
) 
  64             next 
= current
->NextInCycle(); 
  74 // Create the radiobox for two-step construction 
  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 
) 
  83     wxCArrayString 
chs(choices
); 
  86         parent
, id
, label
, pos
, size
, chs
.GetCount(), 
  87         chs
.GetStrings(), majorDim
, style
, val
, name
); 
  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 
) 
  97     m_macIsUserPane 
= false ; 
  99     if ( !wxControl::Create( parent
, id
, pos
, size
, style
, val
, name 
) ) 
 104     m_noItems 
= (unsigned int)n
; 
 105     m_noRowsOrCols 
= majorDim
; 
 106     m_radioButtonCycle 
= NULL
; 
 108     SetMajorDim( majorDim 
== 0 ? n 
: majorDim
, style 
); 
 110     m_labelOrig 
= m_label 
= label
; 
 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; 
 118     m_peer 
= new wxMacControl( this ); 
 120     OSStatus err 
= CreateGroupBoxControl( 
 121         MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), 
 122         &bounds
, CFSTR("") , true /*primary*/, 
 123         m_peer
->GetControlRefAddr() ); 
 126     for (i 
= 0; i 
< n
; i
++) 
 128         wxRadioButton 
*radBtn 
= new wxRadioButton( 
 131             GetLabelText(choices
[i
]), 
 132             wxPoint( 5, 20 * i 
+ 10 ), 
 134             i 
== 0 ? wxRB_GROUP 
: 0 ); 
 137             m_radioButtonCycle 
= radBtn
; 
 138 //        m_radioButtonCycle = radBtn->AddInCycle( m_radioButtonCycle ); 
 142     MacPostControlCreate( pos
, size 
); 
 147 // Enables or disables the entire radiobox 
 149 bool wxRadioBox::Enable(bool enable
) 
 151     wxRadioButton 
*current
; 
 153     if (!wxControl::Enable( enable 
)) 
 156     current 
= m_radioButtonCycle
; 
 157     for (unsigned int i 
= 0; i 
< m_noItems
; i
++) 
 159         current
->Enable( enable 
); 
 160         current 
= current
->NextInCycle(); 
 166 // Enables or disables an given button 
 168 bool wxRadioBox::Enable(unsigned int item
, bool enable
) 
 170     if (!IsValid( item 
)) 
 174     wxRadioButton 
*current 
= m_radioButtonCycle
; 
 178         current 
= current
->NextInCycle(); 
 181     return current
->Enable( enable 
); 
 184 bool wxRadioBox::IsItemEnabled(unsigned int item
) const 
 186     if (!IsValid( item 
)) 
 190     wxRadioButton 
*current 
= m_radioButtonCycle
; 
 194         current 
= current
->NextInCycle(); 
 197     return current
->IsEnabled(); 
 200 // Returns the radiobox label 
 202 wxString 
wxRadioBox::GetLabel() const 
 204     return wxControl::GetLabel(); 
 207 // Returns the label for the given button 
 209 wxString 
wxRadioBox::GetString(unsigned int item
) const 
 211     wxRadioButton 
*current
; 
 213     if (!IsValid( item 
)) 
 214         return wxEmptyString
; 
 217     current 
= m_radioButtonCycle
; 
 221         current 
= current
->NextInCycle(); 
 224     return current
->GetLabel(); 
 227 // Returns the zero-based position of the selected button 
 229 int wxRadioBox::GetSelection() const 
 232     wxRadioButton 
*current
; 
 235     current 
= m_radioButtonCycle
; 
 236     while (!current
->GetValue()) 
 239         current 
= current
->NextInCycle(); 
 245 // Sets the radiobox label 
 247 void wxRadioBox::SetLabel(const wxString
& label
) 
 249     return wxControl::SetLabel( label 
); 
 252 // Sets the label of a given button 
 254 void wxRadioBox::SetString(unsigned int item
,const wxString
& label
) 
 256     if (!IsValid( item 
)) 
 260     wxRadioButton 
*current 
= m_radioButtonCycle
; 
 264         current 
= current
->NextInCycle(); 
 267     return current
->SetLabel( label 
); 
 270 // Sets a button by passing the desired position. This does not cause 
 271 // wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted 
 273 void wxRadioBox::SetSelection(int item
) 
 276     wxRadioButton 
*current
; 
 278     if (!IsValid( item 
)) 
 282     current 
= m_radioButtonCycle
; 
 286         current 
= current
->NextInCycle(); 
 289     current
->SetValue( true ); 
 292 // Shows or hides the entire radiobox 
 294 bool wxRadioBox::Show(bool show
) 
 296     wxRadioButton 
*current
; 
 298     current 
= m_radioButtonCycle
; 
 299     for (unsigned int i
=0; i
<m_noItems
; i
++) 
 301         current
->Show( show 
); 
 302         current 
= current
->NextInCycle(); 
 305     wxControl::Show( show 
); 
 310 // Shows or hides the given button 
 312 bool wxRadioBox::Show(unsigned int item
, bool show
) 
 314     if (!IsValid( item 
)) 
 318     wxRadioButton 
*current 
= m_radioButtonCycle
; 
 322         current 
= current
->NextInCycle(); 
 325     return current
->Show( show 
); 
 328 bool wxRadioBox::IsItemShown(unsigned int item
) const 
 330     if (!IsValid( item 
)) 
 334     wxRadioButton 
*current 
= m_radioButtonCycle
; 
 338         current 
= current
->NextInCycle(); 
 341     return current
->IsShown(); 
 345 // Simulates the effect of the user issuing a command to the item 
 347 void wxRadioBox::Command( wxCommandEvent
& event 
) 
 349     SetSelection( event
.GetInt() ); 
 350     ProcessCommand( event 
); 
 353 // Sets the selected button to receive keyboard input 
 355 void wxRadioBox::SetFocus() 
 357     wxRadioButton 
*current
; 
 359     current 
= m_radioButtonCycle
; 
 360     while (!current
->GetValue()) 
 362         current 
= current
->NextInCycle(); 
 368 // Simulates the effect of the user issuing a command to the item 
 370 #define RADIO_SIZE 20 
 372 void wxRadioBox::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
 375     wxRadioButton 
*current
; 
 377     // define the position 
 379     int x_current
, y_current
; 
 380     int x_offset
, y_offset
; 
 381     int widthOld
, heightOld
; 
 383     GetSize( &widthOld
, &heightOld 
); 
 384     GetPosition( &x_current
, &y_current 
); 
 388     if (!(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 390         if (x 
== wxDefaultCoord
) 
 391             x_offset 
= x_current
; 
 392         if (y 
== wxDefaultCoord
) 
 393             y_offset 
= y_current
; 
 397     int charWidth
, charHeight
; 
 398     int maxWidth
, maxHeight
; 
 399     int eachWidth
[128], eachHeight
[128]; 
 400     int totWidth
, totHeight
; 
 403         wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 
 404         &charWidth
, &charHeight 
); 
 410     for (unsigned int i 
= 0 ; i 
< m_noItems
; i
++) 
 412         GetTextExtent(GetString(i
), &eachWidth
[i
], &eachHeight
[i
] ); 
 413         eachWidth
[i
] = (int)(eachWidth
[i
] + RADIO_SIZE
); 
 414         eachHeight
[i
] = (int)((3 * eachHeight
[i
]) / 2); 
 416         if (maxWidth 
< eachWidth
[i
]) 
 417             maxWidth 
= eachWidth
[i
]; 
 418         if (maxHeight 
< eachHeight
[i
]) 
 419             maxHeight 
= eachHeight
[i
]; 
 422     totHeight 
= GetRowCount() * maxHeight
; 
 423     totWidth  
= GetColumnCount() * (maxWidth 
+ charWidth
); 
 425     wxSize sz 
= DoGetSizeFromClientSize( wxSize( totWidth
, totHeight 
) ) ; 
 427     // change the width / height only when specified 
 428     if ( width 
== wxDefaultCoord 
) 
 430         if ( sizeFlags 
& wxSIZE_AUTO_WIDTH 
) 
 436     if ( height 
== wxDefaultCoord 
) 
 438         if ( sizeFlags 
& wxSIZE_AUTO_HEIGHT 
) 
 444     wxControl::DoSetSize( x_offset
, y_offset
, width
, height
, wxSIZE_AUTO 
); 
 446     // arrange radio buttons 
 447     int x_start
, y_start
; 
 455     current 
= m_radioButtonCycle
; 
 456     for (i 
= 0 ; i 
< (int)m_noItems
; i
++) 
 458         // not to do for the zero button! 
 459         if ((i 
> 0) && ((i 
% GetMajorDim()) == 0)) 
 461             if (m_windowStyle 
& wxRA_SPECIFY_ROWS
) 
 463                 x_offset 
+= maxWidth 
+ charWidth
; 
 469                 y_offset 
+= maxHeight 
; //+ charHeight / 2 
 473         current
->SetSize( x_offset
, y_offset
, eachWidth
[i
], eachHeight
[i
]); 
 474         current 
= current
->NextInCycle(); 
 476         if (m_windowStyle 
& wxRA_SPECIFY_ROWS
) 
 477             y_offset 
+= maxHeight 
; // + charHeight / 2 
 479             x_offset 
+= maxWidth 
+ charWidth
; 
 483 wxSize 
wxRadioBox::DoGetBestSize() const 
 485     int charWidth
, charHeight
; 
 486     int maxWidth
, maxHeight
; 
 487     int eachWidth
, eachHeight
; 
 488     int totWidth
, totHeight
; 
 490     wxFont font 
= GetFont(); // GetParent()->GetFont() 
 492         wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 
 493         &charWidth
, &charHeight
, NULL
, NULL
, &font 
); 
 500     for (unsigned int i 
= 0 ; i 
< m_noItems
; i
++) 
 502         GetTextExtent(GetString(i
), &eachWidth
, &eachHeight
, NULL
, NULL
, &font 
); 
 503         eachWidth  
= (int)(eachWidth 
+ RADIO_SIZE
); 
 504         eachHeight 
= (int)((3 * eachHeight
) / 2); 
 505         if (maxWidth 
< eachWidth
) 
 506             maxWidth 
= eachWidth
; 
 507         if (maxHeight 
< eachHeight
) 
 508             maxHeight 
= eachHeight
; 
 511     totHeight 
= GetRowCount() * maxHeight
; 
 512     totWidth  
= GetColumnCount() * (maxWidth 
+ charWidth
); 
 514     wxSize sz 
= DoGetSizeFromClientSize( wxSize( totWidth
, totHeight 
) ); 
 518     // handle radio box title as well 
 519     GetTextExtent( GetLabel(), &eachWidth
, NULL 
); 
 520     eachWidth  
= (int)(eachWidth 
+ RADIO_SIZE
) +  3 * charWidth
; 
 521     if (totWidth 
< eachWidth
) 
 522         totWidth 
= eachWidth
; 
 524     return wxSize( totWidth
, totHeight 
); 
 527 #endif // wxUSE_RADIOBOX