]> git.saurik.com Git - wxWidgets.git/blame - src/generic/vlbox.cpp
no real changes, just some reformatting
[wxWidgets.git] / src / generic / vlbox.cpp
CommitLineData
e0c6027b 1///////////////////////////////////////////////////////////////////////////////
e19ac18a 2// Name: src/generic/vlbox.cpp
e0c6027b
VZ
3// Purpose: implementation of wxVListBox
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 31.05.03
7// RCS-ID: $Id$
8// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
0a53b9b8 9// License: wxWindows license
e0c6027b
VZ
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
179e085f
RN
27#if wxUSE_LISTBOX
28
2a673eb1
WS
29#include "wx/vlbox.h"
30
e0c6027b
VZ
31#ifndef WX_PRECOMP
32 #include "wx/settings.h"
bb178b29 33 #include "wx/dcclient.h"
2a673eb1 34 #include "wx/listbox.h"
e0c6027b
VZ
35#endif //WX_PRECOMP
36
0975a8a0 37#include "wx/dcbuffer.h"
be465555 38#include "wx/selstore.h"
04125489 39#include "wx/renderer.h"
e0c6027b
VZ
40
41// ----------------------------------------------------------------------------
42// event tables
43// ----------------------------------------------------------------------------
44
45BEGIN_EVENT_TABLE(wxVListBox, wxVScrolledWindow)
46 EVT_PAINT(wxVListBox::OnPaint)
47
48 EVT_KEY_DOWN(wxVListBox::OnKeyDown)
49 EVT_LEFT_DOWN(wxVListBox::OnLeftDown)
50 EVT_LEFT_DCLICK(wxVListBox::OnLeftDClick)
04125489
VZ
51
52 EVT_SET_FOCUS(wxVListBox::OnSetOrKillFocus)
53 EVT_KILL_FOCUS(wxVListBox::OnSetOrKillFocus)
e0c6027b
VZ
54END_EVENT_TABLE()
55
56// ============================================================================
57// implementation
58// ============================================================================
59
0c8392ca
RD
60IMPLEMENT_ABSTRACT_CLASS(wxVListBox, wxVScrolledWindow)
61
e0c6027b
VZ
62// ----------------------------------------------------------------------------
63// wxVListBox creation
64// ----------------------------------------------------------------------------
65
66void wxVListBox::Init()
67{
970b97a2
VZ
68 m_current =
69 m_anchor = wxNOT_FOUND;
be465555 70 m_selStore = NULL;
e0c6027b
VZ
71}
72
73bool wxVListBox::Create(wxWindow *parent,
74 wxWindowID id,
75 const wxPoint& pos,
76 const wxSize& size,
e0c6027b
VZ
77 long style,
78 const wxString& name)
79{
a047aff2 80#ifdef __WXMSW__
9543d01c
VZ
81 if ( (style & wxBORDER_MASK) == wxDEFAULT )
82 style |= wxBORDER_THEME;
a047aff2
JS
83#endif
84
fef7400f 85 style |= wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE;
e0c6027b
VZ
86 if ( !wxVScrolledWindow::Create(parent, id, pos, size, style, name) )
87 return false;
88
be465555
VZ
89 if ( style & wxLB_MULTIPLE )
90 m_selStore = new wxSelectionStore;
e0c6027b 91
dc596072
RD
92 // make sure the native widget has the right colour since we do
93 // transparent drawing by default
94 SetBackgroundColour(GetBackgroundColour());
04125489
VZ
95
96 // leave m_colBgSel in an invalid state: it means for OnDrawBackground()
97 // to use wxRendererNative instead of painting selection bg ourselves
98 m_colBgSel = wxNullColour;
9a9b4940 99
0975a8a0
JS
100 // flicker-free drawing requires this
101 SetBackgroundStyle(wxBG_STYLE_CUSTOM);
102
e0c6027b
VZ
103 return true;
104}
105
be465555
VZ
106wxVListBox::~wxVListBox()
107{
108 delete m_selStore;
109}
110
111void wxVListBox::SetItemCount(size_t count)
112{
9543d01c
VZ
113 // don't leave the current index invalid
114 if ( m_current != wxNOT_FOUND && (size_t)m_current >= count )
115 m_current = count - 1; // also ok when count == 0 as wxNOT_FOUND == -1
116
be465555
VZ
117 if ( m_selStore )
118 {
119 // tell the selection store that our number of items has changed
120 m_selStore->SetItemCount(count);
121 }
122
f18eaf26 123 SetRowCount(count);
be465555
VZ
124}
125
e0c6027b
VZ
126// ----------------------------------------------------------------------------
127// selection handling
128// ----------------------------------------------------------------------------
129
be465555
VZ
130bool wxVListBox::IsSelected(size_t line) const
131{
132 return m_selStore ? m_selStore->IsSelected(line) : (int)line == m_current;
133}
134
135bool wxVListBox::Select(size_t item, bool select)
136{
137 wxCHECK_MSG( m_selStore, false,
138 _T("Select() may only be used with multiselection listbox") );
139
140 wxCHECK_MSG( item < GetItemCount(), false,
141 _T("Select(): invalid item index") );
142
143 bool changed = m_selStore->SelectItem(item, select);
144 if ( changed )
145 {
146 // selection really changed
e02c72fa 147 RefreshRow(item);
be465555
VZ
148 }
149
150 DoSetCurrent(item);
151
152 return changed;
153}
154
155bool wxVListBox::SelectRange(size_t from, size_t to)
e0c6027b 156{
be465555
VZ
157 wxCHECK_MSG( m_selStore, false,
158 _T("SelectRange() may only be used with multiselection listbox") );
159
160 // make sure items are in correct order
161 if ( from > to )
162 {
163 size_t tmp = from;
164 from = to;
165 to = tmp;
166 }
167
168 wxCHECK_MSG( to < GetItemCount(), false,
169 _T("SelectRange(): invalid item index") );
170
171 wxArrayInt changed;
172 if ( !m_selStore->SelectRange(from, to, true, &changed) )
173 {
174 // too many items have changed, we didn't record them in changed array
175 // so we have no choice but to refresh everything between from and to
e02c72fa 176 RefreshRows(from, to);
be465555
VZ
177 }
178 else // we've got the indices of the changed items
179 {
180 const size_t count = changed.GetCount();
181 if ( !count )
182 {
183 // nothing changed
184 return false;
185 }
186
187 // refresh just the lines which have really changed
188 for ( size_t n = 0; n < count; n++ )
189 {
e02c72fa 190 RefreshRow(changed[n]);
be465555
VZ
191 }
192 }
193
194 // something changed
195 return true;
196}
197
198bool wxVListBox::DoSelectAll(bool select)
199{
200 wxCHECK_MSG( m_selStore, false,
201 _T("SelectAll may only be used with multiselection listbox") );
202
203 size_t count = GetItemCount();
204 if ( count )
205 {
206 wxArrayInt changed;
207 if ( !m_selStore->SelectRange(0, count - 1, select) ||
208 !changed.IsEmpty() )
209 {
210 Refresh();
211
212 // something changed
213 return true;
214 }
215 }
216
217 return false;
218}
219
220bool wxVListBox::DoSetCurrent(int current)
221{
6c9210a7
VZ
222 wxASSERT_MSG( current == wxNOT_FOUND ||
223 (current >= 0 && (size_t)current < GetItemCount()),
224 _T("wxVListBox::DoSetCurrent(): invalid item index") );
225
be465555 226 if ( current == m_current )
e0c6027b
VZ
227 {
228 // nothing to do
be465555 229 return false;
e0c6027b
VZ
230 }
231
be465555 232 if ( m_current != wxNOT_FOUND )
e02c72fa 233 RefreshRow(m_current);
e0c6027b 234
be465555 235 m_current = current;
e0c6027b 236
be465555 237 if ( m_current != wxNOT_FOUND )
e0c6027b
VZ
238 {
239 // if the line is not visible at all, we scroll it into view but we
240 // don't need to refresh it -- it will be redrawn anyhow
be465555 241 if ( !IsVisible(m_current) )
e0c6027b 242 {
e02c72fa 243 ScrollToRow(m_current);
e0c6027b
VZ
244 }
245 else // line is at least partly visible
246 {
247 // it is, indeed, only partly visible, so scroll it into view to
248 // make it entirely visible
e02c72fa
VZ
249 while ( (size_t)m_current + 1 == GetVisibleRowsEnd() &&
250 ScrollToRow(GetVisibleBegin() + 1) ) ;
e0c6027b
VZ
251
252 // but in any case refresh it as even if it was only partly visible
253 // before we need to redraw it entirely as its background changed
e02c72fa 254 RefreshRow(m_current);
e0c6027b 255 }
be465555 256 }
e0c6027b 257
be465555
VZ
258 return true;
259}
e0c6027b 260
be465555
VZ
261void wxVListBox::SendSelectedEvent()
262{
263 wxASSERT_MSG( m_current != wxNOT_FOUND,
264 _T("SendSelectedEvent() shouldn't be called") );
265
266 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, GetId());
267 event.SetEventObject(this);
687706f5 268 event.SetInt(m_current);
be465555
VZ
269
270 (void)GetEventHandler()->ProcessEvent(event);
271}
272
273void wxVListBox::SetSelection(int selection)
274{
6c9210a7
VZ
275 wxCHECK_RET( selection == wxNOT_FOUND ||
276 (selection >= 0 && (size_t)selection < GetItemCount()),
277 _T("wxVListBox::SetSelection(): invalid item index") );
278
de5d3a20
VZ
279 if ( HasMultipleSelection() )
280 {
ad679137
VZ
281 if (selection != wxNOT_FOUND)
282 Select(selection);
283 else
284 DeselectAll();
de5d3a20
VZ
285 m_anchor = selection;
286 }
be465555
VZ
287
288 DoSetCurrent(selection);
289}
290
291size_t wxVListBox::GetSelectedCount() const
292{
293 return m_selStore ? m_selStore->GetSelectedCount()
294 : m_current == wxNOT_FOUND ? 0 : 1;
295}
296
297int wxVListBox::GetFirstSelected(unsigned long& cookie) const
298{
299 cookie = 0;
300
301 return GetNextSelected(cookie);
302}
303
304int wxVListBox::GetNextSelected(unsigned long& cookie) const
305{
306 wxCHECK_MSG( m_selStore, wxNOT_FOUND,
307 _T("GetFirst/NextSelected() may only be used with multiselection listboxes") );
308
309 while ( cookie < GetItemCount() )
310 {
311 if ( IsSelected(cookie++) )
312 return cookie - 1;
e0c6027b 313 }
be465555
VZ
314
315 return wxNOT_FOUND;
e0c6027b
VZ
316}
317
04125489
VZ
318void wxVListBox::RefreshSelected()
319{
320 // only refresh those items which are currently visible and selected:
321 for ( size_t n = GetVisibleBegin(), end = GetVisibleEnd(); n < end; n++ )
322 {
323 if ( IsSelected(n) )
f18eaf26 324 RefreshRow(n);
04125489
VZ
325 }
326}
327
293b15f7
VZ
328wxRect wxVListBox::GetItemRect(size_t n) const
329{
330 wxRect itemrect;
331
332 // check that this item is visible
333 const size_t lineMax = GetVisibleEnd();
334 if ( n >= lineMax )
335 return itemrect;
336 size_t line = GetVisibleBegin();
337 if ( n < line )
338 return itemrect;
339
340 while ( line <= n )
341 {
342 itemrect.y += itemrect.height;
343 itemrect.height = OnGetRowHeight(line);
344
345 line++;
346 }
347
348 itemrect.width = GetClientSize().x;
349
350 return itemrect;
351}
352
e0c6027b 353// ----------------------------------------------------------------------------
9a9b4940 354// wxVListBox appearance parameters
e0c6027b
VZ
355// ----------------------------------------------------------------------------
356
357void wxVListBox::SetMargins(const wxPoint& pt)
358{
359 if ( pt != m_ptMargins )
360 {
361 m_ptMargins = pt;
362
363 Refresh();
364 }
365}
366
9a9b4940
VZ
367void wxVListBox::SetSelectionBackground(const wxColour& col)
368{
369 m_colBgSel = col;
370}
371
372// ----------------------------------------------------------------------------
373// wxVListBox painting
374// ----------------------------------------------------------------------------
375
e02c72fa 376wxCoord wxVListBox::OnGetRowHeight(size_t line) const
e0c6027b
VZ
377{
378 return OnMeasureItem(line) + 2*m_ptMargins.y;
379}
380
381void wxVListBox::OnDrawSeparator(wxDC& WXUNUSED(dc),
382 wxRect& WXUNUSED(rect),
383 size_t WXUNUSED(n)) const
384{
385}
386
c848185a
VZ
387bool
388wxVListBox::DoDrawSolidBackground(const wxColour& col,
389 wxDC& dc,
390 const wxRect& rect,
391 size_t n) const
27d0dcd0 392{
c848185a
VZ
393 if ( !col.IsOk() )
394 return false;
395
396 // we need to render selected and current items differently
397 const bool isSelected = IsSelected(n),
398 isCurrent = IsCurrent(n);
399 if ( isSelected || isCurrent )
27d0dcd0 400 {
c848185a 401 if ( isSelected )
27d0dcd0 402 {
04ee05f9 403 dc.SetBrush(wxBrush(col, wxBRUSHSTYLE_SOLID));
27d0dcd0 404 }
c848185a
VZ
405 else // !selected
406 {
407 dc.SetBrush(*wxTRANSPARENT_BRUSH);
408 }
409 dc.SetPen(*(isCurrent ? wxBLACK_PEN : wxTRANSPARENT_PEN));
410 dc.DrawRectangle(rect);
04125489 411 }
c848185a
VZ
412 //else: do nothing for the normal items
413
414 return true;
415}
416
417void wxVListBox::OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const
418{
419 // use wxRendererNative for more native look unless we use custom bg colour
420 if ( !DoDrawSolidBackground(m_colBgSel, dc, rect, n) )
04125489
VZ
421 {
422 int flags = 0;
423 if ( IsSelected(n) )
424 flags |= wxCONTROL_SELECTED;
425 if ( IsCurrent(n) )
426 flags |= wxCONTROL_CURRENT;
d836b8bc 427 if ( wxWindow::FindFocus() == wx_const_cast(wxVListBox*, this) )
04125489
VZ
428 flags |= wxCONTROL_FOCUSED;
429
430 wxRendererNative::Get().DrawItemSelectionRect(
431 wx_const_cast(wxVListBox *, this), dc, rect, flags);
27d0dcd0 432 }
27d0dcd0
VZ
433}
434
435void wxVListBox::OnPaint(wxPaintEvent& WXUNUSED(event))
e0c6027b 436{
0975a8a0
JS
437 wxSize clientSize = GetClientSize();
438
2e992e06 439 wxAutoBufferedPaintDC dc(this);
e0c6027b
VZ
440
441 // the update rectangle
442 wxRect rectUpdate = GetUpdateClientRect();
443
959b1a33
VZ
444 // fill it with background colour
445 dc.SetBackground(GetBackgroundColour());
0975a8a0
JS
446 dc.Clear();
447
e0c6027b 448 // the bounding rectangle of the current line
e02c72fa
VZ
449 wxRect rectRow;
450 rectRow.width = clientSize.x;
e0c6027b
VZ
451
452 // iterate over all visible lines
b1b408af 453 const size_t lineMax = GetVisibleEnd();
e02c72fa 454 for ( size_t line = GetVisibleBegin(); line < lineMax; line++ )
e0c6027b 455 {
e02c72fa 456 const wxCoord hRow = OnGetRowHeight(line);
e0c6027b 457
e02c72fa 458 rectRow.height = hRow;
e0c6027b
VZ
459
460 // and draw the ones which intersect the update rect
e02c72fa 461 if ( rectRow.Intersects(rectUpdate) )
e0c6027b
VZ
462 {
463 // don't allow drawing outside of the lines rectangle
e02c72fa 464 wxDCClipper clip(dc, rectRow);
e0c6027b 465
e02c72fa 466 wxRect rect = rectRow;
27d0dcd0
VZ
467 OnDrawBackground(dc, rect, line);
468
e0c6027b
VZ
469 OnDrawSeparator(dc, rect, line);
470
471 rect.Deflate(m_ptMargins.x, m_ptMargins.y);
472 OnDrawItem(dc, rect, line);
473 }
474 else // no intersection
475 {
e02c72fa 476 if ( rectRow.GetTop() > rectUpdate.GetBottom() )
e0c6027b
VZ
477 {
478 // we are already below the update rect, no need to continue
479 // further
480 break;
481 }
482 //else: the next line may intersect the update rect
483 }
484
e02c72fa 485 rectRow.y += hRow;
e0c6027b
VZ
486 }
487}
488
04125489
VZ
489void wxVListBox::OnSetOrKillFocus(wxFocusEvent& WXUNUSED(event))
490{
491 // we need to repaint the selection when we get the focus since
492 // wxRendererNative in general draws the focused selection differently
493 // from the unfocused selection (see OnDrawItem):
494 RefreshSelected();
495}
496
497
be465555
VZ
498// ============================================================================
499// wxVListBox keyboard/mouse handling
500// ============================================================================
501
970b97a2 502void wxVListBox::DoHandleItemClick(int item, int flags)
be465555
VZ
503{
504 // has anything worth telling the client code about happened?
505 bool notify = false;
506
507 if ( HasMultipleSelection() )
508 {
509 // select the iteem clicked?
510 bool select = true;
511
512 // NB: the keyboard interface we implement here corresponds to
513 // wxLB_EXTENDED rather than wxLB_MULTIPLE but this one makes more
514 // sense IMHO
970b97a2 515 if ( flags & ItemClick_Shift )
be465555
VZ
516 {
517 if ( m_current != wxNOT_FOUND )
518 {
970b97a2
VZ
519 if ( m_anchor == wxNOT_FOUND )
520 m_anchor = m_current;
521
be465555
VZ
522 select = false;
523
970b97a2
VZ
524 // only the range from the selection anchor to new m_current
525 // must be selected
be465555
VZ
526 if ( DeselectAll() )
527 notify = true;
528
970b97a2 529 if ( SelectRange(m_anchor, item) )
be465555
VZ
530 notify = true;
531 }
532 //else: treat it as ordinary click/keypress
533 }
970b97a2 534 else // Shift not pressed
be465555 535 {
970b97a2 536 m_anchor = item;
be465555 537
970b97a2
VZ
538 if ( flags & ItemClick_Ctrl )
539 {
540 select = false;
be465555 541
970b97a2
VZ
542 if ( !(flags & ItemClick_Kbd) )
543 {
544 Toggle(item);
545
546 // the status of the item has definitely changed
547 notify = true;
548 }
549 //else: Ctrl-arrow pressed, don't change selection
550 }
551 //else: behave as in single selection case
be465555 552 }
be465555
VZ
553
554 if ( select )
555 {
556 // make the clicked item the only selection
557 if ( DeselectAll() )
558 notify = true;
559
560 if ( Select(item) )
561 notify = true;
562 }
563 }
564
565 // in any case the item should become the current one
566 if ( DoSetCurrent(item) )
567 {
568 if ( !HasMultipleSelection() )
569 {
570 // this has also changed the selection for single selection case
571 notify = true;
572 }
573 }
574
575 if ( notify )
576 {
577 // notify the user about the selection change
578 SendSelectedEvent();
579 }
580 //else: nothing changed at all
581}
582
e0c6027b 583// ----------------------------------------------------------------------------
be465555 584// keyboard handling
e0c6027b
VZ
585// ----------------------------------------------------------------------------
586
587void wxVListBox::OnKeyDown(wxKeyEvent& event)
588{
970b97a2
VZ
589 // flags for DoHandleItemClick()
590 int flags = ItemClick_Kbd;
591
999836aa 592 int current;
e0c6027b
VZ
593 switch ( event.GetKeyCode() )
594 {
595 case WXK_HOME:
be465555 596 current = 0;
e0c6027b
VZ
597 break;
598
599 case WXK_END:
e02c72fa 600 current = GetRowCount() - 1;
e0c6027b
VZ
601 break;
602
603 case WXK_DOWN:
e02c72fa 604 if ( m_current == (int)GetRowCount() - 1 )
e0c6027b
VZ
605 return;
606
be465555 607 current = m_current + 1;
e0c6027b
VZ
608 break;
609
610 case WXK_UP:
be465555 611 if ( m_current == wxNOT_FOUND )
e02c72fa 612 current = GetRowCount() - 1;
be465555
VZ
613 else if ( m_current != 0 )
614 current = m_current - 1;
615 else // m_current == 0
e0c6027b
VZ
616 return;
617 break;
618
619 case WXK_PAGEDOWN:
e0c6027b 620 PageDown();
e02c72fa 621 current = GetVisibleBegin();
e0c6027b
VZ
622 break;
623
624 case WXK_PAGEUP:
e02c72fa 625 if ( m_current == (int)GetVisibleBegin() )
e0c6027b
VZ
626 {
627 PageUp();
628 }
629
e02c72fa 630 current = GetVisibleBegin();
e0c6027b
VZ
631 break;
632
970b97a2
VZ
633 case WXK_SPACE:
634 // hack: pressing space should work like a mouse click rather than
635 // like a keyboard arrow press, so trick DoHandleItemClick() in
636 // thinking we were clicked
637 flags &= ~ItemClick_Kbd;
638 current = m_current;
639 break;
640
80c700cb
RD
641#ifdef __WXMSW__
642 case WXK_TAB:
643 // Since we are using wxWANTS_CHARS we need to send navigation
644 // events for the tabs on MSW
f029f1d1 645 HandleAsNavigationKey(event);
80c700cb
RD
646 // fall through to default
647#endif
e0c6027b
VZ
648 default:
649 event.Skip();
999836aa 650 current = 0; // just to silent the stupid compiler warnings
8703bc01 651 wxUnusedVar(current);
e0c6027b
VZ
652 return;
653 }
654
970b97a2
VZ
655 if ( event.ShiftDown() )
656 flags |= ItemClick_Shift;
657 if ( event.ControlDown() )
658 flags |= ItemClick_Ctrl;
659
660 DoHandleItemClick(current, flags);
e0c6027b
VZ
661}
662
663// ----------------------------------------------------------------------------
664// wxVListBox mouse handling
665// ----------------------------------------------------------------------------
666
667void wxVListBox::OnLeftDown(wxMouseEvent& event)
668{
c7778877 669 SetFocus();
4e115ed2 670
10368bff 671 int item = VirtualHitTest(event.GetPosition().y);
e0c6027b 672
6c9210a7
VZ
673 if ( item != wxNOT_FOUND )
674 {
970b97a2
VZ
675 int flags = 0;
676 if ( event.ShiftDown() )
677 flags |= ItemClick_Shift;
678
6c9210a7
VZ
679 // under Mac Apple-click is used in the same way as Ctrl-click
680 // elsewhere
be465555 681#ifdef __WXMAC__
970b97a2 682 if ( event.MetaDown() )
be465555 683#else
970b97a2 684 if ( event.ControlDown() )
be465555 685#endif
970b97a2
VZ
686 flags |= ItemClick_Ctrl;
687
688 DoHandleItemClick(item, flags);
6c9210a7 689 }
e0c6027b
VZ
690}
691
4e115ed2 692void wxVListBox::OnLeftDClick(wxMouseEvent& eventMouse)
e0c6027b 693{
10368bff 694 int item = VirtualHitTest(eventMouse.GetPosition().y);
be465555 695 if ( item != wxNOT_FOUND )
e0c6027b 696 {
e0c6027b 697
0975a8a0
JS
698 // if item double-clicked was not yet selected, then treat
699 // this event as a left-click instead
700 if ( item == m_current )
701 {
702 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, GetId());
703 event.SetEventObject(this);
704 event.SetInt(item);
705
706 (void)GetEventHandler()->ProcessEvent(event);
707 }
708 else
709 {
710 OnLeftDown(eventMouse);
711 }
e19ac18a 712
e0c6027b
VZ
713 }
714}
715
dc596072
RD
716
717// ----------------------------------------------------------------------------
718// use the same default attributes as wxListBox
719// ----------------------------------------------------------------------------
720
dc596072
RD
721//static
722wxVisualAttributes
723wxVListBox::GetClassDefaultAttributes(wxWindowVariant variant)
724{
725 return wxListBox::GetClassDefaultAttributes(variant);
726}
179e085f 727
8b939bc0 728#endif