1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:       wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  13 #pragma implementation "choice.h" 
  16 #include "wx/wxprec.h" 
  20 #include "wx/choice.h" 
  22 #include "wx/mac/uma.h" 
  24 #if !USE_SHARED_LIBRARY 
  25 IMPLEMENT_DYNAMIC_CLASS(wxChoice
, wxControl
) 
  28 extern MenuHandle 
NewUniqueMenu() ; 
  32     if ( HasClientObjectData() ) 
  34         size_t 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
, wxWindowID id
, 
  47            const wxArrayString
& choices
, 
  49            const wxValidator
& validator
, 
  52     wxCArrayString 
chs(choices
); 
  54     return Create(parent
, id
, pos
, size
, chs
.GetCount(), chs
.GetStrings(), 
  55                   style
, validator
, name
); 
  58 bool wxChoice::Create(wxWindow 
*parent
, wxWindowID id
, 
  61            int n
, const wxString choices
[], 
  63            const wxValidator
& validator
, 
  66     m_macIsUserPane 
= false ; 
  68     if ( !wxChoiceBase::Create(parent
, id
, pos
, size
, style
, validator
, name
) ) 
  71     Rect bounds 
= wxMacGetBoundsForControl( this , pos 
, size 
) ; 
  73     m_peer 
= new wxMacControl(this) ; 
  74     verify_noerr ( CreatePopupButtonControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()) , &bounds 
, CFSTR("") , 
  75         -12345 , false /* no variable width */ , 0 , 0 , 0 , m_peer
->GetControlRefAddr() ) ); 
  78     m_macPopUpMenuHandle 
=  NewUniqueMenu() ; 
  79     m_peer
->SetData
<MenuHandle
>( kControlNoPart 
, kControlPopupButtonMenuHandleTag 
, (MenuHandle
) m_macPopUpMenuHandle 
) ; 
  80     m_peer
->SetValueAndRange( n 
> 0 ? 1 : 0 , 0 , 0 ) ; 
  81     MacPostControlCreate(pos
,size
) ; 
  83     for ( int i 
= 0; i 
< n
; i
++ ) 
  87     SetBestSize(size
);   // Needed because it is a wxControlWithItems 
  91 // ---------------------------------------------------------------------------- 
  92 // adding/deleting items to/from the list 
  93 // ---------------------------------------------------------------------------- 
  94 int wxChoice::DoAppend(const wxString
& item
) 
  96     UMAAppendMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle 
) , item
, m_font
.GetEncoding() ); 
  97     m_strings
.Add( item 
) ; 
  99     int index 
= m_strings
.GetCount()  - 1  ; 
 100     DoSetItemClientData( index 
, NULL 
) ; 
 101     m_peer
->SetMaximum( GetCount() ) ; 
 105 int wxChoice::DoInsert(const wxString
& item
, int pos
) 
 107     wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT
), -1, wxT("can't insert into sorted list")); 
 108     wxCHECK_MSG((pos
>=0) && (pos
<=GetCount()), -1, wxT("invalid index")); 
 110     if (pos 
== GetCount()) 
 111         return DoAppend(item
); 
 113     UMAAppendMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle 
) , item
, m_font
.GetEncoding() ); 
 114     m_strings
.Insert( item
, pos 
) ; 
 115     m_datas
.Insert( NULL
, pos 
) ; 
 116     DoSetItemClientData( pos 
, NULL 
) ; 
 117     m_peer
->SetMaximum( GetCount() ) ; 
 121 void wxChoice::Delete(int n
) 
 123     wxCHECK_RET( n 
< GetCount(), wxT("invalid item index in wxChoice::Delete") ); 
 124     if ( HasClientObjectData() ) 
 126         delete GetClientObject(n
); 
 128     ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle
) , n 
+ 1) ; 
 129     m_strings
.RemoveAt( n 
) ; 
 130     m_datas
.RemoveAt( n 
) ; 
 131     m_peer
->SetMaximum( GetCount() ) ; 
 134 void wxChoice::Clear() 
 137     for ( int i 
= 0 ; i 
< GetCount() ; i
++ ) 
 139         ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle
) , 1 ) ; 
 143     m_peer
->SetMaximum( 0 ) ; 
 146 void wxChoice::FreeData() 
 148     if ( HasClientObjectData() ) 
 150         size_t count 
= GetCount(); 
 151         for ( size_t n 
= 0; n 
< count
; n
++ ) 
 153             delete GetClientObject(n
); 
 158 // ---------------------------------------------------------------------------- 
 160 // ---------------------------------------------------------------------------- 
 161 int wxChoice::GetSelection() const 
 163     return m_peer
