Files
wxWidgets/samples/wrapsizer/wrapsizer.cpp
T
Richard 7f9a60ce1b Use width-aware sizing in wrapsizer sample
Use GetMinSizeFromKnownDirection() to size the sample initially. This
lets wxWrapSizer compute its height from the chosen width directly,
without an extra layout pass in the constructor.

Fixes #10852.

Closes #27036.
2026-09-22 13:01:48 +02:00

182 lines
5.9 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: wrapsizer.cpp
// Purpose: wxWidgets sample demonstrating wxWrapSizer use
// Author: Arne Steinarson
// Created: 21.01.2008
// Copyright: (c) Arne Steinarson
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/log.h"
#include "wx/wrapsizer.h"
#include "wx/artprov.h"
#ifndef wxHAS_IMAGES_IN_RESOURCES
#include "../sample.xpm"
#endif
// ----------------------------------------------------------------------------
// definitions
// ----------------------------------------------------------------------------
class WrapSizerFrame : public wxFrame
{
public:
WrapSizerFrame();
private:
void OnButton(wxCommandEvent& WXUNUSED(event))
{
Close();
}
void AddToolBarButton(wxToolBar *tb,
const wxString& label,
const wxString& artid)
{
wxBitmap
bm = wxArtProvider::GetBitmap(artid, wxART_TOOLBAR, wxSize(16, 16));
tb->AddTool(wxID_ANY, label, bm);
}
wxToolBar *MakeToolBar()
{
wxToolBar *tb = new wxToolBar(m_panel, wxID_ANY,
wxDefaultPosition, wxDefaultSize,
wxTB_NODIVIDER);
AddToolBarButton(tb, "Help", wxART_HELP_BOOK);
tb->AddSeparator( );
AddToolBarButton(tb, "Open", wxART_FILE_OPEN);
tb->AddSeparator( );
AddToolBarButton(tb, "Up", wxART_GO_DIR_UP);
AddToolBarButton(tb, "Execute", wxART_EXECUTABLE_FILE);
tb->Realize( );
return tb;
}
wxPanel *m_panel;
};
class WrapSizerApp : public wxApp
{
public:
WrapSizerApp() {}
virtual bool OnInit() override
{
new WrapSizerFrame;
return true;
}
};
wxIMPLEMENT_APP(WrapSizerApp);
// ----------------------------------------------------------------------------
// WrapSizerFrame
// ----------------------------------------------------------------------------
WrapSizerFrame::WrapSizerFrame()
: wxFrame(nullptr, wxID_ANY, "wxWrapSizer Sample")
{
SetIcon(wxICON(sample));
m_panel = new wxPanel(this);
// Root sizer, vertical
wxSizer * const sizerRoot = new wxBoxSizer(wxVERTICAL);
// Some toolbars in a wrap sizer
wxSizer * const sizerTop = new wxWrapSizer( wxHORIZONTAL );
sizerTop->Add(MakeToolBar());
sizerTop->Add(20, 1);
sizerTop->Add(MakeToolBar());
sizerTop->Add(20, 1);
sizerTop->Add(MakeToolBar());
sizerRoot->Add(sizerTop, wxSizerFlags().Expand().Border());
// A number of checkboxes inside a wrap sizer
wxStaticBoxSizer *sizerMid = new wxStaticBoxSizer(wxVERTICAL, m_panel,
"With check-boxes");
wxSizer * const sizerMidWrap = new wxWrapSizer(wxHORIZONTAL);
for ( int nCheck = 0; nCheck < 6; nCheck++ )
{
wxCheckBox *chk = new wxCheckBox
(
sizerMid->GetStaticBox(),
wxID_ANY,
wxString::Format("Option %d", nCheck)
);
sizerMidWrap->Add(chk, wxSizerFlags().Centre().Border());
}
sizerMid->Add(sizerMidWrap, wxSizerFlags(100).Expand());
sizerRoot->Add(sizerMid, wxSizerFlags(100).Expand().Border());
// A long wxStaticText that wraps like a wxWrapSizer
sizerRoot->Add( new wxStaticText( m_panel, -1,
"This is very long text that will wrap. This is very long text that will wrap. This is very long text that will wrap.",
wxDefaultPosition, wxDefaultSize, wxST_WRAP
));
// A long wxStaticText that does not wrap
sizerRoot->Add( new wxStaticText( m_panel, -1,
"This is long text that will not wrap. This is long text that will not wrap."
));
// A window of 150px width for comparison.
auto* const ruler = new wxStaticText(m_panel, wxID_ANY, "150px",
wxDefaultPosition, wxSize(150, -1),
wxALIGN_CENTER);
ruler->SetBackgroundColour(*wxYELLOW);
sizerRoot->Add(ruler);
// A long wxStaticText that wraps at 150px
wxStaticText *stattext = new wxStaticText( m_panel, -1, "This is very long text that will wrap at 150px. This is very long text that will wrap at 150px." );
stattext->Wrap( 150 );
sizerRoot->Add( stattext );
// A shaped item inside a box sizer
wxStaticBoxSizer *sizerBottom = new wxStaticBoxSizer(wxVERTICAL, m_panel,
"With wxSHAPED item");
wxSizer *sizerBottomBox = new wxBoxSizer(wxHORIZONTAL);
sizerBottom->Add(sizerBottomBox, wxSizerFlags(100).Expand());
sizerBottomBox->Add(new wxListBox(sizerBottom->GetStaticBox(), wxID_ANY,
wxPoint(0, 0), wxSize(70, 70)),
wxSizerFlags().Expand().Shaped());
sizerBottomBox->AddSpacer(10);
sizerBottomBox->Add(new wxCheckBox(sizerBottom->GetStaticBox(), wxID_ANY,
"A much longer option..."),
wxSizerFlags(100).Border());
sizerRoot->Add(sizerBottom, wxSizerFlags(100).Expand().Border());
// OK Button
sizerRoot->Add(new wxButton(m_panel, wxID_OK),
wxSizerFlags().Centre().DoubleBorder());
Bind(wxEVT_BUTTON, &WrapSizerFrame::OnButton, this, wxID_OK);
// Set sizer for the panel
m_panel->SetSizer(sizerRoot);
wxSize sizeBest = m_panel->GetBestSize();
// wxWrapSizer needs to know the available width to calculate its height.
const wxSize sizeWrapped =
m_panel->GetMinSizeFromKnownDirection(wxHORIZONTAL, sizeBest.x, -1);
if ( sizeWrapped != wxDefaultSize )
sizeBest.y = sizeWrapped.y;
SetClientSize(sizeBest);
Show();
}