1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Stefan Csomor 
   5 // Modified by: JS Lair (99/11/15) first implementation 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:       wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "radioboxbase.h" 
  14 #pragma implementation "radiobox.h" 
  17 //------------------------------------------------------------------------------------- 
  19 //------------------------------------------------------------------------------------- 
  22 #include "wx/arrstr.h" 
  24 #include "wx/radiobox.h" 
  25 #include "wx/radiobut.h" 
  26 #include "wx/mac/uma.h" 
  28 #if !USE_SHARED_LIBRARY 
  29 IMPLEMENT_DYNAMIC_CLASS(wxRadioBox
, wxControl
) 
  32 //------------------------------------------------------------------------------------- 
  34 //------------------------------------------------------------------------------------- 
  35 // Default constructor 
  36 BEGIN_EVENT_TABLE(wxRadioBox
, wxControl
) 
  37 EVT_RADIOBUTTON( -1 , wxRadioBox::OnRadioButton 
) 
  40 void wxRadioBox::OnRadioButton( wxCommandEvent 
&outer 
) 
  42     if ( outer
.IsChecked() ) 
  44         wxCommandEvent 
event(wxEVT_COMMAND_RADIOBOX_SELECTED
, m_windowId
); 
  45         int i 
= GetSelection() ; 
  47         event
.SetString( GetString( i 
) ); 
  48         event
.SetEventObject( this ); 
  49         ProcessCommand(event
); 
  53 wxRadioBox::wxRadioBox() 
  58     m_radioButtonCycle 
= NULL
; 
  61 //------------------------------------------------------------------------------------- 
  62 //         ¥ wxRadioBox(wxWindow*, wxWindowID, const wxString&, const wxPoint&,  
  63 //                        const wxSize&, int, const wxString[], int, long,  
  64 //                        const wxValidator&, const wxString&) 
  65 //------------------------------------------------------------------------------------- 
  66 // Contructor, creating and showing a radiobox 
  71 //------------------------------------------------------------------------------------- 
  73 //------------------------------------------------------------------------------------- 
  74 // Destructor, destroying the radiobox item 
  76 wxRadioBox::~wxRadioBox() 
  78     m_isBeingDeleted 
= TRUE
; 
  80     wxRadioButton 
*next
,*current
; 
  82     current
=m_radioButtonCycle
->NextInCycle(); 
  83     next
