Merge branch 'grid-dragmove'

Improve UI of dragging the wxGrid columns/rows to move them.

See #22457.
This commit is contained in:
Vadim Zeitlin
2022-06-05 13:39:35 +01:00
2 changed files with 100 additions and 31 deletions

View File

@@ -2804,9 +2804,12 @@ protected:
// operation in progress.
int m_dragMoveRowOrCol;
// Last horizontal mouse position while drag-moving a column.
// Last drag marker position while drag-moving a row or column.
int m_dragLastPos;
// Last drag marker colour while drag-moving a row or column.
const wxColour *m_dragLastColour;
// Row or column (depending on m_cursorMode value) currently being resized
// or -1 if there is no resize operation in progress.
int m_dragRowOrCol;
@@ -2988,6 +2991,10 @@ private:
void CheckDoDragScroll(wxGridSubwindow *eventGridWindow, wxGridSubwindow *gridWindow,
wxPoint posEvent, int direction);
// helper for Process...LabelMouseEvent to check whether a drag operation
// would end at the source line, i.e. have no effect
bool CheckIfAtDragSourceLine(const wxGridOperations &oper, int coord);
// return true if the grid should be refreshed right now
bool ShouldRefresh() const
{

View File

@@ -3061,6 +3061,7 @@ void wxGrid::Init()
m_canDragCell = false;
m_dragMoveRowOrCol = -1;
m_dragLastPos = -1;
m_dragLastColour = NULL;
m_dragRowOrCol = -1;
m_dragRowOrColOldSize = -1;
m_isDragging = false;
@@ -3981,6 +3982,33 @@ bool wxGrid::CheckIfDragCancelled(wxMouseEvent *event)
return false;
}
bool wxGrid::CheckIfAtDragSourceLine(const wxGridOperations &oper, int coord)
{
// check whether coord on the dragged line or at max half of a line away
// (the sizes of the lines before/after can be 0, if they are hidden)
int minCoord = oper.GetLineStartPos(this, m_dragMoveRowOrCol);
int maxCoord = minCoord + oper.GetLineSize(this, m_dragMoveRowOrCol);
int lineBefore = oper.GetLineBefore(this, m_dragMoveRowOrCol);
if ( lineBefore == -1 && coord < maxCoord )
return true;
if ( lineBefore != -1 )
minCoord -= oper.GetLineSize(this, lineBefore) / 2;
int posAfter = oper.GetLinePos(this, m_dragMoveRowOrCol) + 1;
int lineAfter = posAfter < oper.GetTotalNumberOfLines(this) ?
oper.GetLineAt(this, posAfter) : -1;
if ( lineAfter == -1 && coord >= minCoord )
return true;
if ( lineAfter != -1 )
maxCoord += oper.GetLineSize(this, lineAfter) / 2;
if ( coord >= minCoord && coord < maxCoord )
return true;
return false;
}
void wxGrid::ProcessRowColLabelMouseEvent( const wxGridOperations &oper, wxMouseEvent& event, wxGridSubwindow* labelWin )
{
const wxGridOperations &dual = oper.Dual();
@@ -4062,15 +4090,22 @@ void wxGrid::ProcessRowColLabelMouseEvent( const wxGridOperations &oper, wxMouse
else
markerPos = oper.GetLineStartPos(this, lineAt);
if ( markerPos != m_dragLastPos )
const wxColour *markerColour;
// Moving to the same place? Draw a grey marker.
if ( CheckIfAtDragSourceLine(oper, coord) )
markerColour = wxLIGHT_GREY;
else
markerColour = wxBLUE;
if ( markerPos != m_dragLastPos || markerColour != m_dragLastColour )
{
wxClientDC dc( headerWin );
oper.PrepareDCForLabels(this, dc);
int markerLength = oper.Select(headerWin->GetClientSize());
// Clean up the last indicator
if ( m_dragLastPos >= 0 )
// Clean up the last indicator if position has changed
if ( m_dragLastPos >= 0 && markerPos != m_dragLastPos )
{
wxPen pen(headerWin->GetBackgroundColour(), 2);
dc.SetPen(pen);
@@ -4083,20 +4118,14 @@ void wxGrid::ProcessRowColLabelMouseEvent( const wxGridOperations &oper, wxMouse
oper.DrawLineLabel(this, dc, lastLine);
}
const wxColour *color;
// Moving to the same place? Don't draw a marker
if ( lineAt == m_dragMoveRowOrCol )
color = wxLIGHT_GREY;
else
color = wxBLUE;
// Draw the marker
wxPen pen(*color, 2);
wxPen pen(*markerColour, 2);
dc.SetPen(pen);
oper.DrawParallelLine(dc, 0, markerLength, markerPos + 1);
dc.SetPen(wxNullPen);
m_dragLastPos = markerPos;
m_dragLastColour = markerColour;
}
}
}
@@ -4130,18 +4159,13 @@ void wxGrid::ProcessRowColLabelMouseEvent( const wxGridOperations &oper, wxMouse
{
if ( oper.CanDragMove(this) )
{
ChangeCursorMode(oper.GetCursorModeMove(), headerWin);
// Show button as pressed
m_dragMoveRowOrCol = line;
wxClientDC dc( headerWin );
oper.PrepareDCForLabels(this, dc);
dc.SetPen( wxPen( headerWin->GetBackgroundColour(), 1 ) );
int lineStart = oper.GetLineStartPos(this, line);
int lineEnd = oper.GetLineEndPos(this, line) - 1;
int lineLength = oper.Select(headerWin->GetClientSize()) - 1;
oper.DrawParallelLine(dc, 0, lineLength, lineStart);
dual.DrawParallelLine(dc, lineStart, lineEnd, 1);
ChangeCursorMode(oper.GetCursorModeMove(), headerWin);
oper.DrawLineLabel(this, dc, line);
}
else
{
@@ -4226,7 +4250,7 @@ void wxGrid::ProcessRowColLabelMouseEvent( const wxGridOperations &oper, wxMouse
}
else if ( m_cursorMode == oper.GetCursorModeMove() )
{
if ( m_dragLastPos == -1 || line == m_dragMoveRowOrCol )
if ( CheckIfAtDragSourceLine(oper, coord) )
{
// the line didn't actually move anywhere, "unpress" the label
if ( oper.GetOrientation() == wxVERTICAL && line != -1 )
@@ -4259,11 +4283,7 @@ void wxGrid::ProcessRowColLabelMouseEvent( const wxGridOperations &oper, wxMouse
{
DoColHeaderClick(line);
}
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, labelWin);
m_dragLastPos = -1;
m_lastMousePos = wxDefaultPosition;
m_isDragging = false;
EndDraggingIfNecessary();
}
// ------------ Right button down
@@ -4489,6 +4509,9 @@ void wxGrid::CancelMouseCapture()
// cancel operation currently in progress, whatever it is
if ( m_winCapture )
{
if ( m_cursorMode == WXGRID_CURSOR_MOVE_COL ||
m_cursorMode == WXGRID_CURSOR_MOVE_ROW )
m_winCapture->Refresh();
DoAfterDraggingEnd();
}
}
@@ -4506,6 +4529,10 @@ void wxGrid::DoAfterDraggingEnd()
m_isDragging = false;
m_startDragPos = wxDefaultPosition;
m_lastMousePos = wxDefaultPosition;
// from drag moving row/col
m_dragMoveRowOrCol = -1;
m_dragLastPos = -1;
m_dragLastColour = NULL;
m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
m_winCapture->SetCursor( *wxSTANDARD_CURSOR );
@@ -5998,6 +6025,7 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
// end row/column moving
m_winCapture->Refresh();
m_dragLastPos = -1;
m_dragLastColour = NULL;
break;
case WXGRID_CURSOR_RESIZE_ROW:
@@ -7069,7 +7097,28 @@ void wxGrid::DrawRowLabel( wxDC& dc, int row )
(gs_defaultHeaderRenderers.rowRenderer);
wxRect rect(0, GetRowTop(row), m_rowLabelWidth, GetRowHeight(row));
rend.DrawBorder(*this, dc, rect);
if ( m_cursorMode == WXGRID_CURSOR_MOVE_ROW )
{
// clear the background:
// when called from ProcessRowColLabelMouseEvent the background is not
// cleared at this point
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(m_colLabelWin->GetBackgroundColour());
dc.DrawRectangle(rect);
}
// draw a border if the row is not being drag-moved
// (in that case it's omitted to have a 'pressed' appearance)
if (m_cursorMode != WXGRID_CURSOR_MOVE_ROW || row != m_dragMoveRowOrCol)
rend.DrawBorder(*this, dc, rect);
else
{
// just highlight the current row
dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT)));
dc.DrawRectangle(rect);
rect.Deflate(GetBorder() == wxBORDER_NONE ? 2 : 1);
}
int hAlign, vAlign;
GetRowLabelAlignment(&hAlign, &vAlign);
@@ -7204,15 +7253,28 @@ void wxGrid::DrawColLabel(wxDC& dc, int col)
}
else
{
// It is reported that we need to erase the background to avoid display
// artefacts, see #12055.
if ( m_cursorMode == WXGRID_CURSOR_MOVE_COL )
{
// clear the background:
// when called from ProcessRowColLabelMouseEvent the background
// is not cleared at this point
wxDCBrushChanger setBrush(dc, m_colLabelWin->GetBackgroundColour());
wxDCPenChanger setPen(dc, *wxTRANSPARENT_PEN);
dc.DrawRectangle(rect);
}
rend.DrawBorder(*this, dc, rect);
// draw a border if the column is not being drag-moved
// (in that case it's omitted to have a 'pressed' appearance)
if (m_cursorMode != WXGRID_CURSOR_MOVE_COL || col != m_dragMoveRowOrCol)
rend.DrawBorder(*this, dc, rect);
else
{
// just highlight the current column
dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT)));
dc.DrawRectangle(rect);
rect.Deflate(GetBorder() == wxBORDER_NONE ? 2 : 1);
}
}
int hAlign, vAlign;