Unify wxGrid code for processing row and column mouse events

Reuse the same code for handling mouse events for both rows and columns
instead of duplicating almost (but not quite) the same code for both of
them.

As part of resolving the inconsistencies between the two versions, add
wxEVT_GRID_ROW_AUTO_SIZE corresponding to the existing event with the
same name for the columns.

Closes #22380.
This commit is contained in:
DietmarSchwertberger
2022-04-30 21:59:36 +02:00
committed by Vadim Zeitlin
parent 1660584a45
commit ec737396d8
5 changed files with 389 additions and 593 deletions

View File

@@ -2802,8 +2802,7 @@ protected:
// Index of the row or column being drag-moved or -1 if there is no move // Index of the row or column being drag-moved or -1 if there is no move
// operation in progress. // operation in progress.
int m_dragMoveRow; int m_dragMoveRowOrCol;
int m_dragMoveCol;
// Last horizontal mouse position while drag-moving a column. // Last horizontal mouse position while drag-moving a column.
int m_dragLastPos; int m_dragLastPos;
@@ -2885,10 +2884,10 @@ protected:
EventResult SendEvent(wxEventType evtType, const wxString& s = wxString()) EventResult SendEvent(wxEventType evtType, const wxString& s = wxString())
{ return SendEvent(evtType, m_currentCellCoords, s); } { return SendEvent(evtType, m_currentCellCoords, s); }
// send wxEVT_GRID_{ROW,COL}_SIZE or wxEVT_GRID_COL_AUTO_SIZE, return true // send wxEVT_GRID_{ROW,COL}_SIZE or wxEVT_GRID_{ROW,COL}_AUTO_SIZE, return true
// if the event was processed, false otherwise // if the event was processed, false otherwise
bool SendGridSizeEvent(wxEventType type, bool SendGridSizeEvent(wxEventType type,
int row, int col, int rowOrCol,
const wxMouseEvent& mouseEv); const wxMouseEvent& mouseEv);
void OnSize( wxSizeEvent& ); void OnSize( wxSizeEvent& );
@@ -2906,6 +2905,7 @@ protected:
{ return false; } { return false; }
friend class WXDLLIMPEXP_FWD_CORE wxGridSelection; friend class WXDLLIMPEXP_FWD_CORE wxGridSelection;
friend class wxGridOperations;
friend class wxGridRowOperations; friend class wxGridRowOperations;
friend class wxGridColumnOperations; friend class wxGridColumnOperations;
@@ -3047,19 +3047,18 @@ private:
void ProcessGridCellMouseEvent(wxMouseEvent& event, wxGridWindow* gridWindow); void ProcessGridCellMouseEvent(wxMouseEvent& event, wxGridWindow* gridWindow);
// process mouse events in the row/column labels/corner windows // process mouse events in the row/column labels/corner windows
void ProcessRowLabelMouseEvent(wxMouseEvent& event, void ProcessRowColLabelMouseEvent(const wxGridOperations &oper,
wxGridRowLabelWindow* rowLabelWin); wxMouseEvent& event,
void ProcessColLabelMouseEvent(wxMouseEvent& event, wxGridSubwindow* rowLabelWin);
wxGridColLabelWindow* colLabelWin);
void ProcessCornerLabelMouseEvent(wxMouseEvent& event); void ProcessCornerLabelMouseEvent(wxMouseEvent& event);
void HandleRowAutosize(int col, const wxMouseEvent& event);
void HandleColumnAutosize(int col, const wxMouseEvent& event); void HandleColumnAutosize(int col, const wxMouseEvent& event);
void DoColHeaderClick(int col); void DoColHeaderClick(int col);
void DoStartResizeRowOrCol(int col, int size); void DoStartResizeRowOrCol(int col, int size);
void DoStartMoveRow(int col); void DoStartMoveRowOrCol(int col);
void DoStartMoveCol(int col);
// These functions should only be called when actually resizing/moving, // These functions should only be called when actually resizing/moving,
// i.e. m_dragRowOrCol and m_dragMoveCol, respectively, are valid. // i.e. m_dragRowOrCol and m_dragMoveCol, respectively, are valid.
@@ -3486,6 +3485,7 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_LABEL_RIGHT_CLICK, wxGrid
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_LABEL_LEFT_DCLICK, wxGridEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_LABEL_LEFT_DCLICK, wxGridEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_LABEL_RIGHT_DCLICK, wxGridEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_LABEL_RIGHT_DCLICK, wxGridEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_ROW_SIZE, wxGridSizeEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_ROW_SIZE, wxGridSizeEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_ROW_AUTO_SIZE, wxGridSizeEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_COL_SIZE, wxGridSizeEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_COL_SIZE, wxGridSizeEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_COL_AUTO_SIZE, wxGridSizeEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_COL_AUTO_SIZE, wxGridSizeEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_RANGE_SELECTING, wxGridRangeSelectEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_RANGE_SELECTING, wxGridRangeSelectEvent );

View File

