]> git.saurik.com Git - wxWidgets.git/blob - src/mac/classic/listbox.cpp
Fixed OpenWatcom (strange) scope related crash.
[wxWidgets.git] / src / mac / classic / listbox.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/classic/listbox.cpp
3 // Purpose: wxListBox
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #if wxUSE_LISTBOX
15
16 #include "wx/listbox.h"
17
18 #ifndef WX_PRECOMP
19 #include "wx/dynarray.h"
20 #include "wx/log.h"
21 #include "wx/app.h"
22 #include "wx/utils.h"
23 #include "wx/button.h"
24 #include "wx/settings.h"
25 #endif
26
27 #include "wx/toplevel.h"
28
29 IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
30
31 BEGIN_EVENT_TABLE(wxListBox, wxControl)
32 EVT_SIZE( wxListBox::OnSize )
33 EVT_CHAR( wxListBox::OnChar )
34 END_EVENT_TABLE()
35
36 #include "wx/mac/uma.h"
37
38 #if PRAGMA_STRUCT_ALIGN
39 #pragma options align=mac68k
40 #elif PRAGMA_STRUCT_PACKPUSH
41 #pragma pack(push, 2)
42 #elif PRAGMA_STRUCT_PACK
43 #pragma pack(2)
44 #endif
45
46 typedef struct {
47 unsigned short instruction;
48 void (*function)();
49 } ldefRec, *ldefPtr, **ldefHandle;
50
51 #if PRAGMA_STRUCT_ALIGN
52 #pragma options align=reset
53 #elif PRAGMA_STRUCT_PACKPUSH
54 #pragma pack(pop)
55 #elif PRAGMA_STRUCT_PACK
56 #pragma pack()
57 #endif
58
59 #if TARGET_CARBON
60 const short kwxMacListItemHeight = 19 ;
61 #else
62 const short kwxMacListItemHeight = 14 ;
63 #endif
64
65 extern "C"
66 {
67 static pascal void wxMacListDefinition( short message, Boolean isSelected, Rect *drawRect,
68 Cell cell, short dataOffset, short dataLength,
69 ListHandle listHandle ) ;
70 }
71
72 static pascal void wxMacListDefinition( short message, Boolean isSelected, Rect *drawRect,
73 Cell cell, short dataOffset, short dataLength,
74 ListHandle listHandle )
75 {
76 wxListBox* list;
77 list = (wxListBox*) GetControlReference( (ControlHandle) GetListRefCon(listHandle) );
78 if ( list == NULL )
79 return ;
80
81 GrafPtr savePort;
82 GrafPtr grafPtr;
83 RgnHandle savedClipRegion;
84 SInt32 savedPenMode;
85 GetPort(&savePort);
86 SetPort((**listHandle).port);
87 grafPtr = (**listHandle).port ;
88 // typecast our refCon
89
90 // Calculate the cell rect.
91
92 switch( message ) {
93 case lInitMsg:
94 break;
95
96 case lCloseMsg:
97 break;
98
99 case lDrawMsg:
100 {
101 const wxString linetext = list->m_stringArray[cell.v] ;
102
103 // Save the current clip region, and set the clip region to the area we are about
104 // to draw.
105
106 savedClipRegion = NewRgn();
107 GetClip( savedClipRegion );
108
109 ClipRect( drawRect );
110 EraseRect( drawRect );
111
112 const wxFont& font = list->GetFont();
113 if ( font.Ok() )
114 {
115 ::TextFont( font.GetMacFontNum() ) ;
116 ::TextSize( font.GetMacFontSize() ) ;
117 ::TextFace( font.GetMacFontStyle() ) ;
118 }
119 else
120 {
121 ::TextFont( kFontIDMonaco ) ;
122 ::TextSize( 9 );
123 ::TextFace( 0 ) ;
124 }
125
126 #if TARGET_CARBON
127 {
128 Rect frame = { drawRect->top, drawRect->left + 4,
129 drawRect->top + kwxMacListItemHeight, drawRect->right + 10000 } ;
130 CFMutableStringRef mString = CFStringCreateMutableCopy( NULL , 0 , wxMacCFStringHolder(linetext , list->GetFont().GetEncoding()) ) ;
131 ::TruncateThemeText( mString , kThemeCurrentPortFont, kThemeStateActive, drawRect->right - drawRect->left , truncEnd , NULL ) ;
132 ::DrawThemeTextBox( mString,
133 kThemeCurrentPortFont,
134 kThemeStateActive,
135 false,
136 &frame,
137 teJustLeft,
138 nil );
139 CFRelease( mString ) ;
140 }
141 #else
142 {
143 wxCharBuffer text = linetext.mb_str( wxConvLocal) ;
144 MoveTo(drawRect->left + 4 , drawRect->top + 10 );
145 DrawText(text, 0 , strlen(text) );
146 }
147 #endif
148 // If the cell is hilited, do the hilite now. Paint the cell contents with the
149 // appropriate QuickDraw transform mode.
150
151 if( isSelected ) {
152 savedPenMode = GetPortPenMode( (CGrafPtr) grafPtr );
153 SetPortPenMode( (CGrafPtr)grafPtr, hilitetransfermode );
154 PaintRect( drawRect );
155 SetPortPenMode( (CGrafPtr)grafPtr, savedPenMode );
156 }
157
158 // Restore the saved clip region.
159
160 SetClip( savedClipRegion );
161 DisposeRgn( savedClipRegion );
162 }
163 break;
164 case lHiliteMsg:
165
166 // Hilite or unhilite the cell. Paint the cell contents with the
167 // appropriate QuickDraw transform mode.
168
169 GetPort( &grafPtr );
170 savedPenMode = GetPortPenMode( (CGrafPtr)grafPtr );
171 SetPortPenMode( (CGrafPtr)grafPtr, hilitetransfermode );
172 PaintRect( drawRect );
173 SetPortPenMode( (CGrafPtr)grafPtr, savedPenMode );
174 break;
175 default :
176 break ;
177 }
178 SetPort(savePort);
179 }
180
181 extern "C" void MacDrawStringCell(Rect *cellRect, Cell lCell, ListHandle theList, long refCon) ;
182 // resources ldef ids
183 const short kwxMacListWithVerticalScrollbar = 128 ;
184 const short kwxMacListWithVerticalAndHorizontalScrollbar = 129 ;
185
186 // ============================================================================
187 // list box control implementation
188 // ============================================================================
189
190 // Listbox item
191 wxListBox::wxListBox()
192 {
193 m_noItems = 0;
194 m_selected = 0;
195 m_macList = NULL ;
196 }
197
198 static ListDefUPP macListDefUPP = NULL ;
199
200 bool wxListBox::Create(wxWindow *parent, wxWindowID id,
201 const wxPoint& pos,
202 const wxSize& size,
203 const wxArrayString& choices,
204 long style,
205 const wxValidator& validator,
206 const wxString& name)
207 {
208 wxCArrayString chs(choices);
209
210 return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
211 style, validator, name);
212 }
213
214 bool wxListBox::Create(wxWindow *parent, wxWindowID id,
215 const wxPoint& pos,
216 const wxSize& size,
217 int n, const wxString choices[],
218 long style,
219 const wxValidator& validator,
220 const wxString& name)
221 {
222 if ( !wxListBoxBase::Create(parent, id, pos, size, style & ~(wxHSCROLL|wxVSCROLL), validator, name) )
223 return false;
224
225 m_noItems = 0 ; // this will be increased by our append command
226 m_selected = 0;
227
228 Rect bounds ;
229 Str255 title ;
230
231 MacPreControlCreate( parent , id , wxEmptyString , pos , size ,style, validator , name , &bounds , title ) ;
232
233 ListDefSpec listDef;
234 listDef.defType = kListDefUserProcType;
235 if ( macListDefUPP == NULL )
236 {
237 macListDefUPP = NewListDefUPP( wxMacListDefinition );
238 }
239 listDef.u.userProc = macListDefUPP ;
240
241 Str255 fontName ;
242 SInt16 fontSize ;
243 Style fontStyle ;
244 #if TARGET_CARBON
245 GetThemeFont(kThemeViewsFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
246 #else
247 GetFontName( kFontIDMonaco , fontName ) ;
248 fontSize = 9 ;
249 fontStyle = normal ;
250 #endif
251 SetFont( wxFont (fontSize, wxSWISS, wxNORMAL, wxNORMAL , false , wxMacMakeStringFromPascal( fontName ) ) ) ;
252 #if TARGET_CARBON
253 Size asize;
254
255
256 CreateListBoxControl( MAC_WXHWND(parent->MacGetRootWindow()), &bounds, false, 0, 1, (style & wxLB_HSCROLL), true,
257 kwxMacListItemHeight, kwxMacListItemHeight, false, &listDef, (ControlRef *)&m_macControl );
258
259 GetControlData( (ControlHandle) m_macControl, kControlNoPart, kControlListBoxListHandleTag,
260 sizeof(ListHandle), (Ptr) &m_macList, &asize);
261
262 SetControlReference( (ControlHandle) m_macControl, (long) this);
263 SetControlVisibility( (ControlHandle) m_macControl, false, false);
264
265 #else
266
267 long result ;
268 wxStAppResource resload ;
269 m_macControl = (WXWidget) ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false ,
270 (style & wxLB_HSCROLL) ? kwxMacListWithVerticalAndHorizontalScrollbar : kwxMacListWithVerticalScrollbar ,
271 0 , 0, kControlListBoxProc , (long) this ) ;
272 ::GetControlData( (ControlHandle) m_macControl , kControlNoPart , kControlListBoxListHandleTag ,
273 sizeof( ListHandle ) , (char*) &m_macList , &result ) ;
274
275 HLock( (Handle) m_macList ) ;
276 ldefHandle ldef ;
277 ldef = (ldefHandle) NewHandle( sizeof(ldefRec) ) ;
278 if ( (**(ListHandle)m_macList).listDefProc != NULL )
279 {
280 (**ldef).instruction = 0x4EF9; /* JMP instruction */
281 (**ldef).function = (void(*)()) listDef.u.userProc;
282 (**(ListHandle)m_macList).listDefProc = (Handle) ldef ;
283 }
284
285 Point pt = (**(ListHandle)m_macList).cellSize ;
286 pt.v = kwxMacListItemHeight ;
287 LCellSize( pt , (ListHandle)m_macList ) ;
288 LAddColumn( 1 , 0 , (ListHandle)m_macList ) ;
289 #endif
290 OptionBits options = 0;
291 if ( style & wxLB_MULTIPLE )
292 {
293 options += lExtendDrag + lUseSense ;
294 }
295 else if ( style & wxLB_EXTENDED )
296 {
297 // default behaviour
298 }
299 else
300 {
301 options = (OptionBits) lOnlyOne ;
302 }
303 SetListSelectionFlags((ListHandle)m_macList, options);
304
305 for ( int i = 0 ; i < n ; i++ )
306 {
307 Append( choices[i] ) ;
308 }
309
310 MacPostControlCreate() ;
311
312 LSetDrawingMode( true , (ListHandle)m_macList ) ;
313
314 return true;
315 }
316
317 wxListBox::~wxListBox()
318 {
319 FreeData() ;
320 // avoid access during destruction
321 SetControlReference( (ControlHandle) m_macControl , NULL ) ;
322 if ( m_macList )
323 {
324 #if !TARGET_CARBON
325 DisposeHandle( (**(ListHandle)m_macList).listDefProc ) ;
326 (**(ListHandle)m_macList).listDefProc = NULL ;
327 #endif
328 m_macList = NULL ;
329 }
330 }
331
332 void wxListBox::FreeData()
333 {
334 #if wxUSE_OWNER_DRAWN
335 if ( m_windowStyle & wxLB_OWNERDRAW )
336 {
337 size_t uiCount = m_aItems.Count();
338 while ( uiCount-- != 0 ) {
339 delete m_aItems[uiCount];
340 m_aItems[uiCount] = NULL;
341 }
342
343 m_aItems.Clear();
344 }
345 else
346 #endif // wxUSE_OWNER_DRAWN
347 if ( HasClientObjectData() )
348 {
349 for ( unsigned int n = 0; n < m_noItems; n++ )
350 {
351 delete GetClientObject(n);
352 }
353 }
354 }
355
356 void wxListBox::DoSetSize(int x, int y,
357 int width, int height,
358 int sizeFlags )
359 {
360 wxControl::DoSetSize( x , y , width , height , sizeFlags ) ;
361 #if TARGET_CARBON
362 Rect bounds ;
363 GetControlBounds( (ControlHandle) m_macControl , &bounds ) ;
364 ControlRef control = GetListVerticalScrollBar( (ListHandle)m_macList ) ;
365 if ( control )
366 {
367 Rect scrollbounds ;
368 GetControlBounds( control , &scrollbounds ) ;
369 if( scrollbounds.right != bounds.right + 1 )
370 {
371 UMAMoveControl( control , bounds.right - (scrollbounds.right - scrollbounds.left) + 1 ,
372 scrollbounds.top ) ;
373 }
374 }
375 #endif
376 }
377 void wxListBox::DoSetFirstItem(int N)
378 {
379 MacScrollTo( N ) ;
380 }
381
382 void wxListBox::Delete(unsigned int n)
383 {
384 wxCHECK_RET( IsValid(n),
385 wxT("invalid index in wxListBox::Delete") );
386
387 #if wxUSE_OWNER_DRAWN
388 delete m_aItems[n];
389 m_aItems.RemoveAt(n);
390 #else // !wxUSE_OWNER_DRAWN
391 if ( HasClientObjectData() )
392 {
393 delete GetClientObject(n);
394 }
395 #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
396 m_stringArray.RemoveAt(n) ;
397 m_dataArray.RemoveAt(n) ;
398 m_noItems--;
399
400 MacDelete(n) ;
401 }
402
403 int wxListBox::DoAppend(const wxString& item)
404 {
405 InvalidateBestSize();
406
407 unsigned int index = m_noItems ;
408 m_stringArray.Add( item ) ;
409 m_dataArray.Add( NULL );
410 m_noItems ++;
411 DoSetItemClientData( index , NULL ) ;
412 MacAppend( item ) ;
413
414 return index ;
415 }
416
417 void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData)
418 {
419 MacSetRedraw( false ) ;
420 Clear() ;
421 int n = choices.GetCount();
422
423 for( int i = 0 ; i < n ; ++i )
424 {
425 if ( clientData )
426 {
427 #if wxUSE_OWNER_DRAWN
428 wxASSERT_MSG(clientData[i] == NULL,
429 wxT("Can't use client data with owner-drawn listboxes"));
430 #else // !wxUSE_OWNER_DRAWN
431 Append( choices[i] , clientData[i] ) ;
432 #endif
433 }
434 else
435 Append( choices[i] ) ;
436 }
437
438 #if wxUSE_OWNER_DRAWN
439 if ( m_windowStyle & wxLB_OWNERDRAW ) {
440 // first delete old items
441 unsigned int ui = m_aItems.Count();
442 while ( ui-- != 0 ) {
443 delete m_aItems[ui];
444 m_aItems[ui] = NULL;
445 }
446 m_aItems.Empty();
447
448 // then create new ones
449 for ( ui = 0; ui < m_noItems; ui++ ) {
450 wxOwnerDrawn *pNewItem = CreateItem(ui);
451 pNewItem->SetName(choices[ui]);
452 m_aItems.Add(pNewItem);
453 }
454 }
455 #endif // wxUSE_OWNER_DRAWN
456 MacSetRedraw( true ) ;
457 }
458
459 bool wxListBox::HasMultipleSelection() const
460 {
461 return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
462 }
463
464 int wxListBox::FindString(const wxString& s, bool bCase) const
465 {
466 if ( s.Right(1) == wxT("*") )
467 {
468 wxString search = s.Left( s.length() - 1 ) ;
469 int len = search.length() ;
470 Str255 s1 , s2 ;
471 wxMacStringToPascal( search , s2 ) ;
472
473 for ( unsigned int i = 0 ; i < m_noItems ; ++ i )
474 {
475 wxMacStringToPascal( m_stringArray[i].Left( len ) , s1 ) ;
476
477 if ( EqualString( s1 , s2 , bCase , false ) )
478 return (int)i ;
479 }
480 if ( s.Left(1) == wxT("*") && s.length() > 1 )
481 {
482 wxString st = s ;
483 st.MakeLower() ;
484 for ( unsigned int i = 0 ; i < m_noItems ; ++i )
485 {
486 if (GetString(i).Lower().Matches(st))
487 return (int)i ;
488 }
489 }
490
491 }
492 else
493 {
494 Str255 s1 , s2 ;
495
496 wxMacStringToPascal( s , s2 ) ;
497
498 for ( unsigned int i = 0 ; i < m_noItems ; ++ i )
499 {
500 wxMacStringToPascal( m_stringArray[i] , s1 ) ;
501
502 if ( EqualString( s1 , s2 , bCase , false ) )
503 return (int)i ;
504 }
505 }
506
507 return wxNOT_FOUND;
508 }
509
510 void wxListBox::Clear()
511 {
512 FreeData();
513 m_noItems = 0;
514 m_stringArray.Empty() ;
515 m_dataArray.Empty() ;
516 MacClear() ;
517 }
518
519 void wxListBox::DoSetSelection(int N, bool select)
520 {
521 wxCHECK_RET( IsValid(N),
522 wxT("invalid index in wxListBox::SetSelection") );
523 MacSetSelection( N , select ) ;
524 GetSelections( m_selectionPreImage ) ;
525 }
526
527 bool wxListBox::IsSelected(int N) const
528 {
529 wxCHECK_MSG( IsValid(N), false,
530 wxT("invalid index in wxListBox::Selected") );
531
532 return MacIsSelected( N ) ;
533 }
534
535 void *wxListBox::DoGetItemClientData(unsigned int n) const
536 {
537 wxCHECK_MSG( IsValid(n), NULL,
538 wxT("invalid index in wxListBox::GetClientData"));
539
540 return (void *)m_dataArray[n];
541 }
542
543 wxClientData *wxListBox::DoGetItemClientObject(unsigned int n) const
544 {
545 return (wxClientData *) DoGetItemClientData( n ) ;
546 }
547
548 void wxListBox::DoSetItemClientData(unsigned int n, void *Client_data)
549 {
550 wxCHECK_RET( IsValid(n),
551 wxT("invalid index in wxListBox::SetClientData") );
552
553 #if wxUSE_OWNER_DRAWN
554 if ( m_windowStyle & wxLB_OWNERDRAW )
555 {
556 // client data must be pointer to wxOwnerDrawn, otherwise we would crash
557 // in OnMeasure/OnDraw.
558 wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
559 }
560 #endif // wxUSE_OWNER_DRAWN
561 wxASSERT_MSG( m_dataArray.GetCount() >= (unsigned int) n , wxT("invalid client_data array") ) ;
562
563 if ( m_dataArray.GetCount() > (size_t) n )
564 {
565 m_dataArray[n] = (char*) Client_data ;
566 }
567 else
568 {
569 m_dataArray.Add( (char*) Client_data ) ;
570 }
571 }
572
573 void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData)
574 {
575 DoSetItemClientData(n, clientData);
576 }
577
578 // Return number of selections and an array of selected integers
579 int wxListBox::GetSelections(wxArrayInt& aSelections) const
580 {
581 return MacGetSelections( aSelections ) ;
582 }
583
584 // Get single selection, for single choice list items
585 int wxListBox::GetSelection() const
586 {
587 return MacGetSelection() ;
588 }
589
590 // Find string for position
591 wxString wxListBox::GetString(unsigned int n) const
592 {
593 return m_stringArray[n] ;
594 }
595
596 void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos)
597 {
598 wxCHECK_RET( IsValidInsert(pos),
599 wxT("invalid index in wxListBox::InsertItems") );
600
601 InvalidateBestSize();
602
603 unsigned int nItems = items.GetCount();
604
605 for ( unsigned int i = 0 ; i < nItems ; i++ )
606 {
607 m_stringArray.Insert( items[i] , pos + i ) ;
608 m_dataArray.Insert( NULL , pos + i ) ;
609 MacInsert( pos + i , items[i] ) ;
610 }
611
612 m_noItems += nItems;
613 }
614
615 void wxListBox::SetString(unsigned int n, const wxString& s)
616 {
617 m_stringArray[n] = s;
618 MacSet(n, s);
619 }
620
621 wxSize wxListBox::DoGetBestSize() const
622 {
623 int lbWidth = 100; // some defaults
624 int lbHeight = 110;
625 int wLine;
626
627 {
628 wxMacPortStateHelper st( UMAGetWindowPort( (WindowRef) MacGetRootWindow() ) ) ;
629
630 if ( m_font.Ok() )
631 {
632 ::TextFont( m_font.GetMacFontNum() ) ;
633 ::TextSize( m_font.GetMacFontSize() ) ;
634 ::TextFace( m_font.GetMacFontStyle() ) ;
635 }
636 else
637 {
638 ::TextFont( kFontIDMonaco ) ;
639 ::TextSize( 9 );
640 ::TextFace( 0 ) ;
641 }
642
643 // Find the widest line
644 for(unsigned int i = 0; i < GetCount(); i++) {
645 wxString str(GetString(i));
646 #if wxUSE_UNICODE
647 Point bounds={0,0} ;
648 SInt16 baseline ;
649 ::GetThemeTextDimensions( wxMacCFStringHolder( str , m_font.GetEncoding() ) ,
650 kThemeCurrentPortFont,
651 kThemeStateActive,
652 false,
653 &bounds,
654 &baseline );
655 wLine = bounds.h ;
656 #else
657 wLine = ::TextWidth( str.c_str() , 0 , str.length() ) ;
658 #endif
659 lbWidth = wxMax(lbWidth, wLine);
660 }
661
662 // Add room for the scrollbar
663 lbWidth += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
664
665 // And just a bit more
666 int cy = 12 ;
667 int cx = ::TextWidth( "X" , 0 , 1 ) ;
668 lbWidth += cx ;
669
670 // don't make the listbox too tall (limit height to around 10 items) but don't
671 // make it too small neither
672 lbHeight = (cy+4) * wxMin(wxMax(GetCount(), 3), 10);
673 }
674 return wxSize(lbWidth, lbHeight);
675 }
676
677 unsigned int wxListBox::GetCount() const
678 {
679 return m_noItems;
680 }
681
682 void wxListBox::SetupColours()
683 {
684 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
685 SetForegroundColour(GetParent()->GetForegroundColour());
686 }
687
688 void wxListBox::Refresh(bool eraseBack, const wxRect *rect)
689 {
690 wxControl::Refresh( eraseBack , rect ) ;
691 // MacRedrawControl() ;
692 }
693
694 #if wxUSE_OWNER_DRAWN
695
696 class wxListBoxItem : public wxOwnerDrawn
697 {
698 public:
699 wxListBoxItem(const wxString& str = wxEmptyString);
700 };
701
702 wxListBoxItem::wxListBoxItem(const wxString& str) : wxOwnerDrawn(str, false)
703 {
704 // no bitmaps/checkmarks
705 SetMarginWidth(0);
706 }
707
708 wxOwnerDrawn *wxListBox::CreateItem(size_t n)
709 {
710 return new wxListBoxItem();
711 }
712
713 #endif //USE_OWNER_DRAWN
714
715 // ============================================================================
716 // list box control implementation
717 // ============================================================================
718
719 /*
720 void MacDrawStringCell(Rect *cellRect, Cell lCell, ListHandle theList, long refCon)
721 {
722 wxListBox* list;
723 // typecast our refCon
724 list = (wxListBox*)refCon;
725
726 MoveTo(cellRect->left + 4 , cellRect->top + 10 );
727 const wxString text = list->m_stringArray[lCell.v] ;
728 ::TextFont( kFontIDMonaco ) ;
729 ::TextSize( 9 );
730 ::TextFace( 0 ) ;
731 DrawText(text, 0 , text.length());
732
733 }
734 */
735 void wxListBox::MacDelete( int N )
736 {
737 LDelRow( 1 , N , (ListHandle)m_macList) ;
738 Refresh();
739 }
740
741 void wxListBox::MacInsert( int n , const wxString& text)
742 {
743 Cell cell = { 0 , 0 } ;
744 cell.v = n ;
745 LAddRow( 1 , cell.v , (ListHandle)m_macList ) ;
746 // LSetCell(text, strlen(text), cell, m_macList);
747 Refresh();
748 }
749
750 void wxListBox::MacAppend( const wxString& text)
751 {
752 Cell cell = { 0 , 0 } ;
753 cell.v = (**(ListHandle)m_macList).dataBounds.bottom ;
754 LAddRow( 1 , cell.v , (ListHandle)m_macList ) ;
755 // LSetCell(text, strlen(text), cell, m_macList);
756 Refresh();
757 }
758
759 void wxListBox::MacClear()
760 {
761 LDelRow( (**(ListHandle)m_macList).dataBounds.bottom , 0 ,(ListHandle) m_macList ) ;
762 Refresh();
763 }
764
765 void wxListBox::MacSetSelection( int n , bool select )
766 {
767 Cell cell = { 0 , 0 } ;
768 if ( ! (m_windowStyle & wxLB_MULTIPLE) )
769 {
770 if ( LGetSelect( true , &cell , (ListHandle)m_macList ) )
771 {
772 LSetSelect( false , cell , (ListHandle)m_macList ) ;
773 }
774 }
775
776 cell.v = n ;
777 LSetSelect( select , cell , (ListHandle)m_macList ) ;
778 LAutoScroll( (ListHandle)m_macList ) ;
779 Refresh();
780 }
781
782 bool wxListBox::MacIsSelected( int n ) const
783 {
784 Cell cell = { 0 , 0 } ;
785 cell.v = n ;
786 return LGetSelect( false , &cell , (ListHandle)m_macList ) ;
787 }
788
789 void wxListBox::MacDestroy()
790 {
791 // DisposeExtLDEFInfo( m_macList ) ;
792 }
793
794 int wxListBox::MacGetSelection() const
795 {
796 Cell cell = { 0 , 0 } ;
797 if ( LGetSelect( true , &cell , (ListHandle)m_macList ) )
798 return cell.v ;
799 else
800 return -1 ;
801 }
802
803 int wxListBox::MacGetSelections( wxArrayInt& aSelections ) const
804 {
805 int no_sel = 0 ;
806
807 aSelections.Empty();
808
809 Cell cell = { 0 , 0 } ;
810 cell.v = 0 ;
811
812 while ( LGetSelect( true , &cell ,(ListHandle) m_macList ) )
813 {
814 aSelections.Add( cell.v ) ;
815 no_sel++ ;
816 cell.v++ ;
817 }
818 return no_sel ;
819 }
820
821 void wxListBox::MacSet( int n , const wxString& text )
822 {
823 // our implementation does not store anything in the list
824 // so we just have to redraw
825 Cell cell = { 0 , 0 } ;
826 cell.v = n ;
827 // LSetCell(text, strlen(text), cell, m_macList);
828 Refresh();
829 }
830
831 void wxListBox::MacScrollTo( int n )
832 {
833 // TODO implement scrolling
834 }
835
836 void wxListBox::OnSize( wxSizeEvent &event)
837 {
838 Point pt;
839
840 #if TARGET_CARBON
841 GetListCellSize((ListHandle)m_macList, &pt);
842 #else
843 pt = (**(ListHandle)m_macList).cellSize ;
844 #endif
845 pt.h = m_width - 15 ;
846 LCellSize( pt , (ListHandle)m_macList ) ;
847 }
848
849 void wxListBox::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED(mouseStillDown))
850 {
851 Boolean wasDoubleClick = false ;
852 long result ;
853
854 ::GetControlData( (ControlHandle) m_macControl , kControlNoPart , kControlListBoxDoubleClickTag , sizeof( wasDoubleClick ) , (char*) &wasDoubleClick , &result ) ;
855 if ( !wasDoubleClick )
856 {
857 MacDoClick() ;
858 }
859 else
860 {
861 MacDoDoubleClick() ;
862 }
863 }
864
865 void wxListBox::MacSetRedraw( bool doDraw )
866 {
867 LSetDrawingMode( doDraw , (ListHandle)m_macList ) ;
868 }
869
870 void wxListBox::MacDoClick()
871 {
872 wxArrayInt aSelections;
873 int n ;
874 size_t count = GetSelections(aSelections);
875
876 if ( count == m_selectionPreImage.GetCount() )
877 {
878 bool hasChanged = false ;
879 for ( size_t i = 0 ; i < count ; ++i )
880 {
881 if ( aSelections[i] != m_selectionPreImage[i] )
882 {
883 hasChanged = true ;
884 break ;
885 }
886 }
887 if ( !hasChanged )
888 {
889 return ;
890 }
891 }
892
893 m_selectionPreImage = aSelections;
894
895 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
896 event.SetEventObject( this );
897
898 if ( count > 0 )
899 {
900 n = aSelections[0];
901 if ( HasClientObjectData() )
902 event.SetClientObject( GetClientObject(n) );
903 else if ( HasClientUntypedData() )
904 event.SetClientData( GetClientData(n) );
905 event.SetString(GetString(n));
906 }
907 else
908 {
909 n = -1;
910 }
911
912 event.SetInt(n);
913
914 GetEventHandler()->ProcessEvent(event);
915 }
916
917 void wxListBox::MacDoDoubleClick()
918 {
919 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, m_windowId);
920 event.SetEventObject( this );
921 GetEventHandler()->ProcessEvent(event) ;
922 }
923
924 void wxListBox::OnChar(wxKeyEvent& event)
925 {
926 if ( event.GetKeyCode() == WXK_RETURN || event.GetKeyCode() == WXK_NUMPAD_ENTER)
927 {
928 wxWindow* parent = GetParent() ;
929 while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL )
930 parent = parent->GetParent() ;
931
932 if ( parent && parent->GetDefaultItem() )
933 {
934 wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
935 wxButton);
936 if ( def && def->IsEnabled() )
937 {
938 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
939 event.SetEventObject(def);
940 def->Command(event);
941 return ;
942 }
943 }
944 event.Skip() ;
945 }
946 /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
947 else if (event.GetKeyCode() == WXK_ESCAPE || (event.GetKeyCode() == '.' && event.MetaDown() ) )
948 {
949 // FIXME: look in ancestors, not just parent.
950 wxWindow* win = GetParent()->FindWindow( wxID_CANCEL ) ;
951 if (win)
952 {
953 wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
954 new_event.SetEventObject( win );
955 win->GetEventHandler()->ProcessEvent( new_event );
956 }
957 }
958 else if ( event.GetKeyCode() == WXK_TAB )
959 {
960 wxNavigationKeyEvent new_event;
961 new_event.SetEventObject( this );
962 new_event.SetDirection( !event.ShiftDown() );
963 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
964 new_event.SetWindowChange( event.ControlDown() );
965 new_event.SetCurrentFocus( this );
966 if ( !GetEventHandler()->ProcessEvent( new_event ) )
967 event.Skip() ;
968 }
969 else if ( event.GetKeyCode() == WXK_DOWN || event.GetKeyCode() == WXK_UP )
970 {
971 // perform the default key handling first
972 wxControl::OnKeyDown( event ) ;
973
974 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
975 event.SetEventObject( this );
976
977 wxArrayInt aSelections;
978 int n, count = GetSelections(aSelections);
979 if ( count > 0 )
980 {
981 n = aSelections[0];
982 if ( HasClientObjectData() )
983 event.SetClientObject( GetClientObject(n) );
984 else if ( HasClientUntypedData() )
985 event.SetClientData( GetClientData(n) );
986 event.SetString(GetString(n));
987 }
988 else
989 {
990 n = -1;
991 }
992
993 event.SetInt(n);
994
995 GetEventHandler()->ProcessEvent(event);
996 }
997 else
998 {
999 if ( event.GetTimestamp() > m_lastTypeIn + 60 )
1000 {
1001 m_typeIn = wxEmptyString ;
1002 }
1003 m_lastTypeIn = event.GetTimestamp() ;
1004 m_typeIn += (char) event.GetKeyCode() ;
1005 int line = FindString(wxT("*")+m_typeIn+wxT("*")) ;
1006 if ( line >= 0 )
1007 {
1008 if ( GetSelection() != line )
1009 {
1010 SetSelection(line) ;
1011 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
1012 event.SetEventObject( this );
1013
1014 if ( HasClientObjectData() )
1015 event.SetClientObject( GetClientObject( line ) );
1016 else if ( HasClientUntypedData() )
1017 event.SetClientData( GetClientData(line) );
1018 event.SetString(GetString(line));
1019
1020 event.SetInt(line);
1021
1022 GetEventHandler()->ProcessEvent(event);
1023 }
1024 }
1025 }
1026 }
1027
1028 #endif // wxUSE_LISTBOX