]>
git.saurik.com Git - wxWidgets.git/blob - src/osx/listbox_osx.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/listbox_osx.cpp
4 // Author: Stefan Csomor
7 // Copyright: (c) Stefan Csomor
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 #include "wx/wxprec.h"
15 #include "wx/listbox.h"
21 #include "wx/settings.h"
22 #include "wx/arrstr.h"
23 #include "wx/dcclient.h"
26 BEGIN_EVENT_TABLE(wxListBox
, wxControl
)
29 #include "wx/osx/private.h"
31 // ============================================================================
32 // list box control implementation
33 // ============================================================================
35 wxListBox::wxListBox()
39 bool wxListBox::Create(
44 const wxArrayString
& choices
,
46 const wxValidator
& validator
,
47 const wxString
& name
)
49 wxCArrayString
chs(choices
);
52 parent
, id
, pos
, size
, chs
.GetCount(), chs
.GetStrings(),
53 style
, validator
, name
);
56 wxListWidgetImpl
* wxListBox::GetListPeer() const
58 wxListWidgetImpl
* impl
= dynamic_cast<wxListWidgetImpl
*> ( GetPeer() );
62 bool wxListBox::Create(
68 const wxString choices
[],
70 const wxValidator
& validator
,
71 const wxString
& name
)
74 m_blockEvents
= false;
76 if ( ! (style
& wxNO_BORDER
) )
77 style
= (style
& ~wxBORDER_MASK
) | wxSUNKEN_BORDER
;
79 wxASSERT_MSG( !(style
& wxLB_MULTIPLE
) || !(style
& wxLB_EXTENDED
),
80 wxT("only a single listbox selection mode can be specified") );
82 if ( !wxListBoxBase::Create( parent
, id
, pos
, size
, style
& ~(wxHSCROLL
| wxVSCROLL
), validator
, name
) )
86 m_strings
.sorted
= new wxSortedArrayString
;
88 m_strings
.unsorted
= new wxArrayString
;
90 SetPeer(wxWidgetImpl::CreateListBox( this, parent
, id
, pos
, size
, style
, GetExtraStyle() ));
92 MacPostControlCreate( pos
, size
);
94 m_textColumn
= GetListPeer()->InsertTextColumn(0,wxEmptyString
);
98 // Needed because it is a wxControlWithItems
99 SetInitialSize( size
);
104 wxListBox::~wxListBox()
106 m_blockEvents
= true;
108 m_blockEvents
= false;
110 // make sure no native events get sent to a object in destruction
114 delete m_strings
.sorted
;
116 delete m_strings
.unsorted
;
118 m_strings
.sorted
= NULL
;
121 void wxListBox::FreeData()
124 m_strings
.sorted
->Clear();
126 m_strings
.unsorted
->Clear();
128 m_itemsClientData
.Clear();
130 GetListPeer()->ListClear();
133 void wxListBox::DoSetFirstItem(int n
)
135 // osx actually only has an implementation for ensuring the visibility of a row, it does so
136 // by scrolling the minimal amount necessary from the current scrolling position.
137 // in order to get the same behaviour I'd have to make sure first that the last line is visible,
138 // followed by a scrollRowToVisible for the desired line
139 GetListPeer()->ListScrollTo( GetCount()-1 );
140 GetListPeer()->ListScrollTo( n
);
143 void wxListBox::EnsureVisible(int n
)
145 GetListPeer()->ListScrollTo( n
);
148 void wxListBox::DoDeleteOneItem(unsigned int n
)
150 wxCHECK_RET( IsValid(n
), wxT("invalid index in wxListBox::Delete") );
152 m_blockEvents
= true;
154 m_strings
.sorted
->RemoveAt(n
);
156 m_strings
.unsorted
->RemoveAt(n
);
158 m_itemsClientData
.RemoveAt(n
);
160 GetListPeer()->ListDelete( n
);
161 m_blockEvents
= false;
163 UpdateOldSelections();
166 void wxListBox::DoClear()
168 m_blockEvents
= true;
170 m_blockEvents
= false;
172 UpdateOldSelections();
175 // ----------------------------------------------------------------------------
177 // ----------------------------------------------------------------------------
179 void wxListBox::DoSetSelection(int n
, bool select
)
181 wxCHECK_RET( n
== wxNOT_FOUND
|| IsValid(n
),
182 wxT("invalid index in wxListBox::SetSelection") );
184 m_blockEvents
= true;
186 if ( n
== wxNOT_FOUND
)
187 GetListPeer()->ListDeselectAll();
189 GetListPeer()->ListSetSelection( n
, select
, HasMultipleSelection() );
191 m_blockEvents
= false;
193 UpdateOldSelections();
196 bool wxListBox::IsSelected(int n
) const
198 wxCHECK_MSG( IsValid(n
), false, wxT("invalid index in wxListBox::Selected") );
200 return GetListPeer()->ListIsSelected( n
);
203 // Return number of selections and an array of selected integers
204 int wxListBox::GetSelections(wxArrayInt
& aSelections
) const
206 return GetListPeer()->ListGetSelections( aSelections
);
209 // Get single selection, for single choice list items
210 int wxListBox::GetSelection() const
212 return GetListPeer()->ListGetSelection();
215 int wxListBox::DoListHitTest(const wxPoint
& inpoint
) const
217 return GetListPeer()->DoListHitTest( inpoint
);
220 // ----------------------------------------------------------------------------
222 // ----------------------------------------------------------------------------
224 void wxListBox::GetValueCallback( unsigned int n
, wxListWidgetColumn
* col
, wxListWidgetCellValue
& value
)
226 if ( col
== m_textColumn
)
227 value
.Set( GetString( n
) );
230 void wxListBox::SetValueCallback( unsigned int WXUNUSED(n
), wxListWidgetColumn
* WXUNUSED(col
) , wxListWidgetCellValue
& WXUNUSED(value
) )
234 wxSize
wxListBox::DoGetBestSize() const
236 int lbWidth
= 100; // some defaults
241 wxClientDC
dc(const_cast<wxListBox
*>(this));
242 dc
.SetFont(GetFont());
244 // Find the widest line
245 for (unsigned int i
= 0; i
< GetCount(); i
++)
247 wxString
str( GetString( i
) );
249 wxCoord width
, height
;
250 dc
.GetTextExtent( str
, &width
, &height
);
252 lbWidth
= wxMax( lbWidth
, wLine
);
255 // Add room for the scrollbar
256 lbWidth
+= wxSystemSettings::GetMetric( wxSYS_VSCROLL_X
);
258 // And just a bit more
261 wxCoord width
, height
;
262 dc
.GetTextExtent( wxT("XX") , &width
, &height
);
266 // don't make the listbox too tall (limit height to around 10 items)
267 // but don't make it too small neither
268 lbHeight
= wxMax( (cy
+ 4) * wxMin( wxMax( GetCount(), 3 ), 10 ), 70 );
271 return wxSize( lbWidth
, lbHeight
);
274 void wxListBox::Refresh(bool eraseBack
, const wxRect
*rect
)
276 wxControl::Refresh( eraseBack
, rect
);
279 // Some custom controls depend on this
280 /* static */ wxVisualAttributes
281 wxListBox::GetClassDefaultAttributes(wxWindowVariant
WXUNUSED(variant
))
283 wxVisualAttributes attr
;
285 attr
.colFg
= wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT
);
286 attr
.colBg
= wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX
);
287 static wxFont font
= wxFont(wxOSX_SYSTEM_FONT_VIEWS
);
293 // below is all code copied from univ
295 // ----------------------------------------------------------------------------
296 // client data handling
297 // ----------------------------------------------------------------------------
299 void wxListBox::DoSetItemClientData(unsigned int n
, void* clientData
)
301 m_itemsClientData
[n
] = clientData
;
304 void *wxListBox::DoGetItemClientData(unsigned int n
) const
306 return m_itemsClientData
[n
];
309 // ----------------------------------------------------------------------------
311 // ----------------------------------------------------------------------------
313 unsigned int wxListBox::GetCount() const
315 return IsSorted() ? m_strings
.sorted
->size()
316 : m_strings
.unsorted
->size();
319 wxString
wxListBox::GetString(unsigned int n
) const
321 return IsSorted() ? m_strings
.sorted
->Item(n
)
322 : m_strings
.unsorted
->Item(n
);
325 int wxListBox::FindString(const wxString
& s
, bool bCase
) const
327 return IsSorted() ? m_strings
.sorted
->Index(s
, bCase
)
328 : m_strings
.unsorted
->Index(s
, bCase
);
331 // ----------------------------------------------------------------------------
332 // adding/inserting strings
333 // ----------------------------------------------------------------------------
335 void wxListBox::OnItemInserted(unsigned int WXUNUSED(pos
))
339 int wxListBox::DoInsertItems(const wxArrayStringsAdapter
& items
,
342 wxClientDataType type
)
344 int idx
= wxNOT_FOUND
;
345 unsigned int startpos
= pos
;
347 const unsigned int numItems
= items
.GetCount();
348 for ( unsigned int i
= 0; i
< numItems
; ++i
)
350 const wxString
& item
= items
[i
];
351 idx
= IsSorted() ? m_strings
.sorted
->Add(item
)
352 : (m_strings
.unsorted
->Insert(item
, pos
), pos
++);
354 m_itemsClientData
.Insert(NULL
, idx
);
355 AssignNewItemClientData(idx
, clientData
, i
, type
);
357 GetListPeer()->ListInsert(startpos
+i
);
362 GetListPeer()->UpdateLineToEnd(startpos
);
364 // Inserting the items may scroll the listbox down to show the last
365 // selected one but we don't want to do it as it could result in e.g. the
366 // first items of a listbox be hidden immediately after its creation so
367 // show the first selected item instead. Ideal would probably be to
368 // preserve the old selection unchanged, in fact, but I don't know how to
369 // get the first visible item so for now do at least this.
370 SetFirstItem(startpos
);
372 UpdateOldSelections();
377 void wxListBox::SetString(unsigned int n
, const wxString
& s
)
379 wxCHECK_RET( !IsSorted(), wxT("can't set string in sorted listbox") );
382 (*m_strings
.sorted
)[n
] = s
;
384 (*m_strings
.unsorted
)[n
] = s
;
386 GetListPeer()->UpdateLine(n
);
390 // common event handling
393 void wxListBox::HandleLineEvent( unsigned int n
, bool doubleClick
)
395 wxCommandEvent
event( doubleClick
? wxEVT_LISTBOX_DCLICK
:
396 wxEVT_LISTBOX
, GetId() );
397 event
.SetEventObject( this );
398 if ( HasClientObjectData() )
399 event
.SetClientObject( GetClientObject(n
) );
400 else if ( HasClientUntypedData() )
401 event
.SetClientData( GetClientData(n
) );
402 event
.SetString( GetString(n
) );
404 event
.SetExtraLong( 1 );
405 HandleWindowEvent(event
);
409 // common list cell value operations
412 void wxListWidgetCellValue::Check( bool check
)
414 Set( check
? 1 : 0 );
417 bool wxListWidgetCellValue::IsChecked() const
419 return GetIntValue() != 0;
424 #endif // wxUSE_LISTBOX