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