Auto resize frames and content

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
mikegl
Earned a small fee
Earned a small fee
Posts: 16
Joined: Fri Jul 12, 2019 12:31 am

Auto resize frames and content

Post by mikegl »

Hello, at first this is my first post and I would like to thank the developers of wxWidgets for the awesome free GUI library which can be used for commercial purposes, too.

I have created a wxFrame which contains two panels one at the left side (containing a glcanvas) and one on the right side (containing a quit button). I have set the mainframe to be resizable. The problem is that if I resize the whole app window then the content doesn't get resized, too. Is there a flag which does this automatically or do I have to handle the wxEVT_SIZE event myself?. Thank you for help.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Auto resize frames and content

Post by doublemax »

wxWidgets uses so called "sizers" for this (classes that derive from wxSizer). There are different kind of sizers for different tasks.

https://docs.wxwidgets.org/trunk/overview_sizer.html
http://neume.sourceforge.net/sizerdemo/

If you happen to be familiar with HTML, sizers work similar to old HTML tables, or flexbox and grid in modern HTML.
Use the source, Luke!
mikegl
Earned a small fee
Earned a small fee
Posts: 16
Joined: Fri Jul 12, 2019 12:31 am

Re: Auto resize frames and content

Post by mikegl »

Ok Thank you I have managed to get the minimal size using the SetSizeHints, but when I want to do this in OnSize to handle the wxEVT_SIZE I cannot expand the window. Nonetheless, I will read through your provided links and hope get it fixed.

Yes, I know HTML and as I know sizers are getting implemented in Qt, too.

Thanks again
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Auto resize frames and content

Post by doublemax »

When using sizers, you don't have to catch the wxEVT_SIZE event. It's all handled for you.

BUT: If you catch wxEVT_SIZE for another, additional reason, you must call event.Skip() inside the event handler, otherwise the default handling (in this case the sizer layout) is not happening.
Use the source, Luke!
mikegl
Earned a small fee
Earned a small fee
Posts: 16
Joined: Fri Jul 12, 2019 12:31 am

Re: Auto resize frames and content

Post by mikegl »

I have removed the event handling for the size but still,it doesn't work. Here is my code which handles the sizer:

Code: Select all

GLFrame::GLFrame(wxWindow* parent, const std::wstring& title, const wxPoint& pos, const wxSize& size)
	:wxFrame(parent, wxID_ANY, title, pos, size, wxDEFAULT_FRAME_STYLE)
{	
	wxBoxSizer* hbox = new wxBoxSizer(wxHORIZONTAL);

	wxPanel* panelCanvas = new wxPanel(this, wxID_ANY, { 0,0 }, {1024, 768});
	GLCanvas* glCanvas = new GLCanvas(panelCanvas, ID_GLCANVAS, nullptr, { 0, 0 }, { 1024, 768 });
	
	wxPanel* panelBtn = new wxPanel(this, wxID_ANY, { 1025, 0 }, {150, 70});
	wxButton* btn = new wxButton(panelBtn, wxID_ANY, L"Quit", { 1, 0 }, {148, 71});

	Connect(wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GLFrame::OnQuit));
	
	hbox->Add(panelCanvas);
	hbox->Add(panelBtn);
	
	// Auto resize
	wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
	sizer->Add(hbox);
	sizer->SetSizeHints(this);
	SetSizer(sizer);

	Fit();
	Centre();
}
And here is a screenshot of the problem:
https://imgur.com/SyzK8BJ
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Auto resize frames and content

Post by doublemax »

Written blindly (without being able to compile and test), but you should get the idea:

Code: Select all

GLFrame::GLFrame(wxWindow* parent, const std::wstring& title, const wxPoint& pos, const wxSize& size)
  :wxFrame(parent, wxID_ANY, title, pos, size, wxDEFAULT_FRAME_STYLE)
{ 
  wxBoxSizer* mainSizer = new wxBoxSizer(wxHORIZONTAL);

  wxPanel *mainPanel = new wxPanel( this, wxID_ANY );
  
  // when using sizers, they will control the position and size of a window
  // the  { 1024, 768 } will only set the minimum size in this case
  GLCanvas* glCanvas = new GLCanvas(mainPanel, ID_GLCANVAS, nullptr, wxDefaultPosition, { 1024, 768 });
  mainSizer->Add( glCanvas, 1, wxEXPAND );
  
  wxButton* btn = new wxButton(mainPanel, wxID_ANY, L"Quit" );
  mainSizer->Add( btn, 0 );

  Connect(wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GLFrame::OnQuit));
  
  mainPanel->SetSizer( mainSizer );

  Fit();
  Centre();
}
Last edited by doublemax on Fri Jul 12, 2019 7:46 pm, edited 1 time in total.
Reason: fix error in code
Use the source, Luke!
mikegl
Earned a small fee
Earned a small fee
Posts: 16
Joined: Fri Jul 12, 2019 12:31 am

Re: Auto resize frames and content

Post by mikegl »

Awesome thank you that did the job (In your code I had only to replace mainSizer->Add(glCanvas, 0) with btn because I got an error of adding the same window twice, but I go the idea) :). In addition, thank you for your quick help.
Post Reply