support column reordering using drag and drop when using wxHeaderCtrl

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57301 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-12-13 00:24:39 +00:00
parent baa4a96705
commit cd68daf58a
4 changed files with 135 additions and 62 deletions

View File

@@ -2133,7 +2133,6 @@ protected:
//Column positions //Column positions
wxArrayInt m_colAt; wxArrayInt m_colAt;
int m_moveToCol;
bool m_canDragRowSize; bool m_canDragRowSize;
bool m_canDragColSize; bool m_canDragColSize;
@@ -2293,10 +2292,11 @@ private:
void DoStartResizeCol(int col); void DoStartResizeCol(int col);
void DoUpdateResizeCol(int x); void DoUpdateResizeCol(int x);
void DoUpdateResizeColWidth(int w); void DoUpdateResizeColWidth(int w);
void DoStartMoveCol(int col);
void DoEndDragResizeRow(); void DoEndDragResizeRow();
void DoEndDragResizeCol(wxMouseEvent *event = NULL); void DoEndDragResizeCol(wxMouseEvent *event = NULL);
void DoEndDragMoveCol(); void DoEndMoveCol(int pos);
// common implementations of methods defined for both rows and columns // common implementations of methods defined for both rows and columns

View File

@@ -3161,6 +3161,18 @@ public:
@event{EVT_GRID_SELECT_CELL(func)} @event{EVT_GRID_SELECT_CELL(func)}
The user moved to, and selected a cell. Processes a The user moved to, and selected a cell. Processes a
@c wxEVT_GRID_SELECT_CELL event type. @c wxEVT_GRID_SELECT_CELL event type.
@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
either prevent the user from reordering the column change completely
(but notice that if you don't want to allow it at all, you simply
shouldn't call wxGrid::EnableDragColMove() in the first place), vetoed
but handled in some way in the handler, e.g. by really moving the
column to the new position at the associated table level, or allowed to
proceed in which case wxGrid::SetColPos() is used to reorder the
columns display order without affecting the use of the column indices
otherwise.
This event macro corresponds to @c wxEVT_GRID_COL_MOVE event type.
@event{EVT_GRID_CMD_CELL_CHANGE(id, func)} @event{EVT_GRID_CMD_CELL_CHANGE(id, func)}
The user changed the data in a cell; variant taking a window The user changed the data in a cell; variant taking a window
identifier. Processes a @c wxEVT_GRID_CELL_CHANGE event type. identifier. Processes a @c wxEVT_GRID_CELL_CHANGE event type.

View File

@@ -1641,7 +1641,9 @@ public:
private: private:
enum // control ids enum // control ids
{ {
Id_Check_UseNative, Id_Check_UseNativeHeader,
Id_Check_DrawNativeLabels,
Id_Check_ShowRowLabels,
Id_Check_EnableColMove Id_Check_EnableColMove
}; };
@@ -1649,7 +1651,26 @@ private:
void OnToggleUseNativeHeader(wxCommandEvent&) void OnToggleUseNativeHeader(wxCommandEvent&)
{ {
m_grid->SetUseNativeColLabels(m_chkUseNative->IsChecked()); m_grid->UseNativeColHeader(m_chkUseNative->IsChecked());
}
void OnUpdateDrawNativeLabelsUI(wxUpdateUIEvent& event)
{
// we don't draw labels at all, native or otherwise, if we use the
// native header control
event.Enable( !m_chkUseNative->GetValue() );
}
void OnToggleDrawNativeLabels(wxCommandEvent&)
{
m_grid->SetUseNativeColLabels(m_chkDrawNative->IsChecked());
}
void OnToggleShowRowLabels(wxCommandEvent&)
{
m_grid->SetRowLabelSize(m_chkShowRowLabels->IsChecked()
? wxGRID_AUTOSIZE
: 0);
} }
void OnToggleColMove(wxCommandEvent&) void OnToggleColMove(wxCommandEvent&)
@@ -1671,7 +1692,20 @@ private:
void OnGridColMove(wxGridEvent& event) void OnGridColMove(wxGridEvent& event)
{ {
UpdateOrder(); // can't update it yet as the order hasn't been changed, so do it a bit
// later
m_shouldUpdateOrder = true;
event.Skip();
}
void OnIdle(wxIdleEvent& event)
{
if ( m_shouldUpdateOrder )
{
m_shouldUpdateOrder = false;
UpdateOrder();
}
event.Skip(); event.Skip();
} }
@@ -1688,6 +1722,8 @@ private:
// controls // controls
wxGrid *m_grid; wxGrid *m_grid;
wxCheckBox *m_chkUseNative, wxCheckBox *m_chkUseNative,
*m_chkDrawNative,
*m_chkShowRowLabels,
*m_chkEnableColMove; *m_chkEnableColMove;
ColIndexEntry *m_txtColIndex, ColIndexEntry *m_txtColIndex,
@@ -1695,28 +1731,49 @@ private:
wxStaticText *m_statOrder; wxStaticText *m_statOrder;
// fla for EVT_IDLE handler
bool m_shouldUpdateOrder;
DECLARE_NO_COPY_CLASS(TabularGridFrame) DECLARE_NO_COPY_CLASS(TabularGridFrame)
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
BEGIN_EVENT_TABLE(TabularGridFrame, wxFrame) BEGIN_EVENT_TABLE(TabularGridFrame, wxFrame)
EVT_CHECKBOX(Id_Check_UseNative, TabularGridFrame::OnToggleUseNativeHeader) EVT_CHECKBOX(Id_Check_UseNativeHeader,
EVT_CHECKBOX(Id_Check_EnableColMove, TabularGridFrame::OnToggleColMove) TabularGridFrame::OnToggleUseNativeHeader)
EVT_CHECKBOX(Id_Check_DrawNativeLabels,
TabularGridFrame::OnToggleDrawNativeLabels)
EVT_CHECKBOX(Id_Check_ShowRowLabels,
TabularGridFrame::OnToggleShowRowLabels)
EVT_CHECKBOX(Id_Check_EnableColMove,
TabularGridFrame::OnToggleColMove)
EVT_UPDATE_UI(Id_Check_DrawNativeLabels,
TabularGridFrame::OnUpdateDrawNativeLabelsUI)
EVT_BUTTON(wxID_APPLY, TabularGridFrame::OnMoveColumn) EVT_BUTTON(wxID_APPLY, TabularGridFrame::OnMoveColumn)
EVT_GRID_COL_MOVE(TabularGridFrame::OnGridColMove) EVT_GRID_COL_MOVE(TabularGridFrame::OnGridColMove)
EVT_IDLE(TabularGridFrame::OnIdle)
END_EVENT_TABLE() END_EVENT_TABLE()
TabularGridFrame::TabularGridFrame() TabularGridFrame::TabularGridFrame()
: wxFrame(NULL, wxID_ANY, "Tabular table") : wxFrame(NULL, wxID_ANY, "Tabular table")
{ {
m_shouldUpdateOrder = false;
wxPanel * const panel = new wxPanel(this);
// create and initialize the grid with the specified data // create and initialize the grid with the specified data
m_grid = new wxGrid(this, wxID_ANY); m_grid = new wxGrid(panel, wxID_ANY,
wxDefaultPosition, wxDefaultSize,
wxBORDER_STATIC | wxWANTS_CHARS);
m_grid->SetTable(new TabularGridTable, true, wxGrid::wxGridSelectRows); m_grid->SetTable(new TabularGridTable, true, wxGrid::wxGridSelectRows);
m_grid->SetUseNativeColLabels();
m_grid->EnableDragColMove(); m_grid->EnableDragColMove();
m_grid->UseNativeColHeader();
m_grid->HideRowLabels();
// add it and the other controls to the frame // add it and the other controls to the frame
wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL); wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL);
@@ -1725,12 +1782,20 @@ TabularGridFrame::TabularGridFrame()
wxSizer * const sizerControls = new wxBoxSizer(wxHORIZONTAL); wxSizer * const sizerControls = new wxBoxSizer(wxHORIZONTAL);
wxSizer * const sizerStyles = new wxBoxSizer(wxVERTICAL); wxSizer * const sizerStyles = new wxBoxSizer(wxVERTICAL);
m_chkUseNative = new wxCheckBox(this, Id_Check_UseNative, m_chkUseNative = new wxCheckBox(panel, Id_Check_UseNativeHeader,
"&Use native header"); "&Use native header");
m_chkUseNative->SetValue(true); m_chkUseNative->SetValue(true);
sizerStyles->Add(m_chkUseNative, wxSizerFlags().Border()); sizerStyles->Add(m_chkUseNative, wxSizerFlags().Border());
m_chkEnableColMove = new wxCheckBox(this, Id_Check_EnableColMove, m_chkDrawNative = new wxCheckBox(panel, Id_Check_DrawNativeLabels,
"&Draw native column labels");
sizerStyles->Add(m_chkDrawNative, wxSizerFlags().Border());
m_chkShowRowLabels = new wxCheckBox(panel, Id_Check_ShowRowLabels,
"Show &row labels");
sizerStyles->Add(m_chkShowRowLabels, wxSizerFlags().Border());
m_chkEnableColMove = new wxCheckBox(panel, Id_Check_EnableColMove,
"Allow column re&ordering"); "Allow column re&ordering");
m_chkEnableColMove->SetValue(true); m_chkEnableColMove->SetValue(true);
sizerStyles->Add(m_chkEnableColMove, wxSizerFlags().Border()); sizerStyles->Add(m_chkEnableColMove, wxSizerFlags().Border());
@@ -1742,21 +1807,21 @@ TabularGridFrame::TabularGridFrame()
wxSizer * const sizerMoveCols = new wxBoxSizer(wxHORIZONTAL); wxSizer * const sizerMoveCols = new wxBoxSizer(wxHORIZONTAL);
const wxSizerFlags const wxSizerFlags
flagsHorz(wxSizerFlags().Border(wxLEFT | wxRIGHT).Centre()); flagsHorz(wxSizerFlags().Border(wxLEFT | wxRIGHT).Centre());
sizerMoveCols->Add(new wxStaticText(this, wxID_ANY, "&Move column"), sizerMoveCols->Add(new wxStaticText(panel, wxID_ANY, "&Move column"),
flagsHorz); flagsHorz);
m_txtColIndex = new ColIndexEntry(this); m_txtColIndex = new ColIndexEntry(panel);
sizerMoveCols->Add(m_txtColIndex, flagsHorz); sizerMoveCols->Add(m_txtColIndex, flagsHorz);
sizerMoveCols->Add(new wxStaticText(this, wxID_ANY, "&to"), flagsHorz); sizerMoveCols->Add(new wxStaticText(panel, wxID_ANY, "&to"), flagsHorz);
m_txtColPos = new ColIndexEntry(this); m_txtColPos = new ColIndexEntry(panel);
sizerMoveCols->Add(m_txtColPos, flagsHorz); sizerMoveCols->Add(m_txtColPos, flagsHorz);
sizerMoveCols->Add(new wxButton(this, wxID_APPLY), flagsHorz); sizerMoveCols->Add(new wxButton(panel, wxID_APPLY), flagsHorz);
sizerColumns->Add(sizerMoveCols, wxSizerFlags().Expand().Border(wxBOTTOM)); sizerColumns->Add(sizerMoveCols, wxSizerFlags().Expand().Border(wxBOTTOM));
wxSizer * const sizerShowCols = new wxBoxSizer(wxHORIZONTAL); wxSizer * const sizerShowCols = new wxBoxSizer(wxHORIZONTAL);
sizerShowCols->Add(new wxStaticText(this, wxID_ANY, "Current order:"), sizerShowCols->Add(new wxStaticText(panel, wxID_ANY, "Current order:"),
flagsHorz); flagsHorz);
m_statOrder = new wxStaticText(this, wxID_ANY, "<default>"); m_statOrder = new wxStaticText(panel, wxID_ANY, "<default>");
sizerShowCols->Add(m_statOrder, flagsHorz); sizerShowCols->Add(m_statOrder, flagsHorz);
sizerColumns->Add(sizerShowCols, wxSizerFlags().Expand().Border(wxTOP)); sizerColumns->Add(sizerShowCols, wxSizerFlags().Expand().Border(wxTOP));
@@ -1764,8 +1829,11 @@ TabularGridFrame::TabularGridFrame()
sizerTop->Add(sizerControls, wxSizerFlags().Expand().Border()); sizerTop->Add(sizerControls, wxSizerFlags().Expand().Border());
SetSizerAndFit(sizerTop); panel->SetSizer(sizerTop);
SetBackgroundColour(*wxWHITE);
SetClientSize(panel->GetBestSize());
SetSizeHints(GetSize());
Show(); Show();
} }
@@ -1773,4 +1841,3 @@ void GridFrame::OnTabularTable(wxCommandEvent&)
{ {
new TabularGridFrame; new TabularGridFrame;
} }

