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())
|
||||
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
|
||||
// position
|
||||
@@ -2238,8 +2246,12 @@ private:
|
||||
// process row/column resizing drag event
|
||||
void DoGridLineDrag(wxMouseEvent& event, const wxGridOperations& oper);
|
||||
|
||||
// process mouse drag event in the grid window
|
||||
void DoGridDragEvent(wxMouseEvent& event, const wxGridCellCoords& coords);
|
||||
// process mouse drag event in the grid window, return false if starting
|
||||
// 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
|
||||
void DoGridCellLeftDown(wxMouseEvent& event,
|
||||
|
@@ -2418,7 +2418,6 @@ void wxGrid::Init()
|
||||
m_selection = NULL;
|
||||
m_defaultCellAttr = NULL;
|
||||
m_typeRegistry = NULL;
|
||||
m_winCapture = NULL;
|
||||
|
||||
m_rowLabelWidth = WXGRID_DEFAULT_ROW_LABEL_WIDTH;
|
||||
m_colLabelHeight = WXGRID_DEFAULT_COL_LABEL_HEIGHT;
|
||||
@@ -3847,18 +3846,33 @@ void wxGrid::CancelMouseCapture()
|
||||
// cancel operation currently in progress, whatever it is
|
||||
if ( m_winCapture )
|
||||
{
|
||||
m_isDragging = false;
|
||||
m_startDragPos = wxDefaultPosition;
|
||||
|
||||
m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
|
||||
m_winCapture->SetCursor( *wxSTANDARD_CURSOR );
|
||||
m_winCapture = NULL;
|
||||
DoAfterDraggingEnd();
|
||||
|
||||
// remove traces of whatever we drew on screen
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void wxGrid::DoAfterDraggingEnd()
|
||||
{
|
||||
m_isDragging = false;
|
||||
m_startDragPos = wxDefaultPosition;
|
||||
|
||||
m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
|
||||
m_winCapture->SetCursor( *wxSTANDARD_CURSOR );
|
||||
m_winCapture = NULL;
|
||||
}
|
||||
|
||||
void wxGrid::EndDraggingIfNecessary()
|
||||
{
|
||||
if ( m_winCapture )
|
||||
{
|
||||
m_winCapture->ReleaseMouse();
|
||||
|
||||
DoAfterDraggingEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void wxGrid::ChangeCursorMode(CursorMode mode,
|
||||
wxWindow *win,
|
||||
bool captureMouse)
|
||||
@@ -3893,11 +3907,7 @@ void wxGrid::ChangeCursorMode(CursorMode mode,
|
||||
win = m_gridWin;
|
||||
}
|
||||
|
||||
if ( m_winCapture )
|
||||
{
|
||||
m_winCapture->ReleaseMouse();
|
||||
m_winCapture = NULL;
|
||||
}
|
||||
EndDraggingIfNecessary();
|
||||
|
||||
m_cursorMode = mode;
|
||||
|
||||
@@ -4015,34 +4025,14 @@ void wxGrid::DoGridLineDrag(wxMouseEvent& event, const wxGridOperations& oper)
|
||||
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 )
|
||||
{
|
||||
case WXGRID_CURSOR_SELECT_CELL:
|
||||
// no further handling if handled by user
|
||||
if ( DoGridCellDrag(event, coords, isFirstDrag) == false )
|
||||
return;
|
||||
break;
|
||||
return DoGridCellDrag(event, coords, isFirstDrag);
|
||||
|
||||
case WXGRID_CURSOR_RESIZE_ROW:
|
||||
DoGridLineDrag(event, wxGridRowOperations());
|
||||
@@ -4056,13 +4046,7 @@ void wxGrid::DoGridDragEvent(wxMouseEvent& event, const wxGridCellCoords& coords
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
if ( isFirstDrag )
|
||||
{
|
||||
wxASSERT_MSG( !m_winCapture, "shouldn't capture the mouse twice" );
|
||||
|
||||
m_winCapture = m_gridWin;
|
||||
m_winCapture->CaptureMouse();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4156,12 +4140,6 @@ wxGrid::DoGridCellLeftUp(wxMouseEvent& event, const wxGridCellCoords& coords)
|
||||
{
|
||||
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
|
||||
{
|
||||
if (m_winCapture)
|
||||
{
|
||||
m_winCapture->ReleaseMouse();
|
||||
m_winCapture = NULL;
|
||||
}
|
||||
|
||||
if ( coords == m_currentCellCoords && m_waitForSlowClick && CanEnableCellControl() )
|
||||
{
|
||||
ClearSelection();
|
||||
@@ -4262,14 +4240,6 @@ wxGrid::DoGridMouseMoveEvent(wxMouseEvent& WXUNUSED(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());
|
||||
|
||||
// coordinates of the cell under mouse
|
||||
@@ -4283,17 +4253,64 @@ void wxGrid::ProcessGridCellMouseEvent(wxMouseEvent& event)
|
||||
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() )
|
||||
DoGridDragEvent(event, coords);
|
||||
else
|
||||
event.Skip();
|
||||
// Note that we must call this one first, before resetting the
|
||||
// drag-related data, as it relies on m_cursorMode being still set and
|
||||
// EndDraggingIfNecessary() resets it.
|
||||
DoGridCellLeftUp(event, coords);
|
||||
|
||||
EndDraggingIfNecessary();
|
||||
return;
|
||||
}
|
||||
|
||||
m_isDragging = false;
|
||||
m_startDragPos = wxDefaultPosition;
|
||||
const bool isDraggingWithLeft = event.Dragging() && event.LeftIsDown();
|
||||
|
||||
// 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
|
||||
if ( event.IsButton() )
|
||||
@@ -4311,12 +4328,6 @@ void wxGrid::ProcessGridCellMouseEvent(wxMouseEvent& event)
|
||||
else if ( event.RightDClick() )
|
||||
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() )
|
||||
{
|
||||
|
Reference in New Issue
Block a user