Add support for rearranging wxGrid rows order interactively

Add EnableDragRowMove() function and wxEVT_GRID_ROW_MOVE, similarly to
the existing column function and event.

Closes #22260.
This commit is contained in:
DietmarSchwertberger
2022-04-07 17:39:56 +02:00
committed by Vadim Zeitlin
parent c39c392bbb
commit 3719ab3725
6 changed files with 612 additions and 125 deletions
+64 -18
View File
@@ -1899,6 +1899,11 @@ public:
bool CanDragColSize(int col) const
{ return m_canDragColSize && DoCanResizeLine(col, m_setFixedCols); }
// interactive row reordering (disabled by default)
bool EnableDragRowMove( bool enable = true );
void DisableDragRowMove() { EnableDragRowMove( false ); }
bool CanDragRowMove() const { return m_canDragRowMove; }
// interactive column reordering (disabled by default)
bool EnableDragColMove( bool enable = true );
void DisableDragColMove() { EnableDragColMove( false ); }
@@ -2053,33 +2058,60 @@ public:
void SetRowSizes(const wxGridSizesInfo& sizeInfo);
// ------- columns (only, for now) reordering
// ------- rows and columns reordering
// columns index <-> positions mapping: by default, the position of the
// column is the same as its index, but the columns can also be reordered
// (either by calling SetColPos() explicitly or by the user dragging the
// columns around) in which case their indices don't correspond to their
// rows and columns index <-> positions mapping: by default, the position
// is the same as its index, but they can also be reordered
// (either by calling SetRowPos()/SetColPos() explicitly or by the user
// dragging around) in which case their indices don't correspond to their
// positions on display any longer
//
// internally we always work with indices except for the functions which
// have "Pos" in their names (and which work with columns, not pixels) and
// only the display and hit testing code really cares about display
// positions at all
// have "Pos" in their names (and which work with rows and columns, not
// pixels) and only the display and hit testing code really cares about
// display positions at all
// set the positions of all columns at once (this method uses the same
// conventions as wxHeaderCtrl::SetColumnsOrder() for the order array)
// set the positions of all rows or columns at once (this method uses the
// same conventions as wxHeaderCtrl::SetColumnsOrder() for the order array)
void SetRowsOrder(const wxArrayInt& order);
void SetColumnsOrder(const wxArrayInt& order);
// return the row index corresponding to the given (valid) position
int GetRowAt(int pos) const
{
return m_rowAt.empty() ? pos : m_rowAt[pos];
}
// return the column index corresponding to the given (valid) position
int GetColAt(int pos) const
{
return m_colAt.empty() ? pos : m_colAt[pos];
}
// reorder the rows so that the row with the given index is now shown
// as the position pos
void SetRowPos(int idx, int pos);
// reorder the columns so that the column with the given index is now shown
// as the position pos
void SetColPos(int idx, int pos);
// return the position at which the row with the given index is
// displayed: notice that this is a slow operation as we don't maintain the
// reverse mapping currently
int GetRowPos(int idx) const
{
wxASSERT_MSG( idx >= 0 && idx < m_numRows, "invalid row index" );
if ( m_rowAt.IsEmpty() )
return idx;
int pos = m_rowAt.Index(idx);
wxASSERT_MSG( pos != wxNOT_FOUND, "invalid row index" );
return pos;
}
// return the position at which the column with the given index is
// displayed: notice that this is a slow operation as we don't maintain the
// reverse mapping currently
@@ -2096,7 +2128,8 @@ public:
return pos;
}
// reset the columns positions to the default order
// reset the rows or columns positions to the default order
void ResetRowPos();
void ResetColPos();
@@ -2718,6 +2751,7 @@ protected:
WXGRID_CURSOR_RESIZE_COL,
WXGRID_CURSOR_SELECT_ROW,
WXGRID_CURSOR_SELECT_COL,
WXGRID_CURSOR_MOVE_ROW,
WXGRID_CURSOR_MOVE_COL
};
@@ -2744,18 +2778,23 @@ protected:
CursorMode m_cursorMode;
//Row positions
wxArrayInt m_rowAt;
//Column positions
wxArrayInt m_colAt;
bool m_canDragRowSize;
bool m_canDragColSize;
bool m_canDragRowMove;
bool m_canDragColMove;
bool m_canHideColumns;
bool m_canDragGridSize;
bool m_canDragCell;
// Index of the column being drag-moved or -1 if there is no move operation
// in progress.
// Index of the row or column being drag-moved or -1 if there is no move
// operation in progress.
int m_dragMoveRow;
int m_dragMoveCol;
// Last horizontal mouse position while drag-moving a column.
@@ -2908,8 +2947,9 @@ private:
// the sorting indicator to effectively show
void UpdateColumnSortingIndicator(int col);
// update the grid after changing the columns order (common part of
// SetColPos() and ResetColPos())
// update the grid after changing the rows or columns order (common part
// of Set{Row,Col}Pos() and Reset{Row,Col}Pos())
void RefreshAfterRowPosChange();
void RefreshAfterColPosChange();
// reset the variables used during dragging operations after it ended,
@@ -2927,11 +2967,12 @@ private:
}
// return the position (not index) of the column at the given logical pixel
// position
// return the position (not index) of the row or column at the given logical
// pixel position
//
// this always returns a valid position, even if the coordinate is out of
// bounds (in which case first/last column is returned)
// bounds (in which case first/last row/column is returned)
int YToPos(int y, wxGridWindow *gridWindow) const;
int XToPos(int x, wxGridWindow *gridWindow) const;
// event handlers and their helpers
@@ -2989,12 +3030,14 @@ private:
void DoColHeaderClick(int col);
void DoStartResizeRowOrCol(int col);
void DoStartMoveRow(int col);
void DoStartMoveCol(int col);
// These functions should only be called when actually resizing/moving,
// i.e. m_dragRowOrCol and m_dragMoveCol, respectively, are valid.
void DoEndDragResizeRow(const wxMouseEvent& event, wxGridWindow *gridWindow);
void DoEndDragResizeCol(const wxMouseEvent& event, wxGridWindow *gridWindow);
void DoEndMoveRow(int pos);
void DoEndMoveCol(int pos);
// Helper function returning the position (only the horizontal component
@@ -3426,6 +3469,7 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_EDITOR_SHOWN, wxGridEvent
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_EDITOR_HIDDEN, wxGridEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_EDITOR_CREATED, wxGridEditorCreatedEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_CELL_BEGIN_DRAG, wxGridEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_ROW_MOVE, wxGridEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_COL_MOVE, wxGridEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_COL_SORT, wxGridEvent );
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_CORE, wxEVT_GRID_TABBING, wxGridEvent );
@@ -3470,6 +3514,7 @@ typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreat
#define EVT_GRID_CMD_ROW_SIZE(id, fn) wx__DECLARE_GRIDSIZEEVT(ROW_SIZE, id, fn)
#define EVT_GRID_CMD_COL_SIZE(id, fn) wx__DECLARE_GRIDSIZEEVT(COL_SIZE, id, fn)
#define EVT_GRID_CMD_COL_AUTO_SIZE(id, fn) wx__DECLARE_GRIDSIZEEVT(COL_AUTO_SIZE, id, fn)
#define EVT_GRID_CMD_ROW_MOVE(id, fn) wx__DECLARE_GRIDEVT(ROW_MOVE, id, fn)
#define EVT_GRID_CMD_COL_MOVE(id, fn) wx__DECLARE_GRIDEVT(COL_MOVE, id, fn)
#define EVT_GRID_CMD_COL_SORT(id, fn) wx__DECLARE_GRIDEVT(COL_SORT, id, fn)
#define EVT_GRID_CMD_RANGE_SELECTING(id, fn) wx__DECLARE_GRIDRANGESELEVT(RANGE_SELECTING, id, fn)
@@ -3496,6 +3541,7 @@ typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreat
#define EVT_GRID_ROW_SIZE(fn) EVT_GRID_CMD_ROW_SIZE(wxID_ANY, fn)
#define EVT_GRID_COL_SIZE(fn) EVT_GRID_CMD_COL_SIZE(wxID_ANY, fn)
#define EVT_GRID_COL_AUTO_SIZE(fn) EVT_GRID_CMD_COL_AUTO_SIZE(wxID_ANY, fn)
#define EVT_GRID_ROW_MOVE(fn) EVT_GRID_CMD_ROW_MOVE(wxID_ANY, fn)
#define EVT_GRID_COL_MOVE(fn) EVT_GRID_CMD_COL_MOVE(wxID_ANY, fn)
#define EVT_GRID_COL_SORT(fn) EVT_GRID_CMD_COL_SORT(wxID_ANY, fn)
#define EVT_GRID_RANGE_SELECTING(fn) EVT_GRID_CMD_RANGE_SELECTING(wxID_ANY, fn)
+9 -11
View File
@@ -572,14 +572,9 @@ public:
// Return the index of the line at the given position
//
// NB: currently this is always identity for the rows as reordering is only
// implemented for the lines
virtual int GetLineAt(const wxGrid *grid, int pos) const = 0;
// Return the display position of the line with the given index.
//
// NB: As GetLineAt(), currently this is always identity for rows.
virtual int GetLinePos(const wxGrid *grid, int line) const = 0;
// Return the index of the line just before the given one or wxNOT_FOUND.
@@ -663,13 +658,16 @@ public:
virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const wxOVERRIDE
{ grid->SetDefaultRowSize(size, resizeExisting); }
virtual int GetLineAt(const wxGrid * WXUNUSED(grid), int pos) const wxOVERRIDE
{ return pos; } // TODO: implement row reordering
virtual int GetLinePos(const wxGrid * WXUNUSED(grid), int line) const wxOVERRIDE
{ return line; } // TODO: implement row reordering
virtual int GetLineAt(const wxGrid *grid, int pos) const wxOVERRIDE
{ return grid->GetRowAt(pos); }
virtual int GetLinePos(const wxGrid *grid, int line) const wxOVERRIDE
{ return grid->GetRowPos(line); }
virtual int GetLineBefore(const wxGrid* WXUNUSED(grid), int line) const wxOVERRIDE
{ return line - 1; }
virtual int GetLineBefore(const wxGrid *grid, int line) const wxOVERRIDE
{
int posBefore = grid->GetRowPos(line) - 1;
return posBefore >= 0 ? grid->GetRowAt(posBefore) : wxNOT_FOUND;
}
virtual wxWindow *GetHeaderWindow(wxGrid *grid) const wxOVERRIDE
{ return grid->GetGridRowLabelWindow(); }
+86 -2
View File
@@ -4480,8 +4480,9 @@ public:
EnableDragGridSize() they can also be resized by dragging the right or
bottom edge of the grid cells.
Columns can also be moved to interactively change their order but this
needs to be explicitly enabled with EnableDragColMove().
Columns and rows can also be moved to interactively change their order
but this needs to be explicitly enabled with EnableDragColMove() and
EnableDragColMove().
*/
//@{
@@ -4534,6 +4535,15 @@ public:
*/
bool CanDragGridSize() const;
/**
Returns @true if rows can be moved by dragging with the mouse.
Rows can be moved by dragging on their labels.
@since 3.1.7
*/
bool CanDragRowMove() const;
/**
Returns @true if the given row can be resized by dragging with the
mouse.
@@ -4586,6 +4596,15 @@ public:
*/
void DisableDragColMove();
/**
Disables row moving by dragging with the mouse.
Equivalent to passing @false to EnableDragRowMove().
@since 3.1.7
*/
void DisableDragRowMove();
/**
Disables column sizing by dragging with the mouse.
@@ -4632,6 +4651,19 @@ public:
*/
bool EnableDragColMove(bool enable = true);
/**
Enables or disables row moving by dragging with the mouse.
Note that reordering rows by dragging them is currently not
supported when the grid has any frozen columns (see FreezeTo()) and if
this method is called with @a enable equal to @true in this situation,
it returns @false without doing anything. Otherwise it returns @true to
indicate that it was successful.
@since 3.1.7
*/
bool EnableDragRowMove(bool enable = true);
/**
Enables or disables column sizing by dragging with the mouse.
@@ -4703,6 +4735,44 @@ public:
*/
void ResetColPos();
/**
Returns the row ID of the specified row position.
@since 3.1.7
*/
int GetRowAt(int rowPos) const;
/**
Returns the position of the specified row.
@since 3.1.7
*/
int GetRowPos(int rowID) const;
/**
Sets the position of the specified row.
@since 3.1.7
*/
void SetRowPos(int rowID, int newPos);
/**
Sets the positions of all rows at once.
This method takes an array containing the indices of the rows in
their display order.
@since 3.1.7
*/
void SetRowsOrder(const wxArrayInt& order);
/**
Resets the position of the rows to the default.
@since 3.1.7
*/
void ResetRowPos();
//@}
@@ -6187,6 +6257,19 @@ public:
The given cell was made current, either by user or by the program via a
call to SetGridCursor() or GoToCell(). Processes a
@c wxEVT_GRID_SELECT_CELL event type.
@event{EVT_GRID_ROW_MOVE(func)}
The user tries to change the order of the rows in the grid by
dragging the row specified by GetRow(). This event can be vetoed to
either prevent the user from reordering the row change completely
(but notice that if you don't want to allow it at all, you simply
shouldn't call wxGrid::EnableDragRowMove() in the first place), vetoed
but handled in some way in the handler, e.g. by really moving the
row to the new position at the associated table level, or allowed to
proceed in which case wxGrid::SetRowPos() is used to reorder the
rows display order without affecting the use of the row indices
otherwise.
This event macro corresponds to @c wxEVT_GRID_ROW_MOVE event type.
It is only available since wxWidgets 3.1.7.
@event{EVT_GRID_COL_MOVE(func)}
The user tries to change the order of the columns in the grid by
dragging the column specified by GetCol(). This event can be vetoed to
@@ -6582,6 +6665,7 @@ wxEventType wxEVT_GRID_EDITOR_SHOWN;
wxEventType wxEVT_GRID_EDITOR_HIDDEN;
wxEventType wxEVT_GRID_EDITOR_CREATED;
wxEventType wxEVT_GRID_CELL_BEGIN_DRAG;
wxEventType wxEVT_GRID_ROW_MOVE;
wxEventType wxEVT_GRID_COL_MOVE;
wxEventType wxEVT_GRID_COL_SORT;
wxEventType wxEVT_GRID_TABBING;
+75 -13
View File
@@ -281,6 +281,7 @@ wxBEGIN_EVENT_TABLE( GridFrame, wxFrame )
EVT_MENU( ID_TOGGLEEDIT, GridFrame::ToggleEditing )
EVT_MENU( ID_TOGGLEROWSIZING, GridFrame::ToggleRowSizing )
EVT_MENU( ID_TOGGLECOLSIZING, GridFrame::ToggleColSizing )
EVT_MENU( ID_TOGGLEROWMOVING, GridFrame::ToggleRowMoving)
EVT_MENU( ID_TOGGLECOLMOVING, GridFrame::ToggleColMoving )
EVT_MENU( ID_TOGGLECOLHIDING, GridFrame::ToggleColHiding )
EVT_MENU( ID_TOGGLEGRIDSIZING, GridFrame::ToggleGridSizing )
@@ -437,6 +438,7 @@ GridFrame::GridFrame()
viewMenu->AppendCheckItem(ID_TOGGLEEDIT,"&Editable");
viewMenu->AppendCheckItem(ID_TOGGLEROWSIZING, "Ro&w drag-resize");
viewMenu->AppendCheckItem(ID_TOGGLECOLSIZING, "C&ol drag-resize");
viewMenu->AppendCheckItem(ID_TOGGLEROWMOVING, "Row drag-move");
viewMenu->AppendCheckItem(ID_TOGGLECOLMOVING, "Col drag-&move");
viewMenu->AppendCheckItem(ID_TOGGLECOLHIDING, "Col hiding popup menu");
viewMenu->AppendCheckItem(ID_TOGGLEGRIDSIZING, "&Grid drag-resize");
@@ -865,6 +867,12 @@ void GridFrame::ToggleColSizing( wxCommandEvent& WXUNUSED(ev) )
GetMenuBar()->IsChecked( ID_TOGGLECOLSIZING ) );
}
void GridFrame::ToggleRowMoving( wxCommandEvent& WXUNUSED(ev) )
{
grid->EnableDragRowMove(
GetMenuBar()->IsChecked( ID_TOGGLEROWMOVING ) );
}
void GridFrame::ToggleColMoving( wxCommandEvent& WXUNUSED(ev) )
{
grid->EnableDragColMove(
@@ -1717,9 +1725,12 @@ void GridFrame::OnSelectCell( wxGridEvent& ev )
<< ", AltDown: "<< (ev.AltDown() ? 'T':'F')
<< ", MetaDown: "<< (ev.MetaDown() ? 'T':'F') << " )";
//Indicate whether this row was moved
if ( grid->GetRowPos( ev.GetRow() ) != ev.GetRow() )
logBuf << " *** Row moved, current position: " << grid->GetRowPos( ev.GetRow() );
//Indicate whether this column was moved
if ( ((wxGrid *)ev.GetEventObject())->GetColPos( ev.GetCol() ) != ev.GetCol() )
logBuf << " *** Column moved, current position: " << ((wxGrid *)ev.GetEventObject())->GetColPos( ev.GetCol() );
if ( grid->GetColPos( ev.GetCol() ) != ev.GetCol() )
logBuf << " *** Column moved, current position: " << grid->GetColPos( ev.GetCol() );
wxLogMessage( "%s", logBuf );
@@ -2432,6 +2443,7 @@ private:
Id_Check_UseNativeHeader,
Id_Check_DrawNativeLabels,
Id_Check_ShowRowLabels,
Id_Check_EnableRowMove,
Id_Check_EnableColMove
};
@@ -2461,6 +2473,11 @@ private:
: 0);
}
void OnToggleRowMove(wxCommandEvent&)
{
m_grid->EnableDragRowMove(m_chkEnableRowMove->IsChecked());
}
void OnToggleColMove(wxCommandEvent&)
{
m_grid->EnableDragColMove(m_chkEnableColMove->IsChecked());
@@ -2474,7 +2491,7 @@ private:
m_grid->SetColSize(col,
event.GetId() == wxID_ADD ? wxGRID_AUTOSIZE : 0);
UpdateOrderAndVisibility();
UpdateColOrderAndVisibility();
}
}
@@ -2487,14 +2504,14 @@ private:
m_grid->SetColPos(col, pos);
UpdateOrderAndVisibility();
UpdateColOrderAndVisibility();
}
void OnResetColumnOrder(wxCommandEvent&)
{
m_grid->ResetColPos();
UpdateOrderAndVisibility();
UpdateColOrderAndVisibility();
}
void OnGridColSort(wxGridEvent& event)
@@ -2504,11 +2521,20 @@ private:
m_grid->IsSortOrderAscending()));
}
void OnGridRowMove(wxGridEvent& event)
{
// can't update it yet as the order hasn't been changed, so do it a bit
// later
m_shouldUpdateRowOrder = true;
event.Skip();
}
void OnGridColMove(wxGridEvent& event)
{
// can't update it yet as the order hasn't been changed, so do it a bit
// later
m_shouldUpdateOrder = true;
m_shouldUpdateColOrder = true;
event.Skip();
}
@@ -2518,23 +2544,29 @@ private:
// we only catch this event to react to the user showing or hiding this
// column using the header control menu and not because we're
// interested in column resizing
UpdateOrderAndVisibility();
UpdateColOrderAndVisibility();
event.Skip();
}
void OnIdle(wxIdleEvent& event)
{
if ( m_shouldUpdateOrder )
if ( m_shouldUpdateColOrder )
{
m_shouldUpdateOrder = false;
UpdateOrderAndVisibility();
m_shouldUpdateColOrder = false;
UpdateColOrderAndVisibility();
}
if ( m_shouldUpdateRowOrder )
{
m_shouldUpdateRowOrder = false;
UpdateRowOrderAndVisibility();
}
event.Skip();
}
void UpdateOrderAndVisibility()
void UpdateColOrderAndVisibility()
{
wxString s;
for ( int pos = 0; pos < TabularGridTable::COL_MAX; pos++ )
@@ -2554,12 +2586,33 @@ private:
m_statOrder->SetLabel(s);
}
void UpdateRowOrderAndVisibility()
{
wxString s;
for ( int pos = 0; pos < TabularGridTable::ROW_MAX; pos++ )
{
const int row = m_grid->GetRowAt(pos);
const bool isHidden = m_grid->GetRowSize(row) == 0;
if ( isHidden )
s << '[';
s << row;
if ( isHidden )
s << ']';
s << ' ';
}
m_statOrder->SetLabel(s);
}
// controls
wxGrid *m_grid;
TabularGridTable *m_table;
wxCheckBox *m_chkUseNative,
*m_chkDrawNative,
*m_chkShowRowLabels,
*m_chkEnableRowMove,
*m_chkEnableColMove;
ColIndexEntry *m_txtColIndex,
@@ -2569,7 +2622,8 @@ private:
wxStaticText *m_statOrder;
// fla for EVT_IDLE handler
bool m_shouldUpdateOrder;
bool m_shouldUpdateRowOrder,
m_shouldUpdateColOrder;
wxDECLARE_NO_COPY_CLASS(TabularGridFrame);
wxDECLARE_EVENT_TABLE();
@@ -2594,6 +2648,7 @@ wxBEGIN_EVENT_TABLE(TabularGridFrame, wxFrame)
EVT_BUTTON(wxID_DELETE, TabularGridFrame::OnShowHideColumn)
EVT_GRID_COL_SORT(TabularGridFrame::OnGridColSort)
EVT_GRID_ROW_MOVE(TabularGridFrame::OnGridRowMove)
EVT_GRID_COL_MOVE(TabularGridFrame::OnGridColMove)
EVT_GRID_COL_SIZE(TabularGridFrame::OnGridColSize)
@@ -2603,7 +2658,7 @@ wxEND_EVENT_TABLE()
TabularGridFrame::TabularGridFrame()
: wxFrame(NULL, wxID_ANY, "Tabular table")
{
m_shouldUpdateOrder = false;
m_shouldUpdateColOrder = false;
wxPanel * const panel = new wxPanel(this);
@@ -2614,6 +2669,7 @@ TabularGridFrame::TabularGridFrame()
wxBORDER_STATIC | wxWANTS_CHARS);
m_grid->AssignTable(m_table, wxGrid::wxGridSelectRows);
m_grid->EnableDragRowMove();
m_grid->EnableDragColMove();
m_grid->UseNativeColHeader();
m_grid->HideRowLabels();
@@ -2638,6 +2694,12 @@ TabularGridFrame::TabularGridFrame()
"Show &row labels");
sizerStyles->Add(m_chkShowRowLabels, wxSizerFlags().Border());
m_chkEnableRowMove = new wxCheckBox(panel, Id_Check_EnableRowMove,
"Allow row reordering");
m_chkEnableRowMove->SetValue(true);
sizerStyles->Add(m_chkEnableRowMove, wxSizerFlags().Border());
sizerControls->Add(sizerStyles);
m_chkEnableColMove = new wxCheckBox(panel, Id_Check_EnableColMove,
"Allow column re&ordering");
m_chkEnableColMove->SetValue(true);
+2
View File
@@ -35,6 +35,7 @@ class GridFrame : public wxFrame
void ToggleEditing( wxCommandEvent& );
void ToggleRowSizing( wxCommandEvent& );
void ToggleColSizing( wxCommandEvent& );
void ToggleRowMoving( wxCommandEvent& );
void ToggleColMoving( wxCommandEvent& );
void ToggleColHiding( wxCommandEvent& );
void ToggleGridSizing( wxCommandEvent& );
@@ -148,6 +149,7 @@ public:
ID_TOGGLEEDIT,
ID_TOGGLEROWSIZING,
ID_TOGGLECOLSIZING,
ID_TOGGLEROWMOVING,
ID_TOGGLECOLMOVING,
ID_TOGGLECOLHIDING,
ID_TOGGLEGRIDSIZING,
+376 -81
View File
File diff suppressed because it is too large Load Diff