Files
wxWidgets/tests/window/clientsize.cpp
T
Vadim Zeitlin c8003a0a06 Use make_unique<>() instead of "new" in the tests
No real changes, just avoid explicit "new" calls.
2026-09-04 15:24:34 +02:00

184 lines
6.7 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Name: tests/controls/clientsize.cpp
// Purpose: Client vs. window size handling unit test
// Author: Vaclav Slavik
// Created: 2008-02-12
// Copyright: (c) 2008 Vaclav Slavik <vslavik@fastmail.fm>
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "testprec.h"
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/panel.h"
#include "wx/settings.h"
#include "wx/sizer.h"
#include "wx/window.h"
#endif // WX_PRECOMP
#include "wx/scrolwin.h"
#include <memory>
#include "asserthelper.h"
#include "waitfor.h"
// ----------------------------------------------------------------------------
// tests themselves
// ----------------------------------------------------------------------------
TEST_CASE("wxWindow::ClientWindowSizeRoundTrip", "[window][client-size]")
{
wxWindow* const w = wxTheApp->GetTopWindow();
REQUIRE( w );
const wxSize sizeWindow = w->GetSize();
const wxSize sizeClient = w->GetClientSize();
INFO("client size: " << sizeClient);
CHECK( sizeWindow == w->ClientToWindowSize(sizeClient) );
INFO("window size: " << sizeWindow);
CHECK( sizeClient == w->WindowToClientSize(sizeWindow) );
}
TEST_CASE("wxWindow::MinClientSize", "[window][client-size]")
{
auto w = make_unique<wxWindow>(wxTheApp->GetTopWindow(), wxID_ANY,
wxDefaultPosition, wxDefaultSize,
wxBORDER_THEME);
w->SetSize(wxSize(1,1));
const wxSize szw = w->GetClientSize();
CHECK(szw.GetWidth() >= 0);
CHECK(szw.GetHeight() >= 0);
}
TEST_CASE("wxWindow::SetClientSize", "[window][client-size]")
{
#if defined(__WXGTK__)
// Under wxGTK we need to have two children (at least) because if there
// is exactly one child its size is set to fill the whole parent frame
// and the window cannot be resized - see wxTopLevelWindowBase::Layout().
auto w0 = make_unique<wxWindow>(wxTheApp->GetTopWindow(), wxID_ANY);
#endif // wxGTK
auto w = make_unique<wxWindow>(wxTheApp->GetTopWindow(), wxID_ANY);
wxRect reqSize = wxTheApp->GetTopWindow()->GetClientRect();
reqSize.Deflate(25);
w->SetClientSize(reqSize.GetSize());
// Wait for the first paint event to be sure
// that window really has its final size.
WaitForPaint waitForPaint(w.get());
w->Show();
waitForPaint.YieldUntilPainted();
// Check if client size has been set as required.
wxRect r = w->GetClientRect();
CHECK(r.width == reqSize.width);
CHECK(r.height == reqSize.height);
}
// Check that the client size of a scrolled window accounts for the scrollbars
// shown in it.
//
TEST_CASE("wxScrolled::ClientSize", "[window][client-size][scroll]")
{
// Check that the borders, if any, are accounted for correctly too.
const long border = GENERATE(wxBORDER_NONE, wxBORDER_SIMPLE);
INFO("border style " << (border == wxBORDER_NONE ? "none" : "simple"));
// This window is not used for anything, but it must exist to prevent the
// test frame from resizing the panel created below to fill it entirely,
// which is what would happen if the panel were its unique child.
auto const sibling =
make_unique<wxWindow>(wxTheApp->GetTopWindow(), wxID_ANY);
// The scrolled window must be really laid out by its parent for the
// scrollbars to appear, so use a sizer in a panel of our own instead of
// just creating it as a child of the test frame.
auto const parent = make_unique<wxPanel>(wxTheApp->GetTopWindow());
// Make the panel big enough for the scrollbars to fit inside it.
parent->SetSize(wxSize(200, 200));
wxScrolledWindow* const
win = new wxScrolledWindow(parent.get(), wxID_ANY,
wxDefaultPosition, wxDefaultSize,
wxHSCROLL | wxVSCROLL | border);
// Using the scroll rate of 1 pixel makes it simpler to reason about the
// scroll positions below.
win->SetScrollRate(1, 1);
wxSizer* const sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(win, wxSizerFlags(1).Expand());
parent->SetSizer(sizer);
parent->Layout();
YieldForAWhile();
// Don't rely on the window having any particular size, we just need it to
// be big enough for the scrollbars to fit inside it.
const wxSize size = win->GetSize();
INFO("scrolled window size: " << size);
REQUIRE( size.x > 100 );
REQUIRE( size.y > 100 );
// Without any scrollbars the client size is just the total size without
// the borders.
const wxSize sizeClientNoScrollbars = win->GetClientSize();
// GetWindowBorderSize() seems to not return the correct result in wxOSX.
#ifndef __WXOSX__
CHECK( sizeClientNoScrollbars == size - win->GetWindowBorderSize() );
#endif
// Now make the virtual size big enough for both scrollbars to appear.
const wxSize sizeVirtual = 2*size;
win->SetVirtualSize(sizeVirtual);
YieldForAWhile();
REQUIRE( win->GetSize() == size );
CHECK( win->IsScrollbarShown(wxHORIZONTAL) );
CHECK( win->IsScrollbarShown(wxVERTICAL) );
const wxSize sizeClient = win->GetClientSize();
INFO("client size with scrollbars: " << sizeClient);
// The scrollbars either take place inside the window, reducing its client
// area by exactly their size, or are drawn on top of the window contents,
// in which case the client size doesn't change at all: this is the case of
// the overlay scrollbars used by default under macOS and also under GTK.
const wxSize sizeLost = sizeClientNoScrollbars - sizeClient;
INFO("client size lost to the scrollbars: " << sizeLost);
if ( sizeLost != wxSize(0, 0) )
{
const wxSize sizeScrollbar
(
wxSystemSettings::GetMetric(wxSYS_VSCROLL_X, win),
wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y, win)
);
// Allow for a small tolerance because the scrollbars may be separated
// from the window contents by a gap under some platforms.
CHECK( sizeLost.x == Approx(sizeScrollbar.x).margin(4) );
CHECK( sizeLost.y == Approx(sizeScrollbar.y).margin(4) );
}
// In any case, the client size must correspond to the part of the virtual
// area which is really visible, i.e. scrolling to the end must leave
// exactly the client size worth of pixels visible.
win->Scroll(sizeVirtual.x, sizeVirtual.y);
const wxSize sizeScrolled = sizeVirtual - sizeClient;
CHECK( win->GetViewStart() == wxPoint(sizeScrolled.x, sizeScrolled.y) );
}