@@ -17,6 +17,9 @@
#include "wx/headerctrl.h" #include "wx/headerctrl.h"
// for wxGridOperations
#include "wx/generic/gridsel.h"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// array classes // array classes
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -167,7 +170,7 @@ private:
// as this is done by the user we should notify the main program about // as this is done by the user we should notify the main program about
// it // it
GetOwner()->SendGridSizeEvent(wxEVT_GRID_COL_SIZE, -1, idx, GetOwner()->SendGridSizeEvent(wxEVT_GRID_COL_SIZE, idx,
GetDummyMouseEvent()); GetDummyMouseEvent());
} }
@@ -243,7 +246,7 @@ private:
void OnBeginReorder(wxHeaderCtrlEvent& event) void OnBeginReorder(wxHeaderCtrlEvent& event)
{ {
GetOwner()->DoStartMoveCol(event.GetColumn()); GetOwner()->DoStartMoveRowOrCol(event.GetColumn());
} }
void OnEndReorder(wxHeaderCtrlEvent& event) void OnEndReorder(wxHeaderCtrlEvent& event)
@@ -479,6 +482,14 @@ public:
// if this object is a wxGridColumnOperations and vice versa. // if this object is a wxGridColumnOperations and vice versa.
virtual wxGridOperations& Dual() const = 0; virtual wxGridOperations& Dual() const = 0;
// returns wxHORIZONTAL or wxVERTICAL for row/col operations
virtual int GetOrientation() const = 0;
// return row/col specific cursor modes
virtual wxGrid::CursorMode GetCursorModeResize() const = 0;
virtual wxGrid::CursorMode GetCursorModeSelect() const = 0;
virtual wxGrid::CursorMode GetCursorModeMove() const = 0;
// Return the total number of rows or columns. // Return the total number of rows or columns.
virtual int GetTotalNumberOfLines(const wxGrid *grid) const = 0; virtual int GetTotalNumberOfLines(const wxGrid *grid) const = 0;
@@ -568,6 +579,8 @@ public:
// Set the row default height or column default width // Set the row default height or column default width
virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const = 0; virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const = 0;
// auto size the row height or column width from the label content
virtual void HandleLineAutosize(wxGrid *grid, int line, const wxMouseEvent& event) const = 0;
// Return the index of the line at the given position // Return the index of the line at the given position
virtual int GetLineAt(const wxGrid *grid, int pos) const = 0; virtual int GetLineAt(const wxGrid *grid, int pos) const = 0;
@@ -587,6 +600,48 @@ public:
// Get the row or column frozen grid window // Get the row or column frozen grid window
virtual wxGridWindow *GetFrozenGrid(wxGrid* grid) const = 0; virtual wxGridWindow *GetFrozenGrid(wxGrid* grid) const = 0;
// return the value of m_canDragRow/ColMove
virtual bool CanDragMove(wxGrid *grid) const = 0;
// call DoEndMoveRow or DoEndMoveColumn
virtual void DoEndMove(wxGrid* grid, int line) const = 0;
// return whether the given row/column can be interactively resized
virtual bool CanDragLineSize(wxGrid *grid, int line) const = 0;
// call DoEndDragResizeRow or DoEndDragResizeCol
virtual void DoEndLineResize(wxGrid *grid, const wxMouseEvent& event, wxGridWindow* gridWindow) const = 0;
// extend current selection block up to given row or column
virtual bool SelectionExtendCurrentBlock(wxGrid *grid, int line,
const wxMouseEvent &event,
wxEventType eventType = wxEVT_GRID_RANGE_SELECTED) const = 0;
// select or de-select a row or column
virtual void SelectLine(wxGrid *grid, int line, wxMouseEvent &event) const = 0;
virtual void DeselectLine(wxGrid * grid, int line) const = 0;
// check whether the row or columns first cell is in selected
virtual bool IsLineInSelection(wxGrid *grid, int line) const = 0;
// sent a result with row or column and the other value -1
virtual wxGrid::EventResult SendEvent(wxGrid *grid, wxEventType eventType,
int line, const wxMouseEvent& event) const = 0;
// call DrawRowLabel or DrawColumnLabel
virtual void DrawLineLabel(wxGrid *grid, wxDC& dc, int line) const = 0;
// make the specified line visible by doing a minimal amount of scrolling
virtual void MakeLineVisible(wxGrid *grid, int line) const = 0;
// set cursor into the first visible cell of the given row or column
virtual void MakeLineCurrent(wxGrid *grid, int line) const = 0;
// This class is never used polymorphically but give it a virtual dtor // This class is never used polymorphically but give it a virtual dtor
// anyhow to suppress g++ complaints about it // anyhow to suppress g++ complaints about it
virtual ~wxGridOperations() { } virtual ~wxGridOperations() { }
@@ -597,6 +652,16 @@ class wxGridRowOperations : public wxGridOperations
public: public:
virtual wxGridOperations& Dual() const wxOVERRIDE; virtual wxGridOperations& Dual() const wxOVERRIDE;
virtual int GetOrientation() const wxOVERRIDE
{ return wxVERTICAL; }
virtual wxGrid::CursorMode GetCursorModeResize() const wxOVERRIDE
{ return wxGrid::WXGRID_CURSOR_RESIZE_ROW; }
virtual wxGrid::CursorMode GetCursorModeSelect() const wxOVERRIDE
{ return wxGrid::WXGRID_CURSOR_SELECT_ROW; }
virtual wxGrid::CursorMode GetCursorModeMove() const wxOVERRIDE
{ return wxGrid::WXGRID_CURSOR_MOVE_ROW; }
virtual int GetTotalNumberOfLines(const wxGrid *grid) const wxOVERRIDE virtual int GetTotalNumberOfLines(const wxGrid *grid) const wxOVERRIDE
{ return grid->GetNumberRows(); } { return grid->GetNumberRows(); }
@@ -655,6 +720,8 @@ public:
{ grid->SetRowSize(line, size); } { grid->SetRowSize(line, size); }
virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const wxOVERRIDE virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const wxOVERRIDE
{ grid->SetDefaultRowSize(size, resizeExisting); } { grid->SetDefaultRowSize(size, resizeExisting); }
virtual void HandleLineAutosize(wxGrid *grid, int line, const wxMouseEvent& event) const wxOVERRIDE
{ grid->HandleRowAutosize(line, event); }
virtual int GetLineAt(const wxGrid *grid, int pos) const wxOVERRIDE virtual int GetLineAt(const wxGrid *grid, int pos) const wxOVERRIDE
{ return grid->GetRowAt(pos); } { return grid->GetRowAt(pos); }
@@ -674,13 +741,70 @@ public:
virtual wxGridWindow *GetFrozenGrid(wxGrid* grid) const wxOVERRIDE virtual wxGridWindow *GetFrozenGrid(wxGrid* grid) const wxOVERRIDE
{ return (wxGridWindow*)grid->GetFrozenRowGridWindow(); } { return (wxGridWindow*)grid->GetFrozenRowGridWindow(); }
virtual bool CanDragMove(wxGrid *grid) const wxOVERRIDE
{ return grid->m_canDragRowMove; }
virtual void DoEndMove(wxGrid* grid, int line) const wxOVERRIDE
{ grid->DoEndMoveRow(line); }
virtual bool CanDragLineSize(wxGrid *grid, int line) const wxOVERRIDE
{ return grid->CanDragRowSize(line); }
virtual void DoEndLineResize(wxGrid *grid, const wxMouseEvent& event,
wxGridWindow* gridWindow) const wxOVERRIDE
{ grid->DoEndDragResizeRow(event, gridWindow); }
virtual bool SelectionExtendCurrentBlock(wxGrid *grid, int line,
const wxMouseEvent &event,
wxEventType eventType = wxEVT_GRID_RANGE_SELECTED) const wxOVERRIDE
{
return grid->m_selection->ExtendCurrentBlock
(
wxGridCellCoords(grid->m_currentCellCoords.GetRow(), 0),
wxGridCellCoords(line, grid->GetNumberCols() - 1),
event,
eventType
);
}
virtual void SelectLine(wxGrid *grid, int line, wxMouseEvent &event) const wxOVERRIDE
{ grid->m_selection->SelectRow(line, event); };
virtual void DeselectLine(wxGrid * grid, int line) const wxOVERRIDE
{ grid->DeselectRow(line); }
virtual bool IsLineInSelection(wxGrid *grid, int line) const wxOVERRIDE
{ return grid->m_selection->IsInSelection(line, 0); }
virtual wxGrid::EventResult SendEvent(wxGrid *grid, wxEventType eventType,
int line, const wxMouseEvent& event) const wxOVERRIDE
{ return grid->SendEvent(eventType, line, -1, event ); }
virtual void DrawLineLabel(wxGrid *grid, wxDC& dc, int line) const wxOVERRIDE
{ grid->DrawRowLabel(dc, line); }
virtual void MakeLineVisible(wxGrid *grid, int line) const wxOVERRIDE
{ grid->MakeCellVisible(line, -1); }
virtual void MakeLineCurrent(wxGrid *grid, int line) const wxOVERRIDE
{ grid->SetCurrentCell(line, grid->GetFirstFullyVisibleColumn()); }
}; };
class wxGridColumnOperations : public wxGridOperations class wxGridColumnOperations : public wxGridOperations
{ {
public: public:
virtual wxGridOperations& Dual() const wxOVERRIDE; virtual wxGridOperations& Dual() const wxOVERRIDE;
virtual int GetOrientation() const wxOVERRIDE
{ return wxHORIZONTAL; }
virtual wxGrid::CursorMode GetCursorModeResize() const wxOVERRIDE
{ return wxGrid::WXGRID_CURSOR_RESIZE_COL; }
virtual wxGrid::CursorMode GetCursorModeSelect() const wxOVERRIDE
{ return wxGrid::WXGRID_CURSOR_SELECT_COL; }
virtual wxGrid::CursorMode GetCursorModeMove() const wxOVERRIDE
{ return wxGrid::WXGRID_CURSOR_MOVE_COL; }
virtual int GetTotalNumberOfLines(const wxGrid *grid) const wxOVERRIDE virtual int GetTotalNumberOfLines(const wxGrid *grid) const wxOVERRIDE
{ return grid->GetNumberCols(); } { return grid->GetNumberCols(); }
@@ -739,6 +863,8 @@ public:
{ grid->SetColSize(line, size); } { grid->SetColSize(line, size); }
virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const wxOVERRIDE virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const wxOVERRIDE
{ grid->SetDefaultColSize(size, resizeExisting); } { grid->SetDefaultColSize(size, resizeExisting); }
virtual void HandleLineAutosize(wxGrid *grid, int line, const wxMouseEvent& event) const wxOVERRIDE
{ grid->HandleColumnAutosize(line, event); }
virtual int GetLineAt(const wxGrid *grid, int pos) const wxOVERRIDE virtual int GetLineAt(const wxGrid *grid, int pos) const wxOVERRIDE
{ return grid->GetColAt(pos); } { return grid->GetColAt(pos); }
@@ -758,6 +884,51 @@ public:
virtual wxGridWindow *GetFrozenGrid(wxGrid* grid) const wxOVERRIDE virtual wxGridWindow *GetFrozenGrid(wxGrid* grid) const wxOVERRIDE
{ return (wxGridWindow*)grid->GetFrozenColGridWindow(); } { return (wxGridWindow*)grid->GetFrozenColGridWindow(); }
virtual bool CanDragMove(wxGrid *grid) const wxOVERRIDE
{ return grid->m_canDragColMove; }
virtual void DoEndMove(wxGrid* grid, int line) const wxOVERRIDE
{ grid->DoEndMoveCol(line); }
virtual bool CanDragLineSize(wxGrid *grid, int line) const wxOVERRIDE
{ return grid->CanDragColSize(line); }
virtual void DoEndLineResize(wxGrid *grid, const wxMouseEvent& event,
wxGridWindow* gridWindow) const wxOVERRIDE
{ grid->DoEndDragResizeCol(event, gridWindow); }
virtual bool SelectionExtendCurrentBlock(wxGrid *grid, int line,
const wxMouseEvent &event,
wxEventType eventType = wxEVT_GRID_RANGE_SELECTED) const wxOVERRIDE
{
return grid->m_selection->ExtendCurrentBlock
(
wxGridCellCoords(0, grid->m_currentCellCoords.GetCol()),
wxGridCellCoords(grid->GetNumberRows() - 1, line),
event,
eventType
);
}
virtual void SelectLine(wxGrid *grid, int line, wxMouseEvent &event) const wxOVERRIDE
{ grid->m_selection->SelectCol(line, event); };
virtual void DeselectLine(wxGrid * grid, int line) const wxOVERRIDE
{ grid->DeselectCol(line); }
virtual bool IsLineInSelection(wxGrid *grid, int line) const wxOVERRIDE
{ return grid->m_selection->IsInSelection(line, 0); }
virtual wxGrid::EventResult SendEvent(wxGrid *grid, wxEventType eventType,
int line, const wxMouseEvent& event) const wxOVERRIDE
{ return grid->SendEvent(eventType, -1, line, event ); }
virtual void DrawLineLabel(wxGrid *grid, wxDC& dc, int line) const wxOVERRIDE
{ grid->DrawColLabel(dc, line); }
virtual void MakeLineVisible(wxGrid *grid, int line) const wxOVERRIDE
{ grid->MakeCellVisible(-1, line); }
virtual void MakeLineCurrent(wxGrid *grid, int line) const wxOVERRIDE
{ grid->SetCurrentCell(grid->GetFirstFullyVisibleRow(), line); }
}; };
// This class abstracts the difference between operations going forward // This class abstracts the difference between operations going forward

