Added always-unsplittable style option (wxSP_PERMIT_UNSPLIT)

Added visual feedback on limits for sash-drag
(Fix of previous broken behaviour: now unplits only if min pane size == 0 or
 if always-unsplittable style flag is used.)


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2552 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Unknown (BV)
1999-05-24 16:19:06 +00:00
parent 86434d7115
commit 370938d99c
2 changed files with 99 additions and 38 deletions

View File

@@ -181,12 +181,14 @@ public:
protected: protected:
// our event handlers // our event handlers
void OnSashPosChanged(wxSplitterEvent& event); void OnSashPosChanged(wxSplitterEvent& event);
void OnSashPosChanging(wxSplitterEvent& event);
void OnDoubleClick(wxSplitterEvent& event); void OnDoubleClick(wxSplitterEvent& event);
void OnUnsplitEvent(wxSplitterEvent& event); void OnUnsplitEvent(wxSplitterEvent& event);
void SendUnsplitEvent(wxWindow *winRemoved); void SendUnsplitEvent(wxWindow *winRemoved);
int m_splitMode; int m_splitMode;
bool m_permitUnsplitAlways;
wxWindow* m_windowOne; wxWindow* m_windowOne;
wxWindow* m_windowTwo; wxWindow* m_windowTwo;
int m_dragMode; int m_dragMode;
@@ -237,14 +239,16 @@ public:
// all // all
void SetSashPosition(int pos) void SetSashPosition(int pos)
{ {
wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED ); wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED
|| GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING);
m_data.pos = pos; m_data.pos = pos;
} }
int GetSashPosition() const int GetSashPosition() const
{ {
wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED ); wxASSERT( GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED
|| GetEventType() == wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING);
return m_data.pos; return m_data.pos;
} }
@@ -300,9 +304,18 @@ typedef void (wxEvtHandler::*wxSplitterEventFunction)(wxSplitterEvent&);
NULL \ NULL \
}, },
#define EVT_SPLITTER_DCLICK(id, fn) \ #define EVT_SPLITTER_SASH_POS_CHANGING(id, fn) \
{ \ { \
wxEVT_COMMAND_SPLITTER_DOUBLECLICKED, \ wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING, \
id, \
-1, \
(wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn, \
NULL \
},
#define EVT_SPLITTER_DCLICK(id, fn) \
{ \
wxEVT_COMMAND_SPLITTER_DOUBLECLICKED, \
id, \ id, \
-1, \ -1, \
(wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn, \ (wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn, \

View File

@@ -40,6 +40,9 @@ BEGIN_EVENT_TABLE(wxSplitterWindow, wxWindow)
EVT_MOUSE_EVENTS(wxSplitterWindow::OnMouseEvent) EVT_MOUSE_EVENTS(wxSplitterWindow::OnMouseEvent)
EVT_SPLITTER_SASH_POS_CHANGED(-1, wxSplitterWindow::OnSashPosChanged) EVT_SPLITTER_SASH_POS_CHANGED(-1, wxSplitterWindow::OnSashPosChanged)
// NB: we borrow OnSashPosChanged for purposes of
// EVT_SPLITTER_SASH_POS_CHANGING since default implementation is identical
EVT_SPLITTER_SASH_POS_CHANGING(-1, wxSplitterWindow::OnSashPosChanged)
EVT_SPLITTER_DCLICK(-1, wxSplitterWindow::OnDoubleClick) EVT_SPLITTER_DCLICK(-1, wxSplitterWindow::OnDoubleClick)
EVT_SPLITTER_UNSPLIT(-1, wxSplitterWindow::OnUnsplitEvent) EVT_SPLITTER_UNSPLIT(-1, wxSplitterWindow::OnUnsplitEvent)
END_EVENT_TABLE() END_EVENT_TABLE()
@@ -48,6 +51,7 @@ END_EVENT_TABLE()
wxSplitterWindow::wxSplitterWindow() wxSplitterWindow::wxSplitterWindow()
{ {
m_splitMode = wxSPLIT_VERTICAL; m_splitMode = wxSPLIT_VERTICAL;
m_permitUnsplitAlways = FALSE;
m_windowOne = (wxWindow *) NULL; m_windowOne = (wxWindow *) NULL;
m_windowTwo = (wxWindow *) NULL; m_windowTwo = (wxWindow *) NULL;
m_dragMode = wxSPLIT_DRAG_NONE; m_dragMode = wxSPLIT_DRAG_NONE;
@@ -78,6 +82,7 @@ wxSplitterWindow::wxSplitterWindow(wxWindow *parent, wxWindowID id,
: wxWindow(parent, id, pos, size, style, name) : wxWindow(parent, id, pos, size, style, name)
{ {
m_splitMode = wxSPLIT_VERTICAL; m_splitMode = wxSPLIT_VERTICAL;
m_permitUnsplitAlways = (style & wxSP_PERMIT_UNSPLIT) != 0;
m_windowOne = (wxWindow *) NULL; m_windowOne = (wxWindow *) NULL;
m_windowTwo = (wxWindow *) NULL; m_windowTwo = (wxWindow *) NULL;
m_dragMode = wxSPLIT_DRAG_NONE; m_dragMode = wxSPLIT_DRAG_NONE;
@@ -212,22 +217,31 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
} }
} }
if ( new_sash_position == 0 ) if ( m_permitUnsplitAlways
|| m_minimumPaneSize == 0 )
{ {
// We remove the first window from the view // Deal with possible unsplit scenarios
wxWindow *removedWindow = m_windowOne; if ( new_sash_position == 0 )
m_windowOne = m_windowTwo; {
m_windowTwo = (wxWindow *) NULL; // We remove the first window from the view
SendUnsplitEvent(removedWindow); wxWindow *removedWindow = m_windowOne;
m_sashPosition = 0; m_windowOne = m_windowTwo;
} m_windowTwo = (wxWindow *) NULL;
else if ( new_sash_position == window_size ) SendUnsplitEvent(removedWindow);
{ m_sashPosition = 0;
// We remove the second window from the view }
wxWindow *removedWindow = m_windowTwo; else if ( new_sash_position == window_size )
m_windowTwo = (wxWindow *) NULL; {
SendUnsplitEvent(removedWindow); // We remove the second window from the view
m_sashPosition = 0; wxWindow *removedWindow = m_windowTwo;
m_windowTwo = (wxWindow *) NULL;
SendUnsplitEvent(removedWindow);
m_sashPosition = 0;
}
else
{
m_sashPosition = new_sash_position;
}
} }
else else
{ {
@@ -260,9 +274,39 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
} }
else if (event.Dragging() && (m_dragMode == wxSPLIT_DRAG_DRAGGING)) else if (event.Dragging() && (m_dragMode == wxSPLIT_DRAG_DRAGGING))
{ {
// Obtain window size. We are only interested in the dimension the sash
// splits up
int new_sash_position =
(int) ( m_splitMode == wxSPLIT_VERTICAL ? x : y );
wxSplitterEvent eventSplitter(wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING,
this);
eventSplitter.m_data.pos = new_sash_position;
if ( GetEventHandler()->ProcessEvent(eventSplitter) )
{
new_sash_position = eventSplitter.GetSashPosition();
if ( new_sash_position == -1 )
{
// change not allowed
return;
}
}
// Erase old tracker // Erase old tracker
DrawSashTracker(m_oldX, m_oldY); DrawSashTracker(m_oldX, m_oldY);
if (m_splitMode == wxSPLIT_VERTICAL)
x = new_sash_position;
else
y = new_sash_position;
if (new_sash_position != -1)
{
// Only modify if permitted
m_oldX = x;
m_oldY = y;
}
#ifdef __WXMSW__ #ifdef __WXMSW__
// As we captured the mouse, we may get the mouse events from outside // As we captured the mouse, we may get the mouse events from outside
// our window - for example, negative values in x, y. This has a weird // our window - for example, negative values in x, y. This has a weird
@@ -270,9 +314,6 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
// signed ones other times: the coordinates turn as big positive // signed ones other times: the coordinates turn as big positive
// numbers and so the sash is drawn on the *right* side of the window // numbers and so the sash is drawn on the *right* side of the window
// instead of the left (or bottom instead of top). Correct this. // instead of the left (or bottom instead of top). Correct this.
m_oldX = x;
m_oldY = y;
if ( (short)m_oldX < 0 ) if ( (short)m_oldX < 0 )
m_oldX = 0; m_oldX = 0;
if ( (short)m_oldY < 0 ) if ( (short)m_oldY < 0 )
@@ -751,26 +792,32 @@ void wxSplitterWindow::OnSashPosChanged(wxSplitterEvent& event)
GetClientSize(&w, &h); GetClientSize(&w, &h);
int window_size = (m_splitMode == wxSPLIT_VERTICAL) ? w : h ; int window_size = (m_splitMode == wxSPLIT_VERTICAL) ? w : h ;
if ( newSashPosition <= UNSPLIT_THRESHOLD ) bool unsplit_scenario = FALSE;
if ( m_permitUnsplitAlways
|| m_minimumPaneSize == 0 )
{ {
// threshold top / left check // Do edge detection if unsplit premitted
newSashPosition = 0; if ( newSashPosition <= UNSPLIT_THRESHOLD )
} {
else if ( newSashPosition < m_minimumPaneSize ) // threshold top / left check
{ newSashPosition = 0;
// If resultant pane would be too small, enlarge it unsplit_scenario = TRUE;
newSashPosition = m_minimumPaneSize; }
if ( newSashPosition >= window_size - UNSPLIT_THRESHOLD )
{
// threshold bottom/right check
newSashPosition = window_size;
unsplit_scenario = TRUE;
}
} }
if ( newSashPosition >= window_size - UNSPLIT_THRESHOLD ) if ( !unsplit_scenario )
{
// threshold bottom/right check
newSashPosition = window_size;
}
else if ( newSashPosition > window_size - m_minimumPaneSize )
{ {
// If resultant pane would be too small, enlarge it // If resultant pane would be too small, enlarge it
newSashPosition = window_size - m_minimumPaneSize; if ( newSashPosition < m_minimumPaneSize )
newSashPosition = m_minimumPaneSize;
if ( newSashPosition > window_size - m_minimumPaneSize )
newSashPosition = window_size - m_minimumPaneSize;
} }
// If the result is out of bounds it means minimum size is too big, // If the result is out of bounds it means minimum size is too big,
@@ -794,7 +841,8 @@ void wxSplitterWindow::OnDoubleClick(wxSplitterEvent& event)
// for compatibility, call the virtual function // for compatibility, call the virtual function
OnDoubleClickSash(event.GetX(), event.GetY()); OnDoubleClickSash(event.GetX(), event.GetY());
if ( GetMinimumPaneSize() == 0 ) if ( GetMinimumPaneSize() == 0
|| m_permitUnsplitAlways)
{ {
Unsplit(); Unsplit();
} }