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
)
54 parent
, id
, pos
, size
, 0, NULL
,
55 style
, validator
, name
);
59 if ( !choices
.empty() )
63 bool wxChoice::Create(wxWindow
*parent
,
68 const wxString choices
[],
70 const wxValidator
& validator
,
71 const wxString
& name
)
73 m_macIsUserPane
= false;
75 if ( !wxChoiceBase::Create( parent
, id
, pos
, size
, style
, validator
, name
) )
78 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
);
80 m_peer
= new wxMacControl( this ) ;
81 OSStatus err
= CreatePopupButtonControl(
82 MAC_WXHWND(parent
->MacGetTopLevelWindowRef()) , &bounds
, CFSTR("") ,
83 -12345 , false /* no variable width */ , 0 , 0 , 0 , m_peer
->GetControlRefAddr() );
86 m_macPopUpMenuHandle
= NewUniqueMenu() ;
87 m_peer
->SetData
<MenuHandle
>( kControlNoPart
, kControlPopupButtonMenuHandleTag
, (MenuHandle
) m_macPopUpMenuHandle
) ;
88 m_peer
->SetValueAndRange( n
> 0 ? 1 : 0 , 0 , 0 );
89 MacPostControlCreate( pos
, size
);
92 if ( style
& wxCB_SORT
)
94 m_strings
= wxArrayString( 1 );
99 // Set the first item as being selected
103 // Needed because it is a wxControlWithItems
104 SetInitialSize( size
);
109 // ----------------------------------------------------------------------------
110 // adding/deleting items to/from the list
111 // ----------------------------------------------------------------------------
113 int wxChoice::DoInsertItems(const wxArrayStringsAdapter
& items
,
115 void **clientData
, wxClientDataType type
)
117 const unsigned int numItems
= items
.GetCount();
118 for( unsigned int i
= 0; i
< numItems
; ++i
, ++pos
)
125 wxArrayString::iterator
126 insertPoint
= std::lower_bound( m_strings
.begin(), m_strings
.end(), items
[i
] );
127 idx
= insertPoint
- m_strings
.begin();
128 m_strings
.insert( insertPoint
, items
[i
] );
134 m_strings
.Insert( items
[i
], idx
);
137 UMAInsertMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle
),
139 m_font
.GetEncoding(),
141 m_datas
.Insert( NULL
, idx
);
142 AssignNewItemClientData(idx
, clientData
, i
, type
);
145 m_peer
->SetMaximum( GetCount() );
150 void wxChoice::DoDeleteOneItem(unsigned int n
)
152 wxCHECK_RET( IsValid(n
) , wxT("wxChoice::Delete: invalid index") );
154 if ( HasClientObjectData() )
155 delete GetClientObject( n
);
157 ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle
) , n
+ 1 ) ;
158 m_strings
.RemoveAt( n
) ;
159 m_datas
.RemoveAt( n
) ;
160 m_peer
->SetMaximum( GetCount() ) ;
163 void wxChoice::DoClear()
165 for ( unsigned int i
= 0 ; i
< GetCount() ; i
++ )
167 ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle
) , 1 ) ;
172 m_peer
->SetMaximum( 0 ) ;
175 // ----------------------------------------------------------------------------
177 // ----------------------------------------------------------------------------
178 int wxChoice::GetSelection() const
180 return m_peer
->GetValue() - 1 ;
183 void wxChoice::SetSelection( int n
)
185 m_peer
->SetValue( n
+ 1 ) ;
188 // ----------------------------------------------------------------------------
189 // string list functions
190 // ----------------------------------------------------------------------------
192 unsigned int wxChoice::GetCount() const
194 return m_strings
.GetCount() ;
197 int wxChoice::FindString( const wxString
& s
, bool bCase
) const
200 // Avoid assert for non-default args passed to sorted array Index
205 return m_strings
.Index( s
, bCase
) ;
208 void wxChoice::SetString(unsigned int n
, const wxString
& s
)
210 wxCHECK_RET( IsValid(n
), wxT("wxChoice::SetString(): invalid index") );
214 // apple menu pos is 1-based
215 UMASetMenuItemText( MAC_WXHMENU(m_macPopUpMenuHandle
) , n
+ 1 , s
, wxFont::GetDefaultEncoding() ) ;
218 wxString
wxChoice::GetString(unsigned int n
) const
220 wxCHECK_MSG( IsValid(n
), wxEmptyString
, wxT("wxChoice::GetString(): invalid index") );
222 return m_strings
[n
] ;
225 // ----------------------------------------------------------------------------
227 // ----------------------------------------------------------------------------
228 void wxChoice::DoSetItemClientData(unsigned int n
, void* clientData
)
230 wxCHECK_RET( IsValid(n
), wxT("wxChoice::DoSetItemClientData: invalid index") );
232 m_datas
[n
] = (char*)clientData
;
235 void * wxChoice::DoGetItemClientData(unsigned int n
) const
237 wxCHECK_MSG( IsValid(n
), NULL
, wxT("wxChoice::DoGetClientData: invalid index") );
239 return (void *)m_datas
[n
];
242 wxInt32
wxChoice::MacControlHit( WXEVENTHANDLERREF
WXUNUSED(handler
) , WXEVENTREF
WXUNUSED(event
) )
244 wxCommandEvent
event( wxEVT_COMMAND_CHOICE_SELECTED
, m_windowId
);
246 // actually n should be made sure by the os to be a valid selection, but ...
247 int n
= GetSelection();
251 event
.SetString( GetStringSelection() );
252 event
.SetEventObject( this );
254 if ( HasClientObjectData() )
255 event
.SetClientObject( GetClientObject( n
) );
256 else if ( HasClientUntypedData() )
257 event
.SetClientData( GetClientData( n
) );
259 ProcessCommand( event
);
265 wxSize
wxChoice::DoGetBestSize() const
267 int lbWidth
= GetCount() > 0 ? 20 : 100; // some defaults
274 GetThemeMetric( kThemeMetricPopupButtonHeight
, &metric
);
279 #if wxMAC_USE_CORE_GRAPHICS
280 wxClientDC
dc(const_cast<wxChoice
*>(this));
282 wxMacPortStateHelper
st( UMAGetWindowPort( (WindowRef
) MacGetTopLevelWindowRef() ) ) ;
285 ::TextFont( m_font
.MacGetFontNum() ) ;
286 ::TextSize( m_font
.MacGetFontSize() ) ;
287 ::TextFace( m_font
.MacGetFontStyle() ) ;
291 ::TextFont( kFontIDMonaco
) ;
296 // Find the widest line
297 for(unsigned int i
= 0; i
< GetCount(); i
++)
299 wxString
str(GetString(i
));
300 #if wxMAC_USE_CORE_GRAPHICS
301 wxCoord width
, height
;
302 dc
.GetTextExtent( str
, &width
, &height
);
306 Point bounds
= { 0, 0 } ;
309 ::GetThemeTextDimensions( wxMacCFStringHolder( str
, m_font
.GetEncoding() ) ,
310 kThemeCurrentPortFont
,
318 wLine
= ::TextWidth( str
.c_str() , 0 , str
.length() ) ;
321 lbWidth
= wxMax( lbWidth
, wLine
) ;
324 // Add room for the popup arrow
325 lbWidth
+= 2 * lbHeight
;
326 #if wxMAC_USE_CORE_GRAPHICS
327 wxCoord width
, height
;
328 dc
.GetTextExtent( wxT("X"), &width
, &height
);
332 // And just a bit more
333 int cx
= ::TextWidth( "X" , 0 , 1 ) ;
338 return wxSize( lbWidth
, lbHeight
);
341 #endif // wxUSE_CHOICE