]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/grid/griddemo.cpp
add headers to the samples' bakefiles so that they show up in MSVC project files
[wxWidgets.git] / samples / grid / griddemo.cpp
index 602ee517c10ce8dc72f954e92e0af231e538af4b..c485fdfe4d15e8706a50474d1d5b0319875552f9 100644 (file)
 #include "wx/colordlg.h"
 #include "wx/fontdlg.h"
 #include "wx/numdlg.h"
+#include "wx/aboutdlg.h"
 
 #include "wx/grid.h"
+#include "wx/headerctrl.h"
 #include "wx/generic/gridctrl.h"
+#include "wx/generic/grideditors.h"
 
 #include "griddemo.h"
 
+#ifndef __WXMSW__
+    #include "../sample.xpm"
+#endif
+
 // ----------------------------------------------------------------------------
 // wxWin macros
 // ----------------------------------------------------------------------------
@@ -131,6 +138,7 @@ BEGIN_EVENT_TABLE( GridFrame, wxFrame )
     EVT_GRID_COL_SIZE( GridFrame::OnColSize )
     EVT_GRID_SELECT_CELL( GridFrame::OnSelectCell )
     EVT_GRID_RANGE_SELECT( GridFrame::OnRangeSelected )
+    EVT_GRID_CELL_CHANGING( GridFrame::OnCellValueChanging )
     EVT_GRID_CELL_CHANGE( GridFrame::OnCellValueChanged )
     EVT_GRID_CELL_BEGIN_DRAG( GridFrame::OnCellBeginDrag )
 
@@ -144,6 +152,8 @@ GridFrame::GridFrame()
                    wxDefaultPosition,
                    wxDefaultSize )
 {
+    SetIcon(wxICON(sample));
+
     wxMenu *fileMenu = new wxMenu;
     fileMenu->Append( ID_VTABLE, _T("&Virtual table test\tCtrl-V"));
     fileMenu->Append( ID_BUGS_TABLE, _T("&Bugs table test\tCtrl-B"));
@@ -1057,13 +1067,36 @@ void GridFrame::OnRangeSelected( wxGridRangeSelectEvent& ev )
     ev.Skip();
 }
 
+void GridFrame::OnCellValueChanging( wxGridEvent& ev )
+{
+    int row = ev.GetRow(),
+        col = ev.GetCol();
+
+    wxLogMessage("Value of cell at (%d, %d): about to change "
+                 "from \"%s\" to \"%s\"",
+                 row, col,
+                 grid->GetCellValue(row, col), ev.GetString());
+
+    // test how vetoing works
+    if ( ev.GetString() == "42" )
+    {
+        wxLogMessage("Vetoing the change.");
+        ev.Veto();
+        return;
+    }
+
+    ev.Skip();
+}
+
 void GridFrame::OnCellValueChanged( wxGridEvent& ev )
 {
     int row = ev.GetRow(),
         col = ev.GetCol();
 
-    wxLogMessage(_T("Value changed for cell at row %d, col %d: now \"%s\""),
-                 row, col, grid->GetCellValue(row, col).c_str());
+    wxLogMessage("Value of cell at (%d, %d) changed and is now \"%s\" "
+                 "(was \"%s\")",
+                 row, col,
+                 grid->GetCellValue(row, col), ev.GetString());
 
     ev.Skip();
 }
@@ -1112,10 +1145,21 @@ void GridFrame::OnEditorHidden( wxGridEvent& ev )
 
 void GridFrame::About(  wxCommandEvent& WXUNUSED(ev) )
 {
-    (void)wxMessageBox( _T("\n\nwxGrid demo \n\n")
-                        _T("Michael Bedward, Julian Smart, Vadim Zeitlin"),
-                        _T("About"),
-                        wxOK );
+    wxAboutDialogInfo aboutInfo;
+    aboutInfo.SetName(wxT("wxGrid demo"));
+    aboutInfo.SetDescription(_("wxGrid sample program"));
+    aboutInfo.AddDeveloper(wxT("Michael Bedward"));
+    aboutInfo.AddDeveloper(wxT("Julian Smart"));
+    aboutInfo.AddDeveloper(wxT("Vadim Zeitlin"));
+
+    // this is just to force the generic version of the about
+    // dialog under wxMSW so that it's easy to test if the grid
+    // repaints correctly when it has lost focus and a dialog
+    // (different from the Windows standard message box -- it doesn't
+    // work with it for some reason) is moved over it.
+    aboutInfo.SetWebSite(wxT("http://www.wxwidgets.org"));
+
+    wxAboutBox(aboutInfo);
 }
 
 
@@ -1560,22 +1604,34 @@ public:
         ROW_MAX = 3
     };
 
