]> git.saurik.com Git - wxWidgets.git/commitdiff
support column reordering using drag and drop when using wxHeaderCtrl
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 13 Dec 2008 00:24:39 +0000 (00:24 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 13 Dec 2008 00:24:39 +0000 (00:24 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57301 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/generic/grid.h
interface/wx/grid.h
samples/grid/griddemo.cpp
src/generic/grid.cpp

index ec0043baf711af09a720a9c1bd88a37a5bafcaae..f38566a86b46839eb84cc7a964834100d7c18bc3 100644 (file)
@@ -2133,7 +2133,6 @@ protected:
 
     //Column positions
     wxArrayInt m_colAt;
-    int m_moveToCol;
 
     bool    m_canDragRowSize;
     bool    m_canDragColSize;
@@ -2293,10 +2292,11 @@ private:
     void DoStartResizeCol(int col);
     void DoUpdateResizeCol(int x);
     void DoUpdateResizeColWidth(int w);
+    void DoStartMoveCol(int col);
 
     void DoEndDragResizeRow();
     void DoEndDragResizeCol(wxMouseEvent *event = NULL);
-    void DoEndDragMoveCol();
+    void DoEndMoveCol(int pos);
 
 
     // common implementations of methods defined for both rows and columns
index 9ec3a7d5653ac9287199277cfc364ff6d151688e..57dd582b07cb8d25f614b8b2671b5df273caa145 100644 (file)
@@ -3161,6 +3161,18 @@ public:
     @event{EVT_GRID_SELECT_CELL(func)}
         The user moved to, and selected a cell. Processes a
         @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)}
         The user changed the data in a cell; variant taking a window
         identifier. Processes a @c wxEVT_GRID_CELL_CHANGE event type.
index 4b4b8be86b62f7a805a75f2ca370fedc5142a0cc..f8b6f36895fb79970f99b64880d73bdf7039924f 100644 (file)
@@ -1641,7 +1641,9 @@ public:
 private:
     enum // control ids
     {
-        Id_Check_UseNative,
+        Id_Check_UseNativeHeader,
+        Id_Check_DrawNativeLabels,
+        Id_Check_ShowRowLabels,
         Id_Check_EnableColMove
     };
 
@@ -1649,7 +1651,26 @@ private:
 
     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&)
@@ -1671,7 +1692,20 @@ private:
 
     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();
     }
@@ -1688,6 +1722,8 @@ private:
     // controls
     wxGrid *m_grid;
     wxCheckBox *m_chkUseNative,
+               *m_chkDrawNative,
+               *m_chkShowRowLabels,
                *m_chkEnableColMove;
 
     ColIndexEntry *m_txtColIndex,
@@ -1695,28 +1731,49 @@ private:
 
     wxStaticText *m_statOrder;
 
+    // fla for EVT_IDLE handler
+    bool m_shouldUpdateOrder;
+
     DECLARE_NO_COPY_CLASS(TabularGridFrame)
     DECLARE_EVENT_TABLE()
 };
 
 BEGIN_EVENT_TABLE(TabularGridFrame, wxFrame)
-    EVT_CHECKBOX(Id_Check_UseNative, TabularGridFrame::OnToggleUseNativeHeader)
-    EVT_CHECKBOX(Id_Check_EnableColMove, TabularGridFrame::OnToggleColMove)
+    EVT_CHECKBOX(Id_Check_UseNativeHeader,
+                 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_GRID_COL_MOVE(TabularGridFrame::OnGridColMove)
+
+    EVT_IDLE(TabularGridFrame::OnIdle)
 END_EVENT_TABLE()
 
 TabularGridFrame::TabularGridFrame()
                 : wxFrame(NULL, wxID_ANY, "Tabular table")
 {
+    m_shouldUpdateOrder = false;
+
+    wxPanel * const panel = new wxPanel(this);
+
     // 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->SetUseNativeColLabels();
     m_grid->EnableDragColMove();
+    m_grid->UseNativeColHeader();
+    m_grid->HideRowLabels();
 
     // add it and the other controls to the frame
     wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL);
@@ -1725,12 +1782,20 @@ TabularGridFrame::TabularGridFrame()
     wxSizer * const sizerControls = new wxBoxSizer(wxHORIZONTAL);
 
     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");
     m_chkUseNative->SetValue(true);
     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");
     m_chkEnableColMove->SetValue(true);
     sizerStyles->Add(m_chkEnableColMove, wxSizerFlags().Border());
@@ -1742,21 +1807,21 @@ TabularGridFrame::TabularGridFrame()
     wxSizer * const sizerMoveCols = new wxBoxSizer(wxHORIZONTAL);
     const wxSizerFlags
         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);
-    m_txtColIndex = new ColIndexEntry(this);
+    m_txtColIndex = new ColIndexEntry(panel);
     sizerMoveCols->Add(m_txtColIndex, flagsHorz);
-    sizerMoveCols->Add(new wxStaticText(this, wxID_ANY, "&to"), flagsHorz);
-    m_txtColPos = new ColIndexEntry(this);
+    sizerMoveCols->Add(new wxStaticText(panel, wxID_ANY, "&to"), flagsHorz);
+    m_txtColPos = new ColIndexEntry(panel);
     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));
 
     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);
-    m_statOrder = new wxStaticText(this, wxID_ANY, "<default>");
+    m_statOrder = new wxStaticText(panel, wxID_ANY, "<default>");
     sizerShowCols->Add(m_statOrder, flagsHorz);
     sizerColumns->Add(sizerShowCols, wxSizerFlags().Expand().Border(wxTOP));
 