=current
->NextInCycle(); 
  84     while (current
!=m_radioButtonCycle
) { 
  87         next
=current
->NextInCycle(); 
  92 //------------------------------------------------------------------------------------- 
  94 //------------------------------------------------------------------------------------- 
  95 // Create the radiobox for two-step construction 
  97 bool wxRadioBox::Create(wxWindow 
*parent
, wxWindowID id
, const wxString
& label
, 
  98                         const wxPoint
& pos
, const wxSize
& size
, 
  99                         const wxArrayString
& choices
, 
 100                         int majorDim
, long style
, 
 101                         const wxValidator
& val
, const wxString
& name
) 
 103     wxCArrayString 
chs(choices
); 
 105     return Create(parent
, id
, label
, pos
, size
, chs
.GetCount(), 
 106                   chs
.GetStrings(), majorDim
, style
, val
, name
); 
 109 bool wxRadioBox::Create(wxWindow 
*parent
, wxWindowID id
, const wxString
& label
, 
 110                         const wxPoint
& pos
, const wxSize
& size
, 
 111                         int n
, const wxString choices
[], 
 112                         int majorDim
, long style
, 
 113                         const wxValidator
& val
, const wxString
& name
) 
 115     if ( !wxControl::Create(parent
, id
, pos
, size
, style
, val
, name
) ) 
 121     m_noRowsOrCols 
= majorDim
; 
 122     m_radioButtonCycle 
= NULL
; 
 127         m_majorDim 
= majorDim 
; 
 133     MacPreControlCreate( parent 
, id 
,  wxStripMenuCodes(label
) , pos 
, size 
,style
, val 
, name 
, &bounds 
, title 
) ; 
 135     m_macControl 
= ::NewControl( MAC_WXHWND(parent
->MacGetRootWindow()) , &bounds 
, title 
, false , 0 , 0 , 1,  
 136         kControlGroupBoxTextTitleProc 
, (long) this ) ; 
 138     for (i 
= 0; i 
< n
; i
++) 
 140         wxRadioButton 
*radBtn 
= new wxRadioButton
 
 144                                         wxStripMenuCodes(choices
[i
]), 
 147                                         i 
== 0 ? wxRB_GROUP 
: 0 
 150             m_radioButtonCycle 
= radBtn 
; 
 151         //        m_radioButtonCycle=radBtn->AddInCycle(m_radioButtonCycle); 
 155     MacPostControlCreate() ; 
 161 //------------------------------------------------------------------------------------- 
 163 //------------------------------------------------------------------------------------- 
 164 // Enables or disables the entire radiobox 
 166 bool wxRadioBox::Enable(bool enable
) 
 169     wxRadioButton 
*current
; 
 171     if (!wxControl::Enable(enable
)) 
 174     current 
= m_radioButtonCycle
; 
 175     for (i 
= 0; i 
< m_noItems
; i
++) { 
 176         current
->Enable(enable
); 
 177         current 
= current
->NextInCycle(); 
 182 //------------------------------------------------------------------------------------- 
 183 //         ¥ Enable(int, bool) 
 184 //------------------------------------------------------------------------------------- 
 185 // Enables or disables an given button 
 187 void wxRadioBox::Enable(int item
, bool enable
) 
 190     wxRadioButton 
*current
; 
 192     if ((item 
< 0) || (item 
>= m_noItems
)) 
 196     current 
= m_radioButtonCycle
; 
 199         current 
= current
->NextInCycle(); 
 201     current
->Enable(enable
); 
 204 //------------------------------------------------------------------------------------- 
 206 //------------------------------------------------------------------------------------- 
 207 // Returns the radiobox label 
 209 wxString 
wxRadioBox::GetLabel() const 
 211     return wxControl::GetLabel(); 
 214 //------------------------------------------------------------------------------------- 
 216 //------------------------------------------------------------------------------------- 
 217 // Returns the label for the given button 
 219 wxString 
wxRadioBox::GetString(int item
) const 
 222     wxRadioButton 
*current
; 
 224     if ((item 
< 0) || (item 
>= m_noItems
)) 
 225         return wxEmptyString
; 
 228     current 
= m_radioButtonCycle
; 
 231         current 
= current
->NextInCycle(); 
 233     return current
->GetLabel(); 
 236 //------------------------------------------------------------------------------------- 
 238 //------------------------------------------------------------------------------------- 
 239 // Returns the zero-based position of the selected button 
 241 int wxRadioBox::GetSelection() const 
 244     wxRadioButton 
*current
; 
 247     current
=m_radioButtonCycle
; 
 248     while (!current
->GetValue()) { 
 250         current
=current
->NextInCycle(); 
 256 //------------------------------------------------------------------------------------- 
 258 //------------------------------------------------------------------------------------- 
 259 // Returns the number of buttons in the radiobox 
 264 //------------------------------------------------------------------------------------- 
 265 //         ¥ SetLabel(const wxString&) 
 266 //------------------------------------------------------------------------------------- 
 267 // Sets the radiobox label 
 269 void wxRadioBox::SetLabel(const wxString
& label
) 
 271     return wxControl::SetLabel(label
); 
 274 //------------------------------------------------------------------------------------- 
 275 //         ¥ SetLabel(int, const wxString&) 
 276 //------------------------------------------------------------------------------------- 
 277 // Sets the label of a given button 
 279 void wxRadioBox::SetString(int item
,const wxString
& label
) 
 282     wxRadioButton 
*current
; 
 284     if ((item 
< 0) || (item 
>= m_noItems
)) 
 287     current
=m_radioButtonCycle
; 
 290         current
=current
->NextInCycle(); 
 292     return current
->SetLabel(label
); 
 295 //------------------------------------------------------------------------------------- 
 297 //------------------------------------------------------------------------------------- 
 298 // Sets a button by passing the desired position. This does not cause  
 299 // wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted 
 301 void wxRadioBox::SetSelection(int item
) 
 304     wxRadioButton 
*current
; 
 306     if ((item 
< 0) || (item 
>= m_noItems
)) 
 309     current
=m_radioButtonCycle
; 
 312         current
=current
->NextInCycle(); 
 314     current
->SetValue(true); 
 318 //------------------------------------------------------------------------------------- 
 320 //------------------------------------------------------------------------------------- 
 321 // Shows or hides the entire radiobox  
 323 bool wxRadioBox::Show(bool show
) 
 326     wxRadioButton 
*current
; 
 328     wxControl::Show(show
); 
 330     current
=m_radioButtonCycle
; 
 331        for (i
=0;i
<m_noItems
;i
++) { 
 333         current
=current
->NextInCycle(); 
 338 //------------------------------------------------------------------------------------- 
 340 //------------------------------------------------------------------------------------- 
 341 // Shows or hides the given button  
 343 void wxRadioBox::Show(int item
, bool show
) 
 346     wxRadioButton 
*current
; 
 348     if ((item 
< 0) || (item 
>= m_noItems
)) 
 351     current
=m_radioButtonCycle
; 
 354         current
=current
->NextInCycle(); 
 359 //------------------------------------------------------------------------------------- 
 361 //------------------------------------------------------------------------------------- 
 362 // Simulates the effect of the user issuing a command to the item 
 364 void wxRadioBox::Command (wxCommandEvent 
& event
) 
 366     SetSelection (event
.GetInt()); 
 367     ProcessCommand (event
); 
 370 //------------------------------------------------------------------------------------- 
 372 //------------------------------------------------------------------------------------- 
 373 // Sets the selected button to receive keyboard input 
 375 void wxRadioBox::SetFocus() 
 378     wxRadioButton 
*current
; 
 381     current
=m_radioButtonCycle
; 
 382     while (!current
->GetValue()) { 
 384         current
=current
->NextInCycle(); 
 390 //------------------------------------------------------------------------------------- 
 392 //------------------------------------------------------------------------------------- 
 393 // Simulates the effect of the user issuing a command to the item 
 395 #define RADIO_SIZE 20 
 397 void wxRadioBox::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
 400     wxRadioButton 
*current
; 
 402     // define the position 
 404     int x_current
, y_current
; 
 405     int x_offset
,y_offset
; 
 406     int widthOld
, heightOld
; 
 407     GetSize(&widthOld
, &heightOld
); 
 411     GetPosition(&x_current
, &y_current
); 
 412     if ((x 
== -1) && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 413         x_offset 
= x_current
; 
 414     if ((y 
== -1)&& !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 415         y_offset 
= y_current
; 
 419     int charWidth
,charHeight
; 
 420     int maxWidth
,maxHeight
; 
 421     int eachWidth
[128],eachHeight
[128]; 
 422     int totWidth
,totHeight
; 
 424     SetFont(GetParent()->GetFont()); 
 425     GetTextExtent(wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), &charWidth
, &charHeight
); 
 430     for (i 
= 0 ; i 
< m_noItems
; i
++) 
 432         GetTextExtent(GetString(i
), &eachWidth
[i
], &eachHeight
[i
]); 
 433         eachWidth
[i
] = (int)(eachWidth
[i
] + RADIO_SIZE
); 
 434         eachHeight
[i
] = (int)((3*eachHeight
[i
])/2); 
 435         if (maxWidth
<eachWidth
[i
]) maxWidth 
= eachWidth
[i
]; 
 436         if (maxHeight
<eachHeight
[i
]) maxHeight 
= eachHeight
[i
]; 
 439     totHeight 
= GetRowCount() * (maxHeight 
+ charHeight
/2) + charHeight 
; 
 440     totWidth  
= GetColumnCount() * (maxWidth 
+ charWidth
) + charWidth
; 
 442     // only change our width/height if asked for 
 445         if ( sizeFlags 
& wxSIZE_AUTO_WIDTH 
) 
 453         if ( sizeFlags 
& wxSIZE_AUTO_HEIGHT 
) 
 459     wxControl::DoSetSize(x_offset
,y_offset
,width
,height
,wxSIZE_AUTO
); 
 461     // arrange radiobuttons 
 468     if ( UMAGetSystemVersion() >= 0x1030 ) 
 470                 //need to add a few more pixels for the top border on panther 
 471                 y_start 
= y_start 
+ 5; //how many exactly should this be to meet the HIG? 
 476     current
=m_radioButtonCycle
;   
 477     for ( i 
= 0 ; i 
< m_noItems
; i
++) 
 479         if (i
&&((i%m_majorDim
)==0)) // not to do for the zero button! 
 481             if (m_windowStyle 
& wxRA_VERTICAL
) 
 483                 x_offset 
+= maxWidth 
+ charWidth
; 
 489                 y_offset 
+= maxHeight 
; /*+ charHeight/2;*/ 
 493         current
->SetSize(x_offset
,y_offset
,eachWidth
[i
],eachHeight
[i
]); 
 494         current
=current
->NextInCycle(); 
 496         if (m_windowStyle 
& wxRA_SPECIFY_ROWS
) 
 497             y_offset 
+= maxHeight 
; /*+ charHeight/2;*/ 
 499             x_offset 
+= maxWidth 
+ charWidth
; 
 503 wxSize 
wxRadioBox::DoGetBestSize() const 
 505     int charWidth
, charHeight
; 
 506     int maxWidth
, maxHeight
; 
 507     int eachWidth
, eachHeight
; 
 508     int totWidth
, totHeight
; 
 510     wxFont font 
= GetParent()->GetFont(); 
 511     GetTextExtent(wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 
 512         &charWidth
, &charHeight
, NULL
, NULL
, &font
); 
 518     for (int i 
= 0 ; i 
< m_noItems
; i
++) 
 520         GetTextExtent(GetString(i
), &eachWidth
, &eachHeight
); 
 521         eachWidth  
= (int)(eachWidth 
+ RADIO_SIZE
) ; 
 522         eachHeight 
= (int)((3 * eachHeight
) / 2); 
 523         if (maxWidth 
< eachWidth
)     maxWidth 
= eachWidth
; 
 524         if (maxHeight 
< eachHeight
)   maxHeight 
= eachHeight
; 
 527     totHeight 
= GetRowCount() * (maxHeight 
+ charHeight
/2) + charHeight 
; 
 528     totWidth  
= GetColumnCount() * (maxWidth 
+ charWidth
) + charWidth
; 
 530     if ( UMAGetSystemVersion() >= 0x1030 ) 
 532         //need to add a few more pixels for the static boxborder on panther 
 533         totHeight 
= totHeight 
+ 10; //how many exactly should this be to meet the HIG? 
 535     // handle radio box title as well 
 536     GetTextExtent(GetTitle(), &eachWidth
, NULL
); 
 537     eachWidth  
= (int)(eachWidth 
+ RADIO_SIZE
) + 3 * charWidth 
; 
 538     if (totWidth 
< eachWidth
)      
 539         totWidth 
= eachWidth
; 
 541     return wxSize(totWidth
, totHeight
); 
 543 //------------------------------------------------------------------------------------- 
 545 //------------------------------------------------------------------------------------- 
 546 // return the number of buttons in the vertical direction 
 548 int wxRadioBox::GetRowCount() const 
 550     if ( m_windowStyle 
& wxRA_SPECIFY_ROWS 
) 
 556         return (m_noItems 
+ m_majorDim 
- 1)/m_majorDim
; 
 560 //------------------------------------------------------------------------------------- 
 562 //------------------------------------------------------------------------------------- 
 563 // return the number of buttons in the horizontal direction 
 565 int wxRadioBox::GetColumnCount() const 
 567     if ( m_windowStyle 
& wxRA_SPECIFY_ROWS 
) 
 569         return (m_noItems 
+ m_majorDim 
- 1)/m_majorDim
;