+    TabularGridTable() { m_sortOrder = NULL; }
+
     virtual int GetNumberRows() { return ROW_MAX; }
     virtual int GetNumberCols() { return COL_MAX; }
 
     virtual wxString GetValue(int row, int col)
     {
-        // notice that column parameter here always refers to the internal
-        // column index, independently of its position on the screen
-        static const char *filedata[][COL_MAX] =
+        if ( m_sortOrder )
+            row = m_sortOrder[row];
+
+        switch ( col )
         {
-            { "autoexec", "bat",    "412", "Apr 17  2004" },
-            { "boot",     "ini",    "604", "May 27  2006" },
-            { "io",       "sys",  "40774", "May 31  1994" },
-        };
-        wxCOMPILE_TIME_ASSERT( WXSIZEOF(filedata) == ROW_MAX, Mismatch );
+            case COL_NAME:
+            case COL_EXT:
+                return GetNameOrExt(row, col);
+
+            case COL_SIZE:
+                return wxString::Format("%lu", GetSize(row));
+
+            case COL_DATE:
+                return GetDate(row).FormatDate();
 
-        return filedata[row][col];
+            case COL_MAX:
+            default:
+                wxFAIL_MSG( "unknown column" );
+        }
+
+        return wxString();
     }
 
     virtual void SetValue(int, int, const wxString&)
@@ -1585,8 +1641,10 @@ public:
 
     virtual wxString GetColLabelValue(int col)
     {
+        // notice that column parameter here always refers to the internal
+        // column index, independently of its position on the screen
         static const char *labels[] = { "Name", "Extension", "Size", "Date" };
-        wxCOMPILE_TIME_ASSERT( WXSIZEOF(labels) == COL_MAX, Mismatch );
+        wxCOMPILE_TIME_ASSERT( WXSIZEOF(labels) == COL_MAX, LabelsMismatch );
 
         return labels[col];
     }
@@ -1595,6 +1653,54 @@ public:
     {
         wxFAIL_MSG( "shouldn't be called" );
     }
+
+    void Sort(int col, bool ascending)
+    {
+        // we hardcode all sorting orders for simplicity here
+        static int sortOrders[COL_MAX][2][ROW_MAX] =
+        {
+            // descending   ascending
+            { { 2, 1, 0 }, { 0, 1, 2 } },
+            { { 2, 1, 0 }, { 0, 1, 2 } },
+            { { 2, 1, 0 }, { 0, 1, 2 } },
+            { { 1, 0, 2 }, { 2, 0, 1 } },
+        };
+
+        m_sortOrder = col == wxNOT_FOUND ? NULL : sortOrders[col][ascending];
+    }
+
+private:
+    wxString GetNameOrExt(int row, int col) const
+    {
+        static const char *
+            names[] = { "autoexec.bat", "boot.ini", "io.sys" };
+        wxCOMPILE_TIME_ASSERT( WXSIZEOF(names) == ROW_MAX, NamesMismatch );
+
+        const wxString s(names[row]);
+        return col == COL_NAME ? s.BeforeFirst('.') : s.AfterLast('.');
+    }
+
+    unsigned long GetSize(int row) const
+    {
+        static const unsigned long
+            sizes[] = { 412, 604, 40774 };
+        wxCOMPILE_TIME_ASSERT( WXSIZEOF(sizes) == ROW_MAX, SizesMismatch );
+
+        return sizes[row];
+    }
+
+    wxDateTime GetDate(int row) const
+    {
+        static const char *
+            dates[] = { "2004-04-17", "2006-05-27", "1994-05-31" };
+        wxCOMPILE_TIME_ASSERT( WXSIZEOF(dates) == ROW_MAX, DatesMismatch );
+
+        wxDateTime dt;
+        dt.ParseISODate(dates[row]);
+        return dt;
+    }
+
+    int *m_sortOrder;
 };
 
 // specialized text control for column indexes entry
@@ -1636,7 +1742,9 @@ public:
 private:
     enum // control ids
     {
-        Id_Check_UseNative,
+        Id_Check_UseNativeHeader,
+        Id_Check_DrawNativeLabels,
+        Id_Check_ShowRowLabels,
         Id_Check_EnableColMove
     };
 
@@ -1644,7 +1752,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&)
@@ -1652,6 +1779,18 @@ private:
         m_grid->EnableDragColMove(m_chkEnableColMove->IsChecked());
     }
 
