]> git.saurik.com Git - wxWidgets.git/blob - src/mac/listbox.cpp
e17f1b8213b7c9e92488ff23dad784160ff0aa4f
[wxWidgets.git] / src / mac / listbox.cpp
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
21 #include "wx/utils.h"
22 #include "extldef.h"
23
24 #if !USE_SHARED_LIBRARY
25 IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
26
27 BEGIN_EVENT_TABLE(wxListBox, wxControl)
28 EVT_SIZE( wxListBox::OnSize )
29 END_EVENT_TABLE()
30 #endif
31
32 #include <wx/mac/uma.h>
33
34 extern "C" void MacDrawStringCell(Rect *cellRect, Cell lCell, ListHandle theList, long refCon) ;
35 const short kwxMacListWithVerticalScrollbar = 128 ;
36
37 // ============================================================================
38 // list box control implementation
39 // ============================================================================
40
41 // Listbox item
42 wxListBox::wxListBox()
43 {
44 m_noItems = 0;
45 m_selected = 0;
46 }
47
48 bool 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 {
56 m_noItems = 0 ; // this will be increased by our append command
57 m_selected = 0;
58
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;
105 }
106
107 wxListBox::~wxListBox()
108 {
109 // DisposeExtLDEFInfo( m_macList ) ;
110 }
111
112 void wxListBox::SetFirstItem(int N)
113 {
114 MacScrollTo( N ) ;
115 }
116
117 void wxListBox::SetFirstItem(const wxString& s)
118 {
119 MacScrollTo( FindString( s ) ) ;
120 }
121
122 void wxListBox::Delete(int N)
123 {
124 m_dataArray.Remove( N ) ;
125 m_stringArray.Remove( N ) ;
126 m_noItems --;
127
128 MacDelete( N ) ;
129 }
130
131 void wxListBox::Append(const wxString& item)
132 {
133 Append( item , NULL ) ;
134 }
135
136 void wxListBox::Append(const wxString& item, char *Client_data)
137 {
138 if( wxApp::s_macDefaultEncodingIsPC )
139 {
140 m_stringArray.Add( wxMacMakeMacStringFromPC( item ) ) ;
141 }
142 else
143 m_stringArray.Add( item ) ;
144 m_dataArray.Add( Client_data ) ;
145 m_noItems ++;
146
147 MacAppend( item ) ;
148 }
149
150 void wxListBox::Set(int n, const wxString *choices, char** clientData)
151 {
152 Clear() ;
153 for( int i = 0 ; i < n ; ++i )
154 {
155 if ( clientData )
156 Append( choices[i] , clientData[0] ) ;
157 else
158 Append( choices[i] ) ;
159 }
160 }
161
162 int wxListBox::FindString(const wxString& st) const
163 {
164 wxString s ;
165 if( wxApp::s_macDefaultEncodingIsPC )
166 {
167 s = wxMacMakeMacStringFromPC( st ) ;
168 }
169 else
170 s = st ;
171
172 if ( s.Right(1) == "*" )
173 {
174 wxString search = s.Left( s.Length() - 1 ) ;
175 int len = search.Length() ;
176 for ( int i = 0 ; i < m_noItems ; ++ i )
177 {
178 if ( equalstring( m_stringArray[i].Left( len ) , search , false , false ) )
179 return i ;
180 }
181 }
182 else
183 {
184 for ( int i = 0 ; i < m_noItems ; ++ i )
185 {
186 if ( equalstring( m_stringArray[i] , s , false , false ) )
187 return i ;
188 }
189 }
190 return -1;
191 }
192
193 void wxListBox::Clear()
194 {
195 m_noItems = 0;
196 m_stringArray.Empty() ;
197 m_dataArray.Empty() ;
198 MacClear() ;
199 }
200
201 void wxListBox::SetSelection(int N, bool select)
202 {
203 wxCHECK_RET( N >= 0 && N < m_noItems,
204 "invalid index in wxListBox::SetSelection" );
205 MacSetSelection( N , select ) ;
206 }
207
208 bool wxListBox::Selected(int N) const
209 {
210 wxCHECK_MSG( N >= 0 && N < m_noItems, FALSE,
211 "invalid index in wxListBox::Selected" );
212
213 return MacIsSelected( N ) ;
214 }
215
216 void wxListBox::Deselect(int N)
217 {
218 wxCHECK_RET( N >= 0 && N < m_noItems,
219 "invalid index in wxListBox::Deselect" );
220
221 SetSelection( N , false ) ;
222 }
223
224 char *wxListBox::GetClientData(int N) const
225 {
226 wxCHECK_MSG( N >= 0 && N < m_noItems, NULL,
227 "invalid index in wxListBox::GetClientData" );
228
229 return m_dataArray[N];
230 }
231
232 void wxListBox::SetClientData(int N, char *Client_data)
233 {
234 wxCHECK_RET( N >= 0 && N < m_noItems,
235 "invalid index in wxListBox::SetClientData" );
236
237 m_dataArray[N] = Client_data ;
238 }
239
240 // Return number of selections and an array of selected integers
241 int wxListBox::GetSelections(wxArrayInt& aSelections) const
242 {
243 return MacGetSelections( aSelections ) ;
244
245 /* TODO
246 if ((m_windowStyle & wxLB_MULTIMacE) || (m_windowStyle & wxLB_EXTENDED))
247 {
248 int no_sel = ??
249 for ( int n = 0; n < no_sel; n++ )
250 aSelections.Add(??);
251
252 return no_sel;
253 }
254 else // single-selection listbox
255 {
256 aSelections.Add(??);
257
258 return 1;
259 }
260 */
261 }
262
263 // Get single selection, for single choice list items
264 int wxListBox::GetSelection() const
265 {
266 return MacGetSelection() ;
267 }
268
269 // Find string for position
270 wxString wxListBox::GetString(int N) const
271 {
272 if( wxApp::s_macDefaultEncodingIsPC )
273 {
274 return wxMacMakePCStringFromMac( m_stringArray[N] ) ;
275 }
276 else
277 return m_stringArray[N] ;
278 }
279
280 void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
281 {
282 for ( int i = 0 ; i < nItems ; i++ )
283 {
284 m_stringArray.Insert( items[i] , pos + i ) ;
285 m_dataArray.Insert( NULL , pos + i ) ;
286 MacInsert( pos + i , items[i] ) ;
287 }
288
289 m_noItems += nItems;
290 }
291
292 void wxListBox::SetString(int N, const wxString& s)
293 {
294 m_stringArray[N] = s ;
295 MacSet( N , s ) ;
296 }
297
298 int wxListBox::Number () const
299 {
300 return m_noItems;
301 }
302
303 // For single selection items only
304 wxString wxListBox::GetStringSelection () const
305 {
306 int sel = GetSelection ();
307 if (sel > -1)
308 {
309 return GetString (sel);
310 }
311 else
312 return wxString("");
313 }
314
315 bool wxListBox::SetStringSelection (const wxString& s, bool flag)
316 {
317 int sel = FindString (s);
318 if (sel > -1)
319 {
320 SetSelection (sel, flag);
321 return TRUE;
322 }
323 else
324 return FALSE;
325 }
326
327 void wxListBox::Command (wxCommandEvent & event)
328 {
329 if (event.m_extraLong)
330 SetSelection (event.m_commandInt);
331 else
332 {
333 Deselect (event.m_commandInt);
334 return;
335 }
336 ProcessCommand (event);
337 }
338
339 // ============================================================================
340 // list box control implementation
341 // ============================================================================
342
343 void MacDrawStringCell(Rect *cellRect, Cell lCell, ListHandle theList, long refCon)
344 {
345 wxListBox* list;
346 // typecast our refCon
347 list = (wxListBox*)refCon;
348
349 MoveTo(cellRect->left + 4 , cellRect->top + 10 );
350 const wxString text = list->m_stringArray[lCell.v] ;
351 ::TextFont( kFontIDMonaco ) ;
352 ::TextSize( 9 );
353 ::TextFace( 0 ) ;
354 DrawText(text, 0 , text.Length());
355
356 }
357
358 void wxListBox::MacDelete( int N )
359 {
360 ListHandle list ;
361 long result ;
362 Cell cell = { 0 , 0 } ;
363 UMAGetControlData( m_macControl , kControlNoPart , kControlListBoxListHandleTag , sizeof( ListHandle ) , (char*) &list , &result ) ;
364 LDelRow( 1 , N , list ) ;
365 }
366
367 void wxListBox::MacInsert( int n , const char * text)
368 {
369 Cell cell ;
370
371 cell.h = 0 ;
372 cell.v = n ;
373
374 LAddRow( 1 , cell.v , m_macList ) ;
375 }
376
377 void wxListBox::MacAppend( const char * text)
378 {
379 Cell cell = { 0 , 0 } ;
380 cell.v = (**m_macList).dataBounds.bottom ;
381 LAddRow( 1 , cell.v , m_macList ) ;
382 }
383
384 void wxListBox::MacClear()
385 {
386 LDelRow( (**m_macList).dataBounds.bottom , 0 , m_macList ) ;
387 }
388
389 void wxListBox::MacSetSelection( int n , bool select )
390 {
391 Cell cell = { 0 , 0 } ;
392 if ( LGetSelect( TRUE , &cell , m_macList ) )
393 {
394 LSetSelect( false , cell , m_macList ) ;
395 }
396
397 cell.v = n ;
398 LSetSelect( select , cell , m_macList ) ;
399 LAutoScroll( m_macList ) ;
400 }
401
402 bool wxListBox::MacIsSelected( int n ) const
403 {
404 Cell cell = { 0 , 0 } ;
405 cell.v = n ;
406 return LGetSelect( false , &cell , m_macList ) ;
407 }
408
409 void wxListBox::MacDestroy()
410 {
411 // DisposeExtLDEFInfo( m_macList ) ;
412 }
413
414 int wxListBox::MacGetSelection() const
415 {
416 Cell cell = { 0 , 0 } ;
417 if ( LGetSelect( true , &cell , m_macList ) )
418 return cell.v ;
419 else
420 return -1 ;
421 }
422
423 int wxListBox::MacGetSelections( wxArrayInt& aSelections ) const
424 {
425 int no_sel = 0 ;
426
427 aSelections.Empty();
428
429 Cell cell = { 0 , 0 } ;
430 cell.v = 0 ;
431
432 while ( LGetSelect( true , &cell , m_macList ) )
433 {
434 aSelections.Add( cell.v ) ;
435 no_sel++ ;
436 cell.v++ ;
437 }
438 return no_sel ;
439 }
440
441 void wxListBox::MacSet( int n , const char * text )
442 {
443 // our implementation does not store anything in the list
444 // so we just have to redraw
445 Cell cell = { 0 , 0 } ;
446 cell.v = n ;
447 LDraw( cell , m_macList ) ;
448 }
449
450 void wxListBox::MacScrollTo( int n )
451 {
452 // TODO implement scrolling
453 }
454
455 void wxListBox::OnSize( const wxSizeEvent &event)
456 {
457 Point pt = (**m_macList).cellSize ;
458 pt.h = m_width - 15 /* scrollbar */ - m_macHorizontalBorder * 2 ;
459 LCellSize( pt , m_macList ) ;
460 }
461
462 void wxListBox::MacHandleControlClick( ControlHandle control , SInt16 controlpart )
463 {
464 Boolean wasDoubleClick = false ;
465 long result ;
466
467 UMAGetControlData( m_macControl , kControlNoPart , kControlListBoxDoubleClickTag , sizeof( wasDoubleClick ) , (char*) &wasDoubleClick , &result ) ;
468 if ( !wasDoubleClick )
469 {
470 MacDoClick() ;
471 }
472 else
473 {
474 MacDoDoubleClick() ;
475 }
476 }
477
478 void wxListBox::MacSetRedraw( bool doDraw )
479 {
480 LSetDrawingMode( doDraw , m_macList ) ;
481
482 }
483
484 void wxListBox::MacDoClick()
485 {
486 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
487 wxArrayInt aSelections;
488 int count = GetSelections(aSelections);
489 if ( count > 0 )
490 {
491 event.m_commandInt = aSelections[0] ;
492 event.m_clientData = GetClientData(event.m_commandInt);
493 wxString str(GetString(event.m_commandInt));
494 if (str != "")
495 event.m_commandString = copystring((char *)(const char *)str);
496 }
497 else
498 {
499 return ;
500 /*
501 event.m_commandInt = -1 ;
502 event.m_commandString = copystring("") ;
503 */
504 }
505
506 event.SetEventObject( this );
507 ProcessCommand(event);
508 if (event.m_commandString)
509 delete[] event.m_commandString ;
510 }
511
512 void wxListBox::MacDoDoubleClick()
513 {
514 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, m_windowId);
515 event.SetEventObject( this );
516 GetEventHandler()->ProcessEvent(event) ;
517 }