->GetValue() -1 ; 
 166 void wxChoice::SetSelection(int n
) 
 168     m_peer
->SetValue( n 
+ 1 ) ; 
 171 // ---------------------------------------------------------------------------- 
 172 // string list functions 
 173 // ---------------------------------------------------------------------------- 
 175 int wxChoice::GetCount() const 
 177     return m_strings
.GetCount() ; 
 180 int wxChoice::FindString(const wxString
& s
) const 
 182     for( int i 
= 0 ; i 
< GetCount() ; i
++ ) 
 184         if ( GetString( i 
).IsSameAs(s
, false) ) 
 190 void wxChoice::SetString(int n
, const wxString
& s
) 
 192     wxFAIL_MSG(wxT("wxChoice::SetString() not yet implemented")); 
 193 #if 0 // should do this, but no Insert() so far 
 199 wxString 
wxChoice::GetString(int n
) const 
 201     wxCHECK_MSG( n 
>= 0 && (size_t)n 
< m_strings
.GetCount(), _T(""), 
 202                     _T("wxChoice::GetString(): invalid index") ); 
 204     return m_strings
[n
] ; 
 207 // ---------------------------------------------------------------------------- 
 209 // ---------------------------------------------------------------------------- 
 210 void wxChoice::DoSetItemClientData( int n
, void* clientData 
) 
 212     wxCHECK_RET( n 
>= 0 && (size_t)n 
< m_datas
.GetCount(), 
 213                  wxT("invalid index in wxChoice::SetClientData") ); 
 215     m_datas
[n
] = (char*) clientData 
; 
 218 void *wxChoice::DoGetItemClientData(int n
) const 
 220     wxCHECK_MSG( n 
>= 0 && (size_t)n 
< m_datas
.GetCount(), NULL
, 
 221                  wxT("invalid index in wxChoice::GetClientData") ); 
 222     return (void *)m_datas
[n
]; 
 225 void wxChoice::DoSetItemClientObject( int n
, wxClientData
* clientData 
) 
 227     DoSetItemClientData(n
, clientData
); 
 230 wxClientData
* wxChoice::DoGetItemClientObject( int n 
) const 
 232     return (wxClientData 
*)DoGetItemClientData(n
); 
 235 wxInt32 
wxChoice::MacControlHit(WXEVENTHANDLERREF 
WXUNUSED(handler
) , WXEVENTREF 
WXUNUSED(event
) ) 
 237     wxCommandEvent 
event(wxEVT_COMMAND_CHOICE_SELECTED
, m_windowId 
); 
 238     int n 
= GetSelection(); 
 239     // actually n should be made sure by the os to be a valid selection, but ... 
 243         event
.SetString(GetStringSelection()); 
 244         event
.SetEventObject(this); 
 245         if ( HasClientObjectData() ) 
 246             event
.SetClientObject( GetClientObject(n
) ); 
 247         else if ( HasClientUntypedData() ) 
 248             event
.SetClientData( GetClientData(n
) ); 
 249         ProcessCommand(event
); 
 254 wxSize 
wxChoice::DoGetBestSize() const 
 256     int lbWidth 
= GetCount() > 0 ? 20 : 100;  // some defaults 
 261     GetThemeMetric(kThemeMetricPopupButtonHeight 
, &metric 
); 
 265         wxMacPortStateHelper 
st( UMAGetWindowPort( (WindowRef
) MacGetTopLevelWindowRef() ) ) ; 
 268             ::TextFont( m_font
.MacGetFontNum() ) ; 
 269             ::TextSize( m_font
.MacGetFontSize() ) ; 
 270             ::TextFace( m_font
.MacGetFontStyle() ) ; 
 274             ::TextFont( kFontIDMonaco 
) ; 
 278         // Find the widest line 
 279         for(int i 
= 0; i 
< GetCount(); i
++) { 
 280             wxString 
str(GetString(i
)); 
 284             ::GetThemeTextDimensions( wxMacCFStringHolder( str 
, m_font
.GetEncoding() ) , 
 285                 kThemeCurrentPortFont
, 
 292             wLine 
= ::TextWidth( str
.c_str() , 0 , str
.Length() ) ; 
 294             lbWidth 
= wxMax(lbWidth
, wLine
); 
 296         // Add room for the popup arrow 
 297         lbWidth 
+= 2 * lbHeight 
; 
 298         // And just a bit more 
 299         int cx 
= ::TextWidth( "X" , 0 , 1 ) ; 
 303     return wxSize(lbWidth
, lbHeight
); 
 306 #endif // wxUSE_CHOICE