View File

@@ -275,9 +275,14 @@ private:
event.Skip(); event.Skip();
} }
void OnBeginReorder(wxHeaderCtrlEvent& event)
{
GetOwner()->DoStartMoveCol(event.GetColumn());
}
void OnEndReorder(wxHeaderCtrlEvent& event) void OnEndReorder(wxHeaderCtrlEvent& event)
{ {
event.Skip(); // TODO: position it at event.GetNewOrder() GetOwner()->DoEndMoveCol(event.GetNewOrder());
} }
wxVector<wxGridHeaderColumn> m_columns; wxVector<wxGridHeaderColumn> m_columns;
@@ -291,6 +296,7 @@ BEGIN_EVENT_TABLE(wxGridHeaderCtrl, wxHeaderCtrl)
EVT_HEADER_RESIZING(wxID_ANY, wxGridHeaderCtrl::OnResizing) EVT_HEADER_RESIZING(wxID_ANY, wxGridHeaderCtrl::OnResizing)
EVT_HEADER_END_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnEndResize) EVT_HEADER_END_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnEndResize)
EVT_HEADER_BEGIN_REORDER(wxID_ANY, wxGridHeaderCtrl::OnBeginReorder)
EVT_HEADER_END_REORDER(wxID_ANY, wxGridHeaderCtrl::OnEndReorder) EVT_HEADER_END_REORDER(wxID_ANY, wxGridHeaderCtrl::OnEndReorder)
END_EVENT_TABLE() END_EVENT_TABLE()
@@ -5888,7 +5894,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
GetColLabelWindow()->CaptureMouse(); GetColLabelWindow()->CaptureMouse();
if ( m_cursorMode == WXGRID_CURSOR_MOVE_COL ) if ( m_cursorMode == WXGRID_CURSOR_MOVE_COL )
m_dragRowOrCol = XToCol( x ); DoStartMoveCol(XToCol(x));
} }
if ( event.LeftIsDown() ) if ( event.LeftIsDown() )
@@ -5911,25 +5917,15 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
case WXGRID_CURSOR_MOVE_COL: case WXGRID_CURSOR_MOVE_COL:
{ {
if ( x < 0 ) int posNew = XToPos(x);
m_moveToCol = GetColAt( 0 ); int colNew = GetColAt(posNew);
else
m_moveToCol = XToCol( x );
// determine the position of the drop marker
int markerX; int markerX;
if ( x >= GetColLeft(colNew) + (GetColWidth(colNew) / 2) )
if ( m_moveToCol < 0 ) markerX = GetColRight(colNew);
markerX = GetColRight( GetColAt( m_numCols - 1 ) );
else if ( x >= (GetColLeft( m_moveToCol ) + (GetColWidth(m_moveToCol) / 2)) )
{
m_moveToCol = GetColAt( GetColPos( m_moveToCol ) + 1 );
if ( m_moveToCol < 0 )
markerX = GetColRight( GetColAt( m_numCols - 1 ) );
else
markerX = GetColLeft( m_moveToCol );
}
else else
markerX = GetColLeft( m_moveToCol ); markerX = GetColLeft(colNew);
if ( markerX != m_dragLastPos ) if ( markerX != m_dragLastPos )
{ {
@@ -5955,9 +5951,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
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 ( (m_moveToCol == m_dragRowOrCol) if ( colNew == m_dragRowOrCol )
|| (GetColPos( m_moveToCol ) == GetColPos( m_dragRowOrCol ) + 1)
|| (m_moveToCol < 0 && m_dragRowOrCol == GetColAt( m_numCols - 1 )))
color = wxLIGHT_GREY; color = wxLIGHT_GREY;
else else
color = wxBLUE; color = wxBLUE;
@@ -6096,9 +6090,15 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
break; break;
case WXGRID_CURSOR_MOVE_COL: case WXGRID_CURSOR_MOVE_COL:
DoEndDragMoveCol(); if ( m_dragLastPos == -1 )
{
SendEvent( wxEVT_GRID_COL_MOVE, -1, m_dragRowOrCol, event ); // The user clicked on the column but didn't actually drag
m_colWindow->Refresh(); // "unpress" the column
}
else
{
DoEndMoveCol(XToPos(x));
}
break; break;
case WXGRID_CURSOR_SELECT_COL: case WXGRID_CURSOR_SELECT_COL:
@@ -6763,26 +6763,20 @@ void wxGrid::DoEndDragResizeCol(wxMouseEvent *event)
SendEvent( wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol ); SendEvent( wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol );
} }
void wxGrid::DoEndDragMoveCol() void wxGrid::DoStartMoveCol(int col)
{ {
//The user clicked on the column but didn't actually drag m_dragRowOrCol = col;
if ( m_dragLastPos < 0 ) }
{
m_colWindow->Refresh(); //Do this to "unpress" the column
return;
}
int newPos; void wxGrid::DoEndMoveCol(int pos)
if ( m_moveToCol == -1 ) {
newPos = m_numCols - 1; wxASSERT_MSG( m_dragRowOrCol != -1, "no matching DoStartMoveCol?" );
else
{
newPos = GetColPos( m_moveToCol );
if ( newPos > GetColPos( m_dragRowOrCol ) )
newPos--;
}
SetColPos( m_dragRowOrCol, newPos ); if ( SendEvent(wxEVT_GRID_COL_MOVE, -1, m_dragRowOrCol) != -1 )
SetColPos(m_dragRowOrCol, pos);
//else: vetoed by user
m_dragRowOrCol = -1;
} }
void wxGrid::SetColPos(int idx, int pos) void wxGrid::SetColPos(int idx, int pos)