]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/listbox.cpp
added spinctrl to be ignored when clicked (otherwise its siblings on the same window...
[wxWidgets.git] / src / mac / carbon / listbox.cpp
CommitLineData
e9576ca5
SC
1///////////////////////////////////////////////////////////////////////////////
2// Name: listbox.cpp
3// Purpose: wxListBox
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "listbox.h"
14#endif
15
03e11df5 16#include "wx/app.h"
e9576ca5
SC
17#include "wx/listbox.h"
18#include "wx/settings.h"
422644a3 19#include "wx/toplevel.h"
e9576ca5
SC
20#include "wx/dynarray.h"
21#include "wx/log.h"
22
519cb848 23#include "wx/utils.h"
519cb848 24
2f1ae414 25#if !USE_SHARED_LIBRARY
e9576ca5 26 IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
519cb848
SC
27
28BEGIN_EVENT_TABLE(wxListBox, wxControl)
a8e6bf8a 29 EVT_SIZE( wxListBox::OnSize )
519cb848 30END_EVENT_TABLE()
2f1ae414 31#endif
e9576ca5 32
d497dca4 33#include "wx/mac/uma.h"
519cb848 34
573ac9dc
SC
35#if PRAGMA_STRUCT_ALIGN
36 #pragma options align=mac68k
37#elif PRAGMA_STRUCT_PACKPUSH
38 #pragma pack(push, 2)
39#elif PRAGMA_STRUCT_PACK
40 #pragma pack(2)
41#endif
e42e45a9
SC
42
43typedef struct {
44 unsigned short instruction;
45 void (*function)();
46} ldefRec, *ldefPtr, **ldefHandle;
47
573ac9dc
SC
48#if PRAGMA_STRUCT_ALIGN
49 #pragma options align=reset
50#elif PRAGMA_STRUCT_PACKPUSH
51 #pragma pack(pop)
52#elif PRAGMA_STRUCT_PACK
53 #pragma pack()
54#endif
55
e42e45a9
SC
56extern "C"
57{
58static pascal void wxMacListDefinition( short message, Boolean isSelected, Rect *drawRect,
a8e6bf8a
RR
59 Cell cell, short dataOffset, short dataLength,
60 ListHandle listHandle ) ;
e42e45a9
SC
61}
62
63static pascal void wxMacListDefinition( short message, Boolean isSelected, Rect *drawRect,
a8e6bf8a
RR
64 Cell cell, short dataOffset, short dataLength,
65 ListHandle listHandle )
66{
a8e6bf8a
RR
67 GrafPtr savePort;
68 GrafPtr grafPtr;
69 RgnHandle savedClipRegion;
70 SInt32 savedPenMode;
71 wxListBox* list;
e42e45a9
SC
72 GetPort(&savePort);
73 SetPort((**listHandle).port);
74 grafPtr = (**listHandle).port ;
a8e6bf8a
RR
75 // typecast our refCon
76 list = (wxListBox*) GetControlReference( (ControlHandle) GetListRefCon(listHandle) );
77
78 // Calculate the cell rect.
79
80 switch( message ) {
81 case lInitMsg:
82 break;
83
84 case lCloseMsg:
85 break;
86
87 case lDrawMsg:
88 {
89 const wxString text = list->m_stringArray[cell.v] ;
90
91 // Save the current clip region, and set the clip region to the area we are about
92 // to draw.
93
94 savedClipRegion = NewRgn();
95 GetClip( savedClipRegion );
96
97 ClipRect( drawRect );
98 EraseRect( drawRect );
99
100 MoveTo(drawRect->left + 4 , drawRect->top + 10 );
101 ::TextFont( kFontIDMonaco ) ;
102 ::TextSize( 9 );
103 ::TextFace( 0 ) ;
e42e45a9 104
a8e6bf8a
RR
105 DrawText(text, 0 , text.Length());
106 // If the cell is hilited, do the hilite now. Paint the cell contents with the
107 // appropriate QuickDraw transform mode.
108
109 if( isSelected ) {
76a5e5d2
SC
110 savedPenMode = GetPortPenMode( (CGrafPtr) grafPtr );
111 SetPortPenMode( (CGrafPtr)grafPtr, hilitetransfermode );
a8e6bf8a 112 PaintRect( drawRect );
76a5e5d2 113 SetPortPenMode( (CGrafPtr)grafPtr, savedPenMode );
a8e6bf8a
RR
114 }
115
116 // Restore the saved clip region.
117
118 SetClip( savedClipRegion );
119 DisposeRgn( savedClipRegion );
120 }
121 break;
122 case lHiliteMsg:
123
124 // Hilite or unhilite the cell. Paint the cell contents with the
125 // appropriate QuickDraw transform mode.
126
127 GetPort( &grafPtr );
76a5e5d2
SC
128 savedPenMode = GetPortPenMode( (CGrafPtr)grafPtr );
129 SetPortPenMode( (CGrafPtr)grafPtr, hilitetransfermode );
a8e6bf8a 130 PaintRect( drawRect );
76a5e5d2 131 SetPortPenMode( (CGrafPtr)grafPtr, savedPenMode );
a8e6bf8a
RR
132 break;
133 default :
134 break ;
135 }
136 SetPort(savePort);
e42e45a9
SC
137}
138
519cb848
SC
139extern "C" void MacDrawStringCell(Rect *cellRect, Cell lCell, ListHandle theList, long refCon) ;
140const short kwxMacListWithVerticalScrollbar = 128 ;
dbfc5b97 141const short kwxMacListItemHeight = 14 ;
519cb848 142
e9576ca5
SC
143// ============================================================================
144// list box control implementation
145// ============================================================================
146
147// Listbox item
148wxListBox::wxListBox()
149{
150 m_noItems = 0;
151 m_selected = 0;
2f1ae414 152 m_macList = NULL ;
e9576ca5
SC
153}
154
e42e45a9
SC
155static ListDefUPP macListDefUPP = NULL ;
156
e9576ca5
SC
157bool wxListBox::Create(wxWindow *parent, wxWindowID id,
158 const wxPoint& pos,
159 const wxSize& size,
160 int n, const wxString choices[],
161 long style,
162 const wxValidator& validator,
163 const wxString& name)
164{
60149370
GD
165 m_noItems = 0 ; // this will be increased by our append command
166 m_selected = 0;
167
168 Rect bounds ;
169 Str255 title ;
170
171 MacPreControlCreate( parent , id , "" , pos , size ,style, validator , name , &bounds , title ) ;
e9576ca5 172
60149370 173 ListDefSpec listDef;
e42e45a9
SC
174 listDef.defType = kListDefUserProcType;
175 if ( macListDefUPP == NULL )
176 {
177 macListDefUPP = NewListDefUPP( wxMacListDefinition );
178 }
a8e6bf8a 179 listDef.u.userProc = macListDefUPP ;
de043984 180
e42e45a9 181#if TARGET_CARBON
60149370 182 Size asize;
519cb848 183
519cb848 184
962cbf2e
GD
185 CreateListBoxControl( MAC_WXHWND(parent->MacGetRootWindow()), &bounds, false, 0, 1, false, true,
186 kwxMacListItemHeight, kwxMacListItemHeight, false, &listDef, (ControlRef *)&m_macControl );
519cb848 187
76a5e5d2 188 GetControlData( (ControlHandle) m_macControl, kControlNoPart, kControlListBoxListHandleTag,
60149370 189 sizeof(ListHandle), (Ptr) &m_macList, &asize);
519cb848 190
76a5e5d2
SC
191 SetControlReference( (ControlHandle) m_macControl, (long) this);
192 SetControlVisibility( (ControlHandle) m_macControl, false, false);
519cb848 193
60149370 194#else
de043984 195
a8e6bf8a 196 long result ;
fe3fcb05 197 wxStAppResource resload ;
76a5e5d2 198 m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false ,
a8e6bf8a
RR
199 kwxMacListWithVerticalScrollbar , 0 , 0,
200 kControlListBoxProc , (long) this ) ;
76a5e5d2 201 ::GetControlData( (ControlHandle) m_macControl , kControlNoPart , kControlListBoxListHandleTag ,
a8e6bf8a 202 sizeof( ListHandle ) , (char*) &m_macList , &result ) ;
60149370
GD
203
204 HLock( (Handle) m_macList ) ;
e42e45a9
SC
205 ldefHandle ldef ;
206 ldef = (ldefHandle) NewHandle( sizeof(ldefRec) ) ;
76a5e5d2 207 if ( (**(ListHandle)m_macList).listDefProc != NULL )
e42e45a9
SC
208 {
209 (**ldef).instruction = 0x4EF9; /* JMP instruction */
210 (**ldef).function = (void(*)()) listDef.u.userProc;
76a5e5d2 211 (**(ListHandle)m_macList).listDefProc = (Handle) ldef ;
e42e45a9
SC
212 }
213
76a5e5d2 214 Point pt = (**(ListHandle)m_macList).cellSize ;
dbfc5b97 215 pt.v = kwxMacListItemHeight ;
76a5e5d2
SC
216 LCellSize( pt , (ListHandle)m_macList ) ;
217 LAddColumn( 1 , 0 , (ListHandle)m_macList ) ;
e42e45a9
SC
218#endif
219 OptionBits options = 0;
60149370
GD
220 if ( style & wxLB_MULTIPLE )
221 {
e42e45a9 222 options += lNoExtend ;
60149370
GD
223 }
224 else if ( style & wxLB_EXTENDED )
225 {
e42e45a9 226 options += lExtendDrag ;
60149370
GD
227 }
228 else
229 {
e42e45a9 230 options = lOnlyOne ;
60149370 231 }
76a5e5d2 232 SetListSelectionFlags((ListHandle)m_macList, options);
60149370
GD
233
234 MacPostControlCreate() ;
235
236 for ( int i = 0 ; i < n ; i++ )
237 {
a8e6bf8a 238 Append( choices[i] ) ;
60149370
GD
239 }
240
76a5e5d2 241 LSetDrawingMode( true , (ListHandle)m_macList ) ;
519cb848 242
60149370 243 return TRUE;
e9576ca5
SC
244}
245
246wxListBox::~wxListBox()
247{
a8e6bf8a
RR
248 Free() ;
249 if ( m_macList )
250 {
60149370 251#if !TARGET_CARBON
76a5e5d2
SC
252 DisposeHandle( (**(ListHandle)m_macList).listDefProc ) ;
253 (**(ListHandle)m_macList).listDefProc = NULL ;
60149370 254#endif
a8e6bf8a
RR
255 m_macList = NULL ;
256 }
e9576ca5
SC
257}
258
e7549107 259void wxListBox::Free()
e9576ca5 260{
e7549107
SC
261#if wxUSE_OWNER_DRAWN
262 if ( m_windowStyle & wxLB_OWNERDRAW )
263 {
264 size_t uiCount = m_aItems.Count();
265 while ( uiCount-- != 0 ) {
266 delete m_aItems[uiCount];
267 }
268
269 m_aItems.Clear();
270 }
271 else
272#endif // wxUSE_OWNER_DRAWN
273 if ( HasClientObjectData() )
274 {
275 for ( size_t n = 0; n < (size_t)m_noItems; n++ )
276 {
277 delete GetClientObject(n);
278 }
279 }
e9576ca5
SC
280}
281
8614041b
SC
282void wxListBox::DoSetSize(int x, int y,
283 int width, int height,
284 int sizeFlags )
285{
a8e6bf8a 286 wxControl::DoSetSize( x , y , width , height , sizeFlags ) ;
8614041b 287#if TARGET_CARBON
a8e6bf8a 288 Rect bounds ;
76a5e5d2 289 GetControlBounds( (ControlHandle) m_macControl , &bounds ) ;
962cbf2e 290 ControlRef control = GetListVerticalScrollBar( (ListHandle)m_macList ) ;
a8e6bf8a
RR
291 if ( control )
292 {
293 Rect scrollbounds ;
294 GetControlBounds( control , &scrollbounds ) ;
295 if( scrollbounds.right != bounds.right + 1 )
296 {
297 UMAMoveControl( control , bounds.right - (scrollbounds.right - scrollbounds.left) + 1 ,
298 scrollbounds.top ) ;
299 }
300 }
8614041b
SC
301#endif
302}
e7549107 303void wxListBox::DoSetFirstItem(int N)
e9576ca5 304{
a8e6bf8a 305 MacScrollTo( N ) ;
e9576ca5
SC
306}
307
308void wxListBox::Delete(int N)
309{
e7549107
SC
310 wxCHECK_RET( N >= 0 && N < m_noItems,
311 wxT("invalid index in wxListBox::Delete") );
312
313#if wxUSE_OWNER_DRAWN
314 delete m_aItems[N];
0baac61e 315 m_aItems.RemoveAt(N);
e7549107
SC
316#else // !wxUSE_OWNER_DRAWN
317 if ( HasClientObjectData() )
318 {
319 delete GetClientObject(N);
320 }
321#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
a8e6bf8a
RR
322 m_stringArray.Remove( N ) ;
323 m_dataArray.RemoveAt( N ) ;
324 m_noItems --;
325
326 MacDelete( N ) ;
e9576ca5
SC
327}
328
e7549107 329int wxListBox::DoAppend(const wxString& item)
e9576ca5 330{
a8e6bf8a
RR
331 int index = m_noItems ;
332 if( wxApp::s_macDefaultEncodingIsPC )
333 {
334 m_stringArray.Add( wxMacMakeMacStringFromPC( item ) ) ;
335 m_dataArray.Add( NULL );
336 }
337 else {
338 m_stringArray.Add( item ) ;
339 m_dataArray.Add( NULL );
340 }
341 m_noItems ++;
342 DoSetItemClientData( index , NULL ) ;
343 MacAppend( item ) ;
e7549107 344
a8e6bf8a 345 return index ;
e9576ca5
SC
346}
347
e7549107
SC
348void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData)
349{
350 MacSetRedraw( false ) ;
519cb848 351 Clear() ;
e7549107
SC
352 int n = choices.GetCount();
353
519cb848
SC
354 for( int i = 0 ; i < n ; ++i )
355 {
a8e6bf8a
RR
356 if ( clientData )
357 {
e7549107
SC
358#if wxUSE_OWNER_DRAWN
359 wxASSERT_MSG(clientData[i] == NULL,
360 wxT("Can't use client data with owner-drawn listboxes"));
361#else // !wxUSE_OWNER_DRAWN
a8e6bf8a 362 Append( choices[i] , clientData[i] ) ;
e7549107 363 #endif
a8e6bf8a
RR
364 }
365 else
366 Append( choices[i] ) ;
519cb848 367 }
e7549107
SC
368
369#if wxUSE_OWNER_DRAWN
370 if ( m_windowStyle & wxLB_OWNERDRAW ) {
371 // first delete old items
372 size_t ui = m_aItems.Count();
373 while ( ui-- != 0 ) {
374 delete m_aItems[ui];
375 }
376 m_aItems.Empty();
377
378 // then create new ones
379 for ( ui = 0; ui < (size_t)m_noItems; ui++ ) {
380 wxOwnerDrawn *pNewItem = CreateItem(ui);
381 pNewItem->SetName(choices[ui]);
382 m_aItems.Add(pNewItem);
383 }
384 }
385#endif // wxUSE_OWNER_DRAWN
386 MacSetRedraw( true ) ;
387}
388
389bool wxListBox::HasMultipleSelection() const
390{
391 return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
e9576ca5
SC
392}
393
519cb848 394int wxListBox::FindString(const wxString& st) const
e9576ca5 395{
a8e6bf8a
RR
396 wxString s ;
397 if( wxApp::s_macDefaultEncodingIsPC )
398 {
399 s = wxMacMakeMacStringFromPC( st ) ;
400 }
401 else
402 s = st ;
403
404 if ( s.Right(1) == "*" )
405 {
406 wxString search = s.Left( s.Length() - 1 ) ;
407 int len = search.Length() ;
408 Str255 s1 , s2 ;
03e11df5
GD
409
410#if TARGET_CARBON
a8e6bf8a 411 c2pstrcpy( (StringPtr) s2 , search.c_str() ) ;
03e11df5 412#else
a8e6bf8a
RR
413 strcpy( (char *) s2 , search.c_str() ) ;
414 c2pstr( (char *) s2 ) ;
03e11df5
GD
415#endif
416
a8e6bf8a
RR
417 for ( int i = 0 ; i < m_noItems ; ++ i )
418 {
03e11df5 419#if TARGET_CARBON
a8e6bf8a 420 c2pstrcpy( (StringPtr) s1 , m_stringArray[i].Left( len ).c_str() ) ;
03e11df5 421#else
a8e6bf8a
RR
422 strcpy( (char *) s1 , m_stringArray[i].Left( len ).c_str() ) ;
423 c2pstr( (char *) s1 ) ;
03e11df5 424#endif
a8e6bf8a
RR
425 if ( EqualString( s1 , s2 , false , false ) )
426 return i ;
427 }
428 if ( s.Left(1) == "*" && s.Length() > 1 )
429 {
430 s.MakeLower() ;
431 for ( int i = 0 ; i < m_noItems ; ++i )
432 {
433 if ( GetString(i).Lower().Matches(s) )
434 return i ;
435 }
436 }
437
438 }
439 else
440 {
441 Str255 s1 , s2 ;
03e11df5
GD
442
443#if TARGET_CARBON
a8e6bf8a 444 c2pstrcpy( (StringPtr) s2 , s.c_str() ) ;
03e11df5 445#else
a8e6bf8a
RR
446 strcpy( (char *) s2 , s.c_str() ) ;
447 c2pstr( (char *) s2 ) ;
03e11df5
GD
448#endif
449
a8e6bf8a
RR
450 for ( int i = 0 ; i < m_noItems ; ++ i )
451 {
03e11df5 452#if TARGET_CARBON
a8e6bf8a 453 c2pstrcpy( (StringPtr) s1 , m_stringArray[i].c_str() ) ;
03e11df5 454#else
a8e6bf8a
RR
455 strcpy( (char *) s1 , m_stringArray[i].c_str() ) ;
456 c2pstr( (char *) s1 ) ;
03e11df5 457#endif
a8e6bf8a
RR
458 if ( EqualString( s1 , s2 , false , false ) )
459 return i ;
460 }
519cb848
SC
461 }
462 return -1;
e9576ca5
SC
463}
464
465void wxListBox::Clear()
466{
e7549107 467 Free();
e9576ca5 468 m_noItems = 0;
519cb848
SC
469 m_stringArray.Empty() ;
470 m_dataArray.Empty() ;
471 MacClear() ;
e9576ca5
SC
472}
473
474void wxListBox::SetSelection(int N, bool select)
475{
519cb848
SC
476 wxCHECK_RET( N >= 0 && N < m_noItems,
477 "invalid index in wxListBox::SetSelection" );
a8e6bf8a
RR
478 MacSetSelection( N , select ) ;
479 GetSelections( m_selectionPreImage ) ;
e9576ca5
SC
480}
481
e7549107 482bool wxListBox::IsSelected(int N) const
e9576ca5 483{
519cb848
SC
484 wxCHECK_MSG( N >= 0 && N < m_noItems, FALSE,
485 "invalid index in wxListBox::Selected" );
486
a8e6bf8a 487 return MacIsSelected( N ) ;
e9576ca5
SC
488}
489
e7549107 490void *wxListBox::DoGetItemClientData(int N) const
e9576ca5 491{
519cb848 492 wxCHECK_MSG( N >= 0 && N < m_noItems, NULL,
60149370 493 wxT("invalid index in wxListBox::GetClientData"));
519cb848 494
e7549107 495 return (void *)m_dataArray[N];
e9576ca5
SC
496}
497
51abe921
SC
498wxClientData *wxListBox::DoGetItemClientObject(int N) const
499{
a8e6bf8a 500 return (wxClientData *) DoGetItemClientData( N ) ;
51abe921
SC
501}
502
e7549107 503void wxListBox::DoSetItemClientData(int N, void *Client_data)
e9576ca5 504{
519cb848
SC
505 wxCHECK_RET( N >= 0 && N < m_noItems,
506 "invalid index in wxListBox::SetClientData" );
507
e7549107
SC
508#if wxUSE_OWNER_DRAWN
509 if ( m_windowStyle & wxLB_OWNERDRAW )
510 {
511 // client data must be pointer to wxOwnerDrawn, otherwise we would crash
512 // in OnMeasure/OnDraw.
513 wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
514 }
515#endif // wxUSE_OWNER_DRAWN
a8e6bf8a
RR
516 wxASSERT_MSG( m_dataArray.GetCount() >= N , "invalid client_data array" ) ;
517
518 if ( m_dataArray.GetCount() > N )
519 {
520 m_dataArray[N] = (char*) Client_data ;
2f1ae414 521 }
8208e181
SC
522 else
523 {
a8e6bf8a 524 m_dataArray.Add( (char*) Client_data ) ;
8208e181 525 }
e7549107
SC
526}
527
528void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData)
529{
530 DoSetItemClientData(n, clientData);
e9576ca5
SC
531}
532
533// Return number of selections and an array of selected integers
534int wxListBox::GetSelections(wxArrayInt& aSelections) const
535{
a8e6bf8a 536 return MacGetSelections( aSelections ) ;
e9576ca5
SC
537}
538
539// Get single selection, for single choice list items
540int wxListBox::GetSelection() const
541{
a8e6bf8a 542 return MacGetSelection() ;
e9576ca5
SC
543}
544
545// Find string for position
546wxString wxListBox::GetString(int N) const
547{
a8e6bf8a
RR
548 if( wxApp::s_macDefaultEncodingIsPC )
549 {
550 return wxMacMakePCStringFromMac( m_stringArray[N] ) ;
551 }
552 else
553 return m_stringArray[N] ;
e9576ca5
SC
554}
555
e7549107 556void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
e9576ca5 557{
e7549107
SC
558 wxCHECK_RET( pos >= 0 && pos <= m_noItems,
559 wxT("invalid index in wxListBox::InsertItems") );
560
561 int nItems = items.GetCount();
562
a8e6bf8a
RR
563 for ( int i = 0 ; i < nItems ; i++ )
564 {
565 m_stringArray.Insert( items[i] , pos + i ) ;
566 m_dataArray.Insert( NULL , pos + i ) ;
567 MacInsert( pos + i , items[i] ) ;
568 }
e9576ca5 569
519cb848 570 m_noItems += nItems;
e9576ca5
SC
571}
572
573void wxListBox::SetString(int N, const wxString& s)
574{
a8e6bf8a
RR
575 wxString str ;
576 if( wxApp::s_macDefaultEncodingIsPC )
577 {
578 str = wxMacMakeMacStringFromPC( s ) ;
579 }
580 else
581 str = s ;
582 m_stringArray[N] = str ;
583 MacSet( N , s ) ;
e9576ca5
SC
584}
585
37e2cb08 586wxSize wxListBox::DoGetBestSize() const
e9576ca5 587{
e7549107 588 return wxSize(100, 100);
e9576ca5
SC
589}
590
51abe921
SC
591int wxListBox::GetCount() const
592{
593 return m_noItems;
594}
595
596void wxListBox::SetupColours()
597{
a756f210 598 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
51abe921
SC
599 SetForegroundColour(GetParent()->GetForegroundColour());
600}
601
60149370
GD
602void wxListBox::Refresh(bool eraseBack, const wxRect *rect)
603{
de043984
SC
604 wxControl::Refresh( eraseBack , rect ) ;
605// MacRedrawControl() ;
60149370
GD
606}
607
51abe921
SC
608#if wxUSE_OWNER_DRAWN
609
610class wxListBoxItem : public wxOwnerDrawn
611{
612public:
613 wxListBoxItem(const wxString& str = "");
614};
615
616wxListBoxItem::wxListBoxItem(const wxString& str) : wxOwnerDrawn(str, FALSE)
617{
618 // no bitmaps/checkmarks
619 SetMarginWidth(0);
620}
621
622wxOwnerDrawn *wxListBox::CreateItem(size_t n)
623{
624 return new wxListBoxItem();
625}
626
627#endif //USE_OWNER_DRAWN
e9576ca5 628
519cb848
SC
629// ============================================================================
630// list box control implementation
631// ============================================================================
632
633void MacDrawStringCell(Rect *cellRect, Cell lCell, ListHandle theList, long refCon)
634{
a8e6bf8a
RR
635 wxListBox* list;
636 // typecast our refCon
637 list = (wxListBox*)refCon;
638
639 MoveTo(cellRect->left + 4 , cellRect->top + 10 );
640 const wxString text = list->m_stringArray[lCell.v] ;
641 ::TextFont( kFontIDMonaco ) ;
642 ::TextSize( 9 );
643 ::TextFace( 0 ) ;
644 DrawText(text, 0 , text.Length());
645
519cb848
SC
646}
647
648void wxListBox::MacDelete( int N )
649{
76a5e5d2 650 LDelRow( 1 , N , (ListHandle)m_macList) ;
60149370 651 Refresh();
519cb848
SC
652}
653
654void wxListBox::MacInsert( int n , const char * text)
655{
60149370
GD
656 Cell cell = { 0 , 0 } ;
657 cell.v = n ;
76a5e5d2 658 LAddRow( 1 , cell.v , (ListHandle)m_macList ) ;
e42e45a9 659// LSetCell(text, strlen(text), cell, m_macList);
60149370 660 Refresh();
519cb848
SC
661}
662
663void wxListBox::MacAppend( const char * text)
664{
60149370 665 Cell cell = { 0 , 0 } ;
76a5e5d2
SC
666 cell.v = (**(ListHandle)m_macList).dataBounds.bottom ;
667 LAddRow( 1 , cell.v , (ListHandle)m_macList ) ;
e42e45a9 668 // LSetCell(text, strlen(text), cell, m_macList);
60149370 669 Refresh();
519cb848
SC
670}
671
672void wxListBox::MacClear()
673{
76a5e5d2 674 LDelRow( (**(ListHandle)m_macList).dataBounds.bottom , 0 ,(ListHandle) m_macList ) ;
60149370 675 Refresh();
519cb848
SC
676}
677
678void wxListBox::MacSetSelection( int n , bool select )
679{
a8e6bf8a
RR
680 Cell cell = { 0 , 0 } ;
681 if ( ! (m_windowStyle & wxLB_MULTIPLE) )
682 {
9f081f02
GD
683 if ( LGetSelect( true , &cell , (ListHandle)m_macList ) )
684 {
685 LSetSelect( false , cell , (ListHandle)m_macList ) ;
686 }
a8e6bf8a
RR
687 }
688
689 cell.v = n ;
76a5e5d2
SC
690 LSetSelect( select , cell , (ListHandle)m_macList ) ;
691 LAutoScroll( (ListHandle)m_macList ) ;
a8e6bf8a 692 Refresh();
519cb848
SC
693}
694
695bool wxListBox::MacIsSelected( int n ) const
696{
a8e6bf8a
RR
697 Cell cell = { 0 , 0 } ;
698 cell.v = n ;
76a5e5d2 699 return LGetSelect( false , &cell , (ListHandle)m_macList ) ;
519cb848
SC
700}
701
702void wxListBox::MacDestroy()
703{
60149370 704// DisposeExtLDEFInfo( m_macList ) ;
519cb848
SC
705}
706
707int wxListBox::MacGetSelection() const
708{
a8e6bf8a 709 Cell cell = { 0 , 0 } ;
76a5e5d2 710 if ( LGetSelect( true , &cell , (ListHandle)m_macList ) )
a8e6bf8a
RR
711 return cell.v ;
712 else
713 return -1 ;
519cb848
SC
714}
715
716int wxListBox::MacGetSelections( wxArrayInt& aSelections ) const
717{
a8e6bf8a
RR
718 int no_sel = 0 ;
719
519cb848
SC
720 aSelections.Empty();
721
a8e6bf8a
RR
722 Cell cell = { 0 , 0 } ;
723 cell.v = 0 ;
724
76a5e5d2 725 while ( LGetSelect( true , &cell ,(ListHandle) m_macList ) )
a8e6bf8a
RR
726 {
727 aSelections.Add( cell.v ) ;
728 no_sel++ ;
729 cell.v++ ;
730 }
731 return no_sel ;
519cb848
SC
732}
733
734void wxListBox::MacSet( int n , const char * text )
735{
a8e6bf8a
RR
736 // our implementation does not store anything in the list
737 // so we just have to redraw
738 Cell cell = { 0 , 0 } ;
739 cell.v = n ;
740// LSetCell(text, strlen(text), cell, m_macList);
741 Refresh();
519cb848
SC
742}
743
744void wxListBox::MacScrollTo( int n )
745{
a8e6bf8a 746 // TODO implement scrolling
519cb848
SC
747}
748
749void wxListBox::OnSize( const wxSizeEvent &event)
750{
60149370
GD
751 Point pt;
752
753#if TARGET_CARBON
962cbf2e 754 GetListCellSize((ListHandle)m_macList, &pt);
60149370 755#else
76a5e5d2 756 pt = (**(ListHandle)m_macList).cellSize ;
60149370
GD
757#endif
758 pt.h = m_width - 15 ;
76a5e5d2 759 LCellSize( pt , (ListHandle)m_macList ) ;
519cb848
SC
760}
761
76a5e5d2 762void wxListBox::MacHandleControlClick( WXWidget control , wxInt16 controlpart )
519cb848 763{
a8e6bf8a
RR
764 Boolean wasDoubleClick = false ;
765 long result ;
519cb848 766
76a5e5d2 767 ::GetControlData( (ControlHandle) m_macControl , kControlNoPart , kControlListBoxDoubleClickTag , sizeof( wasDoubleClick ) , (char*) &wasDoubleClick , &result ) ;
a8e6bf8a
RR
768 if ( !wasDoubleClick )
769 {
770 MacDoClick() ;
771 }
772 else
773 {
774 MacDoDoubleClick() ;
775 }
519cb848
SC
776}
777
778void wxListBox::MacSetRedraw( bool doDraw )
779{
76a5e5d2 780 LSetDrawingMode( doDraw , (ListHandle)m_macList ) ;
a8e6bf8a 781
519cb848
SC
782}
783
784void wxListBox::MacDoClick()
785{
a8e6bf8a
RR
786 wxArrayInt aSelections;
787 int n, count = GetSelections(aSelections);
788
789 if ( count == m_selectionPreImage.GetCount() )
790 {
791 bool hasChanged = false ;
792 for ( int i = 0 ; i < count ; ++i )
793 {
794 if ( aSelections[i] != m_selectionPreImage[i] )
795 {
796 hasChanged = true ;
797 break ;
798 }
799 }
800 if ( !hasChanged )
801 {
802 return ;
803 }
804 }
805
806 m_selectionPreImage = aSelections;
807
808 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
809 event.SetEventObject( this );
810
811 if ( count > 0 )
812 {
813 n = aSelections[0];
814 if ( HasClientObjectData() )
815 event.SetClientObject( GetClientObject(n) );
816 else if ( HasClientUntypedData() )
817 event.SetClientData( GetClientData(n) );
818 event.SetString( GetString(n) );
819 }
820 else
821 {
e7549107 822 n = -1;
a8e6bf8a
RR
823 }
824
e7549107
SC
825 event.m_commandInt = n;
826
827 GetEventHandler()->ProcessEvent(event);
519cb848
SC
828}
829
830void wxListBox::MacDoDoubleClick()
831{
832 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, m_windowId);
833 event.SetEventObject( this );
a8e6bf8a 834 GetEventHandler()->ProcessEvent(event) ;
519cb848 835}