Fix bug in wxSplitterWindow not handling the event state correct in case of sash pos changing or resize.

This commit is contained in:
Gerhard Gruber
2022-01-28 00:04:54 +01:00
parent 5da9d12272
commit bfb5d32582
2 changed files with 37 additions and 29 deletions

View File

@@ -129,7 +129,7 @@ private:
wxSplitterWindow* m_splitter; wxSplitterWindow* m_splitter;
wxWindow *m_replacewindow; wxWindow *m_replacewindow;
int m_sashPos; int m_sashPos;
bool m_lockSash:1; bool m_lockSash;
wxDECLARE_EVENT_TABLE(); wxDECLARE_EVENT_TABLE();
wxDECLARE_NO_COPY_CLASS(MyFrame); wxDECLARE_NO_COPY_CLASS(MyFrame);
@@ -277,7 +277,7 @@ MyFrame::MyFrame()
splitMenu->Append(SPLIT_SETGRAVITY, splitMenu->Append(SPLIT_SETGRAVITY,
"Set &gravity\tCtrl-G", "Set &gravity\tCtrl-G",
"Set gravity of sash"); "Set gravity of sash");
splitMenu->Append(SPLIT_LOCKSASH, splitMenu->AppendCheckItem(SPLIT_LOCKSASH,
"Toggle sash &lock on resize\tCtrl-R", "Toggle sash &lock on resize\tCtrl-R",
"Keep the sash in a fixed position while resizing"); "Keep the sash in a fixed position while resizing");
splitMenu->AppendSeparator(); splitMenu->AppendSeparator();
@@ -550,8 +550,6 @@ void MySplitterWindow::OnPositionChanged(wxSplitterEvent& event)
// new position. If the sash is not locked, this has no effect but // new position. If the sash is not locked, this has no effect but
// doesn't hurt either. // doesn't hurt either.
m_frame->SetSashPos(event.GetSashPosition()); m_frame->SetSashPos(event.GetSashPosition());
event.Skip();
} }
void MySplitterWindow::OnPositionResize(wxSplitterEvent &event) void MySplitterWindow::OnPositionResize(wxSplitterEvent &event)
@@ -560,17 +558,19 @@ void MySplitterWindow::OnPositionResize(wxSplitterEvent &event)
// if it is not locked. Otherwise we hold it at the position // if it is not locked. Otherwise we hold it at the position
// the user specified by manually dragging. // the user specified by manually dragging.
if (m_frame->IsSashLocked()) if (m_frame->IsSashLocked())
{
// We set the last known position to keep the sash in place.
// For this particular example we could also simply use
// event.Veto()
// as well and it would have the same effect.
event.SetSashPosition(m_frame->GetSashPos()); event.SetSashPosition(m_frame->GetSashPos());
}
event.Skip();
} }
void MySplitterWindow::OnPositionChanging(wxSplitterEvent& event) void MySplitterWindow::OnPositionChanging(wxSplitterEvent& event)
{ {
wxLogStatus(m_frame, "Position is changing, now = %d (or %d)", wxLogStatus(m_frame, "Position is changing, now = %d (or %d)",
event.GetSashPosition(), GetSashPosition()); event.GetSashPosition(), GetSashPosition());
event.Skip();
} }
void MySplitterWindow::OnDClick(wxSplitterEvent& event) void MySplitterWindow::OnDClick(wxSplitterEvent& event)
@@ -579,6 +579,7 @@ void MySplitterWindow::OnDClick(wxSplitterEvent& event)
m_frame->SetStatusText("Splitter double clicked", 1); m_frame->SetStatusText("Splitter double clicked", 1);
#endif // wxUSE_STATUSBAR #endif // wxUSE_STATUSBAR
// Let the splitter window handle the event as well.
event.Skip(); event.Skip();
} }
@@ -588,6 +589,7 @@ void MySplitterWindow::OnUnsplitEvent(wxSplitterEvent& event)
m_frame->SetStatusText("Splitter unsplit", 1); m_frame->SetStatusText("Splitter unsplit", 1);
#endif // wxUSE_STATUSBAR #endif // wxUSE_STATUSBAR
// Let the splitter window handle the event as well.
event.Skip(); event.Skip();
} }

View File

@@ -488,19 +488,22 @@ void wxSplitterWindow::OnSize(wxSizeEvent& event)
update.m_data.resize.oldSize = old_size; update.m_data.resize.oldSize = old_size;
update.m_data.resize.newSize = size; update.m_data.resize.newSize = size;
if (!DoSendEvent(update)) if (DoSendEvent(update))
{
if (update.IsAllowed())
{
// If the user set the sashposition to -1
// we keep the already calculated value, otherwise
// the user provided the new position.
int userPos = update.GetSashPosition();
if (userPos != -1)
newPosition = userPos;
}
else
{ {
// the event handler vetoed the change // the event handler vetoed the change
newPosition = -1; newPosition = -1;
} }
else
{
// If the user set the sashposition to -1
// we keep the already calculated value,
// otherwise the user provided the new position.
int userPos = update.GetSashPosition();
if (userPos != -1)
newPosition = userPos;
} }
// Also check if the second window became too small. // Also check if the second window became too small.
@@ -925,7 +928,7 @@ void wxSplitterWindow::UpdateSize()
bool wxSplitterWindow::DoSendEvent(wxSplitterEvent& event) bool wxSplitterWindow::DoSendEvent(wxSplitterEvent& event)
{ {
return !GetEventHandler()->ProcessEvent(event) || event.IsAllowed(); return GetEventHandler()->ProcessEvent(event);
} }
wxSize wxSplitterWindow::DoGetBestSize() const wxSize wxSplitterWindow::DoGetBestSize() const
@@ -1032,15 +1035,18 @@ int wxSplitterWindow::OnSashPositionChanging(int newSashPosition)
wxSplitterEvent event(wxEVT_SPLITTER_SASH_POS_CHANGING, this); wxSplitterEvent event(wxEVT_SPLITTER_SASH_POS_CHANGING, this);
event.m_data.resize.pos = newSashPosition; event.m_data.resize.pos = newSashPosition;
if ( !DoSendEvent(event) ) if (DoSendEvent(event))
{
if (event.IsAllowed())
{
// it could have been changed by it
newSashPosition = event.GetSashPosition();
}
else
{ {
// the event handler vetoed the change // the event handler vetoed the change
newSashPosition = -1; newSashPosition = -1;
} }
else
{
// it could have been changed by it
newSashPosition = event.GetSashPosition();
} }
return newSashPosition; return newSashPosition;