]> git.saurik.com Git - wxWidgets.git/blame - src/osx/carbon/choice.cpp
was incorrectly forcing the font to 12 in most cases, fixes #4745
[wxWidgets.git] / src / osx / carbon / choice.cpp
CommitLineData
489468fe
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/mac/carbon/choice.cpp
3// Purpose: wxChoice
4// Author: Stefan Csomor
5// Modified by:
6// Created: 1998-01-01
7// RCS-ID: $Id$
8// Copyright: (c) Stefan Csomor
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#if wxUSE_CHOICE
15
16#include "wx/choice.h"
17
18#ifndef WX_PRECOMP
19 #include "wx/menu.h"
20 #include "wx/dcclient.h"
21#endif
22
1f0c8f31 23#include "wx/osx/uma.h"
489468fe
SC
24
25extern MenuHandle NewUniqueMenu() ;
26
27IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControlWithItems)
28
29
30wxChoice::~wxChoice()
31{
32 if ( HasClientObjectData() )
33 {
34 unsigned int i, max = GetCount();
35
36 for ( i = 0; i < max; ++i )
37 delete GetClientObject( i );
38 }
39
40 // DeleteMenu( m_macPopUpMenuId ) ;
41 // DisposeMenu( m_macPopUpMenuHandle ) ;
42}
43
44bool wxChoice::Create(wxWindow *parent,
45 wxWindowID id,
46 const wxPoint& pos,
47 const wxSize& size,
48 const wxArrayString& choices,
49 long style,
50 const wxValidator& validator,
51 const wxString& name )
52{
53 if ( !Create( parent, id, pos, size, 0, NULL, style, validator, name ) )
54 return false;
55
56 Append( choices );
57
58 if ( !choices.empty() )
59 SetSelection( 0 );
60
61 SetInitialSize( size );
62
63 return true;
64}
65
66bool wxChoice::Create(wxWindow *parent,
67 wxWindowID id,
68 const wxPoint& pos,
69 const wxSize& size,
70 int n,
71 const wxString choices[],
72 long style,
73 const wxValidator& validator,
74 const wxString& name )
75{
76 m_macIsUserPane = false;
77
78 if ( !wxChoiceBase::Create( parent, id, pos, size, style, validator, name ) )
79 return false;
80
81 Rect bounds = wxMacGetBoundsForControl( this , pos , size );
82
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() );
87 verify_noerr( err );
88
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 );
93
94#if !wxUSE_STL
95 if ( style & wxCB_SORT )
96 // autosort
97 m_strings = wxArrayString( 1 );
98#endif
99
100 Append(n, choices);
101
102 // Set the first item as being selected
103 if (n > 0)
104 SetSelection( 0 );
105
106 // Needed because it is a wxControlWithItems
107 SetInitialSize( size );
108
109 return true;
110}
111
112// ----------------------------------------------------------------------------
113// adding/deleting items to/from the list
114// ----------------------------------------------------------------------------
115
116int wxChoice::DoInsertItems(const wxArrayStringsAdapter & items,
117 unsigned int pos,
118 void **clientData, wxClientDataType type)
119{
120 const unsigned int numItems = items.GetCount();
121 for( unsigned int i = 0; i < numItems; ++i, ++pos )
122 {
123 unsigned int idx;
124
125#if wxUSE_STL
126 if ( IsSorted() )
127 {
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] );
132 }
133 else
134#endif // wxUSE_STL
135 {
136 idx = pos;
137 m_strings.Insert( items[i], idx );
138 }
139
140 UMAInsertMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle ),
141 items[i],
142 GetFont().GetEncoding(),
143 idx);
144 m_datas.Insert( NULL, idx );
145 AssignNewItemClientData(idx, clientData, i, type);
146 }
147
148 m_peer->SetMaximum( GetCount() );
149
150 return pos - 1;
151}
152
153void wxChoice::DoDeleteOneItem(unsigned int n)
154{
155 wxCHECK_RET( IsValid(n) , wxT("wxChoice::Delete: invalid index") );
156
157 if ( HasClientObjectData() )
158 delete GetClientObject( n );
159
160 ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1 ) ;
161 m_strings.RemoveAt( n ) ;
162 m_datas.RemoveAt( n ) ;
163 m_peer->SetMaximum( GetCount() ) ;
164}
165
166void wxChoice::DoClear()
167{
168 for ( unsigned int i = 0 ; i < GetCount() ; i++ )
169 {
170 ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , 1 ) ;
171 }
172
173 m_strings.Empty() ;
174 m_datas.Empty() ;
175 m_peer->SetMaximum( 0 ) ;
176}
177
178// ----------------------------------------------------------------------------
179// selection
180// ----------------------------------------------------------------------------
181int wxChoice::GetSelection() const
182{
183 return m_peer->GetValue() - 1 ;
184}
185
186void wxChoice::SetSelection( int n )
187{
188 m_peer->SetValue( n + 1 ) ;
189}
190
191// ----------------------------------------------------------------------------
192// string list functions
193// ----------------------------------------------------------------------------
194
195unsigned int wxChoice::GetCount() const
196{
197 return m_strings.GetCount() ;
198}
199
200int wxChoice::FindString( const wxString& s, bool bCase ) const
201{
202#if !wxUSE_STL
203 // Avoid assert for non-default args passed to sorted array Index
204 if ( IsSorted() )
205 bCase = true;
206#endif
207
208 return m_strings.Index( s , bCase ) ;
209}
210
211void wxChoice::SetString(unsigned int n, const wxString& s)
212{
213 wxCHECK_RET( IsValid(n), wxT("wxChoice::SetString(): invalid index") );
214
215 m_strings[n] = s ;
216
217 // apple menu pos is 1-based
218 UMASetMenuItemText( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1 , s , wxFont::GetDefaultEncoding() ) ;
219}
220
221wxString wxChoice::GetString(unsigned int n) const
222{
223 wxCHECK_MSG( IsValid(n), wxEmptyString, wxT("wxChoice::GetString(): invalid index") );
224
225 return m_strings[n] ;
226}
227
228// ----------------------------------------------------------------------------
229// client data
230// ----------------------------------------------------------------------------
231void wxChoice::DoSetItemClientData(unsigned int n, void* clientData)
232{
233 wxCHECK_RET( IsValid(n), wxT("wxChoice::DoSetItemClientData: invalid index") );
234
235 m_datas[n] = (char*)clientData ;
236}
237
238void * wxChoice::DoGetItemClientData(unsigned int n) const
239{
240 wxCHECK_MSG( IsValid(n), NULL, wxT("wxChoice::DoGetClientData: invalid index") );
241
242 return (void *)m_datas[n];
243}
244
245wxInt32 wxChoice::MacControlHit( WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) )
246{
247 wxCommandEvent event( wxEVT_COMMAND_CHOICE_SELECTED, m_windowId );
248
249 // actually n should be made sure by the os to be a valid selection, but ...
250 int n = GetSelection();
251 if ( n > -1 )
252 {
253 event.SetInt( n );
254 event.SetString( GetStringSelection() );
255 event.SetEventObject( this );
256
257 if ( HasClientObjectData() )
258 event.SetClientObject( GetClientObject( n ) );
259 else if ( HasClientUntypedData() )
260 event.SetClientData( GetClientData( n ) );
261
262 ProcessCommand( event );
263 }
264
265 return noErr ;
266}
267
268wxSize wxChoice::DoGetBestSize() const
269{
270 int lbWidth = GetCount() > 0 ? 20 : 100; // some defaults
271 int lbHeight = 20;
272 int wLine;
273
274 SInt32 metric ;
275
276 GetThemeMetric( kThemeMetricPopupButtonHeight , &metric );
277 lbHeight = metric ;
278
279 {
280 wxClientDC dc(const_cast<wxChoice*>(this));
281
282 // Find the widest line
283 for(unsigned int i = 0; i < GetCount(); i++)
284 {
285 wxString str(GetString(i));
286
287 wxCoord width, height ;
288 dc.GetTextExtent( str , &width, &height);
289 wLine = width ;
290
291 lbWidth = wxMax( lbWidth, wLine ) ;
292 }
293
294 // Add room for the popup arrow
295 lbWidth += 2 * lbHeight ;
296
297 wxCoord width, height ;
298 dc.GetTextExtent( wxT("X"), &width, &height);
299 int cx = width ;
300 lbHeight += 4;
301
302 lbWidth += cx ;
303 }
304
305 return wxSize( lbWidth, lbHeight );
306}
307
308#endif // wxUSE_CHOICE