Add wxNotebook::GetTabRect() to retrieve the tab position

This function is currently only implemented in wxMSW and wxUniv and just
asserts under the other platforms.

Also add a helper GetTabOrientation().

Update the documentation and add a minimal test case for the new
function.

Closes #22941.
This commit is contained in:
Gerhard Gruber 2022-11-03 23:36:22 +01:00 committed by Vadim Zeitlin
parent b4b23ac423
commit 065ff2d2d8
8 changed files with 114 additions and 22 deletions

View file

@ -93,6 +93,9 @@ public:
// style.
void SetTabSize(const wxSize& sz) override;
// Return the position and size of the tab for the given page
wxRect GetTabRect(size_t page) const override;
// hit test
virtual int HitTest(const wxPoint& pt, long *flags = nullptr) const override;

View file

@ -139,6 +139,13 @@ public:
// new is wxNOT_FOUND)
void SendPageChangedEvent(int nPageOld, int nPageNew = wxNOT_FOUND);
// return wxTOP/wxBOTTOM/wxRIGHT/wxLEFT
wxDirection GetTabOrientation() const;
// return the rectangle in window coordinates of the page selector.
// For example, for a wxNotebook this would be its tab.
virtual wxRect GetTabRect(size_t page) const;
#if wxUSE_EXTENDED_RTTI
// XTI accessors
virtual void AddPageInfo( wxNotebookPageInfo* info );

View file

@ -93,9 +93,6 @@ public:
// return true if all tabs have the same width
bool FixedSizeTabs() const { return HasFlag(wxNB_FIXEDWIDTH); }
// return wxTOP/wxBOTTOM/wxRIGHT/wxLEFT
wxDirection GetTabOrientation() const;
// return true if the notebook has tabs at the sidesand not at the top (or
// bottom) as usual
bool IsVertical() const;
@ -121,6 +118,9 @@ public:
// refresh the currently selected tab
void RefreshCurrent();
// get the tab rect
wxRect GetTabRect(size_t page) const override;
protected:
virtual wxNotebookPage *DoRemovePage(size_t nPage) override;
@ -164,9 +164,6 @@ protected:
// refresh all tabs
void RefreshAllTabs();
// get the tab rect (inefficient, don't use this in a loop)
wxRect GetTabRect(int page) const;
// get the rectangle containing all tabs
wxRect GetAllTabsRect() const;

View file

@ -191,6 +191,30 @@ public:
*/
virtual void SetPadding(const wxSize& padding);
/**
This is a convenience function mapping wxBK_TOP etc styles to one of the
wxDirection enum elements.
@since 3.3.0
*/
wxDirection GetTabOrientation() const;
/**
Return the rectangle of the given page tab in window coordinates.
This function always returns the rectangle for the specified tab, even
if the tab is currently not visible.
If @a page is invalid, an assert failure is triggered and an empty
rectangle is returned.
@note Currently only available in Univ and MSW and always asserts in
the other ports.
@since 3.3.0
*/
virtual wxRect GetTabRect(size_t page) const;
// implementations of pure virtuals
virtual int GetPageImage(size_t nPage) const;
virtual bool SetPageImage(size_t page, int image);

View file

@ -33,6 +33,8 @@
extern WXDLLEXPORT_DATA(const char) wxNotebookNameStr[] = "notebook";
#define IS_VALID_PAGE(nPage) ((nPage) < GetPageCount())
wxDEFINE_EVENT( wxEVT_NOTEBOOK_PAGE_CHANGED, wxBookCtrlEvent );
wxDEFINE_EVENT( wxEVT_NOTEBOOK_PAGE_CHANGING, wxBookCtrlEvent );
@ -197,4 +199,27 @@ void wxNotebookBase::SendPageChangedEvent(int nPageOld, int nPageNew)
GetEventHandler()->ProcessEvent(event);
}
wxDirection wxNotebookBase::GetTabOrientation() const
{
long style = GetWindowStyle();
if ( style & wxBK_BOTTOM )
return wxBOTTOM;
else if ( style & wxBK_RIGHT )
return wxRIGHT;
else if ( style & wxBK_LEFT )
return wxLEFT;
// wxBK_TOP == 0 so we don't have to test for it
return wxTOP;
}
wxRect wxNotebookBase::GetTabRect(size_t page) const
{
wxRect r;
wxCHECK_MSG(IS_VALID_PAGE(page), r, wxT("invalid notebook page"));
wxFAIL_MSG("Not implemented");
return r;
}
#endif // wxUSE_NOTEBOOK

