]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/listbox.cpp
wxDrawerWindow - [ 909351 ] Drawer window for OS X Carbon - somewhat heavily modified
[wxWidgets.git] / src / mac / carbon / listbox.cpp
CommitLineData
e9576ca5
SC
1///////////////////////////////////////////////////////////////////////////////
2// Name: listbox.cpp
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
12#ifdef __GNUG__
13#pragma implementation "listbox.h"
14#endif
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
2f1ae414 26#if !USE_SHARED_LIBRARY
e40298d5 27IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
519cb848
SC
28
29BEGIN_EVENT_TABLE(wxListBox, wxControl)
36ba5f7c 30#if !__WXMAC_OSX__
e40298d5
JS
31 EVT_SIZE( wxListBox::OnSize )
32 EVT_CHAR( wxListBox::OnChar )
facd6764 33#endif
519cb848 34END_EVENT_TABLE()
2f1ae414 35#endif
e9576ca5 36
facd6764
SC
37#include "wx/mac/uma.h"
38
a9fc5eec
SC
39const short kTextColumnId = 1024 ;
40
facd6764 41// new databrowserbased version
8e0f22c0
SC
42// because of the limited insert
43// functionality of DataBrowser,
44// we just introduce id s corresponding
45// to the line number
facd6764
SC
46
47// Listbox item
48wxListBox::wxListBox()
49{
50 m_noItems = 0;
51 m_selected = 0;
52 m_macList = NULL ;
53}
54
55bool wxListBox::Create(wxWindow *parent, wxWindowID id,
56 const wxPoint& pos,
57 const wxSize& size,
58 const wxArrayString& choices,
59 long style,
60 const wxValidator& validator,
61 const wxString& name)
62{
63 wxCArrayString chs(choices);
64
65 return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
66 style, validator, name);
67}
68
83ce5634
SC
69#if TARGET_API_MAC_OSX
70static pascal void DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID,
71 DataBrowserItemNotification message, DataBrowserItemDataRef itemData)
72#else
73static pascal void DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID,
74 DataBrowserItemNotification message)
75#endif
76{
77 long ref = GetControlReference( browser ) ;
78 if ( ref )
79 {
469d8d5d 80 wxListBox* list = wxDynamicCast( (wxObject*) ref , wxListBox ) ;
8e0f22c0
SC
81 size_t i = itemID - 1 ;
82 if (i >= 0 && i < list->GetCount() )
83 {
84 bool trigger = false ;
85 wxCommandEvent event(
86 wxEVT_COMMAND_LISTBOX_SELECTED, list->GetId() );
87 switch( message )
83ce5634 88 {
8e0f22c0
SC
89 case kDataBrowserItemDeselected :
90 if ( list->HasMultipleSelection() )
83ce5634 91 trigger = true ;
8e0f22c0
SC
92 break ;
93 case kDataBrowserItemSelected :
94 trigger = true ;
95 break ;
96 case kDataBrowserItemDoubleClicked :
97 event.SetEventType(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED) ;
98 trigger = true ;
99 break ;
100 default :
101 break ;
83ce5634 102 }
8e0f22c0
SC
103 if ( trigger )
104 {
105 event.SetEventObject( list );
106 if ( list->HasClientObjectData() )
107 event.SetClientObject( list->GetClientObject(i) );
108 else if ( list->HasClientUntypedData() )
109 event.SetClientData( list->GetClientData(i) );
110 event.SetString( list->GetString(i) );
111 event.SetInt(i) ;
112 event.SetExtraLong( list->HasMultipleSelection() ? message == kDataBrowserItemSelected : TRUE );
113 wxPostEvent( list->GetEventHandler() , event ) ;
114 // direct notification is not always having the listbox GetSelection() having in synch with event
115 // list->GetEventHandler()->ProcessEvent(event) ;
116 }
117 }
83ce5634
SC
118 }
119}
120
121
facd6764
SC
122static pascal OSStatus ListBoxGetSetItemData(ControlRef browser,
123 DataBrowserItemID itemID, DataBrowserPropertyID property,
124 DataBrowserItemDataRef itemData, Boolean changeValue)
125{
126 OSStatus err = errDataBrowserPropertyNotSupported;
127
128 if ( ! changeValue )
129 {
130 switch (property)
131 {
132
a9fc5eec 133 case kTextColumnId:
facd6764
SC
134 {
135 long ref = GetControlReference( browser ) ;
136 if ( ref )
137 {
469d8d5d 138 wxListBox* list = wxDynamicCast( (wxObject*) ref , wxListBox ) ;
8e0f22c0
SC
139 size_t i = itemID - 1 ;
140 if (i >= 0 && i < list->GetCount() )
141 {
142 wxMacCFStringHolder cf( list->GetString(i) , list->GetFont().GetEncoding() ) ;
143 verify_noerr( ::SetDataBrowserItemDataText( itemData , cf ) ) ;
144 err = noErr ;
145 }
facd6764
SC
146 }
147 }
148 break;
149
150 default:
151
152 break;
153 }
154 }
155
156 return err;
157}
158bool wxListBox::Create(wxWindow *parent, wxWindowID id,
159 const wxPoint& pos,
160 const wxSize& size,
161 int n, const wxString choices[],
162 long style,
163 const wxValidator& validator,
164 const wxString& name)
165{
166 m_macIsUserPane = FALSE ;
5e6f42cd
SC
167
168 wxASSERT_MSG( !(style & wxLB_MULTIPLE) || !(style & wxLB_EXTENDED),
169 _T("only one of listbox selection modes can be specified") );
facd6764
SC
170
171 if ( !wxListBoxBase::Create(parent, id, pos, size, style & ~(wxHSCROLL|wxVSCROLL), validator, name) )
172 return false;
173
174 m_noItems = 0 ; // this will be increased by our append command
175 m_selected = 0;
facd6764
SC
176
177 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
facd6764 178
21fd5529 179 m_peer = new wxMacControl() ;
5ca0d812 180 verify_noerr( ::CreateDataBrowserControl( MAC_WXHWND(parent->MacGetTopLevelWindowRef()), &bounds, kDataBrowserListView , m_peer->GetControlRefAddr() ) );
facd6764
SC
181
182 DataBrowserSelectionFlags options = kDataBrowserDragSelect ;
183 if ( style & wxLB_MULTIPLE )
184 {
185 options += kDataBrowserAlwaysExtendSelection + kDataBrowserCmdTogglesSelection ;
186 }
187 else if ( style & wxLB_EXTENDED )
188 {
189 // default behaviour
190 }
191 else
192 {
193 options += kDataBrowserSelectOnlyOne ;
194 }
5ca0d812 195 verify_noerr(m_peer->SetSelectionFlags( options ) );
facd6764
SC
196
197 DataBrowserListViewColumnDesc columnDesc ;
198 columnDesc.headerBtnDesc.titleOffset = 0;
199 columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
200
201 columnDesc.headerBtnDesc.btnFontStyle.flags =
202 kControlUseFontMask | kControlUseJustMask;
203
204 columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlNoContent;
205 columnDesc.propertyDesc.propertyType = kDataBrowserTextType;
206 columnDesc.headerBtnDesc.btnFontStyle.just = teFlushDefault;
207 columnDesc.headerBtnDesc.minimumWidth = 0;
208 columnDesc.headerBtnDesc.maximumWidth = 10000;
209
210 columnDesc.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont;
211 columnDesc.headerBtnDesc.btnFontStyle.style = normal;
212 columnDesc.headerBtnDesc.titleString = NULL ; // CFSTR( "" );
213
a9fc5eec 214 columnDesc.propertyDesc.propertyID = kTextColumnId;
facd6764 215 columnDesc.propertyDesc.propertyType = kDataBrowserTextType;
c2697b87 216 columnDesc.propertyDesc.propertyFlags =
9bd2d050 217#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
c2697b87
SC
218 kDataBrowserListViewTypeSelectColumn |
219#endif
220 kDataBrowserTableViewSelectionColumn ;
facd6764
SC
221
222
5ca0d812
SC
223 verify_noerr(m_peer->AddListViewColumn( &columnDesc, kDataBrowserListViewAppendColumn) ) ;
224 verify_noerr(m_peer->AutoSizeListViewColumns() ) ;
225 verify_noerr(m_peer->SetHasScrollBars(false , true ) ) ;
226 verify_noerr(m_peer->SetTableViewHiliteStyle(kDataBrowserTableViewFillHilite ) ) ;
227 verify_noerr(m_peer->SetListViewHeaderBtnHeight( 0 ) ) ;
facd6764
SC
228 DataBrowserCallbacks callbacks ;
229
230 callbacks.version = kDataBrowserLatestCallbacks;
231
232 InitDataBrowserCallbacks(&callbacks);
233
234 callbacks.u.v1.itemDataCallback =
235 NewDataBrowserItemDataUPP(ListBoxGetSetItemData);
236
83ce5634
SC
237 callbacks.u.v1.itemNotificationCallback =
238#if TARGET_API_MAC_OSX
239 (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc) ;
240#else
241 NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc) ;
242#endif
5ca0d812 243 m_peer->SetCallbacks( &callbacks);
facd6764 244
8e0f22c0
SC
245#if TARGET_API_MAC_OSX
246 // there is a redraw bug in 10.2.X
247 if ( UMAGetSystemVersion() < 0x1030 )
248 m_peer->SetData( kControlNoPart, kControlDataBrowserIncludesFrameAndFocusTag, (Boolean) false ) ;
249#endif
250
facd6764
SC
251 MacPostControlCreate(pos,size) ;
252
253 for ( int i = 0 ; i < n ; i++ )
254 {
255 Append( choices[i] ) ;
256 }
257
d3b5db4b
RD
258 SetBestSize(size); // Needed because it is a wxControlWithItems
259
facd6764
SC
260 return TRUE;
261}
262
263wxListBox::~wxListBox()
264{
5ca0d812 265 m_peer->SetReference( NULL ) ;
facd6764
SC
266 FreeData() ;
267 // avoid access during destruction
268 if ( m_macList )
269 {
270 m_macList = NULL ;
271 }
272}
273
274void wxListBox::FreeData()
275{
276#if wxUSE_OWNER_DRAWN
277 if ( m_windowStyle & wxLB_OWNERDRAW )
278 {
279 size_t uiCount = m_aItems.Count();
280 while ( uiCount-- != 0 ) {
281 delete m_aItems[uiCount];
282 m_aItems[uiCount] = NULL;
283 }
284
285 m_aItems.Clear();
286 }
287 else
288#endif // wxUSE_OWNER_DRAWN
289 if ( HasClientObjectData() )
290 {
291 for ( size_t n = 0; n < (size_t)m_noItems; n++ )
292 {
293 delete GetClientObject(n);
294 }
295 }
296}
297
298void wxListBox::DoSetSize(int x, int y,
299 int width, int height,
300 int sizeFlags )
301{
302 wxControl::DoSetSize( x , y , width , height , sizeFlags ) ;
303}
304
305void wxListBox::DoSetFirstItem(int N)
306{
307 MacScrollTo( N ) ;
308}
309
310void wxListBox::Delete(int N)
311{
312 wxCHECK_RET( N >= 0 && N < m_noItems,
313 wxT("invalid index in wxListBox::Delete") );
314
315#if wxUSE_OWNER_DRAWN
316 delete m_aItems[N];
317 m_aItems.RemoveAt(N);
318#else // !wxUSE_OWNER_DRAWN
319 if ( HasClientObjectData() )
320 {
321 delete GetClientObject(N);
322 }
323#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
324 m_stringArray.RemoveAt( N ) ;
325 m_dataArray.RemoveAt( N ) ;
326 m_noItems --;
327
328 MacDelete( N ) ;
329}
330
331int wxListBox::DoAppend(const wxString& item)
332{
9f884528
RD
333 InvalidateBestSize();
334
facd6764
SC
335 int index = m_noItems ;
336 m_stringArray.Add( item ) ;
337 m_dataArray.Add( NULL );
338 m_noItems ++;
339 DoSetItemClientData( index , NULL ) ;
340 MacAppend( item ) ;
341
342 return index ;
343}
344
345void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData)
346{
347 Clear() ;
348 int n = choices.GetCount();
349
350 for( int i = 0 ; i < n ; ++i )
351 {
352 if ( clientData )
353 {
354#if wxUSE_OWNER_DRAWN
355 wxASSERT_MSG(clientData[i] == NULL,
356 wxT("Can't use client data with owner-drawn listboxes"));
357#else // !wxUSE_OWNER_DRAWN
358 Append( choices[i] , clientData[i] ) ;
359#endif
360 }
361 else
362 Append( choices[i] ) ;
363 }
364
365#if wxUSE_OWNER_DRAWN
366 if ( m_windowStyle & wxLB_OWNERDRAW ) {
367 // first delete old items
368 size_t ui = m_aItems.Count();
369 while ( ui-- != 0 ) {
370 delete m_aItems[ui];
371 m_aItems[ui] = NULL;
372 }
373 m_aItems.Empty();
374
375 // then create new ones
376 for ( ui = 0; ui < (size_t)m_noItems; ui++ ) {
377 wxOwnerDrawn *pNewItem = CreateItem(ui);
378 pNewItem->SetName(choices[ui]);
379 m_aItems.Add(pNewItem);
380 }
381 }
382#endif // wxUSE_OWNER_DRAWN
383}
384
facd6764
SC
385int wxListBox::FindString(const wxString& s) const
386{
387
388 if ( s.Right(1) == wxT("*") )
389 {
390 wxString search = s.Left( s.Length() - 1 ) ;
391 int len = search.Length() ;
392 Str255 s1 , s2 ;
393 wxMacStringToPascal( search , s2 ) ;
394
395 for ( int i = 0 ; i < m_noItems ; ++ i )
396 {
397 wxMacStringToPascal( m_stringArray[i].Left( len ) , s1 ) ;
398
399 if ( EqualString( s1 , s2 , false , false ) )
400 return i ;
401 }
402 if ( s.Left(1) == wxT("*") && s.Length() > 1 )
403 {
404 wxString st = s ;
405 st.MakeLower() ;
406 for ( int i = 0 ; i < m_noItems ; ++i )
407 {
408 if ( GetString(i).Lower().Matches(st) )
409 return i ;
410 }
411 }
412
413 }
414 else
415 {
416 Str255 s1 , s2 ;
417
418 wxMacStringToPascal( s , s2 ) ;
419
420 for ( int i = 0 ; i < m_noItems ; ++ i )
421 {
422 wxMacStringToPascal( m_stringArray[i] , s1 ) ;
423
424 if ( EqualString( s1 , s2 , false , false ) )
425 return i ;
426 }
427 }
428 return -1;
429}
430
431void wxListBox::Clear()
432{
433 FreeData();
434 m_noItems = 0;
435 m_stringArray.Empty() ;
436 m_dataArray.Empty() ;
437 MacClear() ;
438}
439
440void wxListBox::SetSelection(int N, bool select)
441{
442 wxCHECK_RET( N >= 0 && N < m_noItems,
443 wxT("invalid index in wxListBox::SetSelection") );
444 MacSetSelection( N , select ) ;
445 GetSelections( m_selectionPreImage ) ;
446}
447
448bool wxListBox::IsSelected(int N) const
449{
450 wxCHECK_MSG( N >= 0 && N < m_noItems, FALSE,
451 wxT("invalid index in wxListBox::Selected") );
452
453 return MacIsSelected( N ) ;
454}
455
456void *wxListBox::DoGetItemClientData(int N) const
457{
458 wxCHECK_MSG( N >= 0 && N < m_noItems, NULL,
459 wxT("invalid index in wxListBox::GetClientData"));
460
461 return (void *)m_dataArray[N];
462}
463
464wxClientData *wxListBox::DoGetItemClientObject(int N) const
465{
466 return (wxClientData *) DoGetItemClientData( N ) ;
467}
468
469void wxListBox::DoSetItemClientData(int N, void *Client_data)
470{
471 wxCHECK_RET( N >= 0 && N < m_noItems,
472 wxT("invalid index in wxListBox::SetClientData") );
473
474#if wxUSE_OWNER_DRAWN
475 if ( m_windowStyle & wxLB_OWNERDRAW )
476 {
477 // client data must be pointer to wxOwnerDrawn, otherwise we would crash
478 // in OnMeasure/OnDraw.
479 wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
480 }
481#endif // wxUSE_OWNER_DRAWN
482 wxASSERT_MSG( m_dataArray.GetCount() >= (size_t) N , wxT("invalid client_data array") ) ;
483
484 if ( m_dataArray.GetCount() > (size_t) N )
485 {
486 m_dataArray[N] = (char*) Client_data ;
487 }
488 else
489 {
490 m_dataArray.Add( (char*) Client_data ) ;
491 }
492}
493
494void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData)
495{
496 DoSetItemClientData(n, clientData);
497}
498
499// Return number of selections and an array of selected integers
500int wxListBox::GetSelections(wxArrayInt& aSelections) const
501{
502 return MacGetSelections( aSelections ) ;
503}
504
505// Get single selection, for single choice list items
506int wxListBox::GetSelection() const
507{
508 return MacGetSelection() ;
509}
510
511// Find string for position
512wxString wxListBox::GetString(int N) const
513{
514 return m_stringArray[N] ;
515}
516
517void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
518{
519 wxCHECK_RET( pos >= 0 && pos <= m_noItems,
520 wxT("invalid index in wxListBox::InsertItems") );
521
9f884528
RD
522 InvalidateBestSize();
523
facd6764
SC
524 int nItems = items.GetCount();
525
526 for ( int i = 0 ; i < nItems ; i++ )
527 {
528 m_stringArray.Insert( items[i] , pos + i ) ;
529 m_dataArray.Insert( NULL , pos + i ) ;
8e0f22c0 530 m_noItems++ ;
facd6764
SC
531 MacInsert( pos + i , items[i] ) ;
532 }
facd6764
SC
533}
534
535void wxListBox::SetString(int N, const wxString& s)
536{
537 m_stringArray[N] = s ;
538 MacSet( N , s ) ;
539}
540
541wxSize wxListBox::DoGetBestSize() const
542{
543 int lbWidth = 100; // some defaults
544 int lbHeight = 110;
545 int wLine;
546
547 {
548 wxMacPortStateHelper st( UMAGetWindowPort( (WindowRef) MacGetTopLevelWindowRef() ) ) ;
549
550 if ( m_font.Ok() )
551 {
552 ::TextFont( m_font.MacGetFontNum() ) ;
553 ::TextSize( m_font.MacGetFontSize() ) ;
554 ::TextFace( m_font.MacGetFontStyle() ) ;
555 }
556 else
557 {
558 ::TextFont( kFontIDMonaco ) ;
559 ::TextSize( 9 );
560 ::TextFace( 0 ) ;
561 }
562
563 // Find the widest line
564 for(int i = 0; i < GetCount(); i++) {
565 wxString str(GetString(i));
566 #if wxUSE_UNICODE
567 Point bounds={0,0} ;
568 SInt16 baseline ;
569 ::GetThemeTextDimensions( wxMacCFStringHolder( str , m_font.GetEncoding() ) ,
570 kThemeCurrentPortFont,
571 kThemeStateActive,
572 false,
573 &bounds,
574 &baseline );
575 wLine = bounds.h ;
576 #else
577 wLine = ::TextWidth( str.c_str() , 0 , str.Length() ) ;
578 #endif
579 lbWidth = wxMax(lbWidth, wLine);
580 }
581
582 // Add room for the scrollbar
583 lbWidth += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
584
585 // And just a bit more
586 int cy = 12 ;
587 int cx = ::TextWidth( "X" , 0 , 1 ) ;
588 lbWidth += cx ;
589
590 // don't make the listbox too tall (limit height to around 10 items) but don't
591 // make it too small neither
592 lbHeight = (cy+4) * wxMin(wxMax(GetCount(), 3), 10);
593 }
594
595 return wxSize(lbWidth, lbHeight);
596}
597
598int wxListBox::GetCount() const
599{
600 return m_noItems;
601}
602
603void wxListBox::Refresh(bool eraseBack, const wxRect *rect)
604{
605 wxControl::Refresh( eraseBack , rect ) ;
606 // MacRedrawControl() ;
607}
608
609#if wxUSE_OWNER_DRAWN
610
611class wxListBoxItem : public wxOwnerDrawn
612{
613public:
614 wxListBoxItem(const wxString& str = "");
615};
616
617wxListBoxItem::wxListBoxItem(const wxString& str) : wxOwnerDrawn(str, FALSE)
618{
619 // no bitmaps/checkmarks
620 SetMarginWidth(0);
621}
622
623wxOwnerDrawn *wxListBox::CreateItem(size_t n)
624{
625 return new wxListBoxItem();
626}
627
628#endif //USE_OWNER_DRAWN
629
b6a20a20
RD
630
631// Some custom controls depend on this
632/* static */ wxVisualAttributes
633wxListBox::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
634{
635 wxVisualAttributes attr;
636 attr.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
637 attr.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX);
638 attr.font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
639 return attr;
640}
641
facd6764
SC
642// ============================================================================
643// list box control implementation
644// ============================================================================
645
646void wxListBox::MacDelete( int N )
647{
8e0f22c0 648 UInt32 id = m_noItems+1 ;
5ca0d812 649 verify_noerr( m_peer->RemoveItems( kDataBrowserNoItem , 1 , (UInt32*) &id , kDataBrowserItemNoProperty ) ) ;
8e0f22c0 650 verify_noerr( m_peer->UpdateItems( kDataBrowserNoItem , 1 , (UInt32*) kDataBrowserNoItem , kDataBrowserItemNoProperty , kDataBrowserItemNoProperty ) ) ;
facd6764
SC
651}
652
653void wxListBox::MacInsert( int n , const wxString& text)
654{
8e0f22c0
SC
655 UInt32 id = m_noItems ; // this has already been increased
656 verify_noerr( m_peer->AddItems( kDataBrowserNoItem , 1 , (UInt32*) &id , kDataBrowserItemNoProperty ) ) ;
657 verify_noerr( m_peer->UpdateItems( kDataBrowserNoItem , 1 , (UInt32*) kDataBrowserNoItem , kDataBrowserItemNoProperty , kDataBrowserItemNoProperty ) ) ;
facd6764
SC
658}
659
660void wxListBox::MacAppend( const wxString& text)
661{
8e0f22c0
SC
662 UInt32 id = m_noItems ; // this has already been increased
663 verify_noerr( m_peer->AddItems( kDataBrowserNoItem , 1 , (UInt32*) &id , kDataBrowserItemNoProperty ) ) ;
facd6764
SC
664}
665
666void wxListBox::MacClear()
667{
5ca0d812 668 verify_noerr( m_peer->RemoveItems( kDataBrowserNoItem , 0 , NULL , kDataBrowserItemNoProperty ) ) ;
facd6764
SC
669}
670
671void wxListBox::MacSetSelection( int n , bool select )
672{
8e0f22c0 673 UInt32 id = n + 1 ;
5e6f42cd
SC
674 if ( !(GetWindowStyle() & (wxLB_MULTIPLE|wxLB_EXTENDED) ) )
675 {
676 int n = MacGetSelection() ;
677 if ( n >= 0 )
678 {
8e0f22c0 679 UInt32 idOld = n + 1 ;
5ca0d812 680 m_peer->SetSelectedItems( 1 , & idOld , kDataBrowserItemsRemove ) ;
5e6f42cd
SC
681 }
682 }
5ca0d812 683 if ( m_peer->IsItemSelected( id ) != select )
facd6764 684 {
5ca0d812 685 verify_noerr(m_peer->SetSelectedItems( 1 , & id , kDataBrowserItemsToggle ) ) ;
facd6764
SC
686 }
687 MacScrollTo( n ) ;
688}
689
690bool wxListBox::MacIsSelected( int n ) const
691{
8e0f22c0 692 return m_peer->IsItemSelected( n + 1 ) ;
facd6764
SC
693}
694
695int wxListBox::MacGetSelection() const
696{
8e0f22c0 697 for ( size_t i = 0 ; i < GetCount() ; ++i )
facd6764 698 {
8e0f22c0 699 if ( m_peer->IsItemSelected( i + 1 ) )
facd6764
SC
700 {
701 return i ;
702 }
703 }
704 return -1 ;
705}
706
707int wxListBox::MacGetSelections( wxArrayInt& aSelections ) const
708{
709 int no_sel = 0 ;
710
711 aSelections.Empty();
8e0f22c0 712 for ( size_t i = 0 ; i < GetCount() ; ++i )
facd6764 713 {
8e0f22c0 714 if ( m_peer->IsItemSelected( i + 1 ) )
facd6764
SC
715 {
716 aSelections.Add( i ) ;
717 no_sel++ ;
718 }
719 }
720 return no_sel ;
721}
519cb848 722
facd6764
SC
723void wxListBox::MacSet( int n , const wxString& text )
724{
725 // as we don't store the strings we only have to issue a redraw
8e0f22c0 726 UInt32 id = n + 1 ;
5ca0d812 727 verify_noerr( m_peer->UpdateItems( kDataBrowserNoItem , 1 , &id , kDataBrowserItemNoProperty , kDataBrowserItemNoProperty ) ) ;
facd6764 728}
e42e45a9 729
facd6764
SC
730void wxListBox::MacScrollTo( int n )
731{
8e0f22c0 732 UInt32 id = n + 1 ;
5ca0d812 733 verify_noerr( m_peer->RevealItem( id , kTextColumnId , kDataBrowserRevealWithoutSelecting ) ) ;
facd6764
SC
734}
735
5ecae0b7 736#if !TARGET_API_MAC_OSX
facd6764
SC
737void wxListBox::OnSize( wxSizeEvent &event)
738{
739}
5ecae0b7 740#endif
facd6764 741
facd6764
SC
742void wxListBox::MacSetRedraw( bool doDraw )
743{
744 // nothing to do in compositing mode
745}
746
747void wxListBox::MacDoClick()
83ce5634 748{/*
facd6764
SC
749 wxArrayInt aSelections;
750 int n ;
751 size_t count = GetSelections(aSelections);
752
753 if ( count == m_selectionPreImage.GetCount() )
754 {
755 bool hasChanged = false ;
756 for ( size_t i = 0 ; i < count ; ++i )
757 {
758 if ( aSelections[i] != m_selectionPreImage[i] )
759 {
760 hasChanged = true ;
761 break ;
762 }
763 }
764 if ( !hasChanged )
765 {
766 return ;
767 }
768 }
769
770 m_selectionPreImage = aSelections;
771
772 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
773 event.SetEventObject( this );
774
775 if ( count > 0 )
776 {
777 n = aSelections[0];
778 if ( HasClientObjectData() )
779 event.SetClientObject( GetClientObject(n) );
780 else if ( HasClientUntypedData() )
781 event.SetClientData( GetClientData(n) );
782 event.SetString( GetString(n) );
783 }
784 else
785 {
786 n = -1;
787 }
788
789 event.m_commandInt = n;
790
791 GetEventHandler()->ProcessEvent(event);
83ce5634 792*/
facd6764
SC
793}
794
795void wxListBox::MacDoDoubleClick()
796{
83ce5634 797/*
facd6764
SC
798 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, m_windowId);
799 event.SetEventObject( this );
800 GetEventHandler()->ProcessEvent(event) ;
83ce5634 801*/
facd6764
SC
802}
803
5ecae0b7
SC
804#if !TARGET_API_MAC_OSX
805
facd6764
SC
806void wxListBox::OnChar(wxKeyEvent& event)
807{
808 // todo trigger proper events here
809 event.Skip() ;
810 return ;
811
812 if ( event.GetKeyCode() == WXK_RETURN || event.GetKeyCode() == WXK_NUMPAD_ENTER)
813 {
814 wxWindow* parent = GetParent() ;
815 while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL )
816 parent = parent->GetParent() ;
817
818 if ( parent && parent->GetDefaultItem() )
819 {
820 wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
821 wxButton);
822 if ( def && def->IsEnabled() )
823 {
824 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
825 event.SetEventObject(def);
826 def->Command(event);
827 return ;
828 }
829 }
830 event.Skip() ;
831 }
832 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
833 else if (event.GetKeyCode() == WXK_ESCAPE || (event.GetKeyCode() == '.' && event.MetaDown() ) )
834 {
835 // FIXME: look in ancestors, not just parent.
836 wxWindow* win = GetParent()->FindWindow( wxID_CANCEL ) ;
837 if (win)
838 {
839 wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
840 new_event.SetEventObject( win );
841 win->GetEventHandler()->ProcessEvent( new_event );
842 }
843 }
844 else if ( event.GetKeyCode() == WXK_TAB )
845 {
846 wxNavigationKeyEvent new_event;
847 new_event.SetEventObject( this );
848 new_event.SetDirection( !event.ShiftDown() );
849 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
850 new_event.SetWindowChange( event.ControlDown() );
851 new_event.SetCurrentFocus( this );
852 if ( !GetEventHandler()->ProcessEvent( new_event ) )
853 event.Skip() ;
854 }
855 else if ( event.GetKeyCode() == WXK_DOWN || event.GetKeyCode() == WXK_UP )
856 {
857 // perform the default key handling first
858 wxControl::OnKeyDown( event ) ;
859
860 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
861 event.SetEventObject( this );
862
863 wxArrayInt aSelections;
864 int n, count = GetSelections(aSelections);
865 if ( count > 0 )
866 {
867 n = aSelections[0];
868 if ( HasClientObjectData() )
869 event.SetClientObject( GetClientObject(n) );
870 else if ( HasClientUntypedData() )
871 event.SetClientData( GetClientData(n) );
872 event.SetString( GetString(n) );
873 }
874 else
875 {
876 n = -1;
877 }
878
879 event.m_commandInt = n;
880
881 GetEventHandler()->ProcessEvent(event);
882 }
883 else
884 {
885 if ( event.GetTimestamp() > m_lastTypeIn + 60 )
886 {
887 m_typeIn = wxEmptyString ;
888 }
889 m_lastTypeIn = event.GetTimestamp() ;
890 m_typeIn += (char) event.GetKeyCode() ;
891 int line = FindString(wxT("*")+m_typeIn+wxT("*")) ;
892 if ( line >= 0 )
893 {
894 if ( GetSelection() != line )
895 {
896 SetSelection(line) ;
897 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
898 event.SetEventObject( this );
899
900 if ( HasClientObjectData() )
901 event.SetClientObject( GetClientObject( line ) );
902 else if ( HasClientUntypedData() )
903 event.SetClientData( GetClientData(line) );
904 event.SetString( GetString(line) );
905
906 event.m_commandInt = line ;
907
908 GetEventHandler()->ProcessEvent(event);
909 }
910 }
911 }
912}
573ac9dc 913
5ecae0b7
SC
914#endif
915