WxSplitterWindow

From WxWiki
Jump to: navigation, search

Distributing Window Sizes

When the component windows are resized, the change in size may be given completely to one pane or the other. If you'd like to control how the change in size is distributed between the two windows, use the SetSashGravity() function.

From Chapter 4 of Cross-Platform GUI Programming with wxWidgets: SetSashGravity takes a floating-point argument, which determines the position of the sash as the window is resized. A value of 0.0 (the default) means that only the bottom or right child window will be resized, and a value of 1.0 means that only the top or left child window will be resized. Values in between indicate that the change in size should be distributed between both child windows (a value of 0.5 distributes the size evenly).

Using Sizers in Splitter Windows

The children of a wxSplitterWindow must be instances of the wxWindow class or another class derived from wxWindow such as wxPanel. See the inheritance diagram in the wxWindow Class Reference. In the wxSplitterWindow constructor or the Initialize(), SplitVertically(), SplitHorizontally() and Create() functions you must pass a pointer to a wxWindow base class instance or derivative. A wxSizer pointer argument will not compile.

If you want to do advanced layout in either pane of a wxSplitterWindow, use a wxWindow or derivative as the child of the wxSplitterWindow. Then attach a wxSizer to the wxWindow with the SetSizer() function.

After having searched for such solutions for long time, I worked out two examples to show the systematics:

Example 1 is a simple Splitterwindow with two expanding textfields:

#include <wx/wx.h>
#include <wx/log.h>
#include <wx/textctrl.h>
#include <wx/splitter.h>
#include <wx/sizer.h>
 
 
// Declare the application class
class MyApp : public wxApp
{
public:
    // Called on application startup
    virtual bool OnInit();
};
 
// Declare our main frame class
class MyFrame : public wxFrame
{
public:
    // Constructor
    MyFrame(const wxString& title);
};
 
// Implements MyApp& GetApp()
DECLARE_APP(MyApp)
 
// Give wxWidgets the means to create a MyApp object
IMPLEMENT_APP(MyApp)
 
// Initialize the application
bool MyApp::OnInit()
{
    // Create the main application window
    MyFrame *frame = new MyFrame(wxT("Splitter-Sizer App"));
 
    // Show it
    frame->Show(true);
 
    // Start the event loop
    return true;
}
 
MyFrame::MyFrame(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title)
{
  wxBoxSizer *sizermain = new wxBoxSizer(wxVERTICAL);
  wxSplitterWindow *splittermain = new wxSplitterWindow(this, wxID_ANY);
  splittermain->SetSashGravity(0.5);
  splittermain->SetMinimumPaneSize(20); // Smalest size the
  sizermain->Add(splittermain, 1,wxEXPAND,0);
 
  wxPanel *pnl1 = new wxPanel(splittermain, wxID_ANY);
 
  wxBoxSizer *txt1sizer = new wxBoxSizer(wxVERTICAL);
  wxTextCtrl *txt1 = new wxTextCtrl(pnl1, wxID_ANY);
  txt1sizer->Add(txt1, 1,wxEXPAND,0);
  pnl1->SetSizer(txt1sizer);
 
  wxPanel *pnl2 = new wxPanel(splittermain, wxID_ANY);
 
  wxBoxSizer *txt2sizer = new wxBoxSizer(wxVERTICAL);
  wxTextCtrl *txt2 = new wxTextCtrl(pnl2, wxID_ANY);
  txt2sizer->Add(txt2, 1,wxEXPAND,0);
  pnl2->SetSizer(txt2sizer);
 
  splittermain->SplitVertically(pnl1, pnl2);
 
  this->SetSizer(sizermain);
  sizermain->SetSizeHints(this);
}

The relations of objects and sizers in example 1 are shown in this diagram:

SplitterSizerSimple.png

Example 2 is a Splitterwindow with two textfields with surrounding StaticBoxSizer-Fields:

#include <wx/wx.h>
#include <wx/textctrl.h>
#include <wx/splitter.h>
#include <wx/sizer.h>
 
class MyFrame : public wxFrame
{
  public:
    MyFrame() : wxFrame(NULL, wxID_ANY,  wxT("Splitter-StaticBoxSizer-Sample"), wxPoint(50,50), wxSize(800,600))
    {
 
      wxBoxSizer *mainsizer = new wxBoxSizer(wxHORIZONTAL);
      wxSplitterWindow *splittermain = new wxSplitterWindow(this,wxID_ANY);
      mainsizer->Add(splittermain,1,wxBOTTOM|wxLEFT|wxEXPAND,5);
 
      wxPanel *panelgroup1=new wxPanel(splittermain,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL|wxNO_BORDER);
      wxStaticBoxSizer *group1=new wxStaticBoxSizer(wxVERTICAL,panelgroup1,_T("Group 1"));
      group1->SetMinSize(550,-1);
      wxTextCtrl *txt1=new wxTextCtrl( panelgroup1, 
	wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize,
	wxTE_MULTILINE);
      group1->Add(txt1,1,wxALL|wxEXPAND,5);
      panelgroup1->SetSizer(group1);
 
      wxPanel *panelgroup2=new wxPanel(splittermain,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL|wxNO_BORDER);
      wxStaticBoxSizer *group2=new wxStaticBoxSizer(wxVERTICAL,panelgroup2,_T("Group 2"));
      group2->SetMinSize(550,-1);
      wxTextCtrl *txt2=new wxTextCtrl( panelgroup2, wxID_ANY,
	wxT(""), wxDefaultPosition, wxDefaultSize,
	wxTE_MULTILINE);
      group2->Add(txt2,1,wxALL|wxEXPAND,5);
      panelgroup2->SetSizer(group2);
 
      splittermain->SetSashGravity(1.0);
      splittermain->SplitHorizontally(panelgroup2, panelgroup1);
 
      SetSizer(mainsizer);
      mainsizer->SetSizeHints(this);
    }
};
 
class MyApp: public wxApp
{
 
    wxFrame *frame;
public:
    bool OnInit()
    {
	frame = new MyFrame();
	frame->Show();
	return true;
    }
 
};
 
IMPLEMENT_APP(MyApp)

The relations of objects and sizers in example 2 are shown in this diagram:

SplitterStaticBoxSizer.png


Official Documentation

wxSplitterWindow Class Reference