diff --git a/docs/changes.txt b/docs/changes.txt index 4f4e8a5f92..398c252233 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -96,6 +96,7 @@ All (GUI): - Allow customizing window shown by wxBusyInfo. - Add wxAddRemoveCtrl. - Add wxAppProgressIndicator for MSW (Chaobin Zhang) and OS X (Tobias Taschner). +- Add wxListBox::GetTopItem() and GetCountPerPage() (Andreas Falkenhahn). - Add wxTextEntry::ForceUpper(). - Add wxTextEntryDialog::ForceUpper(). - Add wxEVT_MAGNIFY mouse event (Joost Nieuwenhuijse). diff --git a/include/wx/gtk/listbox.h b/include/wx/gtk/listbox.h index 323ca9d9be..a99dca5c43 100644 --- a/include/wx/gtk/listbox.h +++ b/include/wx/gtk/listbox.h @@ -74,6 +74,8 @@ public: virtual void EnsureVisible(int n) wxOVERRIDE; + virtual int GetTopItem() const wxOVERRIDE; + virtual void Update() wxOVERRIDE; static wxVisualAttributes diff --git a/include/wx/listbox.h b/include/wx/listbox.h index e602f624ed..8f649e75a7 100644 --- a/include/wx/listbox.h +++ b/include/wx/listbox.h @@ -72,6 +72,9 @@ public: // necessary virtual void EnsureVisible(int n); + virtual int GetTopItem() const { return wxNOT_FOUND; } + virtual int GetCountPerPage() const; + // a combination of Append() and EnsureVisible(): appends the item to the // listbox and ensures that it is visible i.e. not scrolled out of view void AppendAndEnsureVisible(const wxString& s); @@ -133,6 +136,8 @@ protected: // single selection mode on platforms other than MSW). void UpdateOldSelections(); + wxCoord GetLineHeight() const; + private: wxDECLARE_NO_COPY_CLASS(wxListBoxBase); }; diff --git a/include/wx/msw/listbox.h b/include/wx/msw/listbox.h index c64b63e394..ffd8b68752 100644 --- a/include/wx/msw/listbox.h +++ b/include/wx/msw/listbox.h @@ -95,6 +95,9 @@ public: virtual void EnsureVisible(int n); + virtual int GetTopItem() const; + virtual int GetCountPerPage() const; + // ownerdrawn wxListBox and wxCheckListBox support #if wxUSE_OWNER_DRAWN // override base class virtuals diff --git a/include/wx/osx/core/private.h b/include/wx/osx/core/private.h index 9d0acb46b1..5d91413470 100644 --- a/include/wx/osx/core/private.h +++ b/include/wx/osx/core/private.h @@ -609,6 +609,7 @@ public: // display virtual void ListScrollTo( unsigned int n ) = 0; + virtual int ListGetTopItem() const = 0; virtual void UpdateLine( unsigned int n, wxListWidgetColumn* col = NULL ) = 0; virtual void UpdateLineToEnd( unsigned int n) = 0; diff --git a/include/wx/osx/listbox.h b/include/wx/osx/listbox.h index 5219df8fde..53fd434d97 100644 --- a/include/wx/osx/listbox.h +++ b/include/wx/osx/listbox.h @@ -108,6 +108,8 @@ public: virtual void EnsureVisible(int n) wxOVERRIDE; + virtual int GetTopItem() const wxOVERRIDE; + virtual wxVisualAttributes GetDefaultAttributes() const wxOVERRIDE { return GetClassDefaultAttributes(GetWindowVariant()); diff --git a/interface/wx/listbox.h b/interface/wx/listbox.h index 729e22b79c..aa3e0bb313 100644 --- a/interface/wx/listbox.h +++ b/interface/wx/listbox.h @@ -297,10 +297,29 @@ public: */ virtual bool IsSorted() const; + /** + Return the number of items that can fit vertically in the visible area of + the listbox. + + Returns -1 if the number of items per page couldn't be determined. + + @since 3.1.0 + */ + int GetCountPerPage() const; + + /** + Return the index of the topmost visible item. + + Returns ::wxNOT_FOUND if the method is not implemented for the current + platform. + + @since 3.1.0 + */ + int GetTopItem() const; // NOTE: Phoenix needs to see the implementation of pure virtuals so it // knows that this class is not abstract. - virtual unsigned int GetCount() const; + virtual unsigned int GetCount() const; virtual wxString GetString(unsigned int n) const; virtual void SetString(unsigned int n, const wxString& s); virtual int FindString(const wxString& s, bool bCase = false) const; diff --git a/samples/widgets/listbox.cpp b/samples/widgets/listbox.cpp index e4a5749cc6..fba1742286 100644 --- a/samples/widgets/listbox.cpp +++ b/samples/widgets/listbox.cpp @@ -69,7 +69,9 @@ enum ListboxPage_Listbox, ListboxPage_EnsureVisible, ListboxPage_EnsureVisibleText, - ListboxPage_ContainerTests + ListboxPage_ContainerTests, + ListboxPage_GetTopItem, + ListboxPage_GetCountPerPage }; // ---------------------------------------------------------------------------- @@ -99,6 +101,8 @@ protected: void OnButtonAdd(wxCommandEvent& event); void OnButtonAddSeveral(wxCommandEvent& event); void OnButtonAddMany(wxCommandEvent& event); + void OnButtonTopItem(wxCommandEvent& event); + void OnButtonPageCount(wxCommandEvent& event); void OnListbox(wxCommandEvent& event); void OnListboxDClick(wxCommandEvent& event); @@ -186,6 +190,8 @@ wxBEGIN_EVENT_TABLE(ListboxWidgetsPage, WidgetsPage) EVT_BUTTON(ListboxPage_AddSeveral, ListboxWidgetsPage::OnButtonAddSeveral) EVT_BUTTON(ListboxPage_AddMany, ListboxWidgetsPage::OnButtonAddMany) EVT_BUTTON(ListboxPage_ContainerTests, ItemContainerWidgetsPage::OnButtonTestItemContainer) + EVT_BUTTON(ListboxPage_GetTopItem, ListboxWidgetsPage::OnButtonTopItem) + EVT_BUTTON(ListboxPage_GetCountPerPage, ListboxWidgetsPage::OnButtonPageCount) EVT_TEXT_ENTER(ListboxPage_AddText, ListboxWidgetsPage::OnButtonAdd) EVT_TEXT_ENTER(ListboxPage_DeleteText, ListboxWidgetsPage::OnButtonDelete) @@ -333,6 +339,12 @@ void ListboxWidgetsPage::CreateContent() btn = new wxButton(this, ListboxPage_Clear, wxT("&Clear")); sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); + btn = new wxButton(this, ListboxPage_GetTopItem, wxT("Get top item")); + sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); + + btn = new wxButton(this, ListboxPage_GetCountPerPage, wxT("Get count per page")); + sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); + btn = new wxButton(this, ListboxPage_ContainerTests, wxT("Run &tests")); sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5); @@ -514,6 +526,18 @@ void ListboxWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event)) m_lbox->Clear(); } +void ListboxWidgetsPage::OnButtonTopItem(wxCommandEvent& WXUNUSED(event)) +{ + int item = m_lbox->GetTopItem(); + wxLogMessage("Topmost visible item is: %d", item); +} + +void ListboxWidgetsPage::OnButtonPageCount(wxCommandEvent& WXUNUSED(event)) +{ + int count = m_lbox->GetCountPerPage(); + wxLogMessage("%d items fit into this listbox.", count); +} + void ListboxWidgetsPage::OnButtonAdd(wxCommandEvent& WXUNUSED(event)) { static unsigned int s_item = 0; diff --git a/src/common/lboxcmn.cpp b/src/common/lboxcmn.cpp index 45a4ea82aa..748db330c8 100644 --- a/src/common/lboxcmn.cpp +++ b/src/common/lboxcmn.cpp @@ -33,6 +33,15 @@ #include "wx/log.h" #endif +// the spacing between the lines (in report mode) +static const int LINE_SPACING = 0; + +#ifdef __WXGTK__ +static const int EXTRA_HEIGHT = 6; +#else +static const int EXTRA_HEIGHT = 4; +#endif + extern WXDLLEXPORT_DATA(const char) wxListBoxNameStr[] = "listBox"; // ============================================================================ @@ -340,4 +349,23 @@ void wxListBoxBase::EnsureVisible(int WXUNUSED(n)) // call SetFirstItem() but this is probably even more stupid) } +wxCoord wxListBoxBase::GetLineHeight() const +{ + wxListBoxBase *self = wxConstCast(this, wxListBoxBase); + + wxClientDC dc( self ); + dc.SetFont( GetFont() ); + + wxCoord y; + dc.GetTextExtent(wxT("H"), NULL, &y); + + y += EXTRA_HEIGHT; + + return y + LINE_SPACING; +} + +int wxListBoxBase::GetCountPerPage() const +{ + return GetClientSize().y / GetLineHeight(); +} #endif // wxUSE_LISTBOX diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp index 952b509161..4d53d7779a 100644 --- a/src/gtk/listbox.cpp +++ b/src/gtk/listbox.cpp @@ -771,6 +771,24 @@ void wxListBox::EnsureVisible(int n) DoScrollToCell(n, 0.5, 0); } +int wxListBox::GetTopItem() const +{ + int idx = wxNOT_FOUND; + + GtkTreePath *start; + if ( gtk_tree_view_get_visible_range(m_treeview, &start, NULL) ) + { + gint *ptr = gtk_tree_path_get_indices(start); + + if ( ptr ) + idx = *ptr; + + gtk_tree_path_free(start); + } + + return idx; +} + // ---------------------------------------------------------------------------- // hittest // ---------------------------------------------------------------------------- diff --git a/src/msw/listbox.cpp b/src/msw/listbox.cpp index 551cc579b8..a99c1ff7e6 100644 --- a/src/msw/listbox.cpp +++ b/src/msw/listbox.cpp @@ -253,6 +253,22 @@ void wxListBox::EnsureVisible(int n) DoSetFirstItem(n - countVisible + 1); } +int wxListBox::GetTopItem() const +{ + return SendMessage(GetHwnd(), LB_GETTOPINDEX, 0, 0); +} + +int wxListBox::GetCountPerPage() const +{ + const LRESULT lineHeight = SendMessage(GetHwnd(), LB_GETITEMHEIGHT, 0, 0); + if ( lineHeight == LB_ERR || lineHeight == 0 ) + return -1; + + const RECT r = wxGetClientRect(GetHwnd()); + + return (r.bottom - r.top) / lineHeight; +} + void wxListBox::DoSetFirstItem(int N) { wxCHECK_RET( IsValid(N), diff --git a/src/osx/cocoa/listbox.mm b/src/osx/cocoa/listbox.mm index 7966d70223..44b5e50b61 100644 --- a/src/osx/cocoa/listbox.mm +++ b/src/osx/cocoa/listbox.mm @@ -129,6 +129,8 @@ public : virtual void ListScrollTo( unsigned int n ) wxOVERRIDE ; + virtual int ListGetTopItem() conswxOVERRIDE t; + // accessing content virtual unsigned int ListGetCount() const wxOVERRIDE ; @@ -534,6 +536,13 @@ void wxListWidgetCocoaImpl::ListScrollTo( unsigned int n ) [m_tableView scrollRowToVisible:n]; } +int wxListWidgetCocoaImpl::ListGetTopItem() const +{ + NSScrollView *scrollView = [m_tableView enclosingScrollView]; + NSRect visibleRect = scrollView.contentView.visibleRect; + NSRange range = [m_tableView rowsInRect:visibleRect]; + return range.location; +} void wxListWidgetCocoaImpl::UpdateLine( unsigned int WXUNUSED(n), wxListWidgetColumn* WXUNUSED(col) ) { diff --git a/src/osx/listbox_osx.cpp b/src/osx/listbox_osx.cpp index 131e85f0f7..82c9de9d07 100644 --- a/src/osx/listbox_osx.cpp +++ b/src/osx/listbox_osx.cpp @@ -145,6 +145,11 @@ void wxListBox::EnsureVisible(int n) GetListPeer()->ListScrollTo( n ); } +int wxListBox::GetTopItem() const +{ + return GetListPeer()->ListGetTopItem(); +} + void wxListBox::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::Delete") );