EVT_MOUSE_EVENTS(wxSplitterWindow::OnMouseEvent)
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_UNSPLIT(-1, wxSplitterWindow::OnUnsplitEvent)
END_EVENT_TABLE()
wxSplitterWindow::wxSplitterWindow()
{
m_splitMode = wxSPLIT_VERTICAL;
+ m_permitUnsplitAlways = FALSE;
m_windowOne = (wxWindow *) NULL;
m_windowTwo = (wxWindow *) NULL;
m_dragMode = wxSPLIT_DRAG_NONE;
: wxWindow(parent, id, pos, size, style, name)
{
m_splitMode = wxSPLIT_VERTICAL;
+ m_permitUnsplitAlways = (style & wxSP_PERMIT_UNSPLIT) != 0;
m_windowOne = (wxWindow *) NULL;
m_windowTwo = (wxWindow *) NULL;
m_dragMode = wxSPLIT_DRAG_NONE;
}
}
- if ( new_sash_position == 0 )
+ if ( m_permitUnsplitAlways
+ || m_minimumPaneSize == 0 )
{
- // We remove the first window from the view
- wxWindow *removedWindow = m_windowOne;
- m_windowOne = m_windowTwo;
- m_windowTwo = (wxWindow *) NULL;
- SendUnsplitEvent(removedWindow);
- m_sashPosition = 0;
- }
- else if ( new_sash_position == window_size )
- {
- // We remove the second window from the view
- wxWindow *removedWindow = m_windowTwo;
- m_windowTwo = (wxWindow *) NULL;
- SendUnsplitEvent(removedWindow);
- m_sashPosition = 0;
+ // Deal with possible unsplit scenarios
+ if ( new_sash_position == 0 )
+ {
+ // We remove the first window from the view
+ wxWindow *removedWindow = m_windowOne;
+ m_windowOne = m_windowTwo;
+ m_windowTwo = (wxWindow *) NULL;
+ SendUnsplitEvent(removedWindow);
+ m_sashPosition = 0;
+ }
+ else if ( new_sash_position == window_size )
+ {
+ // We remove the second window from the view
+ wxWindow *removedWindow = m_windowTwo;
+ m_windowTwo = (wxWindow *) NULL;
+ SendUnsplitEvent(removedWindow);
+ m_sashPosition = 0;
+ }
+ else
+ {
+ m_sashPosition = new_sash_position;
+ }
}
else
{
}
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
DrawSashTracker(m_oldX, m_oldY);
- // Draw new one
- DrawSashTracker(x, y);
+ 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__
+ // 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
+ // consequence under MSW where we use unsigned values sometimes and
+ // signed ones other times: the coordinates turn as big positive
+ // 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.
+ if ( (short)m_oldX < 0 )
+ m_oldX = 0;
+ if ( (short)m_oldY < 0 )
+ m_oldY = 0;
+#endif // __WXMSW__
- m_oldX = x;
- m_oldY = y;
+ // Draw new one
+ DrawSashTracker(m_oldX, m_oldY);
}
else if ( event.LeftDClick() )
{
ClientToScreen(&x1, &y1);
ClientToScreen(&x2, &y2);
- screenDC.SetLogicalFunction(wxXOR);
+ screenDC.SetLogicalFunction(wxINVERT);
screenDC.SetPen(*m_sashTrackerPen);
screenDC.SetBrush(*wxTRANSPARENT_BRUSH);
GetClientSize(&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
- newSashPosition = 0;
+ // Do edge detection if unsplit premitted
+ if ( newSashPosition <= UNSPLIT_THRESHOLD )
+ {
+ // threshold top / left check
+ newSashPosition = 0;
+ unsplit_scenario = TRUE;
+ }
+ if ( newSashPosition >= window_size - UNSPLIT_THRESHOLD )
+ {
+ // threshold bottom/right check
+ newSashPosition = window_size;
+ unsplit_scenario = TRUE;
+ }
}
- else if ( newSashPosition >= window_size - UNSPLIT_THRESHOLD )
+
+ if ( !unsplit_scenario )
{
- // threshold bottom/right check
- newSashPosition = window_size;
+ // If resultant pane would be too small, enlarge it
+ if ( newSashPosition < m_minimumPaneSize )
+ newSashPosition = m_minimumPaneSize;
+ if ( newSashPosition > window_size - m_minimumPaneSize )
+ newSashPosition = window_size - m_minimumPaneSize;
}
- // If resultant pane would be too small, enlarge it.
-
- // Check upper / left pane
- if ( newSashPosition < m_minimumPaneSize )
- newSashPosition = m_minimumPaneSize;
-
- // Check lower / right pane (check even if sash was just adjusted)
- 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,
// so split window in half as best compromise.
if ( newSashPosition < 0 || newSashPosition > window_size )
// for compatibility, call the virtual function
OnDoubleClickSash(event.GetX(), event.GetY());
- if ( GetMinimumPaneSize() == 0 )
+ if ( GetMinimumPaneSize() == 0
+ || m_permitUnsplitAlways)
{
Unsplit();
}