]>
Commit | Line | Data |
---|---|---|
e9576ca5 | 1 | /////////////////////////////////////////////////////////////////////////////// |
11e62fe6 | 2 | // Name: src/mac/carbon/listbox.cpp |
e9576ca5 | 3 | // Purpose: wxListBox |
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 |
65571936 | 9 | // Licence: wxWindows licence |
e9576ca5 SC |
10 | /////////////////////////////////////////////////////////////////////////////// |
11 | ||
3d1a4878 SC |
12 | #include "wx/wxprec.h" |
13 | ||
179e085f RN |
14 | #if wxUSE_LISTBOX |
15 | ||
03e11df5 | 16 | #include "wx/app.h" |
e9576ca5 | 17 | #include "wx/listbox.h" |
dc0ace7c | 18 | #include "wx/button.h" |
e9576ca5 | 19 | #include "wx/settings.h" |
422644a3 | 20 | #include "wx/toplevel.h" |
e9576ca5 SC |
21 | #include "wx/dynarray.h" |
22 | #include "wx/log.h" | |
23 | ||
519cb848 | 24 | #include "wx/utils.h" |
519cb848 | 25 | |
fdd4e6cc DS |
26 | #include "wx/mac/uma.h" |
27 | ||
28 | const short kTextColumnId = 1024 ; | |
29 | ||
30 | // new DataBrowser-based version: | |
31 | // because of the limited insert functionality of DataBrowser, | |
32 | // we just introduce IDs corresponding to the line number | |
33 | ||
34 | ||
e40298d5 | 35 | IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl) |
519cb848 SC |
36 | |
37 | BEGIN_EVENT_TABLE(wxListBox, wxControl) | |
684e0b31 | 38 | #ifndef __WXMAC_OSX__ |
393b27ad | 39 | // EVT_SIZE( wxListBox::OnSize ) |
e40298d5 | 40 | EVT_CHAR( wxListBox::OnChar ) |
facd6764 | 41 | #endif |
519cb848 | 42 | END_EVENT_TABLE() |
e9576ca5 | 43 | |
facd6764 | 44 | |
789ae0cf SC |
45 | DataBrowserItemDataUPP gDataBrowserItemDataUPP = NULL ; |
46 | DataBrowserItemNotificationUPP gDataBrowserItemNotificationUPP = NULL ; | |
47 | DataBrowserDrawItemUPP gDataBrowserDrawItemUPP = NULL ; | |
48 | ||
fdd4e6cc | 49 | |
83ce5634 | 50 | #if TARGET_API_MAC_OSX |
c6179a84 | 51 | static pascal void DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID, |
83ce5634 SC |
52 | DataBrowserItemNotification message, DataBrowserItemDataRef itemData) |
53 | #else | |
fdd4e6cc | 54 | static pascal void DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID, |
83ce5634 SC |
55 | DataBrowserItemNotification message) |
56 | #endif | |
57 | { | |
58 | long ref = GetControlReference( browser ) ; | |
59 | if ( ref ) | |
60 | { | |
469d8d5d | 61 | wxListBox* list = wxDynamicCast( (wxObject*) ref , wxListBox ) ; |
45285a62 | 62 | int i = itemID - 1 ; |
8228b893 | 63 | if (i >= 0 && i < (int)list->GetCount() ) |
8e0f22c0 SC |
64 | { |
65 | bool trigger = false ; | |
fdd4e6cc DS |
66 | wxCommandEvent event( wxEVT_COMMAND_LISTBOX_SELECTED, list->GetId() ); |
67 | switch ( message ) | |
83ce5634 | 68 | { |
8e0f22c0 SC |
69 | case kDataBrowserItemDeselected : |
70 | if ( list->HasMultipleSelection() ) | |
fe3dc505 | 71 | trigger = !list->MacIsSelectionSuppressed() ; |
8e0f22c0 | 72 | break ; |
fdd4e6cc | 73 | |
8e0f22c0 | 74 | case kDataBrowserItemSelected : |
fe3dc505 | 75 | trigger = !list->MacIsSelectionSuppressed() ; |
8e0f22c0 | 76 | break ; |
fdd4e6cc | 77 | |
8e0f22c0 | 78 | case kDataBrowserItemDoubleClicked : |
fdd4e6cc | 79 | event.SetEventType( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED ) ; |
8e0f22c0 SC |
80 | trigger = true ; |
81 | break ; | |
fdd4e6cc | 82 | |
8e0f22c0 SC |
83 | default : |
84 | break ; | |
83ce5634 | 85 | } |
fdd4e6cc | 86 | |
8e0f22c0 SC |
87 | if ( trigger ) |
88 | { | |
89 | event.SetEventObject( list ); | |
90 | if ( list->HasClientObjectData() ) | |
fdd4e6cc | 91 | event.SetClientObject( list->GetClientObject( i ) ); |
8e0f22c0 | 92 | else if ( list->HasClientUntypedData() ) |
fdd4e6cc DS |
93 | event.SetClientData( list->GetClientData( i ) ); |
94 | event.SetString( list->GetString( i ) ); | |
95 | event.SetInt( i ) ; | |
96 | event.SetExtraLong( list->HasMultipleSelection() ? message == kDataBrowserItemSelected : true ); | |
8e0f22c0 SC |
97 | wxPostEvent( list->GetEventHandler() , event ) ; |
98 | // direct notification is not always having the listbox GetSelection() having in synch with event | |
c6179a84 VZ |
99 | // list->GetEventHandler()->ProcessEvent(event) ; |
100 | } | |
8e0f22c0 | 101 | } |
83ce5634 SC |
102 | } |
103 | } | |
104 | ||
c6179a84 VZ |
105 | static pascal OSStatus ListBoxGetSetItemData(ControlRef browser, |
106 | DataBrowserItemID itemID, DataBrowserPropertyID property, | |
facd6764 SC |
107 | DataBrowserItemDataRef itemData, Boolean changeValue) |
108 | { | |
de1b0aeb VZ |
109 | OSStatus err = errDataBrowserPropertyNotSupported; |
110 | ||
111 | if ( ! changeValue ) | |
112 | { | |
113 | switch (property) | |
114 | { | |
de1b0aeb VZ |
115 | case kTextColumnId: |
116 | { | |
117 | long ref = GetControlReference( browser ) ; | |
118 | if ( ref ) | |
119 | { | |
120 | wxListBox* list = wxDynamicCast( (wxObject*) ref , wxListBox ) ; | |
45285a62 | 121 | int i = itemID - 1 ; |
8228b893 | 122 | if (i >= 0 && i < (int)list->GetCount() ) |
de1b0aeb | 123 | { |
fdd4e6cc | 124 | wxMacCFStringHolder cf( list->GetString( i ) , list->GetFont().GetEncoding() ) ; |
de1b0aeb VZ |
125 | verify_noerr( ::SetDataBrowserItemDataText( itemData , cf ) ) ; |
126 | err = noErr ; | |
127 | } | |
128 | } | |
129 | } | |
fdd4e6cc | 130 | break; |
c6179a84 | 131 | |
de1b0aeb | 132 | default: |
fdd4e6cc | 133 | break; |
de1b0aeb VZ |
134 | } |
135 | } | |
c6179a84 | 136 | |
de1b0aeb | 137 | return err; |
facd6764 | 138 | } |
fe3dc505 | 139 | |
789ae0cf SC |
140 | static pascal void ListBoxDrawProc( ControlRef browser , DataBrowserItemID item , DataBrowserPropertyID property , |
141 | DataBrowserItemState itemState , const Rect *itemRect , SInt16 depth , Boolean isColorDevice ) | |
142 | { | |
789ae0cf | 143 | CFStringRef cfString; |
fdd4e6cc | 144 | ThemeDrawingState themeState ; |
789ae0cf SC |
145 | long systemVersion; |
146 | ||
789ae0cf | 147 | GetThemeDrawingState( &themeState ) ; |
fdd4e6cc | 148 | cfString = CFStringCreateWithFormat( NULL, NULL, CFSTR("Row %d"), item ); |
de1b0aeb | 149 | |
fdd4e6cc DS |
150 | // In this sample we handle the "selected" state; all others fall through to our "active" state |
151 | if ( itemState == kDataBrowserItemIsSelected ) | |
789ae0cf | 152 | { |
fdd4e6cc DS |
153 | ThemeBrush colorBrushID; |
154 | ||
789ae0cf | 155 | Gestalt( gestaltSystemVersion, &systemVersion ); |
fdd4e6cc DS |
156 | |
157 | // TODO: switch over to wxSystemSettingsNative::GetColour() when kThemeBrushSecondaryHighlightColor is incorporated | |
158 | // Panther DB starts using kThemeBrushSecondaryHighlightColor for inactive browser hilighting | |
159 | if ( (systemVersion >= 0x00001030) && !IsControlActive( browser ) ) | |
160 | colorBrushID = kThemeBrushSecondaryHighlightColor; | |
789ae0cf | 161 | else |
fdd4e6cc | 162 | colorBrushID = kThemeBrushPrimaryHighlightColor; |
789ae0cf | 163 | |
fdd4e6cc DS |
164 | // First paint the hilite rect, then the text on top |
165 | SetThemePen( colorBrushID, 32, true ); | |
166 | PaintRect( itemRect ); | |
789ae0cf SC |
167 | SetThemeDrawingState( themeState , false ) ; |
168 | } | |
fdd4e6cc | 169 | |
789ae0cf | 170 | DrawThemeTextBox( cfString, kThemeApplicationFont, kThemeStateActive, true, itemRect, teFlushDefault, NULL ); |
fdd4e6cc DS |
171 | SetThemeDrawingState( themeState , true ) ; |
172 | ||
de1b0aeb | 173 | if ( cfString != NULL ) |
789ae0cf | 174 | CFRelease( cfString ); |
789ae0cf | 175 | } |
fe3dc505 SC |
176 | |
177 | // Listbox item | |
178 | wxListBox::wxListBox() | |
179 | { | |
fdd4e6cc DS |
180 | m_noItems = 0; |
181 | m_selected = 0; | |
182 | m_macList = NULL ; | |
183 | m_suppressSelection = false ; | |
fe3dc505 SC |
184 | } |
185 | ||
fdd4e6cc DS |
186 | bool wxListBox::Create(wxWindow *parent, |
187 | wxWindowID id, | |
188 | const wxPoint& pos, | |
189 | const wxSize& size, | |
190 | const wxArrayString& choices, | |
191 | long style, | |
192 | const wxValidator& validator, | |
193 | const wxString& name) | |
fe3dc505 SC |
194 | { |
195 | wxCArrayString chs(choices); | |
196 | ||
197 | return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(), | |
198 | style, validator, name); | |
199 | } | |
200 | ||
fdd4e6cc DS |
201 | bool wxListBox::Create(wxWindow *parent, |
202 | wxWindowID id, | |
203 | const wxPoint& pos, | |
204 | const wxSize& size, | |
205 | int n, | |
206 | const wxString choices[], | |
207 | long style, | |
208 | const wxValidator& validator, | |
209 | const wxString& name) | |
facd6764 | 210 | { |
fdd4e6cc | 211 | m_macIsUserPane = false ; |
5e6f42cd SC |
212 | |
213 | wxASSERT_MSG( !(style & wxLB_MULTIPLE) || !(style & wxLB_EXTENDED), | |
214 | _T("only one of listbox selection modes can be specified") ); | |
c6179a84 | 215 | |
facd6764 SC |
216 | if ( !wxListBoxBase::Create(parent, id, pos, size, style & ~(wxHSCROLL|wxVSCROLL), validator, name) ) |
217 | return false; | |
218 | ||
219 | m_noItems = 0 ; // this will be increased by our append command | |
220 | m_selected = 0; | |
facd6764 SC |
221 | |
222 | Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ; | |
facd6764 | 223 | |
fdd4e6cc DS |
224 | m_peer = new wxMacControl( this ) ; |
225 | verify_noerr( | |
226 | ::CreateDataBrowserControl( | |
227 | MAC_WXHWND(parent->MacGetTopLevelWindowRef()), &bounds, | |
228 | kDataBrowserListView, m_peer->GetControlRefAddr() ) ); | |
facd6764 SC |
229 | |
230 | DataBrowserSelectionFlags options = kDataBrowserDragSelect ; | |
231 | if ( style & wxLB_MULTIPLE ) | |
fdd4e6cc | 232 | options |= kDataBrowserAlwaysExtendSelection | kDataBrowserCmdTogglesSelection ; |
facd6764 | 233 | else if ( style & wxLB_EXTENDED ) |
fdd4e6cc | 234 | ; // default behaviour |
facd6764 | 235 | else |
fdd4e6cc DS |
236 | options |= kDataBrowserSelectOnlyOne ; |
237 | ||
238 | verify_noerr( m_peer->SetSelectionFlags( options ) ); | |
de1b0aeb | 239 | |
fdd4e6cc DS |
240 | if ( gDataBrowserItemDataUPP == NULL ) |
241 | gDataBrowserItemDataUPP = NewDataBrowserItemDataUPP(ListBoxGetSetItemData) ; | |
789ae0cf | 242 | if ( gDataBrowserItemNotificationUPP == NULL ) |
de1b0aeb VZ |
243 | { |
244 | gDataBrowserItemNotificationUPP = | |
789ae0cf | 245 | #if TARGET_API_MAC_OSX |
de1b0aeb | 246 | (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc) ; |
789ae0cf | 247 | #else |
de1b0aeb | 248 | NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc) ; |
789ae0cf | 249 | #endif |
de1b0aeb | 250 | } |
fdd4e6cc DS |
251 | |
252 | if ( gDataBrowserDrawItemUPP == NULL ) | |
253 | gDataBrowserDrawItemUPP = NewDataBrowserDrawItemUPP(ListBoxDrawProc) ; | |
789ae0cf SC |
254 | |
255 | DataBrowserCallbacks callbacks ; | |
256 | InitializeDataBrowserCallbacks( &callbacks , kDataBrowserLatestCallbacks ) ; | |
facd6764 | 257 | |
789ae0cf | 258 | callbacks.u.v1.itemDataCallback = gDataBrowserItemDataUPP; |
de1b0aeb | 259 | callbacks.u.v1.itemNotificationCallback = gDataBrowserItemNotificationUPP; |
789ae0cf SC |
260 | m_peer->SetCallbacks( &callbacks); |
261 | ||
262 | DataBrowserCustomCallbacks customCallbacks ; | |
de1b0aeb VZ |
263 | InitializeDataBrowserCustomCallbacks( &customCallbacks , kDataBrowserLatestCustomCallbacks ) ; |
264 | ||
789ae0cf | 265 | customCallbacks.u.v1.drawItemCallback = gDataBrowserDrawItemUPP ; |
de1b0aeb VZ |
266 | |
267 | SetDataBrowserCustomCallbacks( m_peer->GetControlRef() , &customCallbacks ) ; | |
268 | ||
facd6764 SC |
269 | DataBrowserListViewColumnDesc columnDesc ; |
270 | columnDesc.headerBtnDesc.titleOffset = 0; | |
de1b0aeb | 271 | columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc; |
fdd4e6cc | 272 | columnDesc.headerBtnDesc.btnFontStyle.flags = kControlUseFontMask | kControlUseJustMask; |
de1b0aeb VZ |
273 | columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlNoContent; |
274 | columnDesc.headerBtnDesc.btnFontStyle.just = teFlushDefault; | |
275 | columnDesc.headerBtnDesc.minimumWidth = 0; | |
276 | columnDesc.headerBtnDesc.maximumWidth = 10000; | |
c6179a84 | 277 | |
de1b0aeb VZ |
278 | columnDesc.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont; |
279 | columnDesc.headerBtnDesc.btnFontStyle.style = normal; | |
280 | columnDesc.headerBtnDesc.titleString = NULL ; // CFSTR( "" ); | |
facd6764 | 281 | |
de1b0aeb VZ |
282 | columnDesc.propertyDesc.propertyID = kTextColumnId; |
283 | columnDesc.propertyDesc.propertyType = kDataBrowserTextType ; // kDataBrowserCustomType; | |
fdd4e6cc DS |
284 | columnDesc.propertyDesc.propertyFlags = kDataBrowserTableViewSelectionColumn; |
285 | ||
9bd2d050 | 286 | #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 |
fdd4e6cc | 287 | columnDesc.propertyDesc.propertyFlags |= kDataBrowserListViewTypeSelectColumn; |
c2697b87 | 288 | #endif |
facd6764 | 289 | |
fdd4e6cc DS |
290 | verify_noerr( m_peer->AddListViewColumn( &columnDesc, kDataBrowserListViewAppendColumn ) ) ; |
291 | verify_noerr( m_peer->AutoSizeListViewColumns() ) ; | |
292 | verify_noerr( m_peer->SetHasScrollBars( false, true ) ) ; | |
293 | verify_noerr( m_peer->SetTableViewHiliteStyle( kDataBrowserTableViewFillHilite ) ) ; | |
294 | verify_noerr( m_peer->SetListViewHeaderBtnHeight( 0 ) ) ; | |
c6179a84 | 295 | |
789ae0cf SC |
296 | #if 0 |
297 | // shouldn't be necessary anymore under 10.2 | |
298 | m_peer->SetData( kControlNoPart, kControlDataBrowserIncludesFrameAndFocusTag, (Boolean) false ) ; | |
299 | m_peer->SetNeedsFocusRect( true ) ; | |
83ce5634 | 300 | #endif |
facd6764 | 301 | |
fdd4e6cc | 302 | MacPostControlCreate( pos, size ) ; |
facd6764 SC |
303 | |
304 | for ( int i = 0 ; i < n ; i++ ) | |
305 | { | |
306 | Append( choices[i] ) ; | |
307 | } | |
308 | ||
fdd4e6cc DS |
309 | // Needed because it is a wxControlWithItems |
310 | SetBestSize(size); | |
c6179a84 | 311 | |
fdd4e6cc | 312 | return true; |
facd6764 SC |
313 | } |
314 | ||
315 | wxListBox::~wxListBox() | |
316 | { | |
77eddfb7 | 317 | m_peer->SetReference( 0 ) ; |
facd6764 | 318 | FreeData() ; |
fdd4e6cc | 319 | |
facd6764 SC |
320 | // avoid access during destruction |
321 | if ( m_macList ) | |
facd6764 | 322 | m_macList = NULL ; |
facd6764 SC |
323 | } |
324 | ||
325 | void wxListBox::FreeData() | |
326 | { | |
facd6764 SC |
327 | if ( HasClientObjectData() ) |
328 | { | |
aa61d352 | 329 | for ( unsigned int n = 0; n < m_noItems; n++ ) |
facd6764 | 330 | { |
fdd4e6cc | 331 | delete GetClientObject( n ); |
facd6764 SC |
332 | } |
333 | } | |
334 | } | |
335 | ||
336 | void wxListBox::DoSetSize(int x, int y, | |
337 | int width, int height, | |
338 | int sizeFlags ) | |
339 | { | |
340 | wxControl::DoSetSize( x , y , width , height , sizeFlags ) ; | |
341 | } | |
342 | ||
fdd4e6cc | 343 | void wxListBox::DoSetFirstItem(int n) |
facd6764 | 344 | { |
fdd4e6cc | 345 | MacScrollTo( n ) ; |
facd6764 SC |
346 | } |
347 | ||
aa61d352 | 348 | void wxListBox::Delete(unsigned int n) |
facd6764 | 349 | { |
8228b893 | 350 | wxCHECK_RET( IsValid(n), |
facd6764 SC |
351 | wxT("invalid index in wxListBox::Delete") ); |
352 | ||
facd6764 | 353 | if ( HasClientObjectData() ) |
fdd4e6cc DS |
354 | delete GetClientObject( n ); |
355 | ||
356 | m_stringArray.RemoveAt( n ) ; | |
357 | m_dataArray.RemoveAt( n ) ; | |
358 | m_noItems--; | |
facd6764 | 359 | |
fdd4e6cc | 360 | MacDelete( n ) ; |
facd6764 SC |
361 | } |
362 | ||
363 | int wxListBox::DoAppend(const wxString& item) | |
364 | { | |
9f884528 RD |
365 | InvalidateBestSize(); |
366 | ||
aa61d352 | 367 | unsigned int index = m_noItems ; |
facd6764 SC |
368 | m_stringArray.Add( item ) ; |
369 | m_dataArray.Add( NULL ); | |
fdd4e6cc | 370 | m_noItems++; |
facd6764 SC |
371 | DoSetItemClientData( index , NULL ) ; |
372 | MacAppend( item ) ; | |
373 | ||
374 | return index ; | |
375 | } | |
376 | ||
377 | void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData) | |
378 | { | |
379 | Clear() ; | |
aa61d352 | 380 | unsigned int n = choices.GetCount(); |
c6179a84 | 381 | |
8228b893 | 382 | for ( size_t i = 0 ; i < n ; ++i ) |
facd6764 SC |
383 | { |
384 | if ( clientData ) | |
facd6764 | 385 | Append( choices[i] , clientData[i] ) ; |
facd6764 SC |
386 | else |
387 | Append( choices[i] ) ; | |
388 | } | |
facd6764 SC |
389 | } |
390 | ||
11e62fe6 | 391 | int wxListBox::FindString(const wxString& s, bool bCase) const |
facd6764 | 392 | { |
429bf230 | 393 | for ( size_t i = 0 ; i < m_noItems ; ++ i ) |
facd6764 | 394 | { |
429bf230 JS |
395 | if (s.IsSameAs(GetString(i), bCase)) |
396 | return (int)i ; | |
facd6764 | 397 | } |
fdd4e6cc | 398 | |
11e62fe6 | 399 | return wxNOT_FOUND; |
facd6764 SC |
400 | } |
401 | ||
402 | void wxListBox::Clear() | |
403 | { | |
404 | FreeData(); | |
405 | m_noItems = 0; | |
406 | m_stringArray.Empty() ; | |
407 | m_dataArray.Empty() ; | |
408 | MacClear() ; | |
409 | } | |
410 | ||
fdd4e6cc | 411 | void wxListBox::DoSetSelection(int n, bool select) |
facd6764 | 412 | { |
8228b893 | 413 | wxCHECK_RET( n == wxNOT_FOUND || IsValid(n) , |
facd6764 | 414 | wxT("invalid index in wxListBox::SetSelection") ); |
c6179a84 | 415 | |
fdd4e6cc | 416 | if ( n == wxNOT_FOUND ) |
fe3dc505 SC |
417 | MacDeselectAll() ; |
418 | else | |
fdd4e6cc | 419 | MacSetSelection( n , select ) ; |
facd6764 SC |
420 | } |
421 | ||
fdd4e6cc | 422 | bool wxListBox::IsSelected(int n) const |
facd6764 | 423 | { |
8228b893 | 424 | wxCHECK_MSG( IsValid(n), false, |
facd6764 | 425 | wxT("invalid index in wxListBox::Selected") ); |
c6179a84 | 426 | |
fdd4e6cc | 427 | return MacIsSelected( n ) ; |
facd6764 SC |
428 | } |
429 | ||
aa61d352 | 430 | void *wxListBox::DoGetItemClientData(unsigned int n) const |
facd6764 | 431 | { |
8228b893 WS |
432 | wxCHECK_MSG( IsValid(n), NULL, wxT("invalid index in wxListBox::GetClientData")); |
433 | ||
aa61d352 | 434 | wxASSERT_MSG( m_dataArray.GetCount() >= (unsigned int) n , wxT("invalid client_data array") ) ; |
c6179a84 | 435 | |
fdd4e6cc | 436 | return (void *)m_dataArray[n]; |
facd6764 SC |
437 | } |
438 | ||
aa61d352 | 439 | wxClientData *wxListBox::DoGetItemClientObject(unsigned int n) const |
facd6764 | 440 | { |
fdd4e6cc | 441 | return (wxClientData *) DoGetItemClientData( n ) ; |
facd6764 SC |
442 | } |
443 | ||
aa61d352 | 444 | void wxListBox::DoSetItemClientData(unsigned int n, void *clientData) |
facd6764 | 445 | { |
8228b893 | 446 | wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::SetClientData") ); |
c6179a84 | 447 | |
aa61d352 | 448 | wxASSERT_MSG( m_dataArray.GetCount() >= (unsigned int) n , wxT("invalid client_data array") ) ; |
c6179a84 | 449 | |
aa61d352 | 450 | if ( m_dataArray.GetCount() > (unsigned int) n ) |
fdd4e6cc | 451 | m_dataArray[n] = (char*)clientData ; |
facd6764 | 452 | else |
fdd4e6cc | 453 | m_dataArray.Add( (char*)clientData ) ; |
facd6764 SC |
454 | } |
455 | ||
aa61d352 | 456 | void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) |
facd6764 SC |
457 | { |
458 | DoSetItemClientData(n, clientData); | |
459 | } | |
460 | ||
461 | // Return number of selections and an array of selected integers | |
462 | int wxListBox::GetSelections(wxArrayInt& aSelections) const | |
463 | { | |
464 | return MacGetSelections( aSelections ) ; | |
465 | } | |
466 | ||
467 | // Get single selection, for single choice list items | |
468 | int wxListBox::GetSelection() const | |
469 | { | |
470 | return MacGetSelection() ; | |
471 | } | |
472 | ||
473 | // Find string for position | |
aa61d352 | 474 | wxString wxListBox::GetString(unsigned int n) const |
facd6764 | 475 | { |
8228b893 | 476 | wxCHECK_MSG( IsValid(n), wxEmptyString, |
55ae2833 RD |
477 | wxT("invalid index in wxListBox::GetString") ); |
478 | ||
fdd4e6cc | 479 | return m_stringArray[n] ; |
facd6764 SC |
480 | } |
481 | ||
aa61d352 | 482 | void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) |
facd6764 | 483 | { |
8228b893 | 484 | wxCHECK_RET( IsValidInsert(pos), |
facd6764 | 485 | wxT("invalid index in wxListBox::InsertItems") ); |
c6179a84 | 486 | |
9f884528 RD |
487 | InvalidateBestSize(); |
488 | ||
aa61d352 | 489 | unsigned int nItems = items.GetCount(); |
c6179a84 | 490 | |
aa61d352 | 491 | for ( unsigned int i = 0 ; i < nItems ; i++ ) |
facd6764 SC |
492 | { |
493 | m_stringArray.Insert( items[i] , pos + i ) ; | |
494 | m_dataArray.Insert( NULL , pos + i ) ; | |
8e0f22c0 | 495 | m_noItems++ ; |
facd6764 SC |
496 | MacInsert( pos + i , items[i] ) ; |
497 | } | |
facd6764 SC |
498 | } |
499 | ||
aa61d352 | 500 | void wxListBox::SetString(unsigned int n, const wxString& s) |
facd6764 | 501 | { |
fdd4e6cc DS |
502 | m_stringArray[n] = s ; |
503 | MacSet( n , s ) ; | |
facd6764 SC |
504 | } |
505 | ||
506 | wxSize wxListBox::DoGetBestSize() const | |
507 | { | |
508 | int lbWidth = 100; // some defaults | |
509 | int lbHeight = 110; | |
510 | int wLine; | |
511 | ||
512 | { | |
fdd4e6cc | 513 | wxMacPortStateHelper st( UMAGetWindowPort( (WindowRef)MacGetTopLevelWindowRef() ) ) ; |
c6179a84 | 514 | |
fdd4e6cc | 515 | // TODO: clean this up |
facd6764 SC |
516 | if ( m_font.Ok() ) |
517 | { | |
518 | ::TextFont( m_font.MacGetFontNum() ) ; | |
519 | ::TextSize( m_font.MacGetFontSize() ) ; | |
520 | ::TextFace( m_font.MacGetFontStyle() ) ; | |
521 | } | |
522 | else | |
523 | { | |
524 | ::TextFont( kFontIDMonaco ) ; | |
525 | ::TextSize( 9 ); | |
526 | ::TextFace( 0 ) ; | |
527 | } | |
c6179a84 | 528 | |
facd6764 | 529 | // Find the widest line |
aa61d352 | 530 | for (unsigned int i = 0; i < GetCount(); i++) |
fdd4e6cc | 531 | { |
aa61d352 | 532 | wxString str(GetString(i)); |
fdd4e6cc DS |
533 | |
534 | #if wxUSE_UNICODE | |
535 | Point bounds = {0, 0} ; | |
facd6764 | 536 | SInt16 baseline ; |
fdd4e6cc DS |
537 | |
538 | // NB: what if m_font.Ok() == false ??? | |
539 | ::GetThemeTextDimensions( | |
540 | wxMacCFStringHolder( str , m_font.GetEncoding() ) , | |
facd6764 SC |
541 | kThemeCurrentPortFont, |
542 | kThemeStateActive, | |
543 | false, | |
544 | &bounds, | |
545 | &baseline ); | |
546 | wLine = bounds.h ; | |
fdd4e6cc | 547 | #else |
8228b893 | 548 | wLine = ::TextWidth( str.c_str() , 0 , str.length() ) ; |
fdd4e6cc DS |
549 | #endif |
550 | ||
551 | lbWidth = wxMax( lbWidth, wLine ); | |
facd6764 | 552 | } |
c6179a84 | 553 | |
facd6764 SC |
554 | // Add room for the scrollbar |
555 | lbWidth += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X); | |
c6179a84 | 556 | |
facd6764 SC |
557 | // And just a bit more |
558 | int cy = 12 ; | |
559 | int cx = ::TextWidth( "X" , 0 , 1 ) ; | |
560 | lbWidth += cx ; | |
c6179a84 | 561 | |
fdd4e6cc DS |
562 | // don't make the listbox too tall (limit height to around 10 items) |
563 | // but don't make it too small neither | |
9761ab43 | 564 | lbHeight = wxMax( (cy + 4) * wxMin( wxMax( GetCount(), 3 ), 10 ), 70 ); |
facd6764 SC |
565 | } |
566 | ||
fdd4e6cc | 567 | return wxSize( lbWidth, lbHeight ); |
facd6764 SC |
568 | } |
569 | ||
aa61d352 | 570 | unsigned int wxListBox::GetCount() const |
facd6764 SC |
571 | { |
572 | return m_noItems; | |
573 | } | |
574 | ||
575 | void wxListBox::Refresh(bool eraseBack, const wxRect *rect) | |
576 | { | |
577 | wxControl::Refresh( eraseBack , rect ) ; | |
facd6764 SC |
578 | } |
579 | ||
b6a20a20 RD |
580 | // Some custom controls depend on this |
581 | /* static */ wxVisualAttributes | |
582 | wxListBox::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant)) | |
583 | { | |
584 | wxVisualAttributes attr; | |
fdd4e6cc DS |
585 | |
586 | attr.colFg = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ); | |
587 | attr.colBg = wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX ); | |
588 | attr.font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ); | |
589 | ||
b6a20a20 RD |
590 | return attr; |
591 | } | |
592 | ||
facd6764 SC |
593 | // ============================================================================ |
594 | // list box control implementation | |
595 | // ============================================================================ | |
596 | ||
fe3dc505 | 597 | void wxListBox::MacDelete( int n ) |
facd6764 | 598 | { |
fe3dc505 SC |
599 | wxArrayInt selectionBefore ; |
600 | MacGetSelections( selectionBefore ) ; | |
601 | ||
fdd4e6cc DS |
602 | UInt32 id = m_noItems + 1 ; |
603 | ||
5ca0d812 | 604 | verify_noerr( m_peer->RemoveItems( kDataBrowserNoItem , 1 , (UInt32*) &id , kDataBrowserItemNoProperty ) ) ; |
aa61d352 | 605 | for ( unsigned int i = 0 ; i < selectionBefore.GetCount() ; ++i ) |
fe3dc505 SC |
606 | { |
607 | int current = selectionBefore[i] ; | |
608 | if ( current == n ) | |
609 | { | |
610 | // selection was deleted | |
611 | MacSetSelection( current , false ) ; | |
612 | } | |
613 | else if ( current > n ) | |
614 | { | |
615 | // something behind the deleted item was selected -> move up | |
c6179a84 | 616 | MacSetSelection( current - 1 , true ) ; |
fe3dc505 SC |
617 | MacSetSelection( current , false ) ; |
618 | } | |
619 | } | |
fdd4e6cc | 620 | |
fe3dc505 | 621 | // refresh all |
fdd4e6cc DS |
622 | verify_noerr( |
623 | m_peer->UpdateItems( | |
624 | kDataBrowserNoItem, 1, (UInt32*)kDataBrowserNoItem, | |
625 | kDataBrowserItemNoProperty, kDataBrowserItemNoProperty ) ) ; | |
facd6764 SC |
626 | } |
627 | ||
fdd4e6cc | 628 | void wxListBox::MacInsert( int n , const wxString& text ) |
facd6764 | 629 | { |
fe3dc505 SC |
630 | wxArrayInt selectionBefore ; |
631 | MacGetSelections( selectionBefore ) ; | |
632 | ||
fdd4e6cc DS |
633 | // this has already been increased |
634 | UInt32 id = m_noItems ; | |
635 | verify_noerr( m_peer->AddItems( kDataBrowserNoItem , 1 , (UInt32*) &id , kDataBrowserItemNoProperty ) ) ; | |
fe3dc505 SC |
636 | |
637 | for ( int i = selectionBefore.GetCount()-1 ; i >= 0 ; --i ) | |
638 | { | |
639 | int current = selectionBefore[i] ; | |
640 | if ( current >= n ) | |
641 | { | |
c6179a84 | 642 | MacSetSelection( current + 1 , true ) ; |
fe3dc505 SC |
643 | MacSetSelection( current , false ) ; |
644 | } | |
645 | } | |
646 | ||
647 | // refresh all | |
fdd4e6cc DS |
648 | verify_noerr( |
649 | m_peer->UpdateItems( | |
650 | kDataBrowserNoItem, 1, (UInt32*)kDataBrowserNoItem, | |
651 | kDataBrowserItemNoProperty, kDataBrowserItemNoProperty ) ) ; | |
facd6764 SC |
652 | } |
653 | ||
fdd4e6cc | 654 | void wxListBox::MacAppend( const wxString& text ) |
facd6764 | 655 | { |
8e0f22c0 | 656 | UInt32 id = m_noItems ; // this has already been increased |
fdd4e6cc | 657 | verify_noerr( m_peer->AddItems( kDataBrowserNoItem , 1 , (UInt32*) &id , kDataBrowserItemNoProperty ) ) ; |
fe3dc505 | 658 | // no need to deal with selections nor refreshed, as we have appended |
facd6764 SC |
659 | } |
660 | ||
661 | void wxListBox::MacClear() | |
662 | { | |
5ca0d812 | 663 | verify_noerr( m_peer->RemoveItems( kDataBrowserNoItem , 0 , NULL , kDataBrowserItemNoProperty ) ) ; |
facd6764 SC |
664 | } |
665 | ||
c6179a84 | 666 | void wxListBox::MacDeselectAll() |
fe3dc505 SC |
667 | { |
668 | bool former = MacSuppressSelection( true ) ; | |
669 | verify_noerr(m_peer->SetSelectedItems( 0 , NULL , kDataBrowserItemsRemove ) ) ; | |
670 | MacSuppressSelection( former ) ; | |
671 | } | |
672 | ||
facd6764 SC |
673 | void wxListBox::MacSetSelection( int n , bool select ) |
674 | { | |
fe3dc505 | 675 | bool former = MacSuppressSelection( true ) ; |
8e0f22c0 | 676 | UInt32 id = n + 1 ; |
fe3dc505 | 677 | |
5ca0d812 | 678 | if ( m_peer->IsItemSelected( id ) != select ) |
facd6764 | 679 | { |
fe3dc505 | 680 | if ( select ) |
fdd4e6cc | 681 | verify_noerr( m_peer->SetSelectedItems( 1 , & id , HasMultipleSelection() ? kDataBrowserItemsAdd : kDataBrowserItemsAssign ) ) ; |
fe3dc505 | 682 | else |
fdd4e6cc | 683 | verify_noerr( m_peer->SetSelectedItems( 1 , & id , kDataBrowserItemsRemove ) ) ; |
facd6764 | 684 | } |
fdd4e6cc | 685 | |
facd6764 | 686 | MacScrollTo( n ) ; |
fe3dc505 SC |
687 | MacSuppressSelection( former ) ; |
688 | } | |
689 | ||
fdd4e6cc | 690 | bool wxListBox::MacSuppressSelection( bool suppress ) |
fe3dc505 | 691 | { |
de1b0aeb VZ |
692 | bool former = m_suppressSelection ; |
693 | m_suppressSelection = suppress ; | |
694 | return former ; | |
facd6764 SC |
695 | } |
696 | ||
697 | bool wxListBox::MacIsSelected( int n ) const | |
698 | { | |
8e0f22c0 | 699 | return m_peer->IsItemSelected( n + 1 ) ; |
facd6764 SC |
700 | } |
701 | ||
702 | int wxListBox::MacGetSelection() const | |
703 | { | |
aa61d352 | 704 | for ( unsigned int i = 0 ; i < GetCount() ; ++i ) |
facd6764 | 705 | { |
8e0f22c0 | 706 | if ( m_peer->IsItemSelected( i + 1 ) ) |
facd6764 | 707 | return i ; |
facd6764 | 708 | } |
fdd4e6cc | 709 | |
fe3dc505 | 710 | return -1 ; |
facd6764 SC |
711 | } |
712 | ||
713 | int wxListBox::MacGetSelections( wxArrayInt& aSelections ) const | |
714 | { | |
715 | int no_sel = 0 ; | |
c6179a84 | 716 | |
facd6764 | 717 | aSelections.Empty(); |
c6179a84 | 718 | |
fe3dc505 SC |
719 | UInt32 first , last ; |
720 | m_peer->GetSelectionAnchor( &first , &last ) ; | |
721 | if ( first != kDataBrowserNoItem ) | |
facd6764 | 722 | { |
0b9cd93c | 723 | for ( size_t i = first ; i <= last ; ++i ) |
facd6764 | 724 | { |
fe3dc505 SC |
725 | if ( m_peer->IsItemSelected( i ) ) |
726 | { | |
727 | aSelections.Add( i - 1 ) ; | |
728 | no_sel++ ; | |
729 | } | |
facd6764 SC |
730 | } |
731 | } | |
fdd4e6cc | 732 | |
facd6764 SC |
733 | return no_sel ; |
734 | } | |
519cb848 | 735 | |
facd6764 SC |
736 | void wxListBox::MacSet( int n , const wxString& text ) |
737 | { | |
738 | // as we don't store the strings we only have to issue a redraw | |
8e0f22c0 | 739 | UInt32 id = n + 1 ; |
5ca0d812 | 740 | verify_noerr( m_peer->UpdateItems( kDataBrowserNoItem , 1 , &id , kDataBrowserItemNoProperty , kDataBrowserItemNoProperty ) ) ; |
facd6764 | 741 | } |
e42e45a9 | 742 | |
facd6764 SC |
743 | void wxListBox::MacScrollTo( int n ) |
744 | { | |
8e0f22c0 | 745 | UInt32 id = n + 1 ; |
fdd4e6cc | 746 | verify_noerr( m_peer->RevealItem( id , kTextColumnId , kDataBrowserRevealWithoutSelecting ) ) ; |
facd6764 SC |
747 | } |
748 | ||
443e2f09 VZ |
749 | int wxListBox::DoListHitTest(const wxPoint& inpoint) const |
750 | { | |
751 | OSErr err; | |
752 | ||
753 | // There are few reasons why this is complicated: | |
754 | // 1) There is no native hittest function for mac | |
755 | // 2) GetDataBrowserItemPartBounds only works on visible items | |
756 | // 3) We can't do it through GetDataBrowserTableView[Item]RowHeight | |
757 | // because what it returns is basically inaccurate in the context | |
758 | // of the coordinates we want here, but we use this as a guess | |
759 | // for where the first visible item lies | |
760 | ||
761 | wxPoint point = inpoint; | |
762 | // interestingly enough 10.2 (and below?) have GetDataBrowserItemPartBounds | |
763 | // giving root window coordinates but 10.3 and above give client coordinates | |
764 | // so we only compare using root window coordinates on 10.3 and up | |
765 | if ( UMAGetSystemVersion() < 0x1030 ) | |
766 | MacClientToRootWindow(&point.x, &point.y); | |
767 | ||
768 | // get column property id (req. for call to itempartbounds) | |
c00fed0e | 769 | DataBrowserTableViewColumnID colId = 0; |
443e2f09 VZ |
770 | err = GetDataBrowserTableViewColumnProperty(m_peer->GetControlRef(), 0, &colId); |
771 | wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserTableViewColumnProperty")); | |
772 | ||
773 | // OK, first we need to find the first visible item we have - | |
774 | // this will be the "low" for our binary search. There is no real | |
775 | // easy way around this, as we will need to do a SLOW linear search | |
776 | // until we find a visible item, but we can do a cheap calculation | |
777 | // via the row height to speed things up a bit | |
778 | UInt32 scrollx, scrolly; | |
779 | err = GetDataBrowserScrollPosition(m_peer->GetControlRef(), &scrollx, &scrolly); | |
780 | wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserScrollPosition")); | |
781 | ||
782 | UInt16 height; | |
783 | err = GetDataBrowserTableViewRowHeight(m_peer->GetControlRef(), &height); | |
784 | wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserTableViewRowHeight")); | |
785 | ||
786 | // these indices are 0-based, as usual, so we need to add 1 to them when | |
787 | // passing them to data browser functions which use 1-based indices | |
788 | int low = scrolly / height, | |
789 | high = GetCount() - 1; | |
790 | ||
791 | ||
792 | // search for the first visible item (note that the scroll guess above | |
793 | // is the low bounds of where the item might lie so we only use that as a | |
794 | // starting point - we should reach it within 1 or 2 iterations of the loop) | |
795 | while ( low <= high ) | |
796 | { | |
797 | Rect bounds; | |
798 | err = GetDataBrowserItemPartBounds(m_peer->GetControlRef(), low + 1, colId, | |
799 | kDataBrowserPropertyEnclosingPart, | |
800 | &bounds); //note +1 to trans to mac id | |
801 | if ( err == noErr ) | |
802 | break; | |
803 | ||
804 | // errDataBrowserItemNotFound is expected as it simply means that the | |
805 | // item is not currently visible -- but other errors are not | |
806 | wxCHECK_MSG( err == errDataBrowserItemNotFound, wxNOT_FOUND, | |
807 | wxT("Unexpected error from GetDataBrowserItemPartBounds") ); | |
808 | ||
809 | low++; | |
810 | } | |
c00fed0e | 811 | |
443e2f09 VZ |
812 | // NOW do a binary search for where the item lies, searching low again if |
813 | // we hit an item that isn't visible | |
814 | while ( low <= high ) | |
c00fed0e | 815 | { |
443e2f09 VZ |
816 | int mid = (low + high) / 2; |
817 | ||
c00fed0e | 818 | Rect bounds; |
443e2f09 VZ |
819 | err = GetDataBrowserItemPartBounds(m_peer->GetControlRef(), mid + 1, colId, |
820 | kDataBrowserPropertyEnclosingPart, | |
821 | &bounds); //note +1 to trans to mac id | |
822 | wxCHECK_MSG( err == noErr || err == errDataBrowserItemNotFound, | |
823 | wxNOT_FOUND, | |
824 | wxT("Unexpected error from GetDataBrowserItemPartBounds") ); | |
825 | ||
826 | if ( err == errDataBrowserItemNotFound ) | |
c00fed0e | 827 | { |
443e2f09 VZ |
828 | // item not visible, attempt to find a visible one |
829 | high = mid - 1; // search lower | |
830 | } | |
831 | else // visible item, do actual hitttest | |
832 | { | |
833 | // if point is within the bounds, return this item (since we assume | |
834 | // all x coords of items are equal we only test the x coord in | |
835 | // equality) | |
836 | if( (point.x >= bounds.left && point.x <= bounds.right) && | |
837 | (point.y >= bounds.top && point.y <= bounds.bottom) ) | |
838 | { | |
839 | return mid; // found! | |
840 | } | |
841 | ||
842 | if ( point.y < bounds.top ) | |
843 | high = mid - 1; // index(bounds) greater then key(point) | |
844 | else | |
845 | low = mid + 1; // index(bounds) less then key(point) | |
c00fed0e VZ |
846 | } |
847 | } | |
443e2f09 | 848 | |
c00fed0e VZ |
849 | return wxNOT_FOUND; |
850 | } | |
851 | ||
5ecae0b7 SC |
852 | #if !TARGET_API_MAC_OSX |
853 | ||
facd6764 SC |
854 | void wxListBox::OnChar(wxKeyEvent& event) |
855 | { | |
fdd4e6cc | 856 | // TODO: trigger proper events here |
facd6764 SC |
857 | event.Skip() ; |
858 | return ; | |
c6179a84 | 859 | |
facd6764 SC |
860 | if ( event.GetKeyCode() == WXK_RETURN || event.GetKeyCode() == WXK_NUMPAD_ENTER) |
861 | { | |
862 | wxWindow* parent = GetParent() ; | |
fdd4e6cc DS |
863 | |
864 | while ( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL ) | |
facd6764 | 865 | parent = parent->GetParent() ; |
c6179a84 | 866 | |
facd6764 SC |
867 | if ( parent && parent->GetDefaultItem() ) |
868 | { | |
fdd4e6cc | 869 | wxButton *def = wxDynamicCast(parent->GetDefaultItem(), wxButton); |
facd6764 SC |
870 | if ( def && def->IsEnabled() ) |
871 | { | |
fdd4e6cc DS |
872 | wxCommandEvent event( wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() ); |
873 | event.SetEventObject( def ); | |
874 | def->Command( event ); | |
875 | ||
facd6764 SC |
876 | return ; |
877 | } | |
878 | } | |
fdd4e6cc | 879 | |
facd6764 SC |
880 | event.Skip() ; |
881 | } | |
fdd4e6cc | 882 | |
facd6764 SC |
883 | /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */ |
884 | else if (event.GetKeyCode() == WXK_ESCAPE || (event.GetKeyCode() == '.' && event.MetaDown() ) ) | |
885 | { | |
de1b0aeb | 886 | // FIXME: look in ancestors, not just parent. |
facd6764 SC |
887 | wxWindow* win = GetParent()->FindWindow( wxID_CANCEL ) ; |
888 | if (win) | |
889 | { | |
de1b0aeb VZ |
890 | wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL); |
891 | new_event.SetEventObject( win ); | |
892 | win->GetEventHandler()->ProcessEvent( new_event ); | |
893 | } | |
facd6764 SC |
894 | } |
895 | else if ( event.GetKeyCode() == WXK_TAB ) | |
896 | { | |
897 | wxNavigationKeyEvent new_event; | |
898 | new_event.SetEventObject( this ); | |
899 | new_event.SetDirection( !event.ShiftDown() ); | |
900 | /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ | |
901 | new_event.SetWindowChange( event.ControlDown() ); | |
902 | new_event.SetCurrentFocus( this ); | |
903 | if ( !GetEventHandler()->ProcessEvent( new_event ) ) | |
904 | event.Skip() ; | |
905 | } | |
906 | else if ( event.GetKeyCode() == WXK_DOWN || event.GetKeyCode() == WXK_UP ) | |
907 | { | |
908 | // perform the default key handling first | |
909 | wxControl::OnKeyDown( event ) ; | |
c6179a84 | 910 | |
fdd4e6cc | 911 | wxCommandEvent event( wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId ); |
facd6764 | 912 | event.SetEventObject( this ); |
c6179a84 | 913 | |
facd6764 SC |
914 | wxArrayInt aSelections; |
915 | int n, count = GetSelections(aSelections); | |
916 | if ( count > 0 ) | |
917 | { | |
918 | n = aSelections[0]; | |
919 | if ( HasClientObjectData() ) | |
fdd4e6cc | 920 | event.SetClientObject( GetClientObject( n ) ); |
facd6764 | 921 | else if ( HasClientUntypedData() ) |
fdd4e6cc | 922 | event.SetClientData( GetClientData( n ) ); |
aa61d352 | 923 | event.SetString(GetString(n)); |
facd6764 SC |
924 | } |
925 | else | |
926 | { | |
927 | n = -1; | |
928 | } | |
c6179a84 | 929 | |
fdd4e6cc | 930 | event.SetInt( n ); |
c6179a84 | 931 | |
facd6764 SC |
932 | GetEventHandler()->ProcessEvent(event); |
933 | } | |
934 | else | |
935 | { | |
936 | if ( event.GetTimestamp() > m_lastTypeIn + 60 ) | |
facd6764 | 937 | m_typeIn = wxEmptyString ; |
fdd4e6cc | 938 | |
facd6764 SC |
939 | m_lastTypeIn = event.GetTimestamp() ; |
940 | m_typeIn += (char) event.GetKeyCode() ; | |
fdd4e6cc | 941 | int line = FindString( wxT("*") + m_typeIn + wxT("*") ) ; |
facd6764 SC |
942 | if ( line >= 0 ) |
943 | { | |
944 | if ( GetSelection() != line ) | |
945 | { | |
fdd4e6cc DS |
946 | SetSelection( line ) ; |
947 | ||
948 | wxCommandEvent event( wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId ); | |
facd6764 | 949 | event.SetEventObject( this ); |
c6179a84 | 950 | |
facd6764 SC |
951 | if ( HasClientObjectData() ) |
952 | event.SetClientObject( GetClientObject( line ) ); | |
953 | else if ( HasClientUntypedData() ) | |
fdd4e6cc | 954 | event.SetClientData( GetClientData( line ) ); |
aa61d352 VZ |
955 | event.SetString(GetString(line)); |
956 | event.SetInt(line); | |
c6179a84 | 957 | |
facd6764 SC |
958 | GetEventHandler()->ProcessEvent(event); |
959 | } | |
960 | } | |
961 | } | |
962 | } | |
573ac9dc | 963 | |
c6179a84 | 964 | #endif // !TARGET_API_MAC_OSX |
5ecae0b7 | 965 | |
179e085f | 966 | #endif |