]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/choice.cpp
textctrl always needs ATSU...
[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{
d34cca53 53 return Create(
a236aa20 54 parent, id, pos, size, 0, NULL,
d34cca53 55 style, validator, name );
a236aa20
VZ
56
57 Append( choices );
58
59 if ( !choices.empty() )
60 SetSelection( 0 );
584ad2a3
MB
61}
62
d34cca53
DS
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 )
e9576ca5 72{
d34cca53 73 m_macIsUserPane = false;
312ebad4 74
d34cca53 75 if ( !wxChoiceBase::Create( parent, id, pos, size, style, validator, name ) )
b45ed7a2
VZ
76 return false;
77
d34cca53 78 Rect bounds = wxMacGetBoundsForControl( this , pos , size );
4c37f124 79
d34cca53
DS
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 );
312ebad4 85
d34cca53 86 m_macPopUpMenuHandle = NewUniqueMenu() ;
21fd5529 87 m_peer->SetData<MenuHandle>( kControlNoPart , kControlPopupButtonMenuHandleTag , (MenuHandle) m_macPopUpMenuHandle ) ;
d34cca53
DS
88 m_peer->SetValueAndRange( n > 0 ? 1 : 0 , 0 , 0 );
89 MacPostControlCreate( pos, size );
34585919 90
7b6986c3 91#if !wxUSE_STL
34585919 92 if ( style & wxCB_SORT )
d34cca53
DS
93 // autosort
94 m_strings = wxArrayString( 1 );
7b6986c3 95#endif
11e62fe6 96
a236aa20 97 Append(n, choices);
d34cca53
DS
98
99 // Set the first item as being selected
100 if (n > 0)
101 SetSelection( 0 );
102
103 // Needed because it is a wxControlWithItems
170acdc9 104 SetInitialSize( size );
d34cca53 105
312ebad4 106 return true;
e9576ca5 107}
e40298d5 108
b668a735
SC
109// ----------------------------------------------------------------------------
110// adding/deleting items to/from the list
111// ----------------------------------------------------------------------------
11e62fe6 112
a236aa20
VZ
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 )
9c707f80 119 {
a236aa20 120 unsigned int idx;
e40298d5 121
a236aa20
VZ
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 }
243dbf1a 136
a236aa20
VZ
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 }
243dbf1a 144
d34cca53
DS
145 m_peer->SetMaximum( GetCount() );
146
a236aa20 147 return pos - 1;
243dbf1a
VZ
148}
149
a236aa20 150void wxChoice::DoDeleteOneItem(unsigned int n)
2597135a 151{
8228b893 152 wxCHECK_RET( IsValid(n) , wxT("wxChoice::Delete: invalid index") );
d34cca53 153
b668a735 154 if ( HasClientObjectData() )
d34cca53
DS
155 delete GetClientObject( n );
156
157 ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1 ) ;
5fe38474 158 m_strings.RemoveAt( n ) ;
3ef585df 159 m_datas.RemoveAt( n ) ;
21fd5529 160 m_peer->SetMaximum( GetCount() ) ;
e9576ca5 161}
e40298d5 162
a236aa20 163void wxChoice::DoClear()
e9576ca5 164{
aa61d352 165 for ( unsigned int i = 0 ; i < GetCount() ; i++ )
519cb848 166 {
e40298d5 167 ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , 1 ) ;
4b651a46 168 }
d34cca53 169
b668a735
SC
170 m_strings.Empty() ;
171 m_datas.Empty() ;
21fd5529 172 m_peer->SetMaximum( 0 ) ;
e9576ca5 173}
e40298d5 174
b668a735
SC
175// ----------------------------------------------------------------------------
176// selection
177// ----------------------------------------------------------------------------
e9576ca5
SC
178int wxChoice::GetSelection() const
179{
d34cca53 180 return m_peer->GetValue() - 1 ;
e9576ca5 181}
e40298d5 182
d34cca53 183void wxChoice::SetSelection( int n )
519cb848 184{
21fd5529 185 m_peer->SetValue( n + 1 ) ;
519cb848 186}
e40298d5 187
b668a735
SC
188// ----------------------------------------------------------------------------
189// string list functions
190// ----------------------------------------------------------------------------
e40298d5 191
aa61d352 192unsigned int wxChoice::GetCount() const
e9576ca5 193{
b668a735 194 return m_strings.GetCount() ;
e9576ca5 195}
e40298d5 196
d34cca53 197int wxChoice::FindString( const wxString& s, bool bCase ) const
e9576ca5 198{
dd61c39d
JS
199#if !wxUSE_STL
200 // Avoid assert for non-default args passed to sorted array Index
a236aa20 201 if ( IsSorted() )
dd61c39d
JS
202 bCase = true;
203#endif
204
11e62fe6 205 return m_strings.Index( s , bCase ) ;
b668a735 206}
e40298d5 207
aa61d352 208void wxChoice::SetString(unsigned int n, const wxString& s)
b668a735 209{
8228b893 210 wxCHECK_RET( IsValid(n), wxT("wxChoice::SetString(): invalid index") );
d34cca53 211
34585919 212 m_strings[n] = s ;
d34cca53 213
34585919
SC
214 // apple menu pos is 1-based
215 UMASetMenuItemText( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1 , s , wxFont::GetDefaultEncoding() ) ;
e9576ca5
SC
216}
217
aa61d352 218wxString wxChoice::GetString(unsigned int n) const
e9576ca5 219{
8228b893 220 wxCHECK_MSG( IsValid(n), wxEmptyString, wxT("wxChoice::GetString(): invalid index") );
17a6a662 221
e40298d5 222 return m_strings[n] ;
e9576ca5 223}
17a6a662 224
b668a735
SC
225// ----------------------------------------------------------------------------
226// client data
227// ----------------------------------------------------------------------------
aa61d352 228void wxChoice::DoSetItemClientData(unsigned int n, void* clientData)
b668a735 229{
8228b893 230 wxCHECK_RET( IsValid(n), wxT("wxChoice::DoSetItemClientData: invalid index") );
c69279ef 231
d34cca53 232 m_datas[n] = (char*)clientData ;
b668a735 233}
e40298d5 234
aa61d352 235void * wxChoice::DoGetItemClientData(unsigned int n) const
b668a735 236{
8228b893 237 wxCHECK_MSG( IsValid(n), NULL, wxT("wxChoice::DoGetClientData: invalid index") );
d34cca53 238
d81cc883 239 return (void *)m_datas[n];
b668a735 240}
e40298d5 241
d34cca53 242wxInt32 wxChoice::MacControlHit( WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) )
b668a735 243{
d34cca53
DS
244 wxCommandEvent event( wxEVT_COMMAND_CHOICE_SELECTED, m_windowId );
245
f2d990ad 246 // actually n should be made sure by the os to be a valid selection, but ...
d34cca53 247 int n = GetSelection();
f2d990ad
SC
248 if ( n > -1 )
249 {
250 event.SetInt( n );
d34cca53
DS
251 event.SetString( GetStringSelection() );
252 event.SetEventObject( this );
253
f2d990ad 254 if ( HasClientObjectData() )
d34cca53 255 event.SetClientObject( GetClientObject( n ) );
f2d990ad 256 else if ( HasClientUntypedData() )
d34cca53
DS
257 event.SetClientData( GetClientData( n ) );
258
259 ProcessCommand( event );
f2d990ad 260 }
d34cca53 261
4c37f124 262 return noErr ;
9453cf2b 263}
e40298d5 264
f2d990ad 265wxSize wxChoice::DoGetBestSize() const
b668a735 266{
637988a4 267 int lbWidth = GetCount() > 0 ? 20 : 100; // some defaults
f2d990ad
SC
268 int lbHeight = 20;
269 int wLine;
d34cca53 270
7cd7bc23 271 SInt32 metric ;
d34cca53
DS
272
273 GetThemeMetric( kThemeMetricPopupButtonHeight , &metric );
c69279ef 274 lbHeight = metric ;
d34cca53 275
e40298d5 276 {
7cd7bc23 277 wxClientDC dc(const_cast<wxChoice*>(this));
e1673e52 278
e40298d5 279 // Find the widest line
aa61d352 280 for(unsigned int i = 0; i < GetCount(); i++)
d34cca53 281 {
aa61d352 282 wxString str(GetString(i));
e1673e52 283
7cd7bc23
SC
284 wxCoord width, height ;
285 dc.GetTextExtent( str , &width, &height);
286 wLine = width ;
e1673e52 287
d34cca53 288 lbWidth = wxMax( lbWidth, wLine ) ;
e40298d5 289 }
d34cca53 290
e40298d5
JS
291 // Add room for the popup arrow
292 lbWidth += 2 * lbHeight ;
e1673e52 293
7cd7bc23
SC
294 wxCoord width, height ;
295 dc.GetTextExtent( wxT("X"), &width, &height);
296 int cx = width ;
53cc4e70 297 lbHeight += 4;
e1673e52 298
e40298d5 299 lbWidth += cx ;
e40298d5 300 }
d34cca53
DS
301
302 return wxSize( lbWidth, lbHeight );
d76240bf 303}
312ebad4
WS
304
305#endif // wxUSE_CHOICE