1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/carbon/choice.cpp 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #include "wx/wxprec.h" 
  16 #include "wx/choice.h" 
  20     #include "wx/dcclient.h" 
  23 #include "wx/mac/uma.h" 
  25 extern MenuHandle 
NewUniqueMenu() ; 
  27 IMPLEMENT_DYNAMIC_CLASS(wxChoice
, wxControlWithItems
) 
  32     if ( HasClientObjectData() ) 
  34         unsigned int i
, max 
= GetCount(); 
  36         for ( i 
= 0; i 
< max
; ++i 
) 
  37             delete GetClientObject( i 
); 
  40     // DeleteMenu( m_macPopUpMenuId ) ; 
  41     // DisposeMenu( m_macPopUpMenuHandle ) ; 
  44 bool wxChoice::Create(wxWindow 
*parent
, 
  48     const wxArrayString
& choices
, 
  50     const wxValidator
& validator
, 
  51     const wxString
& name 
) 
  53     if ( !Create( parent
, id
, pos
, size
, 0, NULL
, style
, validator
, name 
) ) 
  58     if ( !choices
.empty() ) 
  61     SetInitialSize( size 
); 
  66 bool wxChoice::Create(wxWindow 
*parent
, 
  71     const wxString choices
[], 
  73     const wxValidator
& validator
, 
  74     const wxString
& name 
) 
  76     m_macIsUserPane 
= false; 
  78     if ( !wxChoiceBase::Create( parent
, id
, pos
, size
, style
, validator
, name 
) ) 
  81     Rect bounds 
= wxMacGetBoundsForControl( this , pos 
, size 
); 
  83     m_peer 
= new wxMacControl( this ) ; 
  84     OSStatus err 
= CreatePopupButtonControl( 
  85         MAC_WXHWND(parent
->MacGetTopLevelWindowRef()) , &bounds 
, CFSTR("") , 
  86         -12345 , false /* no variable width */ , 0 , 0 , 0 , m_peer
->GetControlRefAddr() ); 
  89     m_macPopUpMenuHandle 
= NewUniqueMenu() ; 
  90     m_peer
->SetData
<MenuHandle
>( kControlNoPart 
, kControlPopupButtonMenuHandleTag 
, (MenuHandle
) m_macPopUpMenuHandle 
) ; 
  91     m_peer
->SetValueAndRange( n 
> 0 ? 1 : 0 , 0 , 0 ); 
  92     MacPostControlCreate( pos
, size 
); 
  95     if ( style 
& wxCB_SORT 
) 
  97         m_strings 
= wxArrayString( 1 ); 
 102     // Set the first item as being selected 
 106     // Needed because it is a wxControlWithItems 
 107     SetInitialSize( size 
); 
 112 // ---------------------------------------------------------------------------- 
 113 // adding/deleting items to/from the list 
 114 // ---------------------------------------------------------------------------- 
 116 int wxChoice::DoInsertItems(const wxArrayStringsAdapter 
& items
, 
 118                             void **clientData
, wxClientDataType type
) 
 120     const unsigned int numItems 
= items
.GetCount(); 
 121     for( unsigned int i 
= 0; i 
< numItems
; ++i
, ++pos 
) 
 128             wxArrayString::iterator
 
 129                 insertPoint 
= std::lower_bound( m_strings
.begin(), m_strings
.end(), items
[i
] ); 
 130             idx 
= insertPoint 
- m_strings
.begin(); 
 131             m_strings
.insert( insertPoint
, items
[i
] ); 
 137             m_strings
.Insert( items
[i
], idx 
); 
 140         UMAInsertMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle 
), 
 142                           m_font
.GetEncoding(), 
 144         m_datas
.Insert( NULL
, idx 
); 
 145         AssignNewItemClientData(idx
, clientData
, i
, type
); 
 148     m_peer
->SetMaximum( GetCount() ); 
 153 void wxChoice::DoDeleteOneItem(unsigned int n
) 
 155     wxCHECK_RET( IsValid(n
) , wxT("wxChoice::Delete: invalid index") ); 
 157     if ( HasClientObjectData() ) 
 158         delete GetClientObject( n 
); 
 160     ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle
) , n 
+ 1 ) ; 
 161     m_strings
.RemoveAt( n 
) ; 
 162     m_datas
.RemoveAt( n 
) ; 
 163     m_peer
