From 65470df33272eff1b5082695bb29a688dd9dca63 Mon Sep 17 00:00:00 2001 From: DietmarSchwertberger Date: Sun, 22 May 2022 21:14:39 +0200 Subject: [PATCH 1/8] introduce CheckIfAtDragSourceLine for a better check if line would be moved; check also f. marker colour change --- include/wx/generic/grid.h | 9 ++++++- src/generic/grid.cpp | 55 ++++++++++++++++++++++++++++++--------- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index 383adc3fa3..d0b7224f4e 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -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 column. int m_dragLastPos; + // Last drag marker colour while drag-moving a 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 { diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 3e4af93b73..36f933bd72 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -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; } } } @@ -4226,7 +4255,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 ) @@ -4262,6 +4291,7 @@ void wxGrid::ProcessRowColLabelMouseEvent( const wxGridOperations &oper, wxMouse ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, labelWin); m_dragLastPos = -1; + m_dragLastColour = NULL; m_lastMousePos = wxDefaultPosition; m_isDragging = false; } @@ -5998,6 +6028,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: From 6cdbd0da1f7bb1921f86e42bdb2b338f8d9d81a3 Mon Sep 17 00:00:00 2001 From: DietmarSchwertberger Date: Mon, 23 May 2022 19:19:15 +0200 Subject: [PATCH 2/8] improve and simplify drawing of (pressed) row/col label --- src/generic/grid.cpp | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 36f933bd72..e438b37d7c 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -4159,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 { @@ -4290,6 +4285,7 @@ void wxGrid::ProcessRowColLabelMouseEvent( const wxGridOperations &oper, wxMouse } ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, labelWin); + m_dragMoveRowOrCol = -1; m_dragLastPos = -1; m_dragLastColour = NULL; m_lastMousePos = wxDefaultPosition; @@ -7100,7 +7096,21 @@ 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); int hAlign, vAlign; GetRowLabelAlignment(&hAlign, &vAlign); @@ -7235,15 +7245,21 @@ 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); } int hAlign, vAlign; From c3d3487ead537dcf76eb4bc50509bdd815e924d4 Mon Sep 17 00:00:00 2001 From: DietmarSchwertberger Date: Thu, 26 May 2022 12:05:43 +0200 Subject: [PATCH 3/8] Redraw label window when mouse capture is lost. while drag move --- src/generic/grid.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index e438b37d7c..d852e4d2f3 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -4515,6 +4515,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(); } } From 4b04384b98046ed16bb8553b6bea9200d2091ba2 Mon Sep 17 00:00:00 2001 From: DietmarSchwertberger Date: Wed, 1 Jun 2022 21:11:56 +0200 Subject: [PATCH 4/8] improve comments --- include/wx/generic/grid.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index d0b7224f4e..1bd58bbf04 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -2804,10 +2804,10 @@ protected: // operation in progress. int m_dragMoveRowOrCol; - // Last drag marker 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 column. + // 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 From 956618db6aa51d0c1a2bcdc0bf20389f87f531a4 Mon Sep 17 00:00:00 2001 From: DietmarSchwertberger Date: Wed, 1 Jun 2022 21:21:11 +0200 Subject: [PATCH 5/8] refactor: reset variables in EndDraggingIfNecessary --- src/generic/grid.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index d852e4d2f3..0437234895 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -4283,13 +4283,7 @@ void wxGrid::ProcessRowColLabelMouseEvent( const wxGridOperations &oper, wxMouse { DoColHeaderClick(line); } - - ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, labelWin); - m_dragMoveRowOrCol = -1; - m_dragLastPos = -1; - m_dragLastColour = NULL; - m_lastMousePos = wxDefaultPosition; - m_isDragging = false; + EndDraggingIfNecessary(); } // ------------ Right button down @@ -4535,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 ); From 1457c5736853b655e1b554c1424e0f9df539fda1 Mon Sep 17 00:00:00 2001 From: DietmarSchwertberger Date: Wed, 1 Jun 2022 21:27:43 +0200 Subject: [PATCH 6/8] highlight dragged col/row label on GTK --- src/generic/grid.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 0437234895..cf8f189500 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -7112,6 +7112,17 @@ void wxGrid::DrawRowLabel( wxDC& dc, int row ) // (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 + { +#ifdef __WXGTK__ + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT))); + dc.DrawRectangle(rect); +#endif + if ( GetBorder() == wxBORDER_NONE ) + rect.Deflate(2); + else + rect.Deflate(1); + } int hAlign, vAlign; GetRowLabelAlignment(&hAlign, &vAlign); @@ -7261,6 +7272,17 @@ void wxGrid::DrawColLabel(wxDC& dc, int col) // (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 + { +#ifdef __WXGTK__ + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT))); + dc.DrawRectangle(rect); +#endif + if ( GetBorder() == wxBORDER_NONE ) + rect.Deflate(2); + else + rect.Deflate(1); + } } int hAlign, vAlign; From 583a9aa557c39bd7ae9261875b8cdc557a2aec1a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 4 Jun 2022 17:09:26 +0200 Subject: [PATCH 7/8] Use ternary operator instead of an "if" No real changes, but calling wxRect::Deflate() once here with the value depending on whether wxBORDER_NONE is used seems more clear in this particular context. --- src/generic/grid.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index cf8f189500..e74135db48 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -7118,10 +7118,7 @@ void wxGrid::DrawRowLabel( wxDC& dc, int row ) dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT))); dc.DrawRectangle(rect); #endif - if ( GetBorder() == wxBORDER_NONE ) - rect.Deflate(2); - else - rect.Deflate(1); + rect.Deflate(GetBorder() == wxBORDER_NONE ? 2 : 1); } int hAlign, vAlign; @@ -7278,10 +7275,7 @@ void wxGrid::DrawColLabel(wxDC& dc, int col) dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT))); dc.DrawRectangle(rect); #endif - if ( GetBorder() == wxBORDER_NONE ) - rect.Deflate(2); - else - rect.Deflate(1); + rect.Deflate(GetBorder() == wxBORDER_NONE ? 2 : 1); } } From b202dec93cd38c3c0684682a834a77c5eeb070de Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 4 Jun 2022 16:17:10 +0100 Subject: [PATCH 8/8] Highlight the grid row/column being dragged on all platforms Remove __WXGTK__ checks and highlight it everywhere, this can be useful under other platforms too depending on the colour schema and not having platform-specific checks is better than having them if they're not absolutely required. If we really want to avoid highlighting in some cases, we should check for the contrast between the border and background colours, but it seems to be much simpler to just always show it. --- src/generic/grid.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index e74135db48..51363b09a1 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -7114,10 +7114,9 @@ void wxGrid::DrawRowLabel( wxDC& dc, int row ) rend.DrawBorder(*this, dc, rect); else { -#ifdef __WXGTK__ + // just highlight the current row dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT))); dc.DrawRectangle(rect); -#endif rect.Deflate(GetBorder() == wxBORDER_NONE ? 2 : 1); } @@ -7271,10 +7270,9 @@ void wxGrid::DrawColLabel(wxDC& dc, int col) rend.DrawBorder(*this, dc, rect); else { -#ifdef __WXGTK__ + // just highlight the current column dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT))); dc.DrawRectangle(rect); -#endif rect.Deflate(GetBorder() == wxBORDER_NONE ? 2 : 1); } }