305 lines
9.0 KiB
C++
305 lines
9.0 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: tests/controls/notebooktest.cpp
|
|
// Purpose: wxNotebook unit test
|
|
// Author: Steven Lamerton
|
|
// Created: 2010-07-02
|
|
// Copyright: (c) 2010 Steven Lamerton
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "testprec.h"
|
|
|
|
#if wxUSE_NOTEBOOK
|
|
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/app.h"
|
|
#include "wx/panel.h"
|
|
#endif // WX_PRECOMP
|
|
|
|
#include "wx/notebook.h"
|
|
|
|
#include "asserthelper.h"
|
|
#include "bookctrlbasetest.h"
|
|
#include "testableframe.h"
|
|
|
|
#include <memory>
|
|
|
|
class NotebookTestCase : public BookCtrlBaseTestCase, public CppUnit::TestCase
|
|
{
|
|
public:
|
|
NotebookTestCase() { m_notebook = nullptr; m_numPageChanges = 0; }
|
|
|
|
virtual void setUp() override;
|
|
virtual void tearDown() override;
|
|
|
|
private:
|
|
virtual wxBookCtrlBase *GetBase() const override { return m_notebook; }
|
|
|
|
virtual wxEventType GetChangedEvent() const override
|
|
{ return wxEVT_NOTEBOOK_PAGE_CHANGED; }
|
|
|
|
virtual wxEventType GetChangingEvent() const override
|
|
{ return wxEVT_NOTEBOOK_PAGE_CHANGING; }
|
|
|
|
|
|
CPPUNIT_TEST_SUITE( NotebookTestCase );
|
|
wxBOOK_CTRL_BASE_TESTS();
|
|
CPPUNIT_TEST( Image );
|
|
CPPUNIT_TEST( RowCount );
|
|
CPPUNIT_TEST( NoEventsOnDestruction );
|
|
CPPUNIT_TEST( GetTabRect );
|
|
CPPUNIT_TEST( HitTestFlags );
|
|
CPPUNIT_TEST_SUITE_END();
|
|
|
|
void RowCount();
|
|
void NoEventsOnDestruction();
|
|
void GetTabRect();
|
|
void HitTestFlags();
|
|
|
|
void OnPageChanged(wxNotebookEvent&) { m_numPageChanges++; }
|
|
|
|
wxNotebook *m_notebook;
|
|
|
|
int m_numPageChanges;
|
|
|
|
wxDECLARE_NO_COPY_CLASS(NotebookTestCase);
|
|
};
|
|
|
|
// register in the unnamed registry so that these tests are run by default
|
|
CPPUNIT_TEST_SUITE_REGISTRATION( NotebookTestCase );
|
|
|
|
// also include in its own registry so that these tests can be run alone
|
|
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( NotebookTestCase, "NotebookTestCase" );
|
|
|
|
void NotebookTestCase::setUp()
|
|
{
|
|
m_notebook = new wxNotebook(wxTheApp->GetTopWindow(), wxID_ANY,
|
|
wxDefaultPosition, wxSize(400, 200));
|
|
AddPanels();
|
|
}
|
|
|
|
void NotebookTestCase::tearDown()
|
|
{
|
|
wxDELETE(m_notebook);
|
|
}
|
|
|
|
void NotebookTestCase::RowCount()
|
|
{
|
|
CPPUNIT_ASSERT_EQUAL(1, m_notebook->GetRowCount());
|
|
|
|
#ifdef __WXMSW__
|
|
wxDELETE(m_notebook);
|
|
m_notebook = new wxNotebook(wxTheApp->GetTopWindow(), wxID_ANY,
|
|
wxDefaultPosition, wxSize(400, 200),
|
|
wxNB_MULTILINE);
|
|
|
|
for( unsigned int i = 0; i < 10; i++ )
|
|
{
|
|
m_notebook->AddPage(new wxPanel(m_notebook), "Panel", false, 0);
|
|
}
|
|
|
|
CPPUNIT_ASSERT( m_notebook->GetRowCount() != 1 );
|
|
#endif
|
|
}
|
|
|
|
void NotebookTestCase::NoEventsOnDestruction()
|
|
{
|
|
// We can't use EventCounter helper here as it doesn't deal with the window
|
|
// it's connected to being destroyed during its life-time, so do it
|
|
// manually.
|
|
m_notebook->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED,
|
|
&NotebookTestCase::OnPageChanged, this);
|
|
|
|
// Normally deleting a page before the selected one results in page
|
|
// selection changing and the corresponding event.
|
|
m_notebook->DeletePage(static_cast<size_t>(0));
|
|
CHECK( m_numPageChanges == 1 );
|
|
|
|
// But deleting the entire control shouldn't generate any events, yet it
|
|
// used to do under GTK+ 3 when a page different from the first one was
|
|
// selected.
|
|
m_notebook->ChangeSelection(1);
|
|
m_notebook->Destroy();
|
|
m_notebook = nullptr;
|
|
CHECK( m_numPageChanges == 1 );
|
|
}
|
|
|
|
TEST_CASE("wxNotebook::AddPageEvents", "[wxNotebook][AddPage][event]")
|
|
{
|
|
wxNotebook* const
|
|
notebook = new wxNotebook(wxTheApp->GetTopWindow(), wxID_ANY,
|
|
wxDefaultPosition, wxSize(400, 200));
|
|
std::unique_ptr<wxNotebook> cleanup(notebook);
|
|
|
|
CHECK( notebook->GetSelection() == wxNOT_FOUND );
|
|
|
|
EventCounter countPageChanging(notebook, wxEVT_NOTEBOOK_PAGE_CHANGING);
|
|
EventCounter countPageChanged(notebook, wxEVT_NOTEBOOK_PAGE_CHANGED);
|
|
|
|
// Add the first page, it is special.
|
|
notebook->AddPage(new wxPanel(notebook), "Initial page");
|
|
|
|
// The selection should have been changed.
|
|
CHECK( notebook->GetSelection() == 0 );
|
|
|
|
// But no events should have been generated.
|
|
CHECK( countPageChanging.GetCount() == 0 );
|
|
CHECK( countPageChanged.GetCount() == 0 );
|
|
|
|
|
|
// Add another page without selecting it.
|
|
notebook->AddPage(new wxPanel(notebook), "Unselected page");
|
|
|
|
// Selection shouldn't have changed.
|
|
CHECK( notebook->GetSelection() == 0 );
|
|
|
|
// And no events should have been generated, of course.
|
|
CHECK( countPageChanging.GetCount() == 0 );
|
|
CHECK( countPageChanged.GetCount() == 0 );
|
|
|
|
|
|
// Finally add another page and do select it.
|
|
notebook->AddPage(new wxPanel(notebook), "Selected page", true);
|
|
|
|
// It should have become selected.
|
|
CHECK( notebook->GetSelection() == 2 );
|
|
|
|
// And events for the selection change should have been generated.
|
|
CHECK( countPageChanging.GetCount() == 1 );
|
|
CHECK( countPageChanged.GetCount() == 1 );
|
|
}
|
|
|
|
void NotebookTestCase::GetTabRect()
|
|
{
|
|
wxNotebook *notebook = new wxNotebook(wxTheApp->GetTopWindow(), wxID_ANY,
|
|
wxDefaultPosition, wxSize(400, 200));
|
|
std::unique_ptr<wxNotebook> cleanup(notebook);
|
|
|
|
notebook->AddPage(new wxPanel(notebook), "Page");
|
|
|
|
// 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");
|
|
|
|
const wxRect rectPage = notebook->GetTabRect(0);
|
|
REQUIRE(rectPage.width != 0);
|
|
REQUIRE(rectPage.height != 0);
|
|
|
|
int x = rectPage.x + rectPage.width;
|
|
for ( size_t i = 1; i < notebook->GetPageCount(); i++ )
|
|
{
|
|
wxRect r = notebook->GetTabRect(i);
|
|
|
|
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.
|
|
if ( r == wxRect() )
|
|
{
|
|
WARN("Skipping test for pages after " << i << " under Wine.");
|
|
break;
|
|
}
|
|
}
|
|
|
|
INFO("Page #" << i << ": rect=" << r);
|
|
REQUIRE(r.x == x);
|
|
REQUIRE(r.y == rectPage.y);
|
|
REQUIRE(r.width == rectPage.width);
|
|
REQUIRE(r.height == rectPage.height);
|
|
|
|
x += r.width;
|
|
}
|
|
#else // !(__WXMSW__ || __WXUNIVERSAL__)
|
|
WX_ASSERT_FAILS_WITH_ASSERT( notebook->GetTabRect(0) );
|
|
#endif // ports
|
|
}
|
|
|
|
void NotebookTestCase::HitTestFlags()
|
|
{
|
|
std::unique_ptr<wxNotebook> notebook;
|
|
|
|
#if defined(__WXMSW__) || defined(__WXUNIVERSAL__)
|
|
long style = 0;
|
|
|
|
SECTION("Top") { style = wxBK_TOP; }
|
|
SECTION("Bottom") { style = wxBK_BOTTOM; }
|
|
SECTION("Left") { style = wxBK_LEFT; }
|
|
SECTION("Right") { style = wxBK_RIGHT; }
|
|
|
|
INFO("Style=" << style);
|
|
|
|
const bool isVertical = style == wxBK_TOP || style == wxBK_BOTTOM;
|
|
|
|
// HitTest() uses TCM_HITTEST for the vertical orientations and it doesn't
|
|
// seem to work correctly under Wine, so skip the test there (for the
|
|
// horizontal tabs we use our own code which does work even under Wine).
|
|
if ( isVertical && wxIsRunningUnderWine() )
|
|
return;
|
|
|
|
notebook.reset(new wxNotebook(wxTheApp->GetTopWindow(), wxID_ANY,
|
|
wxPoint(0, 0), wxSize(400, 200),
|
|
style));
|
|
|
|
// Simulate an icon of standard size, its contents doesn't matter.
|
|
const wxSize imageSize(16, 16);
|
|
wxBookCtrlBase::Images images;
|
|
images.push_back(wxBitmapBundle::FromBitmap(wxBitmap(imageSize)));
|
|
notebook->SetImages(images);
|
|
|
|
notebook->AddPage(new wxPanel(notebook.get()), "First Page", false, 0);
|
|
|
|
const wxRect r = notebook->GetTabRect(0);
|
|
INFO("Rect=" << r);
|
|
|
|
wxPoint pt;
|
|
if ( isVertical )
|
|
pt.y = r.y + r.height / 2;
|
|
else
|
|
pt.x = r.x + r.width / 2;
|
|
|
|
int nowhere = 0;
|
|
int onIcon = 0;
|
|
int onLabel = 0;
|
|
int onItem = 0;
|
|
|
|
const int d = isVertical ? r.width : r.height;
|
|
for (int i = 0; i < d; i++)
|
|
{
|
|
long flags = 0;
|
|
notebook->HitTest(pt, &flags);
|
|
|
|
if (flags & wxBK_HITTEST_NOWHERE)
|
|
nowhere++;
|
|
|
|
if (flags & wxBK_HITTEST_ONICON)
|
|
onIcon++;
|
|
|
|
if (flags & wxBK_HITTEST_ONLABEL)
|
|
onLabel++;
|
|
|
|
if (flags & wxBK_HITTEST_ONITEM)
|
|
onItem++;
|
|
|
|
if (isVertical)
|
|
pt.x++;
|
|
else
|
|
pt.y++;
|
|
}
|
|
|
|
CHECK(nowhere);
|
|
CHECK(onIcon);
|
|
CHECK(onLabel);
|
|
CHECK(onItem);
|
|
#else // !(__WXMSW__ || __WXUNIVERSAL__)
|
|
notebook.reset(new wxNotebook(wxTheApp->GetTopWindow(), wxID_ANY,
|
|
wxDefaultPosition, wxSize(400, 200)));
|
|
notebook->AddPage(new wxPanel(notebook.get()), "First Page");
|
|
|
|
WX_ASSERT_FAILS_WITH_ASSERT(notebook->GetTabRect(0));
|
|
#endif // ports
|
|
}
|
|
|
|
#endif //wxUSE_NOTEBOOK
|