->SetMaximum( GetCount() ) ; 
 166 void wxChoice::DoClear() 
 168     for ( unsigned int i 
= 0 ; i 
< GetCount() ; i
++ ) 
 170         ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle
) , 1 ) ; 
 175     m_peer
->SetMaximum( 0 ) ; 
 178 // ---------------------------------------------------------------------------- 
 180 // ---------------------------------------------------------------------------- 
 181 int wxChoice::GetSelection() const 
 183     return m_peer
->GetValue() - 1 ; 
 186 void wxChoice::SetSelection( int n 
) 
 188     m_peer
->SetValue( n 
+ 1 ) ; 
 191 // ---------------------------------------------------------------------------- 
 192 // string list functions 
 193 // ---------------------------------------------------------------------------- 
 195 unsigned int wxChoice::GetCount() const 
 197     return m_strings
.GetCount() ; 
 200 int wxChoice::FindString( const wxString
& s
, bool bCase 
) const 
 203     // Avoid assert for non-default args passed to sorted array Index 
 208     return m_strings
.Index( s 
, bCase 
) ; 
 211 void wxChoice::SetString(unsigned int n
, const wxString
& s
) 
 213     wxCHECK_RET( IsValid(n
), wxT("wxChoice::SetString(): invalid index") ); 
 217     // apple menu pos is 1-based 
 218     UMASetMenuItemText( MAC_WXHMENU(m_macPopUpMenuHandle
) , n 
+ 1 , s 
, wxFont::GetDefaultEncoding() ) ; 
 221 wxString 
wxChoice::GetString(unsigned int n
) const 
 223     wxCHECK_MSG( IsValid(n
), wxEmptyString
, wxT("wxChoice::GetString(): invalid index") ); 
 225     return m_strings
[n
] ; 
 228 // ---------------------------------------------------------------------------- 
 230 // ---------------------------------------------------------------------------- 
 231 void wxChoice::DoSetItemClientData(unsigned int n
, void* clientData
) 
 233     wxCHECK_RET( IsValid(n
), wxT("wxChoice::DoSetItemClientData: invalid index") ); 
 235     m_datas
[n
] = (char*)clientData 
; 
 238 void * wxChoice::DoGetItemClientData(unsigned int n
) const 
 240     wxCHECK_MSG( IsValid(n
), NULL
, wxT("wxChoice::DoGetClientData: invalid index") ); 
 242     return (void *)m_datas
[n
]; 
 245 wxInt32 
wxChoice::MacControlHit( WXEVENTHANDLERREF 
WXUNUSED(handler
) , WXEVENTREF 
WXUNUSED(event
) ) 
 247     wxCommandEvent 
event( wxEVT_COMMAND_CHOICE_SELECTED
, m_windowId 
); 
 249     // actually n should be made sure by the os to be a valid selection, but ... 
 250     int n 
= GetSelection(); 
 254         event
.SetString( GetStringSelection() ); 
 255         event
.SetEventObject( this ); 
 257         if ( HasClientObjectData() ) 
 258             event
.SetClientObject( GetClientObject( n 
) ); 
 259         else if ( HasClientUntypedData() ) 
 260             event
.SetClientData( GetClientData( n 
) ); 
 262         ProcessCommand( event 
); 
 268 wxSize 
wxChoice::DoGetBestSize() const 
 270     int lbWidth 
= GetCount() > 0 ? 20 : 100;  // some defaults 
 276     GetThemeMetric( kThemeMetricPopupButtonHeight 
, &metric 
); 
 280         wxClientDC 
dc(const_cast<wxChoice
*>(this)); 
 282         // Find the widest line 
 283         for(unsigned int i 
= 0; i 
< GetCount(); i
++) 
 285             wxString 
str(GetString(i
)); 
 287             wxCoord width
, height 
; 
 288             dc
.GetTextExtent( str 
, &width
, &height
); 
 291             lbWidth 
= wxMax( lbWidth
, wLine 
) ; 
 294         // Add room for the popup arrow 
 295         lbWidth 
+= 2 * lbHeight 
; 
 297         wxCoord width
, height 
; 
 298         dc
.GetTextExtent( wxT("X"), &width
, &height
); 
 305     return wxSize( lbWidth
, lbHeight 
); 
 308 #endif // wxUSE_CHOICE