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