]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/listbox.cpp
Added calendar contributed by Lorne White
[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
16#include "wx/listbox.h"
17#include "wx/settings.h"
18#include "wx/dynarray.h"
19#include "wx/log.h"
20
519cb848
SC
21#include "wx/utils.h"
22#include "extldef.h"
23
e9576ca5
SC
24#if !USE_SHARED_LIBRARY
25 IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
519cb848
SC
26
27BEGIN_EVENT_TABLE(wxListBox, wxControl)
28 EVT_SIZE( wxListBox::OnSize )
29END_EVENT_TABLE()
e9576ca5
SC
30#endif
31
519cb848
SC
32#include <wx/mac/uma.h>
33
34extern "C" void MacDrawStringCell(Rect *cellRect, Cell lCell, ListHandle theList, long refCon) ;
35const short kwxMacListWithVerticalScrollbar = 128 ;
36
e9576ca5
SC
37// ============================================================================
38// list box control implementation
39// ============================================================================
40
41// Listbox item
42wxListBox::wxListBox()
43{
44 m_noItems = 0;
45 m_selected = 0;
46}
47
48bool wxListBox::Create(wxWindow *parent, wxWindowID id,
49 const wxPoint& pos,
50 const wxSize& size,
51 int n, const wxString choices[],
52 long style,
53 const wxValidator& validator,
54 const wxString& name)
55{
519cb848 56 m_noItems = 0 ; // this will be increased by our append command
e9576ca5
SC
57 m_selected = 0;
58
519cb848
SC
59 Rect bounds ;
60 Str255 title ;
61 m_macHorizontalBorder = 5 ; // additional pixels around the real control
62 m_macVerticalBorder = 5 ;
63
64 MacPreControlCreate( parent , id , "" , pos , size ,style, validator , name , &bounds , title ) ;
65
66 m_macControl = UMANewControl( parent->GetMacRootWindow() , &bounds , title , true , kwxMacListWithVerticalScrollbar , 0 , 0,
67 kControlListBoxProc , (long) this ) ;
68
69 long result ;
70 UMAGetControlData( m_macControl , kControlNoPart , kControlListBoxListHandleTag , sizeof( ListHandle ) , (char*) &m_macList , &result ) ;
71
72 NewExtLDEFInfo( m_macList , MacDrawStringCell , (long) this ) ;
73 (**m_macList).selFlags = lOnlyOne ;
74 if ( style & wxLB_MULTIPLE )
75 {
76 (**m_macList).selFlags += lNoExtend ;
77 }
78 else if ( style & wxLB_EXTENDED )
79 {
80 (**m_macList).selFlags += lExtendDrag ;
81 }
82 Point pt = (**m_macList).cellSize ;
83 pt.v = 14 ;
84 LCellSize( pt , m_macList ) ;
85
86 LAddColumn( 1 , 0 , m_macList ) ;
87
88 MacPostControlCreate() ;
89
90 ControlFontStyleRec controlstyle ;
91 controlstyle.flags = kControlUseFontMask + kControlUseSizeMask ;
92 //controlstyle.font = kControlFontSmallSystemFont ;
93 controlstyle.font = kFontIDMonaco ;
94 controlstyle.size = 9 ;
95 ::UMASetControlFontStyle( m_macControl , &controlstyle ) ;
96
97 for ( int i = 0 ; i < n ; i++ )
98 {
99 Append( choices[i] ) ;
100 }
101
102 LSetDrawingMode( true , m_macList ) ;
103
104 return TRUE;
e9576ca5
SC
105}
106
107wxListBox::~wxListBox()
108{
e7549107
SC
109 Free() ;
110 DisposeExtLDEFInfo( m_macList ) ;
e9576ca5
SC
111}
112
e7549107 113void wxListBox::Free()
e9576ca5 114{
e7549107
SC
115#if wxUSE_OWNER_DRAWN
116 if ( m_windowStyle & wxLB_OWNERDRAW )
117 {
118 size_t uiCount = m_aItems.Count();
119 while ( uiCount-- != 0 ) {
120 delete m_aItems[uiCount];
121 }
122
123 m_aItems.Clear();
124 }
125 else
126#endif // wxUSE_OWNER_DRAWN
127 if ( HasClientObjectData() )
128 {
129 for ( size_t n = 0; n < (size_t)m_noItems; n++ )
130 {
131 delete GetClientObject(n);
132 }
133 }
e9576ca5
SC
134}
135
e7549107 136void wxListBox::DoSetFirstItem(int N)
e9576ca5 137{
e7549107 138 MacScrollTo( N ) ;
e9576ca5
SC
139}
140
141void wxListBox::Delete(int N)
142{
e7549107
SC
143 wxCHECK_RET( N >= 0 && N < m_noItems,
144 wxT("invalid index in wxListBox::Delete") );
145
146#if wxUSE_OWNER_DRAWN
147 delete m_aItems[N];
148 m_aItems.Remove(N);
149#else // !wxUSE_OWNER_DRAWN
150 if ( HasClientObjectData() )
151 {
152 delete GetClientObject(N);
153 }
154#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
519cb848
SC
155 m_stringArray.Remove( N ) ;
156 m_noItems --;
157
158 MacDelete( N ) ;
e7549107 159 SetHorizontalExtent("");
e9576ca5
SC
160}
161
e7549107 162int wxListBox::DoAppend(const wxString& item)
e9576ca5 163{
e7549107 164 int index = m_noItems ;
519cb848
SC
165 if( wxApp::s_macDefaultEncodingIsPC )
166 {
167 m_stringArray.Add( wxMacMakeMacStringFromPC( item ) ) ;
168 }
169 else
170 m_stringArray.Add( item ) ;
e7549107 171 m_noItems ++;
519cb848 172 MacAppend( item ) ;
e7549107
SC
173
174 SetHorizontalExtent(item);
175
176 return index ;
e9576ca5
SC
177}
178
e7549107
SC
179void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData)
180{
181 MacSetRedraw( false ) ;
519cb848 182 Clear() ;
e7549107
SC
183 int n = choices.GetCount();
184
519cb848
SC
185 for( int i = 0 ; i < n ; ++i )
186 {
187 if ( clientData )
e7549107
SC
188 {
189#if wxUSE_OWNER_DRAWN
190 wxASSERT_MSG(clientData[i] == NULL,
191 wxT("Can't use client data with owner-drawn listboxes"));
192#else // !wxUSE_OWNER_DRAWN
519cb848 193 Append( choices[i] , clientData[0] ) ;
e7549107
SC
194 #endif
195 }
519cb848
SC
196 else
197 Append( choices[i] ) ;
198 }
e7549107
SC
199
200#if wxUSE_OWNER_DRAWN
201 if ( m_windowStyle & wxLB_OWNERDRAW ) {
202 // first delete old items
203 size_t ui = m_aItems.Count();
204 while ( ui-- != 0 ) {
205 delete m_aItems[ui];
206 }
207 m_aItems.Empty();
208
209 // then create new ones
210 for ( ui = 0; ui < (size_t)m_noItems; ui++ ) {
211 wxOwnerDrawn *pNewItem = CreateItem(ui);
212 pNewItem->SetName(choices[ui]);
213 m_aItems.Add(pNewItem);
214 }
215 }
216#endif // wxUSE_OWNER_DRAWN
217 MacSetRedraw( true ) ;
218}
219
220bool wxListBox::HasMultipleSelection() const
221{
222 return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
e9576ca5
SC
223}
224
519cb848 225int wxListBox::FindString(const wxString& st) const
e9576ca5 226{
519cb848
SC
227 wxString s ;
228 if( wxApp::s_macDefaultEncodingIsPC )
229 {
230 s = wxMacMakeMacStringFromPC( st ) ;
231 }
232 else
233 s = st ;
234
235 if ( s.Right(1) == "*" )
236 {
237 wxString search = s.Left( s.Length() - 1 ) ;
238 int len = search.Length() ;
239 for ( int i = 0 ; i < m_noItems ; ++ i )
240 {
241 if ( equalstring( m_stringArray[i].Left( len ) , search , false , false ) )
242 return i ;
243 }
244 }
245 else
246 {
247 for ( int i = 0 ; i < m_noItems ; ++ i )
248 {
249 if ( equalstring( m_stringArray[i] , s , false , false ) )
250 return i ;
251 }
252 }
253 return -1;
e9576ca5
SC
254}
255
256void wxListBox::Clear()
257{
e7549107 258 Free();
e9576ca5 259 m_noItems = 0;
519cb848
SC
260 m_stringArray.Empty() ;
261 m_dataArray.Empty() ;
262 MacClear() ;
e7549107 263 SetHorizontalExtent();
e9576ca5
SC
264}
265
266void wxListBox::SetSelection(int N, bool select)
267{
519cb848
SC
268 wxCHECK_RET( N >= 0 && N < m_noItems,
269 "invalid index in wxListBox::SetSelection" );
270 MacSetSelection( N , select ) ;
e9576ca5
SC
271}
272
e7549107 273bool wxListBox::IsSelected(int N) const
e9576ca5 274{
519cb848
SC
275 wxCHECK_MSG( N >= 0 && N < m_noItems, FALSE,
276 "invalid index in wxListBox::Selected" );
277
278 return MacIsSelected( N ) ;
e9576ca5
SC
279}
280
e7549107 281void *wxListBox::DoGetItemClientData(int N) const
e9576ca5 282{
519cb848
SC
283 wxCHECK_MSG( N >= 0 && N < m_noItems, NULL,
284 "invalid index in wxListBox::GetClientData" );
285
e7549107 286 return (void *)m_dataArray[N];
e9576ca5
SC
287}
288
e7549107 289void wxListBox::DoSetItemClientData(int N, void *Client_data)
e9576ca5 290{
519cb848
SC
291 wxCHECK_RET( N >= 0 && N < m_noItems,
292 "invalid index in wxListBox::SetClientData" );
293
e7549107
SC
294#if wxUSE_OWNER_DRAWN
295 if ( m_windowStyle & wxLB_OWNERDRAW )
296 {
297 // client data must be pointer to wxOwnerDrawn, otherwise we would crash
298 // in OnMeasure/OnDraw.
299 wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
300 }
301#endif // wxUSE_OWNER_DRAWN
302 m_dataArray[N] = (char*) Client_data ;
303}
304
305void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData)
306{
307 DoSetItemClientData(n, clientData);
e9576ca5
SC
308}
309
310// Return number of selections and an array of selected integers
311int wxListBox::GetSelections(wxArrayInt& aSelections) const
312{
519cb848 313 return MacGetSelections( aSelections ) ;
e9576ca5
SC
314
315/* TODO
519cb848 316 if ((m_windowStyle & wxLB_MULTIMacE) || (m_windowStyle & wxLB_EXTENDED))
e9576ca5
SC
317 {
318 int no_sel = ??
319 for ( int n = 0; n < no_sel; n++ )
320 aSelections.Add(??);
321
322 return no_sel;
323 }
324 else // single-selection listbox
325 {
326 aSelections.Add(??);
327
328 return 1;
329 }
330*/
e9576ca5
SC
331}
332
333// Get single selection, for single choice list items
334int wxListBox::GetSelection() const
335{
519cb848 336 return MacGetSelection() ;
e9576ca5
SC
337}
338
339// Find string for position
340wxString wxListBox::GetString(int N) const
341{
519cb848
SC
342 if( wxApp::s_macDefaultEncodingIsPC )
343 {
344 return wxMacMakePCStringFromMac( m_stringArray[N] ) ;
345 }
346 else
347 return m_stringArray[N] ;
e9576ca5
SC
348}
349
e7549107 350void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
e9576ca5 351{
e7549107
SC
352 wxCHECK_RET( pos >= 0 && pos <= m_noItems,
353 wxT("invalid index in wxListBox::InsertItems") );
354
355 int nItems = items.GetCount();
356
519cb848
SC
357 for ( int i = 0 ; i < nItems ; i++ )
358 {
359 m_stringArray.Insert( items[i] , pos + i ) ;
360 m_dataArray.Insert( NULL , pos + i ) ;
361 MacInsert( pos + i , items[i] ) ;
362 }
e9576ca5 363
519cb848 364 m_noItems += nItems;
e9576ca5
SC
365}
366
367void wxListBox::SetString(int N, const wxString& s)
368{
519cb848
SC
369 m_stringArray[N] = s ;
370 MacSet( N , s ) ;
e9576ca5
SC
371}
372
e7549107 373wxSize wxListBox::DoGetBestSize()
e9576ca5 374{
e7549107 375 return wxSize(100, 100);
e9576ca5
SC
376}
377
e9576ca5 378
519cb848
SC
379// ============================================================================
380// list box control implementation
381// ============================================================================
382
383void MacDrawStringCell(Rect *cellRect, Cell lCell, ListHandle theList, long refCon)
384{
385 wxListBox* list;
386 // typecast our refCon
387 list = (wxListBox*)refCon;
388
389 MoveTo(cellRect->left + 4 , cellRect->top + 10 );
390 const wxString text = list->m_stringArray[lCell.v] ;
391 ::TextFont( kFontIDMonaco ) ;
392 ::TextSize( 9 );
393 ::TextFace( 0 ) ;
394 DrawText(text, 0 , text.Length());
395
396}
397
398void wxListBox::MacDelete( int N )
399{
400 ListHandle list ;
401 long result ;
402 Cell cell = { 0 , 0 } ;
403 UMAGetControlData( m_macControl , kControlNoPart , kControlListBoxListHandleTag , sizeof( ListHandle ) , (char*) &list , &result ) ;
404 LDelRow( 1 , N , list ) ;
405}
406
407void wxListBox::MacInsert( int n , const char * text)
408{
409 Cell cell ;
410
411 cell.h = 0 ;
412 cell.v = n ;
413
414 LAddRow( 1 , cell.v , m_macList ) ;
415}
416
417void wxListBox::MacAppend( const char * text)
418{
419 Cell cell = { 0 , 0 } ;
420 cell.v = (**m_macList).dataBounds.bottom ;
421 LAddRow( 1 , cell.v , m_macList ) ;
422}
423
424void wxListBox::MacClear()
425{
426 LDelRow( (**m_macList).dataBounds.bottom , 0 , m_macList ) ;
427}
428
429void wxListBox::MacSetSelection( int n , bool select )
430{
431 Cell cell = { 0 , 0 } ;
432 if ( LGetSelect( TRUE , &cell , m_macList ) )
433 {
434 LSetSelect( false , cell , m_macList ) ;
435 }
436
437 cell.v = n ;
438 LSetSelect( select , cell , m_macList ) ;
439 LAutoScroll( m_macList ) ;
440}
441
442bool wxListBox::MacIsSelected( int n ) const
443{
444 Cell cell = { 0 , 0 } ;
445 cell.v = n ;
446 return LGetSelect( false , &cell , m_macList ) ;
447}
448
449void wxListBox::MacDestroy()
450{
451// DisposeExtLDEFInfo( m_macList ) ;
452}
453
454int wxListBox::MacGetSelection() const
455{
456 Cell cell = { 0 , 0 } ;
457 if ( LGetSelect( true , &cell , m_macList ) )
458 return cell.v ;
459 else
460 return -1 ;
461}
462
463int wxListBox::MacGetSelections( wxArrayInt& aSelections ) const
464{
465 int no_sel = 0 ;
466
467 aSelections.Empty();
468
469 Cell cell = { 0 , 0 } ;
470 cell.v = 0 ;
471
472 while ( LGetSelect( true , &cell , m_macList ) )
473 {
474 aSelections.Add( cell.v ) ;
475 no_sel++ ;
476 cell.v++ ;
477 }
478 return no_sel ;
479}
480
481void wxListBox::MacSet( int n , const char * text )
482{
483 // our implementation does not store anything in the list
484 // so we just have to redraw
485 Cell cell = { 0 , 0 } ;
486 cell.v = n ;
487 LDraw( cell , m_macList ) ;
488}
489
490void wxListBox::MacScrollTo( int n )
491{
492 // TODO implement scrolling
493}
494
495void wxListBox::OnSize( const wxSizeEvent &event)
496{
497 Point pt = (**m_macList).cellSize ;
498 pt.h = m_width - 15 /* scrollbar */ - m_macHorizontalBorder * 2 ;
499 LCellSize( pt , m_macList ) ;
500}
501
502void wxListBox::MacHandleControlClick( ControlHandle control , SInt16 controlpart )
503{
504 Boolean wasDoubleClick = false ;
505 long result ;
506
507 UMAGetControlData( m_macControl , kControlNoPart , kControlListBoxDoubleClickTag , sizeof( wasDoubleClick ) , (char*) &wasDoubleClick , &result ) ;
508 if ( !wasDoubleClick )
509 {
510 MacDoClick() ;
511 }
512 else
513 {
514 MacDoDoubleClick() ;
515 }
516}
517
518void wxListBox::MacSetRedraw( bool doDraw )
519{
520 LSetDrawingMode( doDraw , m_macList ) ;
521
522}
523
524void wxListBox::MacDoClick()
525{
526 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
e7549107
SC
527 event.SetEventObject( this );
528
519cb848 529 wxArrayInt aSelections;
e7549107 530 int n, count = GetSelections(aSelections);
519cb848
SC
531 if ( count > 0 )
532 {
533 event.m_commandInt = aSelections[0] ;
e7549107
SC
534 if ( HasClientObjectData() )
535 event.SetClientObject( GetClientObject(n) );
536 else if ( HasClientUntypedData() )
537 event.SetClientData( GetClientData(n) );
538 event.SetString( GetString(n) );
519cb848
SC
539 }
540 else
541 {
e7549107 542 n = -1;
519cb848
SC
543 }
544
e7549107
SC
545 event.m_commandInt = n;
546
547 GetEventHandler()->ProcessEvent(event);
519cb848
SC
548}
549
550void wxListBox::MacDoDoubleClick()
551{
552 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, m_windowId);
553 event.SetEventObject( this );
554 GetEventHandler()->ProcessEvent(event) ;
555}