1 ///////////////////////////////////////////////////////////////////////////////
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "listbox.h"
16 #include "wx/listbox.h"
17 #include "wx/settings.h"
18 #include "wx/dynarray.h"
24 #if !USE_SHARED_LIBRARY
25 IMPLEMENT_DYNAMIC_CLASS(wxListBox
, wxControl
)
27 BEGIN_EVENT_TABLE(wxListBox
, wxControl
)
28 EVT_SIZE( wxListBox::OnSize
)
32 #include <wx/mac/uma.h>
34 extern "C" void MacDrawStringCell(Rect
*cellRect
, Cell lCell
, ListHandle theList
, long refCon
) ;
35 const short kwxMacListWithVerticalScrollbar
= 128 ;
37 // ============================================================================
38 // list box control implementation
39 // ============================================================================
42 wxListBox::wxListBox()
48 bool wxListBox::Create(wxWindow
*parent
, wxWindowID id
,
51 int n
, const wxString choices
[],
53 const wxValidator
& validator
,
56 m_noItems
= 0 ; // this will be increased by our append command
61 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
62 m_macVerticalBorder
= 5 ;
64 MacPreControlCreate( parent
, id
, "" , pos
, size
,style
, validator
, name
, &bounds
, title
) ;
66 m_macControl
= UMANewControl( parent
->GetMacRootWindow() , &bounds
, title
, true , kwxMacListWithVerticalScrollbar
, 0 , 0,
67 kControlListBoxProc
, (long) this ) ;
70 UMAGetControlData( m_macControl
, kControlNoPart
, kControlListBoxListHandleTag
, sizeof( ListHandle
) , (char*) &m_macList
, &result
) ;
72 NewExtLDEFInfo( m_macList
, MacDrawStringCell
, (long) this ) ;
73 (**m_macList
).selFlags
= lOnlyOne
;
74 if ( style
& wxLB_MULTIPLE
)
76 (**m_macList
).selFlags
+= lNoExtend
;
78 else if ( style
& wxLB_EXTENDED
)
80 (**m_macList
).selFlags
+= lExtendDrag
;
82 Point pt
= (**m_macList
).cellSize
;
84 LCellSize( pt
, m_macList
) ;
86 LAddColumn( 1 , 0 , m_macList
) ;
88 MacPostControlCreate() ;
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
) ;
97 for ( int i
= 0 ; i
< n
; i
++ )
99 Append( choices
[i
] ) ;
102 LSetDrawingMode( true , m_macList
) ;
107 wxListBox::~wxListBox()
110 DisposeExtLDEFInfo( m_macList
) ;
113 void wxListBox::Free()
115 #if wxUSE_OWNER_DRAWN
116 if ( m_windowStyle
& wxLB_OWNERDRAW
)
118 size_t uiCount
= m_aItems
.Count();
119 while ( uiCount
-- != 0 ) {
120 delete m_aItems
[uiCount
];
126 #endif // wxUSE_OWNER_DRAWN
127 if ( HasClientObjectData() )
129 for ( size_t n
= 0; n
< (size_t)m_noItems
; n
++ )
131 delete GetClientObject(n
);
136 void wxListBox::DoSetFirstItem(int N
)
141 void wxListBox::Delete(int N
)
143 wxCHECK_RET( N
>= 0 && N
< m_noItems
,
144 wxT("invalid index in wxListBox::Delete") );
146 #if wxUSE_OWNER_DRAWN
149 #else // !wxUSE_OWNER_DRAWN
150 if ( HasClientObjectData() )
152 delete GetClientObject(N
);
154 #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
155 m_stringArray
.Remove( N
) ;
159 SetHorizontalExtent("");
162 int wxListBox::DoAppend(const wxString
& item
)
164 int index
= m_noItems
;
165 if( wxApp::s_macDefaultEncodingIsPC
)
167 m_stringArray
.Add( wxMacMakeMacStringFromPC( item
) ) ;
170 m_stringArray
.Add( item
) ;
174 SetHorizontalExtent(item
);
179 void wxListBox::DoSetItems(const wxArrayString
& choices
, void** clientData
)
181 MacSetRedraw( false ) ;
183 int n
= choices
.GetCount();
185 for( int i
= 0 ; i
< n
; ++i
)
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
193 Append( choices
[i
] , clientData
[0] ) ;
197 Append( choices
[i
] ) ;
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 ) {
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
);
216 #endif // wxUSE_OWNER_DRAWN
217 MacSetRedraw( true ) ;
220 bool wxListBox::HasMultipleSelection() const
222 return (m_windowStyle
& wxLB_MULTIPLE
) || (m_windowStyle
& wxLB_EXTENDED
);
225 int wxListBox::FindString(const wxString
& st
) const
228 if( wxApp::s_macDefaultEncodingIsPC
)
230 s
= wxMacMakeMacStringFromPC( st
) ;
235 if ( s
.Right(1) == "*" )
237 wxString search
= s
.Left( s
.Length() - 1 ) ;
238 int len
= search
.Length() ;
239 for ( int i
= 0 ; i
< m_noItems
; ++ i
)
241 if ( equalstring( m_stringArray
[i
].Left( len
) , search
, false , false ) )
247 for ( int i
= 0 ; i
< m_noItems
; ++ i
)
249 if ( equalstring( m_stringArray
[i
] , s
, false , false ) )
256 void wxListBox::Clear()
260 m_stringArray
.Empty() ;
261 m_dataArray
.Empty() ;
263 SetHorizontalExtent();
266 void wxListBox::SetSelection(int N
, bool select
)
268 wxCHECK_RET( N
>= 0 && N
< m_noItems
,
269 "invalid index in wxListBox::SetSelection" );
270 MacSetSelection( N
, select
) ;
273 bool wxListBox::IsSelected(int N
) const
275 wxCHECK_MSG( N
>= 0 && N
< m_noItems
, FALSE
,
276 "invalid index in wxListBox::Selected" );
278 return MacIsSelected( N
) ;
281 void *wxListBox::DoGetItemClientData(int N
) const
283 wxCHECK_MSG( N
>= 0 && N
< m_noItems
, NULL
,
284 "invalid index in wxListBox::GetClientData" );
286 return (void *)m_dataArray
[N
];
289 void wxListBox::DoSetItemClientData(int N
, void *Client_data
)
291 wxCHECK_RET( N
>= 0 && N
< m_noItems
,
292 "invalid index in wxListBox::SetClientData" );
294 #if wxUSE_OWNER_DRAWN
295 if ( m_windowStyle
& wxLB_OWNERDRAW
)
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"));
301 #endif // wxUSE_OWNER_DRAWN
302 m_dataArray
[N
] = (char*) Client_data
;
305 void wxListBox::DoSetItemClientObject(int n
, wxClientData
* clientData
)
307 DoSetItemClientData(n
, clientData
);
310 // Return number of selections and an array of selected integers
311 int wxListBox::GetSelections(wxArrayInt
& aSelections
) const
313 return MacGetSelections( aSelections
) ;
316 if ((m_windowStyle & wxLB_MULTIMacE) || (m_windowStyle & wxLB_EXTENDED))
319 for ( int n = 0; n < no_sel; n++ )
324 else // single-selection listbox
333 // Get single selection, for single choice list items
334 int wxListBox::GetSelection() const
336 return MacGetSelection() ;
339 // Find string for position
340 wxString
wxListBox::GetString(int N
) const
342 if( wxApp::s_macDefaultEncodingIsPC
)
344 return wxMacMakePCStringFromMac( m_stringArray
[N
] ) ;
347 return m_stringArray
[N
] ;
350 void wxListBox::DoInsertItems(const wxArrayString
& items
, int pos
)
352 wxCHECK_RET( pos
>= 0 && pos
<= m_noItems
,
353 wxT("invalid index in wxListBox::InsertItems") );
355 int nItems
= items
.GetCount();
357 for ( int i
= 0 ; i
< nItems
; i
++ )
359 m_stringArray
.Insert( items
[i
] , pos
+ i
) ;
360 m_dataArray
.Insert( NULL
, pos
+ i
) ;
361 MacInsert( pos
+ i
, items
[i
] ) ;
367 void wxListBox::SetString(int N
, const wxString
& s
)
369 m_stringArray
[N
] = s
;
373 wxSize
wxListBox::DoGetBestSize()
375 return wxSize(100, 100);
379 // ============================================================================
380 // list box control implementation
381 // ============================================================================
383 void MacDrawStringCell(Rect
*cellRect
, Cell lCell
, ListHandle theList
, long refCon
)
386 // typecast our refCon
387 list
= (wxListBox
*)refCon
;
389 MoveTo(cellRect
->left
+ 4 , cellRect
->top
+ 10 );
390 const wxString text
= list
->m_stringArray
[lCell
.v
] ;
391 ::TextFont( kFontIDMonaco
) ;
394 DrawText(text
, 0 , text
.Length());
398 void wxListBox::MacDelete( int N
)
402 Cell cell
= { 0 , 0 } ;
403 UMAGetControlData( m_macControl
, kControlNoPart
, kControlListBoxListHandleTag
, sizeof( ListHandle
) , (char*) &list
, &result
) ;
404 LDelRow( 1 , N
, list
) ;
407 void wxListBox::MacInsert( int n
, const char * text
)
414 LAddRow( 1 , cell
.v
, m_macList
) ;
417 void wxListBox::MacAppend( const char * text
)
419 Cell cell
= { 0 , 0 } ;
420 cell
.v
= (**m_macList
).dataBounds
.bottom
;
421 LAddRow( 1 , cell
.v
, m_macList
) ;
424 void wxListBox::MacClear()
426 LDelRow( (**m_macList
).dataBounds
.bottom
, 0 , m_macList
) ;
429 void wxListBox::MacSetSelection( int n
, bool select
)
431 Cell cell
= { 0 , 0 } ;
432 if ( LGetSelect( TRUE
, &cell
, m_macList
) )
434 LSetSelect( false , cell
, m_macList
) ;
438 LSetSelect( select
, cell
, m_macList
) ;
439 LAutoScroll( m_macList
) ;
442 bool wxListBox::MacIsSelected( int n
) const
444 Cell cell
= { 0 , 0 } ;
446 return LGetSelect( false , &cell
, m_macList
) ;
449 void wxListBox::MacDestroy()
451 // DisposeExtLDEFInfo( m_macList ) ;
454 int wxListBox::MacGetSelection() const
456 Cell cell
= { 0 , 0 } ;
457 if ( LGetSelect( true , &cell
, m_macList
) )
463 int wxListBox::MacGetSelections( wxArrayInt
& aSelections
) const
469 Cell cell
= { 0 , 0 } ;
472 while ( LGetSelect( true , &cell
, m_macList
) )
474 aSelections
.Add( cell
.v
) ;
481 void wxListBox::MacSet( int n
, const char * text
)
483 // our implementation does not store anything in the list
484 // so we just have to redraw
485 Cell cell
= { 0 , 0 } ;
487 LDraw( cell
, m_macList
) ;
490 void wxListBox::MacScrollTo( int n
)
492 // TODO implement scrolling
495 void wxListBox::OnSize( const wxSizeEvent
&event
)
497 Point pt
= (**m_macList
).cellSize
;
498 pt
.h
= m_width
- 15 /* scrollbar */ - m_macHorizontalBorder
* 2 ;
499 LCellSize( pt
, m_macList
) ;
502 void wxListBox::MacHandleControlClick( ControlHandle control
, SInt16 controlpart
)
504 Boolean wasDoubleClick
= false ;
507 UMAGetControlData( m_macControl
, kControlNoPart
, kControlListBoxDoubleClickTag
, sizeof( wasDoubleClick
) , (char*) &wasDoubleClick
, &result
) ;
508 if ( !wasDoubleClick
)
518 void wxListBox::MacSetRedraw( bool doDraw
)
520 LSetDrawingMode( doDraw
, m_macList
) ;
524 void wxListBox::MacDoClick()
526 wxCommandEvent
event(wxEVT_COMMAND_LISTBOX_SELECTED
, m_windowId
);
527 event
.SetEventObject( this );
529 wxArrayInt aSelections
;
530 int n
, count
= GetSelections(aSelections
);
533 event
.m_commandInt
= aSelections
[0] ;
534 if ( HasClientObjectData() )
535 event
.SetClientObject( GetClientObject(n
) );
536 else if ( HasClientUntypedData() )
537 event
.SetClientData( GetClientData(n
) );
538 event
.SetString( GetString(n
) );
545 event
.m_commandInt
= n
;
547 GetEventHandler()->ProcessEvent(event
);
550 void wxListBox::MacDoDoubleClick()
552 wxCommandEvent
event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
, m_windowId
);
553 event
.SetEventObject( this );
554 GetEventHandler()->ProcessEvent(event
) ;