+    void OnShowHideColumn(wxCommandEvent& event)
+    {
+        int col = m_txtColShowHide->GetCol();
+        if ( col != -1 )
+        {
+            m_grid->SetColSize(col,
+                               event.GetId() == wxID_ADD ? wxGRID_AUTOSIZE : 0);
+
+            UpdateOrderAndVisibility();
+        }
+    }
+
     void OnMoveColumn(wxCommandEvent&)
     {
         int col = m_txtColIndex->GetCol();
@@ -1661,57 +1800,136 @@ private:
 
         m_grid->SetColPos(col, pos);
 
-        UpdateOrder();
+        UpdateOrderAndVisibility();
+    }
+
+    void OnResetColumnOrder(wxCommandEvent&)
+    {
+        m_grid->ResetColPos();
+
+        UpdateOrderAndVisibility();
+    }
+
+    void OnGridColSort(wxGridEvent& event)
+    {
+        const int col = event.GetCol();
+        m_table->Sort(col, !(m_grid->IsSortingBy(col) &&
+                             m_grid->IsSortOrderAscending()));
     }
 
     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 UpdateOrder()
+    void OnGridColSize(wxGridSizeEvent& event)
+    {
+        // 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();
+
+        event.Skip();
+    }
+
+    void OnIdle(wxIdleEvent& event)
+    {
+        if ( m_shouldUpdateOrder )
+        {
+            m_shouldUpdateOrder = false;
+            UpdateOrderAndVisibility();
+        }
+
+        event.Skip();
+    }
+
+    void UpdateOrderAndVisibility()
     {
         wxString s;
         for ( int pos = 0; pos < TabularGridTable::COL_MAX; pos++ )
-            s << m_grid->GetColAt(pos) << ' ';
+        {
+            const int col = m_grid->GetColAt(pos);
+            const bool isHidden = m_grid->GetColSize(col) == 0;
+
+            if ( isHidden )
+                s << '[';
+            s << col;
+            if ( isHidden )
+                s << ']';
+
+            s << ' ';
+        }
 
         m_statOrder->SetLabel(s);
     }
 
     // controls
     wxGrid *m_grid;
+    TabularGridTable *m_table;
     wxCheckBox *m_chkUseNative,
+               *m_chkDrawNative,
+               *m_chkShowRowLabels,
                *m_chkEnableColMove;
 
     ColIndexEntry *m_txtColIndex,
-                  *m_txtColPos;
+                  *m_txtColPos,
+                  *m_txtColShowHide;
 
     wxStaticText *m_statOrder;
 
-    DECLARE_NO_COPY_CLASS(TabularGridFrame)
+    // fla for EVT_IDLE handler
+    bool m_shouldUpdateOrder;
+
+    wxDECLARE_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_BUTTON(wxID_RESET, TabularGridFrame::OnResetColumnOrder)
+    EVT_BUTTON(wxID_ADD, TabularGridFrame::OnShowHideColumn)
+    EVT_BUTTON(wxID_DELETE, TabularGridFrame::OnShowHideColumn)
 
+    EVT_GRID_COL_SORT(TabularGridFrame::OnGridColSort)
     EVT_GRID_COL_MOVE(TabularGridFrame::OnGridColMove)
+    EVT_GRID_COL_SIZE(TabularGridFrame::OnGridColSize)
+
+    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->SetTable(new TabularGridTable, true, wxGrid::wxGridSelectRows);
+    m_table = new TabularGridTable;
+    m_grid = new wxGrid(panel, wxID_ANY,
+                        wxDefaultPosition, wxDefaultSize,
+                        wxBORDER_STATIC | wxWANTS_CHARS);
+    m_grid->SetTable(m_table, 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);
@@ -1720,12 +1938,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());
@@ -1737,30 +1963,43 @@ 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);
+    sizerShowCols->Add(new wxButton(panel, wxID_RESET, "&Reset order"));
     sizerColumns->Add(sizerShowCols, wxSizerFlags().Expand().Border(wxTOP));
 
+    wxSizer * const sizerShowHide = new wxBoxSizer(wxHORIZONTAL);
+    sizerShowHide->Add(new wxStaticText(panel, wxID_ANY, "Show/hide column:"),
+                       flagsHorz);
+    m_txtColShowHide = new ColIndexEntry(panel);
+    sizerShowHide->Add(m_txtColShowHide, flagsHorz);
+    sizerShowHide->Add(new wxButton(panel, wxID_ADD, "&Show"), flagsHorz);
+    sizerShowHide->Add(new wxButton(panel, wxID_DELETE, "&Hide"), flagsHorz);
+    sizerColumns->Add(sizerShowHide, wxSizerFlags().Expand().Border(wxTOP));
+
     sizerControls->Add(sizerColumns, wxSizerFlags(1).Expand().Border());
 
     sizerTop->Add(sizerControls, wxSizerFlags().Expand().Border());
 
-    SetSizerAndFit(sizerTop);
-    SetBackgroundColour(*wxWHITE);
+    panel->SetSizer(sizerTop);
+
+    SetClientSize(panel->GetBestSize());
+    SetSizeHints(GetSize());
+
     Show();
 }
 
@@ -1768,4 +2007,3 @@ void GridFrame::OnTabularTable(wxCommandEvent&)
 {
     new TabularGridFrame;
 }
-