View File

@@ -6381,6 +6381,13 @@ public:
@event{EVT_GRID_CMD_ROW_SIZE(id, func)} @event{EVT_GRID_CMD_ROW_SIZE(id, func)}
The user resized a row, corresponds to @c wxEVT_GRID_ROW_SIZE event The user resized a row, corresponds to @c wxEVT_GRID_ROW_SIZE event
type. type.
@event{EVT_GRID_ROW_AUTO_SIZE(func)}
This event is sent when a row must be resized to its best size, e.g.
when the user double clicks the row divider. The default
implementation simply resizes the row to fit the row label (but
not its contents as this could be too slow for big grids). This macro
corresponds to @c wxEVT_GRID_ROW_AUTO_SIZE event type and is new since
wxWidgets 3.1.7.
@event{EVT_GRID_COL_SIZE(func)} @event{EVT_GRID_COL_SIZE(func)}
Same as EVT_GRID_CMD_COL_SIZE() but uses `wxID_ANY` id. Same as EVT_GRID_CMD_COL_SIZE() but uses `wxID_ANY` id.
@event{EVT_GRID_COL_AUTO_SIZE(func)} @event{EVT_GRID_COL_AUTO_SIZE(func)}
@@ -6654,6 +6661,7 @@ wxEventType wxEVT_GRID_LABEL_RIGHT_CLICK;
wxEventType wxEVT_GRID_LABEL_LEFT_DCLICK; wxEventType wxEVT_GRID_LABEL_LEFT_DCLICK;
wxEventType wxEVT_GRID_LABEL_RIGHT_DCLICK; wxEventType wxEVT_GRID_LABEL_RIGHT_DCLICK;
wxEventType wxEVT_GRID_ROW_SIZE; wxEventType wxEVT_GRID_ROW_SIZE;
wxEventType wxEVT_GRID_ROW_AUTO_SIZE;
wxEventType wxEVT_GRID_COL_SIZE; wxEventType wxEVT_GRID_COL_SIZE;
wxEventType wxEVT_GRID_COL_AUTO_SIZE; wxEventType wxEVT_GRID_COL_AUTO_SIZE;
wxEventType wxEVT_GRID_RANGE_SELECTING; wxEventType wxEVT_GRID_RANGE_SELECTING;

View File

@@ -1564,6 +1564,7 @@ void GridFrame::FreezeOrThaw(wxCommandEvent& ev)
} }
GetMenuBar()->Enable( ID_TOGGLECOLMOVING, !grid->IsFrozen() ); GetMenuBar()->Enable( ID_TOGGLECOLMOVING, !grid->IsFrozen() );
GetMenuBar()->Enable( ID_TOGGLEROWMOVING, !grid->IsFrozen() );
} }
void GridFrame::SetCellFgColour( wxCommandEvent& WXUNUSED(ev) ) void GridFrame::SetCellFgColour( wxCommandEvent& WXUNUSED(ev) )

View File

