]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/choice.cpp
check that the version of __sync_sub_and_fetch that returns a value is supported...
[wxWidgets.git] / src / mac / carbon / choice.cpp
... / ...
CommitLineData
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
23#include "wx/mac/uma.h"
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 return Create(
54 parent, id, pos, size, 0, NULL,
55 style, validator, name );
56
57 Append( choices );
58
59 if ( !choices.empty() )
60 SetSelection( 0 );
61}
62
63bool wxChoice::Create(wxWindow *parent,
64 wxWindowID id,
65 const wxPoint& pos,
66 const wxSize& size,
67 int n,
68 const wxString choices[],
69 long style,
70 const wxValidator& validator,
71 const wxString& name )
72{
73 m_macIsUserPane = false;
74
75 if ( !wxChoiceBase::Create( parent, id, pos, size, style, validator, name ) )
76 return false;
77
78 Rect bounds = wxMacGetBoundsForControl( this , pos , size );
79
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() );
84 verify_noerr( err );
85
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 );
90
91#if !wxUSE_STL
92 if ( style & wxCB_SORT )
93 // autosort
94 m_strings = wxArrayString( 1 );
95#endif
96
97 Append(n, choices);
98
99 // Set the first item as being selected
100 if (n > 0)
101 SetSelection( 0 );
102
103 // Needed because it is a wxControlWithItems
104 SetInitialSize( size );
105
106 return true;
107}
108
109// ----------------------------------------------------------------------------
110// adding/deleting items to/from the list
111// ----------------------------------------------------------------------------
112
113int wxChoice::DoInsertItems(const wxArrayStringsAdapter & items,
114 unsigned int pos,
115 void **clientData, wxClientDataType type)
116{
117 const unsigned int numItems = items.GetCount();
118 for( unsigned int i = 0; i < numItems; ++i, ++pos )
119 {
120 unsigned int idx;
121
122#if wxUSE_STL
123 if ( IsSorted() )
124 {
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] );
129 }
130 else
131#endif // wxUSE_STL
132 {
133 idx = pos;
134 m_strings.Insert( items[i], idx );
135 }
136
137 UMAInsertMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle ),
138 items[i],
139 m_font.GetEncoding(),
140 idx);
141 m_datas.Insert( NULL, idx );
142 AssignNewItemClientData(idx, clientData, i, type);
143 }
144
145 m_peer->SetMaximum( GetCount() );
146
147 return pos - 1;
148}
149
150void wxChoice::DoDeleteOneItem(unsigned int n)
151{
152 wxCHECK_RET( IsValid(n) , wxT("wxChoice::Delete: invalid index") );
153
154 if ( HasClientObjectData() )
155 delete GetClientObject( n );
156
157 ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1 ) ;
158 m_strings.RemoveAt( n ) ;
159 m_datas.RemoveAt( n ) ;
160 m_peer->SetMaximum( GetCount() ) ;
161}
162
163void wxChoice::DoClear()
164{
165 for ( unsigned int i = 0 ; i < GetCount() ; i++ )
166 {
167 ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , 1 ) ;
168 }
169
170 m_strings.Empty() ;
171 m_datas.Empty() ;
172 m_peer->SetMaximum( 0 ) ;
173}
174
175// ----------------------------------------------------------------------------
176// selection
177// ----------------------------------------------------------------------------
178int wxChoice::GetSelection() const
179{
180 return m_peer->GetValue() - 1 ;
181}
182
183void wxChoice::SetSelection( int n )
184{
185 m_peer->SetValue( n + 1 ) ;
186}
187
188// ----------------------------------------------------------------------------
189// string list functions
190// ----------------------------------------------------------------------------
191
192unsigned int wxChoice::GetCount() const
193{
194 return m_strings.GetCount() ;
195}
196
197int wxChoice::FindString( const wxString& s, bool bCase ) const
198{
199#if !wxUSE_STL
200 // Avoid assert for non-default args passed to sorted array Index
201 if ( IsSorted() )
202 bCase = true;
203#endif
204
205 return m_strings.Index( s , bCase ) ;
206}
207
208void wxChoice::SetString(unsigned int n, const wxString& s)
209{
210 wxCHECK_RET( IsValid(n), wxT("wxChoice::SetString(): invalid index") );
211
212 m_strings[n] = s ;
213
214 // apple menu pos is 1-based
215 UMASetMenuItemText( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1 , s , wxFont::GetDefaultEncoding() ) ;
216}
217
218wxString wxChoice::GetString(unsigned int n) const
219{
220 wxCHECK_MSG( IsValid(n), wxEmptyString, wxT("wxChoice::GetString(): invalid index") );
221
222 return m_strings[n] ;
223}
224
225// ----------------------------------------------------------------------------
226// client data
227// ----------------------------------------------------------------------------
228void wxChoice::DoSetItemClientData(unsigned int n, void* clientData)
229{
230 wxCHECK_RET( IsValid(n), wxT("wxChoice::DoSetItemClientData: invalid index") );
231
232 m_datas[n] = (char*)clientData ;
233}
234
235void * wxChoice::DoGetItemClientData(unsigned int n) const
236{
237 wxCHECK_MSG( IsValid(n), NULL, wxT("wxChoice::DoGetClientData: invalid index") );
238
239 return (void *)m_datas[n];
240}
241
242wxInt32 wxChoice::MacControlHit( WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) )
243{
244 wxCommandEvent event( wxEVT_COMMAND_CHOICE_SELECTED, m_windowId );
245
246 // actually n should be made sure by the os to be a valid selection, but ...
247 int n = GetSelection();
248 if ( n > -1 )
249 {
250 event.SetInt( n );
251 event.SetString( GetStringSelection() );
252 event.SetEventObject( this );
253
254 if ( HasClientObjectData() )
255 event.SetClientObject( GetClientObject( n ) );
256 else if ( HasClientUntypedData() )
257 event.SetClientData( GetClientData( n ) );
258
259 ProcessCommand( event );
260 }
261
262 return noErr ;
263}
264
265wxSize wxChoice::DoGetBestSize() const
266{
267 int lbWidth = GetCount() > 0 ? 20 : 100; // some defaults
268 int lbHeight = 20;
269 int wLine;
270
271 SInt32 metric ;
272
273 GetThemeMetric( kThemeMetricPopupButtonHeight , &metric );
274 lbHeight = metric ;
275
276 {
277 wxClientDC dc(const_cast<wxChoice*>(this));
278
279 // Find the widest line
280 for(unsigned int i = 0; i < GetCount(); i++)
281 {
282 wxString str(GetString(i));
283
284 wxCoord width, height ;
285 dc.GetTextExtent( str , &width, &height);
286 wLine = width ;
287
288 lbWidth = wxMax( lbWidth, wLine ) ;
289 }
290
291 // Add room for the popup arrow
292 lbWidth += 2 * lbHeight ;
293
294 wxCoord width, height ;
295 dc.GetTextExtent( wxT("X"), &width, &height);
296 int cx = width ;
297 lbHeight += 4;
298
299 lbWidth += cx ;
300 }
301
302 return wxSize( lbWidth, lbHeight );
303}
304
305#endif // wxUSE_CHOICE