diff --git a/docs/changes.txt b/docs/changes.txt index 4c69315fbd..52c8093504 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -102,6 +102,7 @@ wxMSW: - Add wxThread::MSWGetHandle() (troelsk). - Allow using sizers for laying out wxMDIClientWindow (Artur Wieczorek). - Fix updating wxSlider background when its parent background changes. +- Implement wxListBox::EnsureVisible() (RIVDSL). wxOSX/Cocoa: diff --git a/include/wx/msw/listbox.h b/include/wx/msw/listbox.h index 8d8bd01a87..1181d0fc89 100644 --- a/include/wx/msw/listbox.h +++ b/include/wx/msw/listbox.h @@ -93,6 +93,8 @@ public: int HitTest(const wxPoint& pt) const { return DoHitTestList(pt); } int HitTest(wxCoord x, wxCoord y) const { return DoHitTestList(wxPoint(x, y)); } + virtual void EnsureVisible(int n); + // ownerdrawn wxListBox and wxCheckListBox support #if wxUSE_OWNER_DRAWN // override base class virtuals diff --git a/interface/wx/listbox.h b/interface/wx/listbox.h index e16f32abde..729e22b79c 100644 --- a/interface/wx/listbox.h +++ b/interface/wx/listbox.h @@ -285,12 +285,8 @@ public: /** Ensure that the item with the given index is currently shown. - Scroll the listbox if necessary. - - This method is currently only implemented in wxGTK and wxOSX and does - nothing in other ports. - - @see SetFirstItem() + This method scrolls the listbox only if necessary and doesn't do + anything if this item is already shown, unlike SetFirstItem(). */ virtual void EnsureVisible(int n); diff --git a/src/msw/listbox.cpp b/src/msw/listbox.cpp index aa1a3ef367..2969989031 100644 --- a/src/msw/listbox.cpp +++ b/src/msw/listbox.cpp @@ -221,6 +221,38 @@ void wxListBox::MSWOnItemsChanged() // implementation of wxListBoxBase methods // ---------------------------------------------------------------------------- +void wxListBox::EnsureVisible(int n) +{ + wxCHECK_RET( IsValid(n), + wxT("invalid index in wxListBox::EnsureVisible") ); + + // when item is before the first visible item, make the item the first visible item + const int firstItem = SendMessage(GetHwnd(), LB_GETTOPINDEX, 0, 0); + if ( n <= firstItem ) + { + DoSetFirstItem(n); + return; + } + + // retrieve item height in order to compute last visible item and scroll amount + const int itemHeight = SendMessage(GetHwnd(), LB_GETITEMHEIGHT, 0, 0); + if ( itemHeight == LB_ERR || itemHeight == 0) + return; + + // compute the amount of fully visible items + int countVisible = GetClientSize().y / itemHeight; + if ( !countVisible ) + countVisible = 1; + + // when item is before the last fully visible item, it is already visible + const int lastItem = firstItem + countVisible - 1; + if ( n <= lastItem ) + return; + + // make the item the last visible item by setting the first visible item accordingly + DoSetFirstItem(n - countVisible + 1); +} + void wxListBox::DoSetFirstItem(int N) { wxCHECK_RET( IsValid(N),