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
) ;
161 int wxListBox::DoAppend(const wxString
& item
)
163 int index
= m_noItems
;
164 if( wxApp::s_macDefaultEncodingIsPC
)
166 m_stringArray
.Add( wxMacMakeMacStringFromPC( item
) ) ;
169 m_stringArray
.Add( item
) ;
176 void wxListBox::DoSetItems(const wxArrayString
& choices
, void** clientData
)
178 MacSetRedraw( false ) ;
180 int n
= choices
.GetCount();
182 for( int i
= 0 ; i
< n
; ++i
)
186 #if wxUSE_OWNER_DRAWN
187 wxASSERT_MSG(clientData
[i
] == NULL
,
188 wxT("Can't use client data with owner-drawn listboxes"));
189 #else // !wxUSE_OWNER_DRAWN
190 Append( choices
[i
] , clientData
[0] ) ;
194 Append( choices
[i
] ) ;
197 #if wxUSE_OWNER_DRAWN
198 if ( m_windowStyle
& wxLB_OWNERDRAW
) {
199 // first delete old items
200 size_t ui
= m_aItems
.Count();
201 while ( ui
-- != 0 ) {
206 // then create new ones
207 for ( ui
= 0; ui
< (size_t)m_noItems
; ui
++ ) {
208 wxOwnerDrawn
*pNewItem
= CreateItem(ui
);
209 pNewItem
->SetName(choices
[ui
]);
210 m_aItems
.Add(pNewItem
);
213 #endif // wxUSE_OWNER_DRAWN
214 MacSetRedraw( true ) ;
217 bool wxListBox::HasMultipleSelection() const
219 return (m_windowStyle
& wxLB_MULTIPLE
) || (m_windowStyle
& wxLB_EXTENDED
);
222 int wxListBox::FindString(const wxString
& st
) const
225 if( wxApp::s_macDefaultEncodingIsPC
)
227 s
= wxMacMakeMacStringFromPC( st
) ;
232 if ( s
.Right(1) == "*" )
234 wxString search
= s
.Left( s
.Length() - 1 ) ;
235 int len
= search
.Length() ;
236 for ( int i
= 0 ; i
< m_noItems
; ++ i
)
238 if ( equalstring( m_stringArray
[i
].Left( len
) , search
, false , false ) )
244 for ( int i
= 0 ; i
< m_noItems
; ++ i
)
246 if ( equalstring( m_stringArray
[i
] , s
, false , false ) )
253 void wxListBox::Clear()
257 m_stringArray
.Empty() ;
258 m_dataArray
.Empty() ;
262 void wxListBox::SetSelection(int N
, bool select
)
264 wxCHECK_RET( N
>= 0 && N
< m_noItems
,
265 "invalid index in wxListBox::SetSelection" );
266 MacSetSelection( N
, select
) ;
269 bool wxListBox::IsSelected(int N
) const
271 wxCHECK_MSG( N
>= 0 && N
< m_noItems
, FALSE
,
272 "invalid index in wxListBox::Selected" );
274 return MacIsSelected( N
) ;
277 void *wxListBox::DoGetItemClientData(int N
) const
279 wxCHECK_MSG( N
>= 0 && N
< m_noItems
, NULL
,
280 "invalid index in wxListBox::GetClientData" );
282 return (void *)m_dataArray
[N
];
285 wxClientData
*wxListBox::DoGetItemClientObject(int N
) const
287 return (wxClientData
*) DoGetItemClientData( N
) ;
290 void wxListBox::DoSetItemClientData(int N
, void *Client_data
)
292 wxCHECK_RET( N
>= 0 && N
< m_noItems
,
293 "invalid index in wxListBox::SetClientData" );
295 #if wxUSE_OWNER_DRAWN
296 if ( m_windowStyle
& wxLB_OWNERDRAW
)
298 // client data must be pointer to wxOwnerDrawn, otherwise we would crash
299 // in OnMeasure/OnDraw.
300 wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
302 #endif // wxUSE_OWNER_DRAWN
303 m_dataArray
[N
] = (char*) Client_data
;
306 void wxListBox::DoSetItemClientObject(int n
, wxClientData
* clientData
)
308 DoSetItemClientData(n
, clientData
);
311 // Return number of selections and an array of selected integers
312 int wxListBox::GetSelections(wxArrayInt
& aSelections
) const
314 return MacGetSelections( aSelections
) ;
317 if ((m_windowStyle & wxLB_MULTIMacE) || (m_windowStyle & wxLB_EXTENDED))
320 for ( int n = 0; n < no_sel; n++ )
325 else // single-selection listbox
334 // Get single selection, for single choice list items
335 int wxListBox::GetSelection() const
337 return MacGetSelection() ;
340 // Find string for position
341 wxString
wxListBox::GetString(int N
) const
343 if( wxApp::s_macDefaultEncodingIsPC
)
345 return wxMacMakePCStringFromMac( m_stringArray
[N
] ) ;
348 return m_stringArray
[N
] ;
351 void wxListBox::DoInsertItems(const wxArrayString
& items
, int pos
)
353 wxCHECK_RET( pos
>= 0 && pos
<= m_noItems
,
354 wxT("invalid index in wxListBox::InsertItems") );
356 int nItems
= items
.GetCount();
358 for ( int i
= 0 ; i
< nItems
; i
++ )
360 m_stringArray
.Insert( items
[i
] , pos
+ i
) ;
361 m_dataArray
.Insert( NULL
, pos
+ i
) ;
362 MacInsert( pos
+ i
, items
[i
] ) ;
368 void wxListBox::SetString(int N
, const wxString
& s
)
370 m_stringArray
[N
] = s
;
374 wxSize
wxListBox::DoGetBestSize()
376 return wxSize(100, 100);
379 int wxListBox::GetCount() const
384 void wxListBox::SetupColours()
386 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW
));
387 SetForegroundColour(GetParent()->GetForegroundColour());
390 #if wxUSE_OWNER_DRAWN
392 class wxListBoxItem
: public wxOwnerDrawn
395 wxListBoxItem(const wxString
& str
= "");
398 wxListBoxItem::wxListBoxItem(const wxString
& str
) : wxOwnerDrawn(str
, FALSE
)
400 // no bitmaps/checkmarks
404 wxOwnerDrawn
*wxListBox::CreateItem(size_t n
)
406 return new wxListBoxItem();
409 #endif //USE_OWNER_DRAWN
411 // ============================================================================
412 // list box control implementation
413 // ============================================================================
415 void MacDrawStringCell(Rect
*cellRect
, Cell lCell
, ListHandle theList
, long refCon
)
418 // typecast our refCon
419 list
= (wxListBox
*)refCon
;
421 MoveTo(cellRect
->left
+ 4 , cellRect
->top
+ 10 );
422 const wxString text
= list
->m_stringArray
[lCell
.v
] ;
423 ::TextFont( kFontIDMonaco
) ;
426 DrawText(text
, 0 , text
.Length());
430 void wxListBox::MacDelete( int N
)
434 Cell cell
= { 0 , 0 } ;
435 UMAGetControlData( m_macControl
, kControlNoPart
, kControlListBoxListHandleTag
, sizeof( ListHandle
) , (char*) &list
, &result
) ;
436 LDelRow( 1 , N
, list
) ;
439 void wxListBox::MacInsert( int n
, const char * text
)
446 LAddRow( 1 , cell
.v
, m_macList
) ;
449 void wxListBox::MacAppend( const char * text
)
451 Cell cell
= { 0 , 0 } ;
452 cell
.v
= (**m_macList
).dataBounds
.bottom
;
453 LAddRow( 1 , cell
.v
, m_macList
) ;
456 void wxListBox::MacClear()
458 LDelRow( (**m_macList
).dataBounds
.bottom
, 0 , m_macList
) ;
461 void wxListBox::MacSetSelection( int n
, bool select
)
463 Cell cell
= { 0 , 0 } ;
464 if ( LGetSelect( TRUE
, &cell
, m_macList
) )
466 LSetSelect( false , cell
, m_macList
) ;
470 LSetSelect( select
, cell
, m_macList
) ;
471 LAutoScroll( m_macList
) ;
474 bool wxListBox::MacIsSelected( int n
) const
476 Cell cell
= { 0 , 0 } ;
478 return LGetSelect( false , &cell
, m_macList
) ;
481 void wxListBox::MacDestroy()
483 // DisposeExtLDEFInfo( m_macList ) ;
486 int wxListBox::MacGetSelection() const
488 Cell cell
= { 0 , 0 } ;
489 if ( LGetSelect( true , &cell
, m_macList
) )
495 int wxListBox::MacGetSelections( wxArrayInt
& aSelections
) const
501 Cell cell
= { 0 , 0 } ;
504 while ( LGetSelect( true , &cell
, m_macList
) )
506 aSelections
.Add( cell
.v
) ;
513 void wxListBox::MacSet( int n
, const char * text
)
515 // our implementation does not store anything in the list
516 // so we just have to redraw
517 Cell cell
= { 0 , 0 } ;
519 LDraw( cell
, m_macList
) ;
522 void wxListBox::MacScrollTo( int n
)
524 // TODO implement scrolling
527 void wxListBox::OnSize( const wxSizeEvent
&event
)
529 Point pt
= (**m_macList
).cellSize
;
530 pt
.h
= m_width
- 15 /* scrollbar */ - m_macHorizontalBorder
* 2 ;
531 LCellSize( pt
, m_macList
) ;
534 void wxListBox::MacHandleControlClick( ControlHandle control
, SInt16 controlpart
)
536 Boolean wasDoubleClick
= false ;
539 UMAGetControlData( m_macControl
, kControlNoPart
, kControlListBoxDoubleClickTag
, sizeof( wasDoubleClick
) , (char*) &wasDoubleClick
, &result
) ;
540 if ( !wasDoubleClick
)
550 void wxListBox::MacSetRedraw( bool doDraw
)
552 LSetDrawingMode( doDraw
, m_macList
) ;
556 void wxListBox::MacDoClick()
558 wxCommandEvent
event(wxEVT_COMMAND_LISTBOX_SELECTED
, m_windowId
);
559 event
.SetEventObject( this );
561 wxArrayInt aSelections
;
562 int n
, count
= GetSelections(aSelections
);
566 if ( HasClientObjectData() )
567 event
.SetClientObject( GetClientObject(n
) );
568 else if ( HasClientUntypedData() )
569 event
.SetClientData( GetClientData(n
) );
570 event
.SetString( GetString(n
) );
577 event
.m_commandInt
= n
;
579 GetEventHandler()->ProcessEvent(event
);
582 void wxListBox::MacDoDoubleClick()
584 wxCommandEvent
event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
, m_windowId
);
585 event
.SetEventObject( this );
586 GetEventHandler()->ProcessEvent(event
) ;