Save last wxSplitterWindow position before it was unsplit

Use this position when the window is split again and also save and
restore it from persistent storage in wxPersistentSplitter.

Closes #24329.
This commit is contained in:
Doukas Dergiades 2024-02-12 04:17:53 +02:00 committed by Vadim Zeitlin
parent 7bf295802e
commit f24b3d5483
4 changed files with 91 additions and 0 deletions

View file

@ -226,6 +226,15 @@ public:
// all any more.
wxDEPRECATED_INLINE( void SetSashSize(int WXUNUSED(width)), return; )
// Get the sash position that was last used before Unsplit() was called.
// Horizontal and vertical components correspond to the split in the
// corresponding direction, and are 0 if the splitter hadn't been split in
// this direction at all.
wxPoint GetLastSplitPosition() const;
// Set the default initial sash position to use when the splitter is split.
void SetLastSplitPosition(const wxPoint& pos);
protected:
// event handlers
#if defined(__WXMSW__) || defined(__WXMAC__)
@ -289,6 +298,7 @@ protected:
wxPoint m_ptStart; // mouse position when dragging started
int m_sashStart; // sash position when dragging started
int m_minimumPaneSize;
wxPoint m_lastSplitPosition;
wxCursor m_sashCursorWE;
wxCursor m_sashCursorNS;
wxOverlay m_overlay;

View file

@ -23,6 +23,9 @@
// Special position value of -1 means the splitter is not split at all.
#define wxPERSIST_SPLITTER_POSITION wxASCII_STR("Position")
#define wxPERSIST_SPLITTER_DEFAULT_HORIZONTAL wxASCII_STR("LastHorz")
#define wxPERSIST_SPLITTER_DEFAULT_VERTICAL wxASCII_STR("LastVert")
// ----------------------------------------------------------------------------
// wxPersistentSplitter: supports saving/restoring splitter position
// ----------------------------------------------------------------------------
@ -41,6 +44,14 @@ public:
int pos = splitter->IsSplit() ? splitter->GetSashPosition() : -1;
SaveValue(wxPERSIST_SPLITTER_POSITION, pos);
// Save the previously used position too if we have them.
const wxPoint lastSplitPos = splitter->GetLastSplitPosition();
if ( lastSplitPos.x || lastSplitPos.y )
{
SaveValue(wxPERSIST_SPLITTER_DEFAULT_HORIZONTAL, lastSplitPos.y);
SaveValue(wxPERSIST_SPLITTER_DEFAULT_VERTICAL, lastSplitPos.x);
}
}
virtual bool Restore() override
@ -54,6 +65,14 @@ public:
else
Get()->SetSashPosition(pos);
// Note that it's possible that default position was not stored, in
// which case lastSplitPos will just remain as (0, 0) and that's ok.
wxPoint lastSplitPos;
RestoreValue(wxPERSIST_SPLITTER_DEFAULT_HORIZONTAL, &lastSplitPos.x);
RestoreValue(wxPERSIST_SPLITTER_DEFAULT_VERTICAL, &lastSplitPos.y);
Get()->SetLastSplitPosition(lastSplitPos);
return true;
}

View file

@ -477,6 +477,36 @@ public:
before showing the top-level window.
*/
void UpdateSize();
/**
Get the last sash position before the splitter was unsplit.
The last sash position gets updated each time the window is unsplit. It
is kept internally to allow restoring the sash in its previous position
when if it is split again.
@return Point whose x/y component corresponds to the position of the
vertical/horizontal sash before the last unsplit or 0 if the
splitter was never split in the corresponding direction.
@since 3.3.0
*/
const wxPoint& GetLastSplitPosition() const;
/**
Sets the last sash position.
This does not affect the actual sash position while the window is split
but determines the initial position of the sash when the window gets
split in the future.
@param pos
Point containing the default positions for wxSPLIT_VERTICAL and
wxSPLIT_HORIZONTAL modes respectively in its x and y components.
@since 3.3.0
*/
void SetLastSplitPosition(const wxPoint& pos);
};

View file

@ -840,6 +840,18 @@ int wxSplitterWindow::ConvertSashPosition(int sashPosition) const
}
else // sashPosition == 0
{
// Use last split position if we have it.
if ( m_splitMode == wxSPLIT_VERTICAL )
{
if ( m_lastSplitPosition.x )
return m_lastSplitPosition.x;
}
else if ( m_splitMode == wxSPLIT_HORIZONTAL )
{
if ( m_lastSplitPosition.y )
return m_lastSplitPosition.y;
}
// default, put it in the centre
return GetWindowSize() / 2;
}
@ -871,6 +883,15 @@ bool wxSplitterWindow::Unsplit(wxWindow *toRemove)
return false;
}
if (m_splitMode == wxSPLIT_VERTICAL)
{
m_lastSplitPosition.x = m_sashPosition;
}
else if (m_splitMode == wxSPLIT_HORIZONTAL)
{
m_lastSplitPosition.y = m_sashPosition;
}
OnUnsplit(win);
DoSetSashPosition(0);
SizeWindows();
@ -1086,6 +1107,17 @@ void wxSplitterWindow::OnUnsplit(wxWindow *winRemoved)
winRemoved->Show(false);
}
wxPoint wxSplitterWindow::GetLastSplitPosition() const
{
return m_lastSplitPosition;
}
void wxSplitterWindow::SetLastSplitPosition(const wxPoint& pos)
{
m_lastSplitPosition = pos;
}
#if defined( __WXMSW__ ) || defined( __WXMAC__)
// this is currently called (and needed) under MSW only...