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:
parent
86434d7115
commit
370938d99c
@ -181,12 +181,14 @@ public:
|
||||
protected:
|
||||
// our event handlers
|
||||
void OnSashPosChanged(wxSplitterEvent& event);
|
||||
void OnSashPosChanging(wxSplitterEvent& event);
|
||||
void OnDoubleClick(wxSplitterEvent& event);
|
||||
void OnUnsplitEvent(wxSplitterEvent& event);
|
||||
|
||||
void SendUnsplitEvent(wxWindow *winRemoved);
|
||||
|
||||
int m_splitMode;
|
||||
bool m_permitUnsplitAlways;
|
||||
wxWindow* m_windowOne;
|
||||
wxWindow* m_windowTwo;
|
||||
int m_dragMode;
|
||||
@ -237,14 +239,16 @@ public:
|
||||
// all
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -300,9 +304,18 @@ typedef void (wxEvtHandler::*wxSplitterEventFunction)(wxSplitterEvent&);
|
||||
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, \
|
||||
-1, \
|
||||
(wxObjectEventFunction)(wxEventFunction)(wxSplitterEventFunction) &fn, \
|
||||
|
@ -40,6 +40,9 @@ BEGIN_EVENT_TABLE(wxSplitterWindow, wxWindow)
|
||||
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()
|
||||
@ -48,6 +51,7 @@ 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;
|
||||
@ -78,6 +82,7 @@ wxSplitterWindow::wxSplitterWindow(wxWindow *parent, wxWindowID id,
|
||||
: 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;
|
||||
@ -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
|
||||
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
|
||||
{
|
||||
@ -260,9 +274,39 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
|
||||
}
|
||||
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);
|
||||
|
||||
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
|
||||
@ -270,9 +314,6 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
|
||||
// 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.
|
||||
m_oldX = x;
|
||||
m_oldY = y;
|
||||
|
||||
if ( (short)m_oldX < 0 )
|
||||
m_oldX = 0;
|
||||
if ( (short)m_oldY < 0 )
|
||||
@ -751,26 +792,32 @@ void wxSplitterWindow::OnSashPosChanged(wxSplitterEvent& event)
|
||||
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;
|
||||
}
|
||||
else if ( newSashPosition < m_minimumPaneSize )
|
||||
{
|
||||
// If resultant pane would be too small, enlarge it
|
||||
newSashPosition = m_minimumPaneSize;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
if ( newSashPosition >= window_size - UNSPLIT_THRESHOLD )
|
||||
{
|
||||
// threshold bottom/right check
|
||||
newSashPosition = window_size;
|
||||
}
|
||||
else if ( newSashPosition > window_size - m_minimumPaneSize )
|
||||
if ( !unsplit_scenario )
|
||||
{
|
||||
// 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,
|
||||
@ -794,7 +841,8 @@ void wxSplitterWindow::OnDoubleClick(wxSplitterEvent& event)
|
||||
// for compatibility, call the virtual function
|
||||
OnDoubleClickSash(event.GetX(), event.GetY());
|
||||
|
||||
if ( GetMinimumPaneSize() == 0 )
|
||||
if ( GetMinimumPaneSize() == 0
|
||||
|| m_permitUnsplitAlways)
|
||||
{
|
||||
Unsplit();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user