]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/listbox.cpp
update docs, add to class list
[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)
684e0b31 30#ifndef __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 ) ;
45285a62 81 int i = itemID - 1 ;
8e0f22c0
SC
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 ) ;
45285a62 139 int i = itemID - 1 ;
8e0f22c0
SC
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{
6c6ea7be
VZ
442 if ( N == wxNOT_FOUND )
443 {
444 // unselect everything
445 int sel = MacGetSelection() ;
446 if ( sel != wxNOT_FOUND )
447 {
448 UInt32 id = sel + 1 ;
449 verify_noerr(
450 m_peer->SetSelectedItems( 1 , & id , kDataBrowserItemsRemove )
451 );
452 }
453
454 return;
455 }
456
facd6764
SC
457 wxCHECK_RET( N >= 0 && N < m_noItems,
458 wxT("invalid index in wxListBox::SetSelection") );
459 MacSetSelection( N , select ) ;
460 GetSelections( m_selectionPreImage ) ;
461}
462
463bool wxListBox::IsSelected(int N) const
464{
465 wxCHECK_MSG( N >= 0 && N < m_noItems, FALSE,
466 wxT("invalid index in wxListBox::Selected") );
467
468 return MacIsSelected( N ) ;
469}
470
471void *wxListBox::DoGetItemClientData(int N) const
472{
473 wxCHECK_MSG( N >= 0 && N < m_noItems, NULL,
474 wxT("invalid index in wxListBox::GetClientData"));
475
476 return (void *)m_dataArray[N];
477}
478
479wxClientData *wxListBox::DoGetItemClientObject(int N) const
480{
481 return (wxClientData *) DoGetItemClientData( N ) ;
482}
483
484void wxListBox::DoSetItemClientData(int N, void *Client_data)
485{
486 wxCHECK_RET( N >= 0 && N < m_noItems,
487 wxT("invalid index in wxListBox::SetClientData") );
488
489#if wxUSE_OWNER_DRAWN
490 if ( m_windowStyle & wxLB_OWNERDRAW )
491 {
492 // client data must be pointer to wxOwnerDrawn, otherwise we would crash
493 // in OnMeasure/OnDraw.
494 wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
495 }
496#endif // wxUSE_OWNER_DRAWN
497 wxASSERT_MSG( m_dataArray.GetCount() >= (size_t) N , wxT("invalid client_data array") ) ;
498
499 if ( m_dataArray.GetCount() > (size_t) N )
500 {
501 m_dataArray[N] = (char*) Client_data ;
502 }
503 else
504 {
505 m_dataArray.Add( (char*) Client_data ) ;
506 }
507}
508
509void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData)
510{
511 DoSetItemClientData(n, clientData);
512}
513
514// Return number of selections and an array of selected integers
515int wxListBox::GetSelections(wxArrayInt& aSelections) const
516{
517 return MacGetSelections( aSelections ) ;
518}
519
520// Get single selection, for single choice list items
521int wxListBox::GetSelection() const
522{
523 return MacGetSelection() ;
524}
525
526// Find string for position
527wxString wxListBox::GetString(int N) const
528{
529 return m_stringArray[N] ;
530}
531
532void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
533{
534 wxCHECK_RET( pos >= 0 && pos <= m_noItems,
535 wxT("invalid index in wxListBox::InsertItems") );
536
9f884528
RD
537 InvalidateBestSize();
538
facd6764
SC
539 int nItems = items.GetCount();
540
541 for ( int i = 0 ; i < nItems ; i++ )
542 {
543 m_stringArray.Insert( items[i] , pos + i ) ;
544 m_dataArray.Insert( NULL , pos + i ) ;
8e0f22c0 545 m_noItems++ ;
facd6764
SC
546 MacInsert( pos + i , items[i] ) ;
547 }
facd6764
SC
548}
549
550void wxListBox::SetString(int N, const wxString& s)
551{
552 m_stringArray[N] = s ;
553 MacSet( N , s ) ;
554}
555
556wxSize wxListBox::DoGetBestSize() const
557{
558 int lbWidth = 100; // some defaults
559 int lbHeight = 110;
560 int wLine;
561
562 {
563 wxMacPortStateHelper st( UMAGetWindowPort( (WindowRef) MacGetTopLevelWindowRef() ) ) ;
564
565 if ( m_font.Ok() )
566 {
567 ::TextFont( m_font.MacGetFontNum() ) ;
568 ::TextSize( m_font.MacGetFontSize() ) ;
569 ::TextFace( m_font.MacGetFontStyle() ) ;
570 }
571 else
572 {
573 ::TextFont( kFontIDMonaco ) ;
574 ::TextSize( 9 );
575 ::TextFace( 0 ) ;
576 }
577
578 // Find the widest line
579 for(int i = 0; i < GetCount(); i++) {
580 wxString str(GetString(i));
581 #if wxUSE_UNICODE
582 Point bounds={0,0} ;
583 SInt16 baseline ;
584 ::GetThemeTextDimensions( wxMacCFStringHolder( str , m_font.GetEncoding() ) ,
585 kThemeCurrentPortFont,
586 kThemeStateActive,
587 false,
588 &bounds,
589 &baseline );
590 wLine = bounds.h ;
591 #else
592 wLine = ::TextWidth( str.c_str() , 0 , str.Length() ) ;
593 #endif
594 lbWidth = wxMax(lbWidth, wLine);
595 }
596
597 // Add room for the scrollbar
598 lbWidth += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
599
600 // And just a bit more
601 int cy = 12 ;
602 int cx = ::TextWidth( "X" , 0 , 1 ) ;
603 lbWidth += cx ;
604
605 // don't make the listbox too tall (limit height to around 10 items) but don't
606 // make it too small neither
607 lbHeight = (cy+4) * wxMin(wxMax(GetCount(), 3), 10);
608 }
609
610 return wxSize(lbWidth, lbHeight);
611}
612
613int wxListBox::GetCount() const
614{
615 return m_noItems;
616}
617
618void wxListBox::Refresh(bool eraseBack, const wxRect *rect)
619{
620 wxControl::Refresh( eraseBack , rect ) ;
621 // MacRedrawControl() ;
622}
623
624#if wxUSE_OWNER_DRAWN
625
626class wxListBoxItem : public wxOwnerDrawn
627{
628public:
629 wxListBoxItem(const wxString& str = "");
630};
631
632wxListBoxItem::wxListBoxItem(const wxString& str) : wxOwnerDrawn(str, FALSE)
633{
634 // no bitmaps/checkmarks
635 SetMarginWidth(0);
636}
637
638wxOwnerDrawn *wxListBox::CreateItem(size_t n)
639{
640 return new wxListBoxItem();
641}
642
643#endif //USE_OWNER_DRAWN
644
b6a20a20
RD
645
646// Some custom controls depend on this
647/* static */ wxVisualAttributes
648wxListBox::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
649{
650 wxVisualAttributes attr;
651 attr.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
652 attr.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX);
653 attr.font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
654 return attr;
655}
656
facd6764
SC
657// ============================================================================
658// list box control implementation
659// ============================================================================
660
661void wxListBox::MacDelete( int N )
662{
8e0f22c0 663 UInt32 id = m_noItems+1 ;
5ca0d812 664 verify_noerr( m_peer->RemoveItems( kDataBrowserNoItem , 1 , (UInt32*) &id , kDataBrowserItemNoProperty ) ) ;
8e0f22c0 665 verify_noerr( m_peer->UpdateItems( kDataBrowserNoItem , 1 , (UInt32*) kDataBrowserNoItem , kDataBrowserItemNoProperty , kDataBrowserItemNoProperty ) ) ;
facd6764
SC
666}
667
668void wxListBox::MacInsert( int n , const wxString& text)
669{
8e0f22c0
SC
670 UInt32 id = m_noItems ; // this has already been increased
671 verify_noerr( m_peer->AddItems( kDataBrowserNoItem , 1 , (UInt32*) &id , kDataBrowserItemNoProperty ) ) ;
672 verify_noerr( m_peer->UpdateItems( kDataBrowserNoItem , 1 , (UInt32*) kDataBrowserNoItem , kDataBrowserItemNoProperty , kDataBrowserItemNoProperty ) ) ;
facd6764
SC
673}
674
675void wxListBox::MacAppend( const wxString& text)
676{
8e0f22c0
SC
677 UInt32 id = m_noItems ; // this has already been increased
678 verify_noerr( m_peer->AddItems( kDataBrowserNoItem , 1 , (UInt32*) &id , kDataBrowserItemNoProperty ) ) ;
facd6764
SC
679}
680
681void wxListBox::MacClear()
682{
5ca0d812 683 verify_noerr( m_peer->RemoveItems( kDataBrowserNoItem , 0 , NULL , kDataBrowserItemNoProperty ) ) ;
facd6764
SC
684}
685
686void wxListBox::MacSetSelection( int n , bool select )
687{
8e0f22c0 688 UInt32 id = n + 1 ;
5e6f42cd
SC
689 if ( !(GetWindowStyle() & (wxLB_MULTIPLE|wxLB_EXTENDED) ) )
690 {
691 int n = MacGetSelection() ;
692 if ( n >= 0 )
693 {
8e0f22c0 694 UInt32 idOld = n + 1 ;
5ca0d812 695 m_peer->SetSelectedItems( 1 , & idOld , kDataBrowserItemsRemove ) ;
5e6f42cd
SC
696 }
697 }
5ca0d812 698 if ( m_peer->IsItemSelected( id ) != select )
facd6764 699 {
5ca0d812 700 verify_noerr(m_peer->SetSelectedItems( 1 , & id , kDataBrowserItemsToggle ) ) ;
facd6764
SC
701 }
702 MacScrollTo( n ) ;
703}
704
705bool wxListBox::MacIsSelected( int n ) const
706{
8e0f22c0 707 return m_peer->IsItemSelected( n + 1 ) ;
facd6764
SC
708}
709
710int wxListBox::MacGetSelection() const
711{
45285a62 712 for ( int i = 0 ; i < GetCount() ; ++i )
facd6764 713 {
8e0f22c0 714 if ( m_peer->IsItemSelected( i + 1 ) )
facd6764
SC
715 {
716 return i ;
717 }
718 }
719 return -1 ;
720}
721
722int wxListBox::MacGetSelections( wxArrayInt& aSelections ) const
723{
724 int no_sel = 0 ;
725
726 aSelections.Empty();
45285a62 727 for ( int i = 0 ; i < GetCount() ; ++i )
facd6764 728 {
8e0f22c0 729 if ( m_peer->IsItemSelected( i + 1 ) )
facd6764
SC
730 {
731 aSelections.Add( i ) ;
732 no_sel++ ;
733 }
734 }
735 return no_sel ;
736}
519cb848 737
facd6764
SC
738void wxListBox::MacSet( int n , const wxString& text )
739{
740 // as we don't store the strings we only have to issue a redraw
8e0f22c0 741 UInt32 id = n + 1 ;
5ca0d812 742 verify_noerr( m_peer->UpdateItems( kDataBrowserNoItem , 1 , &id , kDataBrowserItemNoProperty , kDataBrowserItemNoProperty ) ) ;
facd6764 743}
e42e45a9 744
facd6764
SC
745void wxListBox::MacScrollTo( int n )
746{
8e0f22c0 747 UInt32 id = n + 1 ;
5ca0d812 748 verify_noerr( m_peer->RevealItem( id , kTextColumnId , kDataBrowserRevealWithoutSelecting ) ) ;
facd6764
SC
749}
750
5ecae0b7 751#if !TARGET_API_MAC_OSX
facd6764
SC
752void wxListBox::OnSize( wxSizeEvent &event)
753{
754}
5ecae0b7 755#endif
facd6764 756
facd6764
SC
757void wxListBox::MacSetRedraw( bool doDraw )
758{
759 // nothing to do in compositing mode
760}
761
762void wxListBox::MacDoClick()
83ce5634 763{/*
facd6764
SC
764 wxArrayInt aSelections;
765 int n ;
766 size_t count = GetSelections(aSelections);
767
768 if ( count == m_selectionPreImage.GetCount() )
769 {
770 bool hasChanged = false ;
771 for ( size_t i = 0 ; i < count ; ++i )
772 {
773 if ( aSelections[i] != m_selectionPreImage[i] )
774 {
775 hasChanged = true ;
776 break ;
777 }
778 }
779 if ( !hasChanged )
780 {
781 return ;
782 }
783 }
784
785 m_selectionPreImage = aSelections;
786
787 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
788 event.SetEventObject( this );
789
790 if ( count > 0 )
791 {
792 n = aSelections[0];
793 if ( HasClientObjectData() )
794 event.SetClientObject( GetClientObject(n) );
795 else if ( HasClientUntypedData() )
796 event.SetClientData( GetClientData(n) );
797 event.SetString( GetString(n) );
798 }
799 else
800 {
801 n = -1;
802 }
803
804 event.m_commandInt = n;
805
806 GetEventHandler()->ProcessEvent(event);
83ce5634 807*/
facd6764
SC
808}
809
810void wxListBox::MacDoDoubleClick()
811{
83ce5634 812/*
facd6764
SC
813 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, m_windowId);
814 event.SetEventObject( this );
815 GetEventHandler()->ProcessEvent(event) ;
83ce5634 816*/
facd6764
SC
817}
818
5ecae0b7
SC
819#if !TARGET_API_MAC_OSX
820
facd6764
SC
821void wxListBox::OnChar(wxKeyEvent& event)
822{
823 // todo trigger proper events here
824 event.Skip() ;
825 return ;
826
827 if ( event.GetKeyCode() == WXK_RETURN || event.GetKeyCode() == WXK_NUMPAD_ENTER)
828 {
829 wxWindow* parent = GetParent() ;
830 while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL )
831 parent = parent->GetParent() ;
832
833 if ( parent && parent->GetDefaultItem() )
834 {
835 wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
836 wxButton);
837 if ( def && def->IsEnabled() )
838 {
839 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
840 event.SetEventObject(def);
841 def->Command(event);
842 return ;
843 }
844 }
845 event.Skip() ;
846 }
847 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
848 else if (event.GetKeyCode() == WXK_ESCAPE || (event.GetKeyCode() == '.' && event.MetaDown() ) )
849 {
850 // FIXME: look in ancestors, not just parent.
851 wxWindow* win = GetParent()->FindWindow( wxID_CANCEL ) ;
852 if (win)
853 {
854 wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
855 new_event.SetEventObject( win );
856 win->GetEventHandler()->ProcessEvent( new_event );
857 }
858 }
859 else if ( event.GetKeyCode() == WXK_TAB )
860 {
861 wxNavigationKeyEvent new_event;
862 new_event.SetEventObject( this );
863 new_event.SetDirection( !event.ShiftDown() );
864 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
865 new_event.SetWindowChange( event.ControlDown() );
866 new_event.SetCurrentFocus( this );
867 if ( !GetEventHandler()->ProcessEvent( new_event ) )
868 event.Skip() ;
869 }
870 else if ( event.GetKeyCode() == WXK_DOWN || event.GetKeyCode() == WXK_UP )
871 {
872 // perform the default key handling first
873 wxControl::OnKeyDown( event ) ;
874
875 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
876 event.SetEventObject( this );
877
878 wxArrayInt aSelections;
879 int n, count = GetSelections(aSelections);
880 if ( count > 0 )
881 {
882 n = aSelections[0];
883 if ( HasClientObjectData() )
884 event.SetClientObject( GetClientObject(n) );
885 else if ( HasClientUntypedData() )
886 event.SetClientData( GetClientData(n) );
887 event.SetString( GetString(n) );
888 }
889 else
890 {
891 n = -1;
892 }
893
894 event.m_commandInt = n;
895
896 GetEventHandler()->ProcessEvent(event);
897 }
898 else
899 {
900 if ( event.GetTimestamp() > m_lastTypeIn + 60 )
901 {
902 m_typeIn = wxEmptyString ;
903 }
904 m_lastTypeIn = event.GetTimestamp() ;
905 m_typeIn += (char) event.GetKeyCode() ;
906 int line = FindString(wxT("*")+m_typeIn+wxT("*")) ;
907 if ( line >= 0 )
908 {
909 if ( GetSelection() != line )
910 {
911 SetSelection(line) ;
912 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
913 event.SetEventObject( this );
914
915 if ( HasClientObjectData() )
916 event.SetClientObject( GetClientObject( line ) );
917 else if ( HasClientUntypedData() )
918 event.SetClientData( GetClientData(line) );
919 event.SetString( GetString(line) );
920
921 event.m_commandInt = line ;
922
923 GetEventHandler()->ProcessEvent(event);
924 }
925 }
926 }
927}
573ac9dc 928
5ecae0b7
SC
929#endif
930