@@ -1764,8 +1829,11 @@ TabularGridFrame::TabularGridFrame()
 
     sizerTop->Add(sizerControls, wxSizerFlags().Expand().Border());
 
-    SetSizerAndFit(sizerTop);
-    SetBackgroundColour(*wxWHITE);
+    panel->SetSizer(sizerTop);
+
+    SetClientSize(panel->GetBestSize());
+    SetSizeHints(GetSize());
+
     Show();
 }
 
@@ -1773,4 +1841,3 @@ void GridFrame::OnTabularTable(wxCommandEvent&)
 {
     new TabularGridFrame;
 }
-
index 3ec21337c0539c7b3da9ac68df076e1d49954328..3e8c74b0b712211e01a70e379ee596ef95fbf4ed 100644 (file)
@@ -275,9 +275,14 @@ private:
         event.Skip();
     }
 
+    void OnBeginReorder(wxHeaderCtrlEvent& event)
+    {
+        GetOwner()->DoStartMoveCol(event.GetColumn());
+    }
+
     void OnEndReorder(wxHeaderCtrlEvent& event)
     {
-        event.Skip(); // TODO: position it at event.GetNewOrder()
+        GetOwner()->DoEndMoveCol(event.GetNewOrder());
     }
 
     wxVector<wxGridHeaderColumn> m_columns;
@@ -291,6 +296,7 @@ BEGIN_EVENT_TABLE(wxGridHeaderCtrl, wxHeaderCtrl)
     EVT_HEADER_RESIZING(wxID_ANY, wxGridHeaderCtrl::OnResizing)
     EVT_HEADER_END_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnEndResize)
 
+    EVT_HEADER_BEGIN_REORDER(wxID_ANY, wxGridHeaderCtrl::OnBeginReorder)
     EVT_HEADER_END_REORDER(wxID_ANY, wxGridHeaderCtrl::OnEndReorder)
 END_EVENT_TABLE()
 
@@ -5888,7 +5894,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
             GetColLabelWindow()->CaptureMouse();
 
             if ( m_cursorMode == WXGRID_CURSOR_MOVE_COL )
-                m_dragRowOrCol = XToCol( x );
+                DoStartMoveCol(XToCol(x));
         }
 
         if ( event.LeftIsDown() )
@@ -5911,25 +5917,15 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
 
                 case WXGRID_CURSOR_MOVE_COL:
                 {
-                    if ( x < 0 )
-                        m_moveToCol = GetColAt( 0 );
-                    else
-                        m_moveToCol = XToCol( x );
+                    int posNew = XToPos(x);
+                    int colNew = GetColAt(posNew);
 
+                    // determine the position of the drop marker
                     int markerX;
-
-                    if ( m_moveToCol < 0 )
-                        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 );
-                    }
+                    if ( x >= GetColLeft(colNew) + (GetColWidth(colNew) / 2) )
+                        markerX = GetColRight(colNew);
                     else
-                        markerX = GetColLeft( m_moveToCol );
+                        markerX = GetColLeft(colNew);
 
                     if ( markerX != m_dragLastPos )
                     {
@@ -5955,9 +5951,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
 
                         const wxColour *color;
                         //Moving to the same place? Don't draw a marker
-                        if ( (m_moveToCol == m_dragRowOrCol)
-                          || (GetColPos( m_moveToCol ) == GetColPos( m_dragRowOrCol ) + 1)
-                          || (m_moveToCol < 0 && m_dragRowOrCol == GetColAt( m_numCols - 1 )))
+                        if ( colNew == m_dragRowOrCol )
                             color = wxLIGHT_GREY;
                         else
                             color = wxBLUE;
@@ -6096,9 +6090,15 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
                 break;
 
             case WXGRID_CURSOR_MOVE_COL:
-                DoEndDragMoveCol();
-
-                SendEvent( wxEVT_GRID_COL_MOVE, -1, m_dragRowOrCol, event );
+                if ( m_dragLastPos == -1 )
+                {
+                    // The user clicked on the column but didn't actually drag
+                    m_colWindow->Refresh();   // "unpress" the column
+                }
+                else
+                {
+                    DoEndMoveCol(XToPos(x));
+                }
                 break;
 
             case WXGRID_CURSOR_SELECT_COL:
@@ -6763,26 +6763,20 @@ void wxGrid::DoEndDragResizeCol(wxMouseEvent *event)
         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
-    if ( m_dragLastPos < 0 )
-    {
-        m_colWindow->Refresh();   //Do this to "unpress" the column
-        return;
-    }
+    m_dragRowOrCol = col;
+}
 
-    int newPos;
-    if ( m_moveToCol == -1 )
-        newPos = m_numCols - 1;
-    else
-    {
-        newPos = GetColPos( m_moveToCol );
-        if ( newPos > GetColPos( m_dragRowOrCol ) )
-            newPos--;
-    }
+void wxGrid::DoEndMoveCol(int pos)
+{
+    wxASSERT_MSG( m_dragRowOrCol != -1, "no matching DoStartMoveCol?" );
+
+    if ( SendEvent(wxEVT_GRID_COL_MOVE, -1, m_dragRowOrCol) != -1 )
+        SetColPos(m_dragRowOrCol, pos);
+    //else: vetoed by user
 
-    SetColPos( m_dragRowOrCol, newPos );
+    m_dragRowOrCol = -1;
 }
 
 void wxGrid::SetColPos(int idx, int pos)