1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/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/osx/private.h"
25 IMPLEMENT_DYNAMIC_CLASS(wxChoice
, wxControlWithItems
)
29 if ( HasClientObjectData() )
31 unsigned int i
, max
= GetCount();
33 for ( i
= 0; i
< max
; ++i
)
34 delete GetClientObject( i
);
39 bool wxChoice::Create(wxWindow
*parent
,
43 const wxArrayString
& choices
,
45 const wxValidator
& validator
,
46 const wxString
& name
)
48 if ( !Create( parent
, id
, pos
, size
, 0, NULL
, style
, validator
, name
) )
53 if ( !choices
.empty() )
56 SetInitialSize( size
);
61 bool wxChoice::Create(wxWindow
*parent
,
66 const wxString choices
[],
68 const wxValidator
& validator
,
69 const wxString
& name
)
71 m_macIsUserPane
= false;
73 if ( !wxChoiceBase::Create( parent
, id
, pos
, size
, style
, validator
, name
) )
76 m_popUpMenu
= new wxMenu();
77 m_popUpMenu
->SetNoEventsMode(true);
79 m_peer
= wxWidgetImpl::CreateChoice( this, parent
, id
, m_popUpMenu
, pos
, size
, style
, GetExtraStyle() );
81 MacPostControlCreate( pos
, size
);
84 if ( style
& wxCB_SORT
)
86 m_strings
= wxArrayString( 1 );
91 // Set the first item as being selected
95 // Needed because it is a wxControlWithItems
96 SetInitialSize( size
);
101 // ----------------------------------------------------------------------------
102 // adding/deleting items to/from the list
103 // ----------------------------------------------------------------------------
105 int wxChoice::DoInsertItems(const wxArrayStringsAdapter
& items
,
107 void **clientData
, wxClientDataType type
)
109 const unsigned int numItems
= items
.GetCount();
110 for( unsigned int i
= 0; i
< numItems
; ++i
, ++pos
)
117 wxArrayString::iterator
118 insertPoint
= std::lower_bound( m_strings
.begin(), m_strings
.end(), items
[i
] );
119 idx
= insertPoint
- m_strings
.begin();
120 m_strings
.insert( insertPoint
, items
[i
] );
126 m_strings
.Insert( items
[i
], idx
);
129 wxString text
= items
[i
];
130 if (text
== wxEmptyString
)
131 text
= " "; // menu items can't have empty labels
132 m_popUpMenu
->Insert( idx
, i
+1, text
);
133 m_datas
.Insert( NULL
, idx
);
134 AssignNewItemClientData(idx
, clientData
, i
, type
);
137 m_peer
->SetMaximum( GetCount() );
142 void wxChoice::DoDeleteOneItem(unsigned int n
)
144 wxCHECK_RET( IsValid(n
) , wxT("wxChoice::Delete: invalid index") );
146 if ( HasClientObjectData() )
147 delete GetClientObject( n
);
149 m_popUpMenu
->Delete( m_popUpMenu
->FindItemByPosition( n
) );
151 m_strings
.RemoveAt( n
) ;
152 m_datas
.RemoveAt( n
) ;
153 m_peer
->SetMaximum( GetCount() ) ;
157 void wxChoice::DoClear()
159 for ( unsigned int i
= 0 ; i
< GetCount() ; i
++ )
161 m_popUpMenu
->Delete( m_popUpMenu
->FindItemByPosition( 0 ) );
167 m_peer
->SetMaximum( 0 ) ;
170 // ----------------------------------------------------------------------------
172 // ----------------------------------------------------------------------------
173 int wxChoice::GetSelection() const
175 return m_peer
->GetValue();
178 void wxChoice::SetSelection( int n
)
180 m_peer
->SetValue( n
);
183 // ----------------------------------------------------------------------------
184 // string list functions
185 // ----------------------------------------------------------------------------
187 unsigned int wxChoice::GetCount() const
189 return m_strings
.GetCount() ;
192 int wxChoice::FindString( const wxString
& s
, bool bCase
) const
195 // Avoid assert for non-default args passed to sorted array Index
200 return m_strings
.Index( s
, bCase
) ;
203 void wxChoice::SetString(unsigned int n
, const wxString
& s
)
205 wxCHECK_RET( IsValid(n
), wxT("wxChoice::SetString(): invalid index") );
209 m_popUpMenu
->FindItemByPosition( n
)->SetItemLabel( s
) ;
212 wxString
wxChoice::GetString(unsigned int n
) const
214 wxCHECK_MSG( IsValid(n
), wxEmptyString
, wxT("wxChoice::GetString(): invalid index") );
216 return m_strings
[n
] ;
219 // ----------------------------------------------------------------------------
221 // ----------------------------------------------------------------------------
222 void wxChoice::DoSetItemClientData(unsigned int n
, void* clientData
)
224 wxCHECK_RET( IsValid(n
), wxT("wxChoice::DoSetItemClientData: invalid index") );
226 m_datas
[n
] = (char*)clientData
;
229 void * wxChoice::DoGetItemClientData(unsigned int n
) const
231 wxCHECK_MSG( IsValid(n
), NULL
, wxT("wxChoice::DoGetClientData: invalid index") );
233 return (void *)m_datas
[n
];
236 bool wxChoice::OSXHandleClicked( double WXUNUSED(timestampsec
) )
238 wxCommandEvent
event( wxEVT_COMMAND_CHOICE_SELECTED
, m_windowId
);
240 // actually n should be made sure by the os to be a valid selection, but ...
241 int n
= GetSelection();
245 event
.SetString( GetStringSelection() );
246 event
.SetEventObject( this );
248 if ( HasClientObjectData() )
249 event
.SetClientObject( GetClientObject( n
) );
250 else if ( HasClientUntypedData() )
251 event
.SetClientData( GetClientData( n
) );
253 ProcessCommand( event
);
259 wxSize
wxChoice::DoGetBestSize() const
261 int lbWidth
= GetCount() > 0 ? 20 : 100; // some defaults
262 wxSize baseSize
= wxWindow::DoGetBestSize();
263 int lbHeight
= baseSize
.y
;
267 wxClientDC
dc(const_cast<wxChoice
*>(this));
269 // Find the widest line
270 for(unsigned int i
= 0; i
< GetCount(); i
++)
272 wxString
str(GetString(i
));
274 wxCoord width
, height
;
275 dc
.GetTextExtent( str
, &width
, &height
);
278 lbWidth
= wxMax( lbWidth
, wLine
) ;
281 // Add room for the popup arrow
282 lbWidth
+= 2 * lbHeight
;
284 wxCoord width
, height
;
285 dc
.GetTextExtent( wxT("X"), &width
, &height
);
291 return wxSize( lbWidth
, lbHeight
);
294 #endif // wxUSE_CHOICE