@@ -138,6 +138,7 @@ wxDEFINE_EVENT( wxEVT_GRID_LABEL_RIGHT_CLICK, wxGridEvent );
wxDEFINE_EVENT( wxEVT_GRID_LABEL_LEFT_DCLICK, wxGridEvent ); wxDEFINE_EVENT( wxEVT_GRID_LABEL_LEFT_DCLICK, wxGridEvent );
wxDEFINE_EVENT( wxEVT_GRID_LABEL_RIGHT_DCLICK, wxGridEvent ); wxDEFINE_EVENT( wxEVT_GRID_LABEL_RIGHT_DCLICK, wxGridEvent );
wxDEFINE_EVENT( wxEVT_GRID_ROW_SIZE, wxGridSizeEvent ); wxDEFINE_EVENT( wxEVT_GRID_ROW_SIZE, wxGridSizeEvent );
wxDEFINE_EVENT( wxEVT_GRID_ROW_AUTO_SIZE, wxGridSizeEvent );
wxDEFINE_EVENT( wxEVT_GRID_COL_SIZE, wxGridSizeEvent ); wxDEFINE_EVENT( wxEVT_GRID_COL_SIZE, wxGridSizeEvent );
wxDEFINE_EVENT( wxEVT_GRID_COL_AUTO_SIZE, wxGridSizeEvent ); wxDEFINE_EVENT( wxEVT_GRID_COL_AUTO_SIZE, wxGridSizeEvent );
wxDEFINE_EVENT( wxEVT_GRID_ROW_MOVE, wxGridEvent ); wxDEFINE_EVENT( wxEVT_GRID_ROW_MOVE, wxGridEvent );
@@ -2180,7 +2181,7 @@ void wxGridRowLabelWindow::OnPaint( wxPaintEvent& WXUNUSED(event) )
void wxGridRowLabelWindow::OnMouseEvent( wxMouseEvent& event ) void wxGridRowLabelWindow::OnMouseEvent( wxMouseEvent& event )
{ {
m_owner->ProcessRowLabelMouseEvent( event, this ); m_owner->ProcessRowColLabelMouseEvent( wxGridRowOperations(), event, this );
} }
void wxGridRowLabelWindow::OnMouseWheel( wxMouseEvent& event ) void wxGridRowLabelWindow::OnMouseWheel( wxMouseEvent& event )
@@ -2229,7 +2230,7 @@ void wxGridColLabelWindow::OnPaint( wxPaintEvent& WXUNUSED(event) )
void wxGridColLabelWindow::OnMouseEvent( wxMouseEvent& event ) void wxGridColLabelWindow::OnMouseEvent( wxMouseEvent& event )
{ {
m_owner->ProcessColLabelMouseEvent( event, this ); m_owner->ProcessRowColLabelMouseEvent( wxGridColumnOperations(), event, this );
} }
void wxGridColLabelWindow::OnMouseWheel( wxMouseEvent& event ) void wxGridColLabelWindow::OnMouseWheel( wxMouseEvent& event )
@@ -3040,8 +3041,7 @@ void wxGrid::Init()
m_canDragColSize = true; m_canDragColSize = true;
m_canDragGridSize = true; m_canDragGridSize = true;
m_canDragCell = false; m_canDragCell = false;
m_dragMoveRow = -1; m_dragMoveRowOrCol = -1;
m_dragMoveCol = -1;
m_dragLastPos = -1; m_dragLastPos = -1;
m_dragRowOrCol = -1; m_dragRowOrCol = -1;
m_dragRowOrColOldSize = -1; m_dragRowOrColOldSize = -1;
@@ -3963,10 +3963,13 @@ bool wxGrid::CheckIfDragCancelled(wxMouseEvent *event)
return false; return false;
} }
void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindow* rowLabelWin ) void wxGrid::ProcessRowColLabelMouseEvent( const wxGridOperations &oper, wxMouseEvent& event, wxGridSubwindow* labelWin )
{ {
int y; const wxGridOperations &dual = oper.Dual();
wxGridWindow *gridWindow = rowLabelWin->IsFrozen() ? m_frozenRowGridWin : m_gridWin;
wxGridSubwindow *headerWin = (wxGridSubwindow *) oper.GetHeaderWindow(this);
wxGridWindow *gridWindow = labelWin->IsFrozen() ? oper.GetFrozenGrid(this) :
m_gridWin;
// store position, before it's modified in the next step // store position, before it's modified in the next step
const wxPoint posEvent = event.GetPosition(); const wxPoint posEvent = event.GetPosition();
@@ -3974,19 +3977,34 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindo
event.SetPosition(posEvent + GetGridWindowOffset(gridWindow)); event.SetPosition(posEvent + GetGridWindowOffset(gridWindow));
// for drag, we could be moving from the window sending the event to the other // for drag, we could be moving from the window sending the event to the other
if ( rowLabelWin->IsFrozen() && event.GetPosition().y > rowLabelWin->GetClientSize().y ) if ( labelWin->IsFrozen() &&
dual.Select( event.GetPosition() ) > dual.Select( labelWin->GetClientSize() ) )
gridWindow = m_gridWin; gridWindow = m_gridWin;
CalcGridWindowUnscrolledPosition(0, event.GetPosition().y, NULL, &y, gridWindow); const wxPoint unscrolledPos = CalcGridWindowUnscrolledPosition(event.GetPosition(), gridWindow);
int row = YToRow( y );
// find y or x mouse coordinate for row / col label window
int coord = dual.Select(unscrolledPos);
// index into data rows/cols; wxNOT_FOUND if outside label window
int line = oper.PosToLine(this, coord, NULL);
// wxNOT_FOUND if not near a line edge; otherwise index into data rows/cols
int lineEdge = PosToEdgeOfLine(coord, oper);
// these are always valid, even if the mouse is outside the row/col range:
// index into displayed rows/cols
int posAt = PosToLinePos(coord, true /* clip */, oper, NULL);
// index into data rows/cols
int lineAt = oper.GetLineAt(this, posAt);
if ( CheckIfDragCancelled(&event) ) if ( CheckIfDragCancelled(&event) )
return; return;
if ( event.Dragging() && (m_winCapture == rowLabelWin) ) if ( event.Dragging() && (m_winCapture == labelWin) )
{ {
// scroll when at the edges or outside the window // scroll when at the edges or outside the window
CheckDoDragScroll(rowLabelWin, m_rowLabelWin, posEvent, wxVERTICAL); CheckDoDragScroll(labelWin, headerWin, posEvent, oper.GetOrientation());
} }
if ( event.Dragging() ) if ( event.Dragging() )
@@ -3995,74 +4013,63 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindo
{ {
m_isDragging = true; m_isDragging = true;
if ( m_cursorMode == WXGRID_CURSOR_MOVE_ROW && row != -1 ) if ( m_cursorMode == oper.GetCursorModeMove() && line != -1 )
DoStartMoveRow(row); DoStartMoveRowOrCol(line);
} }
if ( event.LeftIsDown() ) if ( event.LeftIsDown() )
{ {
switch ( m_cursorMode ) if ( m_cursorMode == oper.GetCursorModeResize() )
{ {
case WXGRID_CURSOR_RESIZE_ROW: DoGridDragResize(event.GetPosition(), oper, gridWindow);
DoGridDragResize(event.GetPosition(), wxGridRowOperations(), gridWindow);
break;
case WXGRID_CURSOR_SELECT_ROW:
if ( !m_selection || m_numRows == 0 || m_numCols == 0 )
break;
// We can't extend the selection from non-selected row,
// which may happen if we Ctrl-clicked it initially.
if ( !m_selection->IsInSelection(m_currentCellCoords) )
break;
if ( row >= 0 )
{
m_selection->ExtendCurrentBlock(
wxGridCellCoords(m_currentCellCoords.GetRow(), 0),
wxGridCellCoords(row, GetNumberCols() - 1),
event,
wxEVT_GRID_RANGE_SELECTING);
} }
break; else if ( m_cursorMode == oper.GetCursorModeSelect() && line >=0 )
case WXGRID_CURSOR_MOVE_ROW:
{ {
int posNew = YToPos(y, NULL); // We can't extend the selection from non-selected row / col,
int rowNew = GetRowAt(posNew); // which may happen if we Ctrl-clicked it initially.
// Therefore check m_selection->IsInSelection(m_currentCellCoords)
// determine the position of the drop marker if ( m_selection && m_numRows && m_numCols &&
int markerY; m_selection->IsInSelection(m_currentCellCoords) )
if ( y >= GetRowTop(rowNew) + (GetRowHeight(rowNew) / 2) ) {
markerY = GetRowBottom(rowNew); oper.SelectionExtendCurrentBlock(this, line, event, wxEVT_GRID_RANGE_SELECTING);
}
}
else if ( m_cursorMode == oper.GetCursorModeMove() )
{
// determine the y or x position of the drop marker
int marker;
if ( coord >= oper.GetLineStartPos(this, lineAt) + (oper.GetLineSize(this, lineAt) / 2) )
marker = oper.GetLineEndPos(this, lineAt);
else else
markerY = GetRowTop(rowNew); marker = oper.GetLineStartPos(this, lineAt);
if ( markerY != m_dragLastPos ) if ( marker != m_dragLastPos )
{ {
wxClientDC dc( m_rowLabelWin ); wxClientDC dc( headerWin );
DoPrepareDC(dc); DoPrepareDC(dc);
int cw, ch; wxSize clientSize = headerWin->GetClientSize();
m_rowLabelWin->GetClientSize( &cw, &ch );
markerY++; marker++;
// Clean up the last indicator // Clean up the last indicator
if ( m_dragLastPos >= 0 ) if ( m_dragLastPos >= 0 )
{ {
wxPen pen( m_rowLabelWin->GetBackgroundColour(), 2 ); wxPen pen(headerWin->GetBackgroundColour(), 2);
dc.SetPen(pen); dc.SetPen(pen);
dc.DrawLine( 0, m_dragLastPos + 1, cw, m_dragLastPos + 1 ); oper.DrawParallelLine(dc, 0, oper.Select(clientSize), m_dragLastPos + 1);
dc.SetPen(wxNullPen); dc.SetPen(wxNullPen);
if ( YToRow( m_dragLastPos ) != -1 ) int lastLine = oper.PosToLine(this, m_dragLastPos, NULL, false);
DrawRowLabel( dc, YToRow( m_dragLastPos ) );
if ( lastLine != -1 )
oper.DrawLineLabel(this, dc, lastLine);
} }
const wxColour *color; const wxColour *color;
// Moving to the same place? Don't draw a marker // Moving to the same place? Don't draw a marker
if ( rowNew == m_dragMoveRow ) if ( lineAt == m_dragMoveRowOrCol )
color = wxLIGHT_GREY; color = wxLIGHT_GREY;
else else
color = wxBLUE; color = wxBLUE;
@@ -4070,21 +4077,12 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindo
// Draw the marker // Draw the marker
wxPen pen(*color, 2); wxPen pen(*color, 2);
dc.SetPen(pen); dc.SetPen(pen);
oper.DrawParallelLine(dc, 0, oper.Select(clientSize), marker);
dc.DrawLine( 0, markerY, cw, markerY );
dc.SetPen(wxNullPen); dc.SetPen(wxNullPen);
m_dragLastPos = markerY - 1; m_dragLastPos = marker - 1;
} }
} }
break;
// default label to suppress warnings about "enumeration value
// 'xxx' not handled in switch
default:
break;
}
} }
return; return;
} }
@@ -4096,87 +4094,82 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindo
// //
if ( event.Entering() || event.Leaving() ) if ( event.Entering() || event.Leaving() )
{ {
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, rowLabelWin); ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, labelWin);
} }
// ------------ Left button pressed // ------------ Left button pressed
// //
else if ( event.LeftDown() ) else if ( event.LeftDown() )
{ {
row = YToEdgeOfRow(y); if ( lineEdge != wxNOT_FOUND && oper.CanDragLineSize(this, lineEdge) )
if ( row != wxNOT_FOUND && CanDragRowSize(row) )
{ {
DoStartResizeRowOrCol(row, GetRowSize(row)); DoStartResizeRowOrCol(lineEdge, oper.GetLineSize(this, lineEdge));
ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, rowLabelWin); ChangeCursorMode(oper.GetCursorModeResize(), labelWin);
}
else // not a request to start resizing
{
row = YToRow(y);
if ( row >= 0 &&
SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, row, -1, event ) == Event_Unhandled )
{
if ( m_canDragRowMove )
{
//Show button as pressed
wxClientDC dc( m_rowLabelWin );
int rowTop = GetRowTop( row );
int rowBottom = GetRowBottom( row ) - 1;
dc.SetPen( wxPen( m_rowLabelWin->GetBackgroundColour(), 1 ) );
dc.DrawLine( 1, rowTop, m_rowLabelWidth-1, rowTop );
dc.DrawLine( 1, rowTop, 1, rowBottom );
ChangeCursorMode(WXGRID_CURSOR_MOVE_ROW, m_rowLabelWin);
} }
else else
{ {
// Check if row selection is possible and allowed, before doing // not a request to start resizing
// anything else, including changing the cursor mode to "select if ( line >= 0 &&
// row". oper.SendEvent( this, wxEVT_GRID_LABEL_LEFT_CLICK, line, event ) == Event_Unhandled )
if ( m_selection && m_numRows > 0 && m_numCols > 0 &&
m_selection->GetSelectionMode() != wxGridSelectColumns )
{ {
bool selectNewRow = false, if ( oper.CanDragMove(this) )
makeRowCurrent = false; {
// Show button as pressed
wxClientDC dc( headerWin );
DoPrepareDC(dc);
int lineTop = oper.GetLineStartPos(this, line);
int lineBottom = oper.GetLineEndPos(this, line) - 1;
dc.SetPen( wxPen( headerWin->GetBackgroundColour(), 1 ) );
oper.DrawParallelLine(dc, 0, m_rowLabelWidth-1, lineTop);
dual.DrawParallelLine(dc, lineTop, lineBottom, 1);
ChangeCursorMode(oper.GetCursorModeMove(), headerWin);
}
else
{
// Check if row/col selection is possible and allowed, before doing
// anything else, including changing the cursor mode to "select
// row"/"select col".
if ( m_selection && m_numRows > 0 && m_numCols > 0 &&
m_selection->GetSelectionMode() != dual.GetSelectionMode() )
{
bool selectNewLine = false,
makeLineCurrent = false;
if ( event.ShiftDown() && !event.CmdDown() ) if ( event.ShiftDown() && !event.CmdDown() )
{ {
// Continue editing the current selection and don't // Continue editing the current selection and don't
// move the grid cursor. // move the grid cursor.
m_selection->ExtendCurrentBlock oper.SelectionExtendCurrentBlock(this, line, event);
( oper.MakeLineVisible(this, line);
wxGridCellCoords(m_currentCellCoords.GetRow(), 0),
wxGridCellCoords(row, GetNumberCols() - 1),
event
);
MakeCellVisible(row, -1);
} }
else if ( event.CmdDown() && !event.ShiftDown() ) else if ( event.CmdDown() && !event.ShiftDown() )
{ {
if ( m_selection->IsInSelection(row, 0) ) if ( oper.IsLineInSelection(this, line) )
{ {
DeselectRow(row); oper.DeselectLine(this, line);
makeRowCurrent = true; makeLineCurrent = true;
} }
else else
{ {
makeRowCurrent = makeLineCurrent =
selectNewRow = true; selectNewLine = true;
} }
} }
else else
{ {
ClearSelection(); ClearSelection();
makeRowCurrent = makeLineCurrent =
selectNewRow = true; selectNewLine = true;
} }
if ( selectNewRow ) if ( selectNewLine )
m_selection->SelectRow(row, event); oper.SelectLine(this, line, event);
if ( makeRowCurrent ) if ( makeLineCurrent )
SetCurrentCell(row, GetFirstFullyVisibleColumn()); oper.MakeLineCurrent(this, line);
ChangeCursorMode(WXGRID_CURSOR_SELECT_ROW, rowLabelWin); ChangeCursorMode(oper.GetCursorModeSelect(), labelWin);
} }
} }
} }
@@ -4187,24 +4180,18 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindo
// //
else if (event.LeftDClick() ) else if (event.LeftDClick() )
{ {
row = YToEdgeOfRow(y); if ( lineEdge != wxNOT_FOUND && oper.CanDragLineSize(this, line) )
if ( row != wxNOT_FOUND && CanDragRowSize(row) )
{ {
// adjust row height depending on label text // adjust row or column size depending on label text
// oper.HandleLineAutosize(this, lineEdge, event);
// TODO: generate RESIZING event, see #10754
AutoSizeRowLabelSize( row );
SendGridSizeEvent(wxEVT_GRID_ROW_SIZE, row, -1, event); ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, labelWin);
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, GetColLabelWindow());
m_dragLastPos = -1; m_dragLastPos = -1;
} }
else // not on row separator or it's not resizable else // not on line separator or it's not resizable
{ {
row = YToRow(y); if ( line >=0 &&
if ( row >=0 && oper.SendEvent( this, wxEVT_GRID_LABEL_LEFT_DCLICK, line, event ) == Event_Unhandled )
SendEvent( wxEVT_GRID_LABEL_LEFT_DCLICK, row, -1, event ) == Event_Unhandled )
{ {
// no default action at the moment // no default action at the moment
} }
@@ -4215,58 +4202,46 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindo
// //
else if ( event.LeftUp() ) else if ( event.LeftUp() )
{ {
switch ( m_cursorMode ) if ( m_cursorMode == oper.GetCursorModeResize() )
{ {
case WXGRID_CURSOR_RESIZE_ROW: oper.DoEndLineResize(this, event, gridWindow);
DoEndDragResizeRow(event, gridWindow); }
break; else if ( m_cursorMode == oper.GetCursorModeMove() )
case WXGRID_CURSOR_MOVE_ROW:
if ( m_dragLastPos == -1 || row == m_dragMoveRow )
{ {
// the row didn't actually move anywhere if ( m_dragLastPos == -1 || line == m_dragMoveRowOrCol )
m_rowLabelWin->Refresh(); // "unpress" the row {
// the line didn't actually move anywhere, "unpress" the label
if ( oper.GetOrientation() == wxVERTICAL && line != -1 )
DoColHeaderClick(line);
oper.GetHeaderWindow(this)->Refresh();
} }
else else
{ {
// get the position of the row we're over // find the target position: start with current mouse position
int pos = YToPos(y, NULL); // (posAt and lineAt are always valid indices, not wxNOT_FOUND)
int posNew = posAt;
// insert the row being dragged either before or after
// it, depending on where exactly it was dropped, so
// find the index of the row we're over: notice
// that the existing "row" variable may be invalid but
// we need a valid one here
const int rowValid = GetRowAt(pos);
// and check if we're on the "near" (left) part of the row
const int middle = GetRowTop(rowValid) +
GetRowHeight(rowValid)/2;
const bool onNearPart = (y <= middle);
// adjust for the row being dragged itself // adjust for the row being dragged itself
if ( pos < GetRowPos(m_dragMoveRow) ) if ( posAt < oper.GetLinePos(this, m_dragMoveRowOrCol) )
pos++; posNew++;
// and if it's on the near part of the target row, // if mouse is on the near part of the target row,
// insert it before it, not after // insert it before it, not after
if ( onNearPart ) if (coord <= oper.GetLineStartPos(this, lineAt) +
pos--; oper.GetLineSize(this, lineAt) / 2 )
posNew--;
DoEndMoveRow(pos); oper.DoEndMove(this, posNew);
} }
break; }
else if ( oper.GetOrientation() == wxHORIZONTAL && line != -1 &&
case WXGRID_CURSOR_SELECT_ROW: (m_cursorMode == WXGRID_CURSOR_SELECT_CELL ||
case WXGRID_CURSOR_SELECT_CELL: m_cursorMode == WXGRID_CURSOR_SELECT_COL) )
case WXGRID_CURSOR_RESIZE_COL: {
case WXGRID_CURSOR_SELECT_COL: DoColHeaderClick(line);
case WXGRID_CURSOR_MOVE_COL:
// nothing to do
break;
} }
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, rowLabelWin); ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, labelWin);
m_dragLastPos = -1; m_dragLastPos = -1;
m_lastMousePos = wxDefaultPosition; m_lastMousePos = wxDefaultPosition;
m_isDragging = false; m_isDragging = false;
@@ -4276,9 +4251,8 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindo
// //
else if ( event.RightDown() ) else if ( event.RightDown() )
{ {
row = YToRow(y); if ( line < 0 ||
if ( row < 0 || oper.SendEvent( this, wxEVT_GRID_LABEL_RIGHT_CLICK, line, event ) == Event_Unhandled )
SendEvent( wxEVT_GRID_LABEL_RIGHT_CLICK, row, -1, event ) == Event_Unhandled )
{ {
// no default action at the moment // no default action at the moment
event.Skip(); event.Skip();
@@ -4289,9 +4263,8 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindo
// //
else if ( event.RightDClick() ) else if ( event.RightDClick() )
{ {
row = YToRow(y); if ( line < 0 ||
if ( row < 0 || oper.SendEvent( this, wxEVT_GRID_LABEL_RIGHT_DCLICK, line, event ) == Event_Unhandled )
SendEvent( wxEVT_GRID_LABEL_RIGHT_DCLICK, row, -1, event ) == Event_Unhandled )
{ {
// no default action at the moment // no default action at the moment
event.Skip(); event.Skip();
@@ -4302,20 +4275,19 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindo
// //
else if ( event.Moving() ) else if ( event.Moving() )
{ {
const int dragRowOrCol = YToEdgeOfRow( y ); if ( lineEdge != wxNOT_FOUND )
if ( dragRowOrCol != wxNOT_FOUND )
{ {
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL ) if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{ {
if ( CanDragRowSize(dragRowOrCol) ) if ( oper.CanDragLineSize(this, lineEdge) )
{ {
ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, rowLabelWin, false); ChangeCursorMode(oper.GetCursorModeResize(), labelWin, false);
} }
} }
} }
else if ( m_cursorMode != WXGRID_CURSOR_SELECT_CELL ) else if ( m_cursorMode != WXGRID_CURSOR_SELECT_CELL )
{ {
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, rowLabelWin, false); ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, labelWin, false);
} }
} }
@@ -4433,366 +4405,6 @@ void wxGrid::DoStartResizeRowOrCol(int col, int size)
m_dragRowOrColOldSize = size; m_dragRowOrColOldSize = size;
} }
void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event, wxGridColLabelWindow* colLabelWin )
{
int x;
wxGridWindow *gridWindow = colLabelWin->IsFrozen() ? m_frozenColGridWin : m_gridWin;
// store position, before it's modified in the next step
const wxPoint posEvent = event.GetPosition();
event.SetPosition(posEvent + GetGridWindowOffset(gridWindow));
// for drag, we could be moving from the window sending the event to the other
if (colLabelWin->IsFrozen() && event.GetPosition().x > colLabelWin->GetClientSize().x)
gridWindow = m_gridWin;
CalcGridWindowUnscrolledPosition(event.GetPosition().x, 0, &x, NULL, gridWindow);
int col = XToCol(x);
if ( CheckIfDragCancelled(&event) )
return;
if ( event.Dragging() && (m_winCapture == colLabelWin) )
{
// scroll when at the edges or outside the window
CheckDoDragScroll(colLabelWin, GetColLabelWindow(), posEvent, wxHORIZONTAL);
}
if ( event.Dragging() )
{
if (!m_isDragging)
{
m_isDragging = true;
if ( m_cursorMode == WXGRID_CURSOR_MOVE_COL && col != -1 )
DoStartMoveCol(col);
}
if ( event.LeftIsDown() )
{
switch ( m_cursorMode )
{
case WXGRID_CURSOR_RESIZE_COL:
DoGridDragResize(event.GetPosition(), wxGridColumnOperations(), gridWindow);
break;
case WXGRID_CURSOR_SELECT_COL:
if ( col != -1 )
{
if ( !m_selection || m_numRows == 0 || m_numCols == 0 )
break;
// We can't extend the selection from non-selected
// column which may happen if we Ctrl-clicked it
// initially.
if ( !m_selection->IsInSelection(m_currentCellCoords) )
break;
m_selection->ExtendCurrentBlock(
wxGridCellCoords(0, m_currentCellCoords.GetCol()),
wxGridCellCoords(GetNumberRows() - 1, col),
event,
wxEVT_GRID_RANGE_SELECTING);
}
break;
case WXGRID_CURSOR_MOVE_COL:
{
int posNew = XToPos(x, NULL);
int colNew = GetColAt(posNew);
// determine the position of the drop marker
int markerX;
if ( x >= GetColLeft(colNew) + (GetColWidth(colNew) / 2) )
markerX = GetColRight(colNew);
else
markerX = GetColLeft(colNew);
if ( markerX != m_dragLastPos )
{
wxClientDC dc( GetColLabelWindow() );
DoPrepareDC(dc);
int cw, ch;
GetColLabelWindow()->GetClientSize( &cw, &ch );
markerX++;
//Clean up the last indicator
if ( m_dragLastPos >= 0 )
{
wxPen pen( GetColLabelWindow()->GetBackgroundColour(), 2 );
dc.SetPen(pen);
dc.DrawLine( m_dragLastPos + 1, 0, m_dragLastPos + 1, ch );
dc.SetPen(wxNullPen);
if ( XToCol( m_dragLastPos ) != -1 )
DrawColLabel( dc, XToCol( m_dragLastPos ) );
}
const wxColour *color;
//Moving to the same place? Don't draw a marker
if ( colNew == m_dragMoveCol )
color = wxLIGHT_GREY;
else
color = wxBLUE;
//Draw the marker
wxPen pen( *color, 2 );
dc.SetPen(pen);
dc.DrawLine( markerX, 0, markerX, ch );
dc.SetPen(wxNullPen);
m_dragLastPos = markerX - 1;
}
}
break;
// default label to suppress warnings about "enumeration value
// 'xxx' not handled in switch
default:
break;
}
}
return;
}
if ( m_isDragging && (event.Entering() || event.Leaving()) )
return;
// ------------ Entering or leaving the window
//
if ( event.Entering() || event.Leaving() )
{
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, colLabelWin);
}
// ------------ Left button pressed
//
else if ( event.LeftDown() )
{
int colEdge = XToEdgeOfCol(x);
if ( colEdge != wxNOT_FOUND && CanDragColSize(colEdge) )
{
DoStartResizeRowOrCol(colEdge, GetColSize(colEdge));
ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, colLabelWin);
}
else // not a request to start resizing
{
if ( col >= 0 &&
SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) == Event_Unhandled )
{
if ( m_canDragColMove )
{
//Show button as pressed
wxClientDC dc( GetColLabelWindow() );
int colLeft = GetColLeft( col );
int colRight = GetColRight( col ) - 1;
dc.SetPen( wxPen( GetColLabelWindow()->GetBackgroundColour(), 1 ) );
dc.DrawLine( colLeft, 1, colLeft, m_colLabelHeight-1 );
dc.DrawLine( colLeft, 1, colRight, 1 );
ChangeCursorMode(WXGRID_CURSOR_MOVE_COL, GetColLabelWindow());
}
else
{
if ( m_selection && m_numRows > 0 && m_numCols > 0 &&
m_selection->GetSelectionMode() != wxGridSelectRows )
{
bool selectNewCol = false,
makeColCurrent = false;
if ( event.ShiftDown() && !event.CmdDown() )
{
// Continue editing the current selection and don't
// move the grid cursor.
m_selection->ExtendCurrentBlock
(
wxGridCellCoords(0, m_currentCellCoords.GetCol()),
wxGridCellCoords(GetNumberRows() - 1, col),
event
);
MakeCellVisible(-1, col);
}
else if ( event.CmdDown() && !event.ShiftDown() )
{
if ( m_selection->IsInSelection(0, col) )
{
DeselectCol(col);
makeColCurrent = true;
}
else
{
makeColCurrent =
selectNewCol = true;
}
}
else
{
ClearSelection();
makeColCurrent =
selectNewCol = true;
}
if ( selectNewCol )
m_selection->SelectCol(col, event);
if ( makeColCurrent )
SetCurrentCell(GetFirstFullyVisibleRow(), col);
ChangeCursorMode(WXGRID_CURSOR_SELECT_COL, colLabelWin);
}
}
}
}
}
// ------------ Left double click
//
if ( event.LeftDClick() )
{
const int colEdge = XToEdgeOfCol(x);
if ( colEdge == -1 )
{
if ( col >= 0 &&
SendEvent( wxEVT_GRID_LABEL_LEFT_DCLICK, -1, col, event ) == Event_Unhandled )
{
// no default action at the moment
}
}
else
{
HandleColumnAutosize(colEdge, event);
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, colLabelWin);
m_dragLastPos = -1;
}
}
// ------------ Left button released
//
else if ( event.LeftUp() )
{
switch ( m_cursorMode )
{
case WXGRID_CURSOR_RESIZE_COL:
DoEndDragResizeCol(event, gridWindow);
break;
case WXGRID_CURSOR_MOVE_COL:
if ( m_dragLastPos == -1 || col == m_dragMoveCol )
{
// the column didn't actually move anywhere
if ( col != -1 )
DoColHeaderClick(col);
m_colLabelWin->Refresh(); // "unpress" the column
}
else
{
// get the position of the column we're over
int pos = XToPos(x, NULL);
// insert the column being dragged either before or after
// it, depending on where exactly it was dropped, so
// find the index of the column we're over: notice
// that the existing "col" variable may be invalid but
// we need a valid one here
const int colValid = GetColAt(pos);
// and check if we're on the "near" (usually left but right
// in RTL case) part of the column
const int middle = GetColLeft(colValid) +
GetColWidth(colValid)/2;
const bool onNearPart = (x <= middle);
// adjust for the column being dragged itself
if ( pos < GetColPos(m_dragMoveCol) )
pos++;
// and if it's on the near part of the target column,
// insert it before it, not after
if ( onNearPart )
pos--;
DoEndMoveCol(pos);
}
break;
case WXGRID_CURSOR_SELECT_COL:
case WXGRID_CURSOR_SELECT_CELL:
if ( col != -1 )
DoColHeaderClick(col);
break;
case WXGRID_CURSOR_RESIZE_ROW:
case WXGRID_CURSOR_SELECT_ROW:
case WXGRID_CURSOR_MOVE_ROW:
// nothing to do, will not happen anyway
break;
}
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, GetColLabelWindow());
m_dragLastPos = -1;
m_lastMousePos = wxDefaultPosition;
m_isDragging = false;
}
// ------------ Right button down
//
else if ( event.RightDown() )
{
if ( col < 0 ||
SendEvent( wxEVT_GRID_LABEL_RIGHT_CLICK, -1, col, event ) == Event_Unhandled )
{
// no default action at the moment
event.Skip();
}
}
// ------------ Right double click
//
else if ( event.RightDClick() )
{
if ( col < 0 ||
SendEvent( wxEVT_GRID_LABEL_RIGHT_DCLICK, -1, col, event ) == Event_Unhandled )
{
// no default action at the moment
event.Skip();
}
}
// ------------ No buttons down and mouse moving
//
else if ( event.Moving() )
{
const int dragRowOrCol = XToEdgeOfCol( x );
if ( dragRowOrCol >= 0 )
{
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
if ( CanDragColSize(dragRowOrCol) )
{
ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, colLabelWin, false);
}
}
}
else if ( m_cursorMode != WXGRID_CURSOR_SELECT_CELL )
{
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, colLabelWin, false);
}
}
// Don't consume the remaining events (e.g. right up).
else
{
event.Skip();
}
}
void wxGrid::ProcessCornerLabelMouseEvent( wxMouseEvent& event ) void wxGrid::ProcessCornerLabelMouseEvent( wxMouseEvent& event )
{ {
if ( event.LeftDown() ) if ( event.LeftDown() )
@@ -4831,15 +4443,26 @@ void wxGrid::ProcessCornerLabelMouseEvent( wxMouseEvent& event )
} }
} }
void wxGrid::HandleRowAutosize(int row, const wxMouseEvent& event)
{
// adjust row height depending on label text
//
// TODO: generate RESIZING event, see #10754
if ( !SendGridSizeEvent(wxEVT_GRID_ROW_AUTO_SIZE, row, event) )
AutoSizeRowLabelSize(row);
SendGridSizeEvent(wxEVT_GRID_ROW_SIZE, row, event);
}
void wxGrid::HandleColumnAutosize(int col, const wxMouseEvent& event) void wxGrid::HandleColumnAutosize(int col, const wxMouseEvent& event)
{ {
// adjust column width depending on label text // adjust column width depending on label text
// //
// TODO: generate RESIZING event, see #10754 // TODO: generate RESIZING event, see #10754
if ( !SendGridSizeEvent(wxEVT_GRID_COL_AUTO_SIZE, -1, col, event) ) if ( !SendGridSizeEvent(wxEVT_GRID_COL_AUTO_SIZE, col, event) )
AutoSizeColLabelSize(col); AutoSizeColLabelSize(col);
SendGridSizeEvent(wxEVT_GRID_COL_SIZE, -1, col, event); SendGridSizeEvent(wxEVT_GRID_COL_SIZE, col, event);
} }
void wxGrid::CancelMouseCapture() void wxGrid::CancelMouseCapture()
@@ -5422,7 +5045,7 @@ void wxGrid::DoEndDragResizeRow(const wxMouseEvent& event, wxGridWindow* gridWin
{ {
DoGridDragResize(event.GetPosition(), wxGridRowOperations(), gridWindow); DoGridDragResize(event.GetPosition(), wxGridRowOperations(), gridWindow);
SendGridSizeEvent(wxEVT_GRID_ROW_SIZE, m_dragRowOrCol, -1, event); SendGridSizeEvent(wxEVT_GRID_ROW_SIZE, m_dragRowOrCol, event);
m_dragRowOrCol = -1; m_dragRowOrCol = -1;
} }
@@ -5431,7 +5054,7 @@ void wxGrid::DoEndDragResizeCol(const wxMouseEvent& event, wxGridWindow* gridWin
{ {
DoGridDragResize(event.GetPosition(), wxGridColumnOperations(), gridWindow); DoGridDragResize(event.GetPosition(), wxGridColumnOperations(), gridWindow);
SendGridSizeEvent(wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol, event); SendGridSizeEvent(wxEVT_GRID_COL_SIZE, m_dragRowOrCol, event);
m_dragRowOrCol = -1; m_dragRowOrCol = -1;
} }
@@ -5470,19 +5093,19 @@ void wxGrid::DoHeaderEndDragResizeCol(int width)
DoEndDragResizeCol(e, m_gridWin); DoEndDragResizeCol(e, m_gridWin);
} }
void wxGrid::DoStartMoveRow(int row) void wxGrid::DoStartMoveRowOrCol(int col)
{ {
m_dragMoveRow = row; m_dragMoveRowOrCol = col;
} }
void wxGrid::DoEndMoveRow(int pos) void wxGrid::DoEndMoveRow(int pos)
{ {
wxASSERT_MSG( m_dragMoveRow != -1, "no matching DoStartMoveRow?" ); wxASSERT_MSG( m_dragMoveRowOrCol != -1, "no matching DoStartMoveRow?" );
if ( SendEvent(wxEVT_GRID_ROW_MOVE, -1, m_dragMoveRow) != Event_Vetoed ) if ( SendEvent(wxEVT_GRID_ROW_MOVE, -1, m_dragMoveRowOrCol) != Event_Vetoed )
SetRowPos(m_dragMoveRow, pos); SetRowPos(m_dragMoveRowOrCol, pos);
m_dragMoveRow = -1; m_dragMoveRowOrCol = -1;
} }
void wxGrid::RefreshAfterRowPosChange() void wxGrid::RefreshAfterRowPosChange()
@@ -5576,19 +5199,14 @@ bool wxGrid::EnableDragRowMove( bool enable )
return true; return true;
} }
void wxGrid::DoStartMoveCol(int col)
{
m_dragMoveCol = col;
}
void wxGrid::DoEndMoveCol(int pos) void wxGrid::DoEndMoveCol(int pos)
{ {
wxASSERT_MSG( m_dragMoveCol != -1, "no matching DoStartMoveCol?" ); wxASSERT_MSG( m_dragMoveRowOrCol != -1, "no matching DoStartMoveCol?" );
if ( SendEvent(wxEVT_GRID_COL_MOVE, -1, m_dragMoveCol) != Event_Vetoed ) if ( SendEvent(wxEVT_GRID_COL_MOVE, -1, m_dragMoveRowOrCol) != Event_Vetoed )
SetColPos(m_dragMoveCol, pos); SetColPos(m_dragMoveRowOrCol, pos);
m_dragMoveCol = -1; m_dragMoveRowOrCol = -1;
} }
void wxGrid::RefreshAfterColPosChange() void wxGrid::RefreshAfterColPosChange()
@@ -5918,11 +5536,9 @@ wxGrid::DoAppendLines(bool (wxGridTableBase::*funcAppend)(size_t),
bool bool
wxGrid::SendGridSizeEvent(wxEventType type, wxGrid::SendGridSizeEvent(wxEventType type,
int row, int col, int rowOrCol,
const wxMouseEvent& mouseEv) const wxMouseEvent& mouseEv)
{ {
int rowOrCol = row == -1 ? col : row;
wxGridSizeEvent gridEvt( GetId(), wxGridSizeEvent gridEvt( GetId(),
type, type,
this, this,