1. Split{Horizontal|Vertical} now accept negative args to set the

size of right/lower pane (positive arg sets the size of
   left/upper one as before, 0 is the same as -1 before: choose
   default)

2. OnSashPositionChange() virtual function added - it may return
   FALSE to cancel position change

3. splitter sample and docs (couldn't compile them though) updated


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@901 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 1998-10-23 13:15:15 +00:00
parent a316819695
commit 0d559d69c8
4 changed files with 305 additions and 208 deletions

View File

@ -189,9 +189,25 @@ programmatically or using the wxSplitterWindow user interface.
The default implementation of this function simply hides {\it removed}. You The default implementation of this function simply hides {\it removed}. You
may wish to delete the window. may wish to delete the window.
\membersection{wxSplitterWindow::OnSashPositionChange}\label{wxsplitterwindowonsashpositionchange}
\func{virtual bool}{OnSashPositionChange}{\param{int }{newSashPosition}
Application-overridable function called when the sash position is changed by
user. It may return FALSE to prevent the change or TRUE to allow it.
\wxheading{Parameters}
\docparam{newSashPosition}{The new sash position (always positive or zero)}
\wxheading{Remarks}
The default implementation of this function verifies that the sizes of both
panes of the splitter are greater than minimum pane size.
\wxheading{See also} \wxheading{See also}
\helpref{wxSplitterWindow::Unsplit}{wxsplitterwindowunsplit} \helpref{wxSplitterWindow::GetMinimumPaneSize}{wxsplitterwindowgetminimumpanesize}
\membersection{wxSplitterWindow::SetSashPosition}\label{wxsplitterwindowsetsashposition} \membersection{wxSplitterWindow::SetSashPosition}\label{wxsplitterwindowsetsashposition}
@ -255,7 +271,7 @@ Only sets the internal variable; does not update the display.
\membersection{wxSplitterWindow::SplitHorizontally}\label{wxsplitterwindowsplithorizontally} \membersection{wxSplitterWindow::SplitHorizontally}\label{wxsplitterwindowsplithorizontally}
\func{bool}{SplitHorizontally}{\param{wxWindow* }{window1}, \param{wxWindow* }{window2}, \func{bool}{SplitHorizontally}{\param{wxWindow* }{window1}, \param{wxWindow* }{window2},
\param{int}{ sashPosition = -1}} \param{int}{ sashPosition = 0}}
Initializes the top and bottom panes of the splitter window. Initializes the top and bottom panes of the splitter window.
@ -265,8 +281,10 @@ Initializes the top and bottom panes of the splitter window.
\docparam{window2}{The bottom pane.} \docparam{window2}{The bottom pane.}
\docparam{sashPosition}{The initial position of the sash. If the value is -1, a default position \docparam{sashPosition}{The initial position of the sash. If this value is
is chosen.} positive, it specifies the size of the upper pane. If it's negative, it's
absolute value gives the size of the lower pane. Finally, specify 0 (default)
to choose the default position (half of the total window height).}
\wxheading{Return value} \wxheading{Return value}
@ -274,8 +292,9 @@ TRUE if successful, FALSE otherwise (the window was already split).
\wxheading{Remarks} \wxheading{Remarks}
This should be called if you wish to initially view two panes. It can also be called at any subsequent time, This should be called if you wish to initially view two panes. It can also be
but the application should check that the window is not currently split using \helpref{IsSplit}{wxsplitterwindowissplit}. called at any subsequent time, but the application should check that the
window is not currently split using \helpref{IsSplit}{wxsplitterwindowissplit}.
\wxheading{See also} \wxheading{See also}
@ -285,7 +304,7 @@ but the application should check that the window is not currently split using \h
\membersection{wxSplitterWindow::SplitVertically}\label{wxsplitterwindowsplitvertically} \membersection{wxSplitterWindow::SplitVertically}\label{wxsplitterwindowsplitvertically}
\func{bool}{SplitVertically}{\param{wxWindow* }{window1}, \param{wxWindow* }{window2}, \func{bool}{SplitVertically}{\param{wxWindow* }{window1}, \param{wxWindow* }{window2},
\param{int}{ sashPosition = -1}} \param{int}{ sashPosition = 0}}
Initializes the left and right panes of the splitter window. Initializes the left and right panes of the splitter window.
@ -295,8 +314,10 @@ Initializes the left and right panes of the splitter window.
\docparam{window2}{The right pane.} \docparam{window2}{The right pane.}
\docparam{sashPosition}{The initial position of the sash. If the value is -1, a default position \docparam{sashPosition}{The initial position of the sash. If this value is
is chosen.} positive, it specifies the size of the left pane. If it's negative, it's
absolute value gives the size of the right pane. Finally, specify 0 (default)
to choose the default position (half of the total window width).}
\wxheading{Return value} \wxheading{Return value}

View File

@ -6,7 +6,7 @@
// Created: 01/02/97 // Created: 01/02/97
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Julian Smart and Markus Holzem // Copyright: (c) Julian Smart and Markus Holzem
// Licence: wxWindows license // Licence: wxWindows license
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#ifndef __SPLITTERH_G__ #ifndef __SPLITTERH_G__
@ -46,32 +46,33 @@
class WXDLLEXPORT wxSplitterWindow: public wxWindow class WXDLLEXPORT wxSplitterWindow: public wxWindow
{ {
DECLARE_DYNAMIC_CLASS(wxSplitterWindow) public:
public:
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Public API // Public API
// Default constructor // Default constructor
wxSplitterWindow(void); wxSplitterWindow();
// Normal constructor // Normal constructor
wxSplitterWindow(wxWindow *parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, wxSplitterWindow(wxWindow *parent, wxWindowID id = -1,
const wxSize& size = wxDefaultSize, long style = wxSP_3D|wxCLIP_CHILDREN, const wxString& name = "splitter"); const wxPoint& pos = wxDefaultPosition,
~wxSplitterWindow(void); const wxSize& size = wxDefaultSize,
long style = wxSP_3D|wxCLIP_CHILDREN,
const wxString& name = "splitter");
~wxSplitterWindow();
// Gets the only or left/top pane // Gets the only or left/top pane
inline wxWindow *GetWindow1(void) { return m_windowOne; } wxWindow *GetWindow1() const { return m_windowOne; }
// Gets the right/bottom pane // Gets the right/bottom pane
inline wxWindow *GetWindow2(void) { return m_windowTwo; } wxWindow *GetWindow2() const { return m_windowTwo; }
// Sets the split mode // Sets the split mode
inline void SetSplitMode(int mode) { m_splitMode = mode; } void SetSplitMode(int mode) { m_splitMode = mode; }
// Gets the split mode // Gets the split mode
inline int GetSplitMode(void) const { return m_splitMode; }; int GetSplitMode() const { return m_splitMode; };
// Initialize with one window // Initialize with one window
void Initialize(wxWindow *window); void Initialize(wxWindow *window);
@ -79,38 +80,49 @@ class WXDLLEXPORT wxSplitterWindow: public wxWindow
// Associates the given window with window 2, drawing the appropriate sash // Associates the given window with window 2, drawing the appropriate sash
// and changing the split mode. // and changing the split mode.
// Does nothing and returns FALSE if the window is already split. // Does nothing and returns FALSE if the window is already split.
// A sashPosition of -1 means choose a default sash position. // A sashPosition of 0 means choose a default sash position,
bool SplitVertically(wxWindow *window1, wxWindow *window2, int sashPosition = -1); // negative sashPosition specifies the size of right/lower pane as it's
bool SplitHorizontally(wxWindow *window1, wxWindow *window2, int sashPosition = -1); // absolute value rather than the size of left/upper pane.
bool SplitVertically(wxWindow *window1,
wxWindow *window2,
int sashPosition = 0);
bool SplitHorizontally(wxWindow *window1,
wxWindow *window2,
int sashPosition = 0);
// Removes the specified (or second) window from the view // Removes the specified (or second) window from the view
// Doesn't actually delete the window. // Doesn't actually delete the window.
bool Unsplit(wxWindow *toRemove = (wxWindow *) NULL); bool Unsplit(wxWindow *toRemove = (wxWindow *) NULL);
// Is the window split? // Is the window split?
inline bool IsSplit(void) const { return (m_windowTwo != NULL); } bool IsSplit() const { return (m_windowTwo != NULL); }
// Sets the sash size // Sets the sash size
inline void SetSashSize(int width) { m_sashSize = width; } void SetSashSize(int width) { m_sashSize = width; }
// Sets the border size // Sets the border size
inline void SetBorderSize(int width) { m_borderSize = width; } void SetBorderSize(int width) { m_borderSize = width; }
// Gets the sash size // Gets the sash size
inline int GetSashSize(void) const { return m_sashSize; } int GetSashSize() const { return m_sashSize; }
// Gets the border size // Gets the border size
inline int GetBorderSize(void) const { return m_borderSize; } int GetBorderSize() const { return m_borderSize; }
// Set the sash position // Set the sash position
void SetSashPosition(int position, bool redaw = TRUE); void SetSashPosition(int position, bool redaw = TRUE);
// Gets the sash position // Gets the sash position
inline int GetSashPosition(void) const { return m_sashPosition; } int GetSashPosition() const { return m_sashPosition; }
// If this is zero, we can remove panes by dragging the sash. // If this is zero, we can remove panes by dragging the sash.
inline void SetMinimumPaneSize(int min) { m_minimumPaneSize = min; } void SetMinimumPaneSize(int min) { m_minimumPaneSize = min; }
inline int GetMinimumPaneSize(void) const { return m_minimumPaneSize; } int GetMinimumPaneSize() const { return m_minimumPaneSize; }
// Called when the sash position is about to be changed, return
// FALSE from here to prevent the change from taking place.
// newSashPosition here is always positive or zero.
virtual bool OnSashPositionChange(int newSashPosition);
// If the sash is moved to an extreme position, a subwindow // If the sash is moved to an extreme position, a subwindow
// is removed from the splitter window, and the app is // is removed from the splitter window, and the app is
@ -147,12 +159,12 @@ class WXDLLEXPORT wxSplitterWindow: public wxWindow
bool SashHitTest(int x, int y, int tolerance = 2); bool SashHitTest(int x, int y, int tolerance = 2);
// Resizes subwindows // Resizes subwindows
void SizeWindows(void); void SizeWindows();
// Initialize colours // Initialize colours
void InitColours(void); void InitColours();
protected: protected:
int m_splitMode; int m_splitMode;
wxWindow* m_windowOne; wxWindow* m_windowOne;
wxWindow* m_windowTwo; wxWindow* m_windowTwo;
@ -174,7 +186,10 @@ class WXDLLEXPORT wxSplitterWindow: public wxWindow
wxPen* m_hilightPen; wxPen* m_hilightPen;
wxBrush* m_faceBrush; wxBrush* m_faceBrush;
wxPen* m_facePen; wxPen* m_facePen;
DECLARE_EVENT_TABLE()
private:
DECLARE_DYNAMIC_CLASS(wxSplitterWindow)
DECLARE_EVENT_TABLE()
}; };
#endif #endif // __SPLITTERH_G__

View File

@ -1,12 +1,12 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: splitter.cpp // Name: m_splitter.cpp
// Purpose: wxSplitterWindow sample // Purpose: wxSplitterWindow sample
// Author: Julian Smart // Author: Julian Smart
// Modified by: // Modified by:
// Created: 04/01/98 // Created: 04/01/98
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Julian Smart and Markus Holzem // Copyright: (c) Julian Smart and Markus Holzem
// Licence: wxWindows license // Licence: wxWindows license
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h". // For compilers that support precompilation, includes "wx/wx.h".
@ -29,36 +29,61 @@ class MyCanvas;
class MyApp: public wxApp class MyApp: public wxApp
{ {
public: public:
bool OnInit(); bool OnInit();
};
class MySplitterWindow : public wxSplitterWindow
{
public:
MySplitterWindow(wxFrame *parent, wxWindowID id) : wxSplitterWindow(parent, id)
{
m_frame = parent;
}
virtual bool OnSashPositionChange(int newSashPosition)
{
if ( !wxSplitterWindow::OnSashPositionChange(newSashPosition) )
return FALSE;
wxString str;
str.Printf("Sash position = %d", newSashPosition);
m_frame->SetStatusText(str);
return TRUE;
}
private:
wxFrame *m_frame;
}; };
class MyFrame: public wxFrame class MyFrame: public wxFrame
{ {
public: public:
MyFrame(wxFrame* frame, const wxString& title, const wxPoint& pos, const wxSize& size); MyFrame(wxFrame* frame, const wxString& title, const wxPoint& pos, const wxSize& size);
virtual ~MyFrame(); virtual ~MyFrame();
bool OnClose(); bool OnClose();
// Menu commands // Menu commands
void SplitHorizontal(wxCommandEvent& event); void SplitHorizontal(wxCommandEvent& event);
void SplitVertical(wxCommandEvent& event); void SplitVertical(wxCommandEvent& event);
void Unsplit(wxCommandEvent& event); void Unsplit(wxCommandEvent& event);
void Quit(wxCommandEvent& event); void SetMinSize(wxCommandEvent& event);
void Quit(wxCommandEvent& event);
// Menu command update functions // Menu command update functions
void UpdateUIHorizontal(wxUpdateUIEvent& event); void UpdateUIHorizontal(wxUpdateUIEvent& event);
void UpdateUIVertical(wxUpdateUIEvent& event); void UpdateUIVertical(wxUpdateUIEvent& event);
void UpdateUIUnsplit(wxUpdateUIEvent& event); void UpdateUIUnsplit(wxUpdateUIEvent& event);
void OnIdle(wxIdleEvent& event);
private: private:
wxMenu* fileMenu; void UpdatePosition();
wxMenuBar* menuBar;
MyCanvas* leftCanvas; wxMenu* fileMenu;
MyCanvas* rightCanvas; wxMenuBar* menuBar;
wxSplitterWindow* splitter; MyCanvas* m_leftCanvas;
MyCanvas* m_rightCanvas;
MySplitterWindow* m_splitter;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
@ -69,7 +94,7 @@ public:
MyCanvas(wxWindow* parent, wxWindowID id, int x, int y, int w, int h); MyCanvas(wxWindow* parent, wxWindowID id, int x, int y, int w, int h);
virtual ~MyCanvas(); virtual ~MyCanvas();
virtual void OnDraw(wxDC& dc); virtual void OnDraw(wxDC& dc);
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
@ -77,11 +102,15 @@ DECLARE_EVENT_TABLE()
BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
END_EVENT_TABLE() END_EVENT_TABLE()
// ID for the menu quit command // ID for the menu commands
#define SPLIT_QUIT 1 enum
#define SPLIT_HORIZONTAL 2 {
#define SPLIT_VERTICAL 3 SPLIT_QUIT,
#define SPLIT_UNSPLIT 4 SPLIT_HORIZONTAL,
SPLIT_VERTICAL,
SPLIT_UNSPLIT,
SPLIT_SETMINSIZE
};
// Window ids // Window ids
#define SPLITTER_WINDOW 100 #define SPLITTER_WINDOW 100
@ -93,68 +122,63 @@ IMPLEMENT_APP(MyApp)
bool MyApp::OnInit(void) bool MyApp::OnInit(void)
{ {
MyFrame* frame = new MyFrame((wxFrame *) NULL, (char *) "wxSplitterWindow Example", wxPoint(50, 50), wxSize(400, 300)); MyFrame* frame = new MyFrame((wxFrame *) NULL, "wxSplitterWindow Example",
wxPoint(50, 50), wxSize(420, 300));
// Show the frame // Show the frame
frame->Show(TRUE); frame->Show(TRUE);
SetTopWindow(frame); SetTopWindow(frame);
return TRUE; return TRUE;
} }
BEGIN_EVENT_TABLE(MyFrame, wxFrame) BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(SPLIT_VERTICAL, MyFrame::SplitVertical) EVT_MENU(SPLIT_VERTICAL, MyFrame::SplitVertical)
EVT_MENU(SPLIT_HORIZONTAL, MyFrame::SplitHorizontal) EVT_MENU(SPLIT_HORIZONTAL, MyFrame::SplitHorizontal)
EVT_MENU(SPLIT_UNSPLIT, MyFrame::Unsplit) EVT_MENU(SPLIT_UNSPLIT, MyFrame::Unsplit)
EVT_MENU(SPLIT_QUIT, MyFrame::Quit) EVT_MENU(SPLIT_QUIT, MyFrame::Quit)
EVT_UPDATE_UI(SPLIT_VERTICAL, MyFrame::UpdateUIVertical) EVT_MENU(SPLIT_SETMINSIZE, MyFrame::SetMinSize)
EVT_UPDATE_UI(SPLIT_HORIZONTAL, MyFrame::UpdateUIHorizontal)
EVT_UPDATE_UI(SPLIT_UNSPLIT, MyFrame::UpdateUIUnsplit) EVT_UPDATE_UI(SPLIT_VERTICAL, MyFrame::UpdateUIVertical)
EVT_IDLE(MyFrame::OnIdle) EVT_UPDATE_UI(SPLIT_HORIZONTAL, MyFrame::UpdateUIHorizontal)
EVT_UPDATE_UI(SPLIT_UNSPLIT, MyFrame::UpdateUIUnsplit)
END_EVENT_TABLE() END_EVENT_TABLE()
// My frame constructor // My frame constructor
MyFrame::MyFrame(wxFrame* frame, const wxString& title, const wxPoint& pos, const wxSize& size): MyFrame::MyFrame(wxFrame* frame, const wxString& title, const wxPoint& pos, const wxSize& size):
wxFrame(frame, SPLITTER_FRAME, title, pos, size) wxFrame(frame, SPLITTER_FRAME, title, pos, size)
{ {
// set the icon CreateStatusBar(2);
#ifdef __WXMSW__
SetIcon(wxIcon("mondrian"));
#endif
CreateStatusBar(1); // Make a menubar
fileMenu = new wxMenu;
fileMenu->Append(SPLIT_VERTICAL, "Split &Vertically", "Split vertically");
fileMenu->Append(SPLIT_HORIZONTAL, "Split &Horizontally", "Split horizontally");
fileMenu->Append(SPLIT_UNSPLIT, "&Unsplit", "Unsplit");
fileMenu->AppendSeparator();
fileMenu->Append(SPLIT_SETMINSIZE, "Set &min size", "Set minimum pane size");
fileMenu->AppendSeparator();
fileMenu->Append(SPLIT_QUIT, "E&xit", "Exit");
// Make a menubar menuBar = new wxMenuBar;
fileMenu = new wxMenu; menuBar->Append(fileMenu, "&File");
fileMenu->Append(SPLIT_VERTICAL, "Split &Vertically", "Split vertically");
fileMenu->Append(SPLIT_HORIZONTAL, "Split &Horizontally", "Split horizontally");
fileMenu->Append(SPLIT_UNSPLIT, "&Unsplit", "Unsplit");
fileMenu->Append(SPLIT_QUIT, "E&xit", "Exit");
menuBar = new wxMenuBar; SetMenuBar(menuBar);
menuBar->Append(fileMenu, "&File");
SetMenuBar(menuBar); m_splitter = new MySplitterWindow(this, SPLITTER_WINDOW);
splitter = new wxSplitterWindow(this, SPLITTER_WINDOW, wxPoint(0, 0), wxSize(400, 400), m_leftCanvas = new MyCanvas(m_splitter, CANVAS1, 0, 0, 400, 400);
// wxSP_BORDER); m_leftCanvas->SetBackgroundColour(*wxRED);
wxSP_3D); m_leftCanvas->SetScrollbars(20, 20, 50, 50);
// wxSP_NOBORDER);
leftCanvas = new MyCanvas(splitter, CANVAS1, 0, 0, 400, 400); m_rightCanvas = new MyCanvas(m_splitter, CANVAS2, 0, 0, 400, 400);
leftCanvas->SetBackgroundColour(*wxRED); m_rightCanvas->SetBackgroundColour(*wxCYAN);
leftCanvas->SetScrollbars(20, 20, 50, 50); m_rightCanvas->SetScrollbars(20, 20, 50, 50);
m_rightCanvas->Show(FALSE);
rightCanvas = new MyCanvas(splitter, CANVAS2, 0, 0, 400, 400); m_splitter->Initialize(m_leftCanvas);
rightCanvas->SetBackgroundColour(*wxCYAN); SetStatusText("Min pane size = 0", 1);
rightCanvas->SetScrollbars(20, 20, 50, 50);
rightCanvas->Show(FALSE);
splitter->Initialize(leftCanvas);
// Set this to prevent unsplitting
// splitter->SetMinimumPaneSize(20);
} }
MyFrame::~MyFrame() MyFrame::~MyFrame()
@ -163,59 +187,75 @@ MyFrame::~MyFrame()
bool MyFrame::OnClose() bool MyFrame::OnClose()
{ {
return TRUE; return TRUE;
} }
void MyFrame::Quit(wxCommandEvent& WXUNUSED(event) ) void MyFrame::Quit(wxCommandEvent& WXUNUSED(event) )
{ {
Close(TRUE); Close(TRUE);
} }
void MyFrame::SplitHorizontal(wxCommandEvent& WXUNUSED(event) ) void MyFrame::SplitHorizontal(wxCommandEvent& WXUNUSED(event) )
{ {
if ( splitter->IsSplit() ) if ( m_splitter->IsSplit() )
splitter->Unsplit(); m_splitter->Unsplit();
leftCanvas->Show(TRUE); m_leftCanvas->Show(TRUE);
rightCanvas->Show(TRUE); m_rightCanvas->Show(TRUE);
splitter->SplitHorizontally( leftCanvas, rightCanvas ); m_splitter->SplitHorizontally( m_leftCanvas, m_rightCanvas );
UpdatePosition();
} }
void MyFrame::SplitVertical(wxCommandEvent& WXUNUSED(event) ) void MyFrame::SplitVertical(wxCommandEvent& WXUNUSED(event) )
{ {
if ( splitter->IsSplit() ) if ( m_splitter->IsSplit() )
splitter->Unsplit(); m_splitter->Unsplit();
leftCanvas->Show(TRUE); m_leftCanvas->Show(TRUE);
rightCanvas->Show(TRUE); m_rightCanvas->Show(TRUE);
splitter->SplitVertically( leftCanvas, rightCanvas ); m_splitter->SplitVertically( m_leftCanvas, m_rightCanvas );
UpdatePosition();
} }
void MyFrame::Unsplit(wxCommandEvent& WXUNUSED(event) ) void MyFrame::Unsplit(wxCommandEvent& WXUNUSED(event) )
{ {
if ( splitter->IsSplit() ) if ( m_splitter->IsSplit() )
splitter->Unsplit(); m_splitter->Unsplit();
SetStatusText("No splitter");
}
void MyFrame::SetMinSize(wxCommandEvent& WXUNUSED(event) )
{
wxString str;
str.Printf("%d", m_splitter->GetMinimumPaneSize());
str = wxGetTextFromUser("Enter minimal size for panes:", "", str, this);
if ( str.IsEmpty() )
return;
int minsize = atoi(str);
m_splitter->SetMinimumPaneSize(minsize);
str.Printf("Min pane size = %d", minsize);
SetStatusText(str, 1);
} }
void MyFrame::UpdateUIHorizontal(wxUpdateUIEvent& event) void MyFrame::UpdateUIHorizontal(wxUpdateUIEvent& event)
{ {
event.Enable( ( (!splitter->IsSplit()) || (splitter->GetSplitMode() != wxSPLIT_HORIZONTAL) ) ); event.Enable( ( (!m_splitter->IsSplit()) || (m_splitter->GetSplitMode() != wxSPLIT_HORIZONTAL) ) );
} }
void MyFrame::UpdateUIVertical(wxUpdateUIEvent& event) void MyFrame::UpdateUIVertical(wxUpdateUIEvent& event)
{ {
event.Enable( ( (!splitter->IsSplit()) || (splitter->GetSplitMode() != wxSPLIT_VERTICAL) ) ); event.Enable( ( (!m_splitter->IsSplit()) || (m_splitter->GetSplitMode() != wxSPLIT_VERTICAL) ) );
} }
void MyFrame::UpdateUIUnsplit(wxUpdateUIEvent& event) void MyFrame::UpdateUIUnsplit(wxUpdateUIEvent& event)
{ {
event.Enable( splitter->IsSplit() ); event.Enable( m_splitter->IsSplit() );
} }
void MyFrame::OnIdle(wxIdleEvent& event) void MyFrame::UpdatePosition()
{ {
if ( GetStatusBar()->GetStatusText(0) != "Ready" ) wxString str;
SetStatusText("Ready"); str.Printf("Sash position = %d", m_splitter->GetSashPosition());
SetStatusText(str);
wxFrame::OnIdle(event);
} }
MyCanvas::MyCanvas(wxWindow* parent, wxWindowID id, int x, int y, int w, int h) : MyCanvas::MyCanvas(wxWindow* parent, wxWindowID id, int x, int y, int w, int h) :
@ -229,13 +269,13 @@ MyCanvas::~MyCanvas()
void MyCanvas::OnDraw(wxDC& dc) void MyCanvas::OnDraw(wxDC& dc)
{ {
dc.SetPen(*wxBLACK_PEN); dc.SetPen(*wxBLACK_PEN);
dc.DrawLine(0, 0, 100, 100); dc.DrawLine(0, 0, 100, 100);
dc.SetBackgroundMode(wxTRANSPARENT); dc.SetBackgroundMode(wxTRANSPARENT);
dc.DrawText("Testing", 50, 50); dc.DrawText("Testing", 50, 50);
dc.SetPen(*wxRED_PEN); dc.SetPen(*wxRED_PEN);
dc.SetBrush(*wxGREEN_BRUSH); dc.SetBrush(*wxGREEN_BRUSH);
dc.DrawRectangle(120, 120, 100, 80); dc.DrawRectangle(120, 120, 100, 80);
} }

View File

@ -6,7 +6,7 @@
// Created: 01/02/97 // Created: 01/02/97
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Julian Smart and Markus Holzem // Copyright: (c) Julian Smart and Markus Holzem
// Licence: wxWindows license // Licence: wxWindows license
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__ #ifdef __GNUG__
@ -42,7 +42,7 @@ BEGIN_EVENT_TABLE(wxSplitterWindow, wxWindow)
END_EVENT_TABLE() END_EVENT_TABLE()
#endif #endif
wxSplitterWindow::wxSplitterWindow(void) wxSplitterWindow::wxSplitterWindow()
{ {
m_splitMode = wxSPLIT_VERTICAL; m_splitMode = wxSPLIT_VERTICAL;
m_windowOne = (wxWindow *) NULL; m_windowOne = (wxWindow *) NULL;
@ -67,9 +67,12 @@ wxSplitterWindow::wxSplitterWindow(void)
m_minimumPaneSize = 0; m_minimumPaneSize = 0;
} }
wxSplitterWindow::wxSplitterWindow(wxWindow *parent, wxWindowID id, const wxPoint& pos, wxSplitterWindow::wxSplitterWindow(wxWindow *parent, wxWindowID id,
const wxSize& size, long style, const wxString& name) const wxPoint& pos,
:wxWindow(parent, id, pos, size, style, name) const wxSize& size,
long style,
const wxString& name)
: wxWindow(parent, id, pos, size, style, name)
{ {
m_splitMode = wxSPLIT_VERTICAL; m_splitMode = wxSPLIT_VERTICAL;
m_windowOne = (wxWindow *) NULL; m_windowOne = (wxWindow *) NULL;
@ -116,7 +119,7 @@ wxSplitterWindow::wxSplitterWindow(wxWindow *parent, wxWindowID id, const wxPoin
// SetBackground(wxBLUE_BRUSH); // SetBackground(wxBLUE_BRUSH);
} }
wxSplitterWindow::~wxSplitterWindow(void) wxSplitterWindow::~wxSplitterWindow()
{ {
delete m_sashCursorWE; delete m_sashCursorWE;
delete m_sashCursorNS; delete m_sashCursorNS;
@ -143,17 +146,17 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
long x, y; long x, y;
event.Position(&x, &y); event.Position(&x, &y);
if (event.LeftDown()) if (event.LeftDown())
{ {
if ( SashHitTest(x, y) ) if ( SashHitTest(x, y) )
{ {
CaptureMouse(); CaptureMouse();
// Required for X to specify that // Required for X to specify that
// that we wish to draw on top of all windows // that we wish to draw on top of all windows
// - and we optimise by specifying the area // - and we optimise by specifying the area
// for creating the overlap window. // for creating the overlap window.
wxScreenDC::StartDrawingOnTop(this); wxScreenDC::StartDrawingOnTop(this);
// We don't say we're dragging yet; we leave that // We don't say we're dragging yet; we leave that
// decision for the Dragging() branch, to ensure // decision for the Dragging() branch, to ensure
@ -162,7 +165,7 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
m_firstX = x; m_firstX = x;
m_firstY = y; m_firstY = y;
} }
} }
else if ( event.LeftUp() && m_dragMode == wxSPLIT_DRAG_LEFT_DOWN ) else if ( event.LeftUp() && m_dragMode == wxSPLIT_DRAG_LEFT_DOWN )
{ {
// Wasn't a proper drag // Wasn't a proper drag
@ -172,11 +175,11 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
SetCursor(*wxSTANDARD_CURSOR); SetCursor(*wxSTANDARD_CURSOR);
} }
else if (event.LeftUp() && m_dragMode == wxSPLIT_DRAG_DRAGGING) else if (event.LeftUp() && m_dragMode == wxSPLIT_DRAG_DRAGGING)
{ {
// We can stop dragging now and see what we've got. // We can stop dragging now and see what we've got.
m_dragMode = wxSPLIT_DRAG_NONE; m_dragMode = wxSPLIT_DRAG_NONE;
ReleaseMouse(); ReleaseMouse();
// Erase old tracker // Erase old tracker
DrawSashTracker(m_oldX, m_oldY); DrawSashTracker(m_oldX, m_oldY);
@ -185,12 +188,10 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
wxScreenDC::EndDrawingOnTop(); wxScreenDC::EndDrawingOnTop();
int w, h; int w, h;
GetClientSize(&w, &h); GetClientSize(&w, &h);
if ( m_splitMode == wxSPLIT_VERTICAL ) if ( m_splitMode == wxSPLIT_VERTICAL )
{ {
// First check if we should veto this resize because if ( !OnSashPositionChange(x) )
// the pane size is too small
if ( wxMax(x, 0) < m_minimumPaneSize || wxMax((w - x), 0) < m_minimumPaneSize)
return; return;
if ( x <= 4 ) if ( x <= 4 )
@ -218,9 +219,7 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
} }
else else
{ {
// First check if we should veto this resize because if ( !OnSashPositionChange(y) )
// the pane size is too small
if ( wxMax(y, 0) < m_minimumPaneSize || wxMax((h - y), 0) < m_minimumPaneSize)
return; return;
if ( y <= 4 ) if ( y <= 4 )
@ -247,36 +246,36 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
} }
} }
SizeWindows(); SizeWindows();
} }
else if (event.Moving() && !event.Dragging()) else if (event.Moving() && !event.Dragging())
{ {
// Just change the cursor if required // Just change the cursor if required
if ( SashHitTest(x, y) ) if ( SashHitTest(x, y) )
{ {
if ( m_splitMode == wxSPLIT_VERTICAL ) if ( m_splitMode == wxSPLIT_VERTICAL )
{ {
SetCursor(*m_sashCursorWE); SetCursor(*m_sashCursorWE);
} }
else else
{ {
SetCursor(*m_sashCursorNS); SetCursor(*m_sashCursorNS);
} }
} }
else else
{ {
SetCursor(*wxSTANDARD_CURSOR); SetCursor(*wxSTANDARD_CURSOR);
} }
} }
else if ( (event.Dragging() && (m_dragMode == wxSPLIT_DRAG_DRAGGING)) || else if ( (event.Dragging() && (m_dragMode == wxSPLIT_DRAG_DRAGGING)) ||
(event.Dragging() && SashHitTest(x, y, 4)) ) (event.Dragging() && SashHitTest(x, y, 4)) )
{ {
if ( m_splitMode == wxSPLIT_VERTICAL ) if ( m_splitMode == wxSPLIT_VERTICAL )
{ {
SetCursor(*m_sashCursorWE); SetCursor(*m_sashCursorWE);
} }
else else
{ {
SetCursor(*m_sashCursorNS); SetCursor(*m_sashCursorNS);
} }
// Detect that this is really a drag: we've moved more than 1 pixel either way // Detect that this is really a drag: we've moved more than 1 pixel either way
@ -300,7 +299,7 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
} }
m_oldX = x; m_oldX = x;
m_oldY = y; m_oldY = y;
} }
else if ( event.LeftDClick() ) else if ( event.LeftDClick() )
{ {
OnDoubleClickSash(x, y); OnDoubleClickSash(x, y);
@ -418,8 +417,8 @@ void wxSplitterWindow::DrawSash(wxDC& dc)
dc.DrawLine(m_sashPosition+m_sashSize-2, 1, m_sashPosition+m_sashSize-2, h-1); dc.DrawLine(m_sashPosition+m_sashSize-2, 1, m_sashPosition+m_sashSize-2, h-1);
dc.SetPen(*m_darkShadowPen); dc.SetPen(*m_darkShadowPen);
dc.DrawLine(m_sashPosition+m_sashSize-1, 2, m_sashPosition+m_sashSize-1, h-2); dc.DrawLine(m_sashPosition+m_sashSize-1, 2, m_sashPosition+m_sashSize-1, h-2);
} }
else else
{ {
dc.SetPen(*m_facePen); dc.SetPen(*m_facePen);
@ -528,7 +527,7 @@ void wxSplitterWindow::DrawSashTracker(int x, int y)
// Position and size subwindows. // Position and size subwindows.
// Note that the border size applies to each subwindow, not // Note that the border size applies to each subwindow, not
// including the edges next to the sash. // including the edges next to the sash.
void wxSplitterWindow::SizeWindows(void) void wxSplitterWindow::SizeWindows()
{ {
int w, h; int w, h;
GetClientSize(&w, &h); GetClientSize(&w, &h);
@ -551,10 +550,8 @@ void wxSplitterWindow::SizeWindows(void)
int w2 = w - 2*m_borderSize - m_sashSize - w1; int w2 = w - 2*m_borderSize - m_sashSize - w1;
int h2 = h - 2*m_borderSize; int h2 = h - 2*m_borderSize;
m_windowOne->SetSize(x1, y1, m_windowOne->SetSize(x1, y1, w1, h1);
w1, h1); m_windowTwo->SetSize(x2, y2, w2, h2);
m_windowTwo->SetSize(x2, y2,
w2, h2);
} }
else else
{ {
@ -585,13 +582,18 @@ bool wxSplitterWindow::SplitVertically(wxWindow *window1, wxWindow *window2, int
if ( IsSplit() ) if ( IsSplit() )
return FALSE; return FALSE;
int w, h;
GetClientSize(&w, &h);
m_splitMode = wxSPLIT_VERTICAL; m_splitMode = wxSPLIT_VERTICAL;
m_windowOne = window1; m_windowOne = window1;
m_windowTwo = window2; m_windowTwo = window2;
if ( sashPosition == -1 ) if ( sashPosition > 0 )
m_sashPosition = 100;
else
m_sashPosition = sashPosition; m_sashPosition = sashPosition;
else if ( sashPosition < 0 )
m_sashPosition = w - sashPosition;
else // default
m_sashPosition = w/2;
SizeWindows(); SizeWindows();
@ -603,13 +605,18 @@ bool wxSplitterWindow::SplitHorizontally(wxWindow *window1, wxWindow *window2, i
if ( IsSplit() ) if ( IsSplit() )
return FALSE; return FALSE;
int w, h;
GetClientSize(&w, &h);
m_splitMode = wxSPLIT_HORIZONTAL; m_splitMode = wxSPLIT_HORIZONTAL;
m_windowOne = window1; m_windowOne = window1;
m_windowTwo = window2; m_windowTwo = window2;
if ( sashPosition == -1 ) if ( sashPosition > 0 )
m_sashPosition = 100;
else
m_sashPosition = sashPosition; m_sashPosition = sashPosition;
else if ( sashPosition < 0 )
m_sashPosition = h - sashPosition;
else // default
m_sashPosition = h/2;
SizeWindows(); SizeWindows();
@ -657,6 +664,31 @@ void wxSplitterWindow::SetSashPosition(int position, bool redraw)
} }
} }
bool wxSplitterWindow::OnSashPositionChange(int newSashPosition)
{
// is the left/upper pane too small?
if ( newSashPosition < m_minimumPaneSize )
return NULL;
// is the right/lower pane too small?
int w, h;
GetClientSize(&w, &h);
if ( m_splitMode == wxSPLIT_VERTICAL )
{
if ( h - newSashPosition < m_minimumPaneSize )
return FALSE;
}
else // m_splitMode = wxSPLIT_HORIZONTAL
{
if ( w - newSashPosition < m_minimumPaneSize )
return FALSE;
}
// it's ok to move sash
return TRUE;
}
// Called when the sash is double-clicked. // Called when the sash is double-clicked.
// The default behaviour is to remove the sash if the // The default behaviour is to remove the sash if the
// minimum pane size is zero. // minimum pane size is zero.
@ -669,50 +701,39 @@ void wxSplitterWindow::OnDoubleClickSash(int WXUNUSED(x), int WXUNUSED(y) )
} }
// Initialize colours // Initialize colours
void wxSplitterWindow::InitColours(void) void wxSplitterWindow::InitColours()
{ {
if ( m_facePen ) wxDELETE( m_facePen );
delete m_facePen; wxDELETE( m_faceBrush );
if ( m_faceBrush ) wxDELETE( m_mediumShadowPen );
delete m_faceBrush; wxDELETE( m_darkShadowPen );
if ( m_mediumShadowPen ) wxDELETE( m_lightShadowPen );
delete m_mediumShadowPen; wxDELETE( m_hilightPen );
if ( m_darkShadowPen )
delete m_darkShadowPen;
if ( m_lightShadowPen )
delete m_lightShadowPen;
if ( m_hilightPen )
delete m_hilightPen;
// Shadow colours // Shadow colours
#if defined(__WIN95__) #if defined(__WIN95__)
// COLORREF ref = ::GetSysColor(COLOR_3DFACE); // Normally light grey
wxColour faceColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); wxColour faceColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
m_facePen = new wxPen(faceColour, 1, wxSOLID); m_facePen = new wxPen(faceColour, 1, wxSOLID);
m_faceBrush = new wxBrush(faceColour, wxSOLID); m_faceBrush = new wxBrush(faceColour, wxSOLID);
// ref = ::GetSysColor(COLOR_3DSHADOW); // Normally dark grey
wxColour mediumShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW)); wxColour mediumShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW));
m_mediumShadowPen = new wxPen(mediumShadowColour, 1, wxSOLID); m_mediumShadowPen = new wxPen(mediumShadowColour, 1, wxSOLID);
// ref = ::GetSysColor(COLOR_3DDKSHADOW); // Normally black
wxColour darkShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DDKSHADOW)); wxColour darkShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DDKSHADOW));
m_darkShadowPen = new wxPen(darkShadowColour, 1, wxSOLID); m_darkShadowPen = new wxPen(darkShadowColour, 1, wxSOLID);
// ref = ::GetSysColor(COLOR_3DLIGHT); // Normally light grey
wxColour lightShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT)); wxColour lightShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT));
m_lightShadowPen = new wxPen(lightShadowColour, 1, wxSOLID); m_lightShadowPen = new wxPen(lightShadowColour, 1, wxSOLID);
// ref = ::GetSysColor(COLOR_3DHILIGHT); // Normally white
wxColour hilightColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHILIGHT)); wxColour hilightColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHILIGHT));
m_hilightPen = new wxPen(hilightColour, 1, wxSOLID); m_hilightPen = new wxPen(hilightColour, 1, wxSOLID);
#else #else // !Win32
m_facePen = new wxPen("LIGHT GREY", 1, wxSOLID); m_facePen = new wxPen("LIGHT GREY", 1, wxSOLID);
m_faceBrush = new wxBrush("LIGHT GREY", wxSOLID); m_faceBrush = new wxBrush("LIGHT GREY", wxSOLID);
m_mediumShadowPen = new wxPen("GREY", 1, wxSOLID); m_mediumShadowPen = new wxPen("GREY", 1, wxSOLID);
m_darkShadowPen = new wxPen("BLACK", 1, wxSOLID); m_darkShadowPen = new wxPen("BLACK", 1, wxSOLID);
m_lightShadowPen = new wxPen("LIGHT GREY", 1, wxSOLID); m_lightShadowPen = new wxPen("LIGHT GREY", 1, wxSOLID);
m_hilightPen = new wxPen("WHITE", 1, wxSOLID); m_hilightPen = new wxPen("WHITE", 1, wxSOLID);
#endif #endif // Win32/!Win32
} }