View file

@ -499,6 +499,21 @@ void wxNotebook::SetTabSize(const wxSize& sz)
::SendMessage(GetHwnd(), TCM_SETITEMSIZE, 0, MAKELPARAM(sz.x, sz.y));
}
wxRect wxNotebook::GetTabRect(size_t page) const
{
wxRect r;
wxCHECK_MSG(IS_VALID_PAGE(page), r, wxT("invalid notebook page"));
if (GetPageCount() > 0)
{
RECT rect;
if (TabCtrl_GetItemRect(GetHwnd(), page, &rect))
r = wxRectFromRECT(rect);
}
return r;
}
wxSize wxNotebook::CalcSizeFromPage(const wxSize& sizePage) const
{
// we can't use TabCtrl_AdjustRect here because it only works for wxNB_TOP

View file

@ -659,21 +659,7 @@ bool wxNotebook::IsVertical() const
return dir == wxLEFT || dir == wxRIGHT;
}
wxDirection wxNotebook::GetTabOrientation() const
{
long style = GetWindowStyle();
if ( style & wxBK_BOTTOM )
return wxBOTTOM;
else if ( style & wxBK_RIGHT )
return wxRIGHT;
else if ( style & wxBK_LEFT )
return wxLEFT;
// wxBK_TOP == 0 so we don't have to test for it
return wxTOP;
}
wxRect wxNotebook::GetTabRect(int page) const
wxRect wxNotebook::GetTabRect(size_t page) const
{
wxRect rect;
wxCHECK_MSG( IS_VALID_PAGE(page), rect, wxT("invalid notebook page") );
@ -688,7 +674,7 @@ wxRect wxNotebook::GetTabRect(int page) const
else
{
widthBefore = 0;
for ( int n = 0; n < page; n++ )
for ( size_t n = 0; n < page; n++ )
{
widthBefore += m_widths[n];
}

View file

@ -45,10 +45,12 @@ private:
CPPUNIT_TEST( Image );
CPPUNIT_TEST( RowCount );
CPPUNIT_TEST( NoEventsOnDestruction );
CPPUNIT_TEST( GetTabRect );
CPPUNIT_TEST_SUITE_END();
void RowCount();
void NoEventsOnDestruction();
void GetTabRect();
void OnPageChanged(wxNotebookEvent&) { m_numPageChanges++; }
@ -163,4 +165,37 @@ TEST_CASE("wxNotebook::AddPageEvents", "[wxNotebook][AddPage][event]")
CHECK( countPageChanged.GetCount() == 1 );
}
void NotebookTestCase::GetTabRect()
{
if (wxIsRunningUnderWine())
{
// Wine behaves different than Windows. Windows reports the size of a
// tab even if it is not visible while Wine returns an empty rectangle.
WARN("Skipping test known to fail under Wine.");
return;
}
wxNotebook *notebook = new wxNotebook(wxTheApp->GetTopWindow(), wxID_ANY,
wxDefaultPosition, wxSize(400, 200));
wxScopedPtr<wxNotebook> cleanup(notebook);
notebook->AddPage(new wxPanel(notebook), "First");
// This function is only really implemented for wxMSW and wxUniv currently.
#if defined(__WXMSW__) || defined(__WXUNIVERSAL__)
// Create many pages, so that at least some of the are not visible.
for ( size_t i = 0; i < 30; i++ )
notebook->AddPage(new wxPanel(notebook), "Page");
for ( size_t i = 0; i < notebook->GetPageCount(); i++ )
{
wxRect r = notebook->GetTabRect(i);
CHECK(r.width != 0);
CHECK(r.height != 0);
}
#else // !(__WXMSW__ || __WXUNIVERSAL__)
WX_ASSERT_FAILS_WITH_ASSERT( notebook->GetTabRect(0) );
#endif // ports
}
#endif //wxUSE_NOTEBOOK