Merge branch 'grid-mouse'
Improve mouse event handling in wxGrid during drag operations. See https://github.com/wxWidgets/wxWidgets/pull/891 Closes #18186.
This commit is contained in:
@@ -2218,6 +2218,14 @@ private:
|
|||||||
// SetColPos() and ResetColPos())
|
// SetColPos() and ResetColPos())
|
||||||
void RefreshAfterColPosChange();
|
void RefreshAfterColPosChange();
|
||||||
|
|
||||||
|
// reset the variables used during dragging operations after it ended,
|
||||||
|
// either because we called EndDraggingIfNecessary() ourselves or because
|
||||||
|
// we lost mouse capture
|
||||||
|
void DoAfterDraggingEnd();
|
||||||
|
|
||||||
|
// release the mouse capture if it's currently captured
|
||||||
|
void EndDraggingIfNecessary();
|
||||||
|
|
||||||
|
|
||||||
// return the position (not index) of the column at the given logical pixel
|
// return the position (not index) of the column at the given logical pixel
|
||||||
// position
|
// position
|
||||||
@@ -2238,8 +2246,12 @@ private:
|
|||||||
// process row/column resizing drag event
|
// process row/column resizing drag event
|
||||||
void DoGridLineDrag(wxMouseEvent& event, const wxGridOperations& oper);
|
void DoGridLineDrag(wxMouseEvent& event, const wxGridOperations& oper);
|
||||||
|
|
||||||
// process mouse drag event in the grid window
|
// process mouse drag event in the grid window, return false if starting
|
||||||
void DoGridDragEvent(wxMouseEvent& event, const wxGridCellCoords& coords);
|
// dragging was vetoed by the user-defined wxEVT_GRID_CELL_BEGIN_DRAG
|
||||||
|
// handler
|
||||||
|
bool DoGridDragEvent(wxMouseEvent& event,
|
||||||
|
const wxGridCellCoords& coords,
|
||||||
|
bool isFirstDrag);
|
||||||
|
|
||||||
// process different clicks on grid cells
|
// process different clicks on grid cells
|
||||||
void DoGridCellLeftDown(wxMouseEvent& event,
|
void DoGridCellLeftDown(wxMouseEvent& event,
|
||||||
|
@@ -2418,7 +2418,6 @@ void wxGrid::Init()
|
|||||||
m_selection = NULL;
|
m_selection = NULL;
|
||||||
m_defaultCellAttr = NULL;
|
m_defaultCellAttr = NULL;
|
||||||
m_typeRegistry = NULL;
|
m_typeRegistry = NULL;
|
||||||
m_winCapture = NULL;
|
|
||||||
|
|
||||||
m_rowLabelWidth = WXGRID_DEFAULT_ROW_LABEL_WIDTH;
|
m_rowLabelWidth = WXGRID_DEFAULT_ROW_LABEL_WIDTH;
|
||||||
m_colLabelHeight = WXGRID_DEFAULT_COL_LABEL_HEIGHT;
|
m_colLabelHeight = WXGRID_DEFAULT_COL_LABEL_HEIGHT;
|
||||||
@@ -3846,6 +3845,15 @@ void wxGrid::CancelMouseCapture()
|
|||||||
{
|
{
|
||||||
// cancel operation currently in progress, whatever it is
|
// cancel operation currently in progress, whatever it is
|
||||||
if ( m_winCapture )
|
if ( m_winCapture )
|
||||||
|
{
|
||||||
|
DoAfterDraggingEnd();
|
||||||
|
|
||||||
|
// remove traces of whatever we drew on screen
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxGrid::DoAfterDraggingEnd()
|
||||||
{
|
{
|
||||||
m_isDragging = false;
|
m_isDragging = false;
|
||||||
m_startDragPos = wxDefaultPosition;
|
m_startDragPos = wxDefaultPosition;
|
||||||
@@ -3853,9 +3861,15 @@ void wxGrid::CancelMouseCapture()
|
|||||||
m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
|
m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
|
||||||
m_winCapture->SetCursor( *wxSTANDARD_CURSOR );
|
m_winCapture->SetCursor( *wxSTANDARD_CURSOR );
|
||||||
m_winCapture = NULL;
|
m_winCapture = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// remove traces of whatever we drew on screen
|
void wxGrid::EndDraggingIfNecessary()
|
||||||
Refresh();
|
{
|
||||||
|
if ( m_winCapture )
|
||||||
|
{
|
||||||
|
m_winCapture->ReleaseMouse();
|
||||||
|
|
||||||
|
DoAfterDraggingEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3893,11 +3907,7 @@ void wxGrid::ChangeCursorMode(CursorMode mode,
|
|||||||
win = m_gridWin;
|
win = m_gridWin;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_winCapture )
|
EndDraggingIfNecessary();
|
||||||
{
|
|
||||||
m_winCapture->ReleaseMouse();
|
|
||||||
m_winCapture = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_cursorMode = mode;
|
m_cursorMode = mode;
|
||||||
|
|
||||||
@@ -4015,34 +4025,14 @@ void wxGrid::DoGridLineDrag(wxMouseEvent& event, const wxGridOperations& oper)
|
|||||||
oper.DrawParallelLineInRect(dc, rectWin, m_dragLastPos);
|
oper.DrawParallelLineInRect(dc, rectWin, m_dragLastPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxGrid::DoGridDragEvent(wxMouseEvent& event, const wxGridCellCoords& coords)
|
bool wxGrid::DoGridDragEvent(wxMouseEvent& event,
|
||||||
|
const wxGridCellCoords& coords,
|
||||||
|
bool isFirstDrag)
|
||||||
{
|
{
|
||||||
if ( !m_isDragging )
|
|
||||||
{
|
|
||||||
// Don't start doing anything until the mouse has been dragged far
|
|
||||||
// enough
|
|
||||||
const wxPoint& pt = event.GetPosition();
|
|
||||||
if ( m_startDragPos == wxDefaultPosition )
|
|
||||||
{
|
|
||||||
m_startDragPos = pt;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( abs(m_startDragPos.x - pt.x) <= DRAG_SENSITIVITY &&
|
|
||||||
abs(m_startDragPos.y - pt.y) <= DRAG_SENSITIVITY )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool isFirstDrag = !m_isDragging;
|
|
||||||
m_isDragging = true;
|
|
||||||
|
|
||||||
switch ( m_cursorMode )
|
switch ( m_cursorMode )
|
||||||
{
|
{
|
||||||
case WXGRID_CURSOR_SELECT_CELL:
|
case WXGRID_CURSOR_SELECT_CELL:
|
||||||
// no further handling if handled by user
|
return DoGridCellDrag(event, coords, isFirstDrag);
|
||||||
if ( DoGridCellDrag(event, coords, isFirstDrag) == false )
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WXGRID_CURSOR_RESIZE_ROW:
|
case WXGRID_CURSOR_RESIZE_ROW:
|
||||||
DoGridLineDrag(event, wxGridRowOperations());
|
DoGridLineDrag(event, wxGridRowOperations());
|
||||||
@@ -4056,13 +4046,7 @@ void wxGrid::DoGridDragEvent(wxMouseEvent& event, const wxGridCellCoords& coords
|
|||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isFirstDrag )
|
return true;
|
||||||
{
|
|
||||||
wxASSERT_MSG( !m_winCapture, "shouldn't capture the mouse twice" );
|
|
||||||
|
|
||||||
m_winCapture = m_gridWin;
|
|
||||||
m_winCapture->CaptureMouse();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -4156,12 +4140,6 @@ wxGrid::DoGridCellLeftUp(wxMouseEvent& event, const wxGridCellCoords& coords)
|
|||||||
{
|
{
|
||||||
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
|
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
|
||||||
{
|
{
|
||||||
if (m_winCapture)
|
|
||||||
{
|
|
||||||
m_winCapture->ReleaseMouse();
|
|
||||||
m_winCapture = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( coords == m_currentCellCoords && m_waitForSlowClick && CanEnableCellControl() )
|
if ( coords == m_currentCellCoords && m_waitForSlowClick && CanEnableCellControl() )
|
||||||
{
|
{
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
@@ -4262,14 +4240,6 @@ wxGrid::DoGridMouseMoveEvent(wxMouseEvent& WXUNUSED(event),
|
|||||||
|
|
||||||
void wxGrid::ProcessGridCellMouseEvent(wxMouseEvent& event)
|
void wxGrid::ProcessGridCellMouseEvent(wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
if ( event.Entering() || event.Leaving() )
|
|
||||||
{
|
|
||||||
// we don't care about these events but we must not reset m_isDragging
|
|
||||||
// if they happen so return before anything else is done
|
|
||||||
event.Skip();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxPoint pos = CalcUnscrolledPosition(event.GetPosition());
|
const wxPoint pos = CalcUnscrolledPosition(event.GetPosition());
|
||||||
|
|
||||||
// coordinates of the cell under mouse
|
// coordinates of the cell under mouse
|
||||||
@@ -4283,17 +4253,64 @@ void wxGrid::ProcessGridCellMouseEvent(wxMouseEvent& event)
|
|||||||
coords.SetCol(coords.GetCol() + cell_cols);
|
coords.SetCol(coords.GetCol() + cell_cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( event.Dragging() )
|
// Releasing the left mouse button must be processed in any case, so deal
|
||||||
|
// with it first.
|
||||||
|
if ( event.LeftUp() )
|
||||||
{
|
{
|
||||||
if ( event.LeftIsDown() )
|
// Note that we must call this one first, before resetting the
|
||||||
DoGridDragEvent(event, coords);
|
// drag-related data, as it relies on m_cursorMode being still set and
|
||||||
else
|
// EndDraggingIfNecessary() resets it.
|
||||||
event.Skip();
|
DoGridCellLeftUp(event, coords);
|
||||||
|
|
||||||
|
EndDraggingIfNecessary();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_isDragging = false;
|
const bool isDraggingWithLeft = event.Dragging() && event.LeftIsDown();
|
||||||
m_startDragPos = wxDefaultPosition;
|
|
||||||
|
// While dragging the mouse, only releasing the left mouse button, which
|
||||||
|
// cancels the drag operation, is processed (above) and any other events
|
||||||
|
// are just ignored while it's in progress.
|
||||||
|
if ( m_isDragging )
|
||||||
|
{
|
||||||
|
if ( isDraggingWithLeft )
|
||||||
|
DoGridDragEvent(event, coords, false /* not first drag */);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check if we're starting a drag operation (if it had been already
|
||||||
|
// started, m_isDragging would be true above).
|
||||||
|
if ( isDraggingWithLeft )
|
||||||
|
{
|
||||||
|
// To avoid accidental drags, don't start doing anything until the
|
||||||
|
// mouse has been dragged far enough.
|
||||||
|
const wxPoint& pt = event.GetPosition();
|
||||||
|
if ( m_startDragPos == wxDefaultPosition )
|
||||||
|
{
|
||||||
|
m_startDragPos = pt;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( abs(m_startDragPos.x - pt.x) <= DRAG_SENSITIVITY &&
|
||||||
|
abs(m_startDragPos.y - pt.y) <= DRAG_SENSITIVITY )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( DoGridDragEvent(event, coords, true /* first drag */) )
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( !m_winCapture, "shouldn't capture the mouse twice" );
|
||||||
|
|
||||||
|
m_winCapture = m_gridWin;
|
||||||
|
m_winCapture->CaptureMouse();
|
||||||
|
|
||||||
|
m_isDragging = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're not dragging, cancel any dragging operation which could have
|
||||||
|
// been in progress.
|
||||||
|
EndDraggingIfNecessary();
|
||||||
|
|
||||||
// deal with various button presses
|
// deal with various button presses
|
||||||
if ( event.IsButton() )
|
if ( event.IsButton() )
|
||||||
@@ -4311,12 +4328,6 @@ void wxGrid::ProcessGridCellMouseEvent(wxMouseEvent& event)
|
|||||||
else if ( event.RightDClick() )
|
else if ( event.RightDClick() )
|
||||||
SendEvent(wxEVT_GRID_CELL_RIGHT_DCLICK, coords, event);
|
SendEvent(wxEVT_GRID_CELL_RIGHT_DCLICK, coords, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this one should be called even if we're not over any cell
|
|
||||||
if ( event.LeftUp() )
|
|
||||||
{
|
|
||||||
DoGridCellLeftUp(event, coords);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if ( event.Moving() )
|
else if ( event.Moving() )
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user