Fix dragging beyond the rightmost column in generic wxHeaderCtrl
Dragging a column header in a wxHeaderCtrl and dropping it past the rightmost column resulted in a crash due to accessing a column with invalid index. Fix this and correctly move the column to the last position when this happens instead. This bug notably affected dragging columns in wxGrid. Closes https://github.com/wxWidgets/wxWidgets/pull/972
This commit is contained in:
committed by
Vadim Zeitlin
parent
6e3f818da1
commit
b07305234c
@@ -98,6 +98,10 @@ private:
|
||||
// column 1 but close enough to the divider separating it from column 0)
|
||||
unsigned int FindColumnAtPoint(int x, bool *onSeparator = NULL) const;
|
||||
|
||||
// return the result of FindColumnAtPoint() if it is a valid column,
|
||||
// otherwise the index of the last (rightmost) displayed column
|
||||
unsigned int FindColumnClosestToPoint(int xPhysical) const;
|
||||
|
||||
// return true if a drag resizing operation is currently in progress
|
||||
bool IsResizing() const;
|
||||
|
||||
|
@@ -208,6 +208,23 @@ unsigned int wxHeaderCtrl::FindColumnAtPoint(int xPhysical, bool *onSeparator) c
|
||||
return COL_NONE;
|
||||
}
|
||||
|
||||
unsigned int wxHeaderCtrl::FindColumnClosestToPoint(int xPhysical) const
|
||||
{
|
||||
const unsigned int colIndexAtPoint = FindColumnAtPoint(xPhysical);
|
||||
|
||||
// valid column found?
|
||||
if ( colIndexAtPoint != COL_NONE )
|
||||
return colIndexAtPoint;
|
||||
|
||||
// if not, xPhysical must be beyond the rightmost column, so return its
|
||||
// index instead -- if we have it
|
||||
const unsigned int count = GetColumnCount();
|
||||
if ( !count )
|
||||
return COL_NONE;
|
||||
|
||||
return m_colIndices[count - 1];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxHeaderCtrl repainting
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -372,7 +389,7 @@ void wxHeaderCtrl::UpdateReorderingMarker(int xPhysical)
|
||||
|
||||
// and also a hint indicating where it is going to be inserted if it's
|
||||
// dropped now
|
||||
unsigned int col = FindColumnAtPoint(xPhysical);
|
||||
unsigned int col = FindColumnClosestToPoint(xPhysical);
|
||||
if ( col != COL_NONE )
|
||||
{
|
||||
static const int DROP_MARKER_WIDTH = 4;
|
||||
@@ -414,15 +431,24 @@ bool wxHeaderCtrl::EndReordering(int xPhysical)
|
||||
|
||||
ReleaseMouse();
|
||||
|
||||
const int colOld = m_colBeingReordered,
|
||||
colNew = FindColumnAtPoint(xPhysical);
|
||||
const int colOld = m_colBeingReordered;
|
||||
const unsigned colNew = FindColumnClosestToPoint(xPhysical);
|
||||
|
||||
m_colBeingReordered = COL_NONE;
|
||||
|
||||
// mouse drag must be longer than min distance m_dragOffset
|
||||
if ( xPhysical - GetColStart(colOld) == m_dragOffset )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( colNew != colOld )
|
||||
// cannot proceed without a valid column index
|
||||
if ( colNew == COL_NONE )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( static_cast<int>(colNew) != colOld )
|
||||
{
|
||||
wxHeaderCtrlEvent event(wxEVT_HEADER_END_REORDER, GetId());
|
||||
event.SetEventObject(this);
|
||||
|
Reference in New Issue
Block a user