]> git.saurik.com Git - wxWidgets.git/commitdiff
column autosizing added
authorVadim Zeitlin <vadim@wxwidgets.org>
Tue, 22 Feb 2000 16:03:54 +0000 (16:03 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Tue, 22 Feb 2000 16:03:54 +0000 (16:03 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6213 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

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

index 3c10ae8507544f6880342dfb4c96a2c21eb3b81a..2420ed4c026ac410a4145c7c11ea5bcd36908757 100644 (file)
@@ -105,6 +105,12 @@ public:
                       int row, int col,
                       bool isSelected) = 0;
 
+    // get the preferred size of the cell for its contents
+    virtual wxSize GetBestSize(wxGrid& grid,
+                               wxGridCellAttr& attr,
+                               wxDC& dc,
+                               int row, int col) = 0;
+
     // virtual dtor for any base class
     virtual ~wxGridCellRenderer();
 };
@@ -121,12 +127,23 @@ public:
                       int row, int col,
                       bool isSelected);
 
+    // return the string extent
+    virtual wxSize GetBestSize(wxGrid& grid,
+                               wxGridCellAttr& attr,
+                               wxDC& dc,
+                               int row, int col);
+
 protected:
     // set the text colours before drawing
     void SetTextColoursAndFont(wxGrid& grid,
                                wxGridCellAttr& attr,
                                wxDC& dc,
                                bool isSelected);
+
+    // calc the string extent for given string/font
+    wxSize DoGetBestSize(wxGridCellAttr& attr,
+                         wxDC& dc,
+                         const wxString& text);
 };
 
 // the default renderer for the cells containing numeric (long) data
@@ -140,6 +157,14 @@ public:
                       const wxRect& rect,
                       int row, int col,
                       bool isSelected);
+
+    virtual wxSize GetBestSize(wxGrid& grid,
+                               wxGridCellAttr& attr,
+                               wxDC& dc,
+                               int row, int col);
+
+protected:
+    wxString GetString(wxGrid& grid, int row, int col);
 };
 
 class WXDLLEXPORT wxGridCellFloatRenderer : public wxGridCellStringRenderer
@@ -161,6 +186,13 @@ public:
                       int row, int col,
                       bool isSelected);
 
+    virtual wxSize GetBestSize(wxGrid& grid,
+                               wxGridCellAttr& attr,
+                               wxDC& dc,
+                               int row, int col);
+protected:
+    wxString GetString(wxGrid& grid, int row, int col);
+
 private:
     // formatting parameters
     int m_width,
@@ -180,6 +212,15 @@ public:
                       const wxRect& rect,
                       int row, int col,
                       bool isSelected);
+
+    // return the checkmark size
+    virtual wxSize GetBestSize(wxGrid& grid,
+                               wxGridCellAttr& attr,
+                               wxDC& dc,
+                               int row, int col);
+
+private:
+    static wxSize ms_sizeCheckMark;
 };
 
 // ----------------------------------------------------------------------------
@@ -1001,6 +1042,14 @@ public:
 
     void     SetColSize( int col, int width );
 
+    // automatically size the column to fit to its contents, if setAsMin is
+    // TRUE, this optimal width will also be set as minimal width for this
+    // column
+    void     AutoSizeColumn( int col, bool setAsMin = TRUE );
+
+    // auto size all columns (very ineffective for big grids!)
+    void     AutoSizeColumns( bool setAsMin = TRUE );
+
     // column won't be resized to be lesser width - this must be called during
     // the grid creation because it won't resize the column if it's already
     // narrower than the minimal width
@@ -1506,8 +1555,6 @@ protected:
     DECLARE_EVENT_TABLE()
 };
 
-
-
 // ----------------------------------------------------------------------------
 // Grid event class and event types
 // ----------------------------------------------------------------------------
index b73608eed9acd025c53c5f7882a0f9eb30791b22..c308c4e38ac5e0855e8a48d29db07fd2400e4e30 100644 (file)
@@ -959,8 +959,13 @@ BugsGridFrame::BugsGridFrame()
     wxGridTableBase *table = new BugsGridTable();
     grid->SetTable(table, TRUE);
 
-    for ( size_t row = 0; row < WXSIZEOF(gs_dataBugsGrid); row++ )
-    {
-        grid->SetReadOnly(row, Col_Id);
-    }
+    wxGridCellAttr *attrRO = new wxGridCellAttr,
+                   *attrRangeEditor = new wxGridCellAttr;
+    attrRO->SetReadOnly();
+    attrRangeEditor->SetEditor(new wxGridCellNumberEditor(1, 5));
+
+    grid->SetColAttr(Col_Id, attrRO);
+    grid->SetColAttr(Col_Priority, attrRangeEditor);
+
+    grid->AutoSizeColumns();
 }
index d728ad8407396cebbe7d156d44a6b42c39772d7f..4779b848a901d2f6f576465a8b0d7362ba562f7d 100644 (file)
@@ -961,6 +961,25 @@ void wxGridCellStringRenderer::SetTextColoursAndFont(wxGrid& grid,
     dc.SetFont( attr.GetFont() );
 }
 
+wxSize wxGridCellStringRenderer::DoGetBestSize(wxGridCellAttr& attr,
+                                               wxDC& dc,
+                                               const wxString& text)
+{
+    wxCoord x, y;
+    dc.SetFont(attr.GetFont());
+    dc.GetTextExtent(text, &x, &y);
+
+    return wxSize(x, y);
+}
+
+wxSize wxGridCellStringRenderer::GetBestSize(wxGrid& grid,
+                                             wxGridCellAttr& attr,
+                                             wxDC& dc,
+                                             int row, int col)
+{
+    return DoGetBestSize(attr, dc, grid.GetCellValue(row, col));
+}
+
 void wxGridCellStringRenderer::Draw(wxGrid& grid,
                                     wxGridCellAttr& attr,
                                     wxDC& dc,
@@ -983,6 +1002,23 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid,
                            rect, hAlign, vAlign);
 }
 
+// ----------------------------------------------------------------------------
+// wxGridCellNumberRenderer
+// ----------------------------------------------------------------------------
+
+wxString wxGridCellNumberRenderer::GetString(wxGrid& grid, int row, int col)
+{
+    wxGridTableBase *table = grid.GetTable();
+    wxString text;
+    if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
+    {
+        text.Printf(_T("%ld"), table->GetValueAsLong(row, col));
+    }
+    //else: leave the string empty or put 0 into it?
+
+    return text;
+}
+
 void wxGridCellNumberRenderer::Draw(wxGrid& grid,
                                     wxGridCellAttr& attr,
                                     wxDC& dc,
@@ -1002,15 +1038,15 @@ void wxGridCellNumberRenderer::Draw(wxGrid& grid,
     wxRect rect = rectCell;
     rect.Inflate(-1);
 
-    wxGridTableBase *table = grid.GetTable();
-    wxString text;
-    if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
-    {
-        text.Printf(_T("%ld"), table->GetValueAsLong(row, col));
-    }
-    //else: leave the string empty or put 0 into it?
+    grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
+}
 
-    grid.DrawTextRectangle(dc, text, rect, hAlign, vAlign);
+wxSize wxGridCellNumberRenderer::GetBestSize(wxGrid& grid,
+                                             wxGridCellAttr& attr,
+                                             wxDC& dc,
+                                             int row, int col)
+{
+    return DoGetBestSize(attr, dc, GetString(grid, row, col));
 }
 
 // ----------------------------------------------------------------------------
@@ -1023,6 +1059,24 @@ wxGridCellFloatRenderer::wxGridCellFloatRenderer(int width, int precision)
     SetPrecision(precision);
 }
 
+wxString wxGridCellFloatRenderer::GetString(wxGrid& grid, int row, int col)
+{
+    wxGridTableBase *table = grid.GetTable();
+    wxString text;
+    if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) )
+    {
+        if ( !m_format )
+        {
+            m_format.Printf(_T("%%%d.%d%%f"), m_width, m_precision);
+        }
+
+        text.Printf(m_format, table->GetValueAsDouble(row, col));
+    }
+    //else: leave the string empty or put 0 into it?
+
+    return text;
+}
+
 void wxGridCellFloatRenderer::Draw(wxGrid& grid,
                                    wxGridCellAttr& attr,
                                    wxDC& dc,
@@ -1042,66 +1096,76 @@ void wxGridCellFloatRenderer::Draw(wxGrid& grid,
     wxRect rect = rectCell;
     rect.Inflate(-1);
 
-    wxGridTableBase *table = grid.GetTable();
-    wxString text;
-    if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) )
-    {
-        if ( !m_format )
-        {
-            m_format.Printf(_T("%%%d.%d%%f"), m_width, m_precision);
-        }
-
-        text.Printf(m_format, table->GetValueAsDouble(row, col));
-    }
-    //else: leave the string empty or put 0 into it?
+    grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign);
+}
 
-    grid.DrawTextRectangle(dc, text, rect, hAlign, vAlign);
+wxSize wxGridCellFloatRenderer::GetBestSize(wxGrid& grid,
+                                            wxGridCellAttr& attr,
+                                            wxDC& dc,
+                                            int row, int col)
+{
+    return DoGetBestSize(attr, dc, GetString(grid, row, col));
 }
 
 // ----------------------------------------------------------------------------
 // wxGridCellBoolRenderer
 // ----------------------------------------------------------------------------
 
-void wxGridCellBoolRenderer::Draw(wxGrid& grid,
-                                  wxGridCellAttr& attr,
-                                  wxDC& dc,
-                                  const wxRect& rect,
-                                  int row, int col,
-                                  bool isSelected)
-{
-    wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
+wxSize wxGridCellBoolRenderer::ms_sizeCheckMark;
 
-    // between checkmark and box
-    static const wxCoord margin = 4;
+// between checkmark and box
+static const wxCoord wxGRID_CHECKMARK_MARGIN = 4;
 
-    // get checkbox size
-    static wxCoord s_checkSize = 0;
-    if ( s_checkSize == 0 )
+wxSize wxGridCellBoolRenderer::GetBestSize(wxGrid& grid,
+                                           wxGridCellAttr& WXUNUSED(attr),
+                                           wxDC& WXUNUSED(dc),
+                                           int WXUNUSED(row),
+                                           int WXUNUSED(col))
+{
+    // compute it only once (no locks for MT safeness in GUI thread...)
+    if ( !ms_sizeCheckMark.x )
     {
-        // compute it only once (no locks for MT safeness in GUI thread...)
+        // get checkbox size
+        wxCoord checkSize = 0;
         wxCheckBox *checkbox = new wxCheckBox(&grid, -1, wxEmptyString);
         wxSize size = checkbox->GetBestSize();
-        s_checkSize = size.y + margin;
+        checkSize = size.y + wxGRID_CHECKMARK_MARGIN;
 
-        // FIXME wxGTK::wxCheckBox::GetBestSize() is really weird...
+        // FIXME wxGTK::wxCheckBox::GetBestSize() gives "wrong" result
 #ifdef __WXGTK__
-        s_checkSize -= size.y / 2;
+        checkSize -= size.y / 2;
 #endif
 
         delete checkbox;
+
+        ms_sizeCheckMark.x = ms_sizeCheckMark.y = checkSize;
     }
 
+    return ms_sizeCheckMark;
+}
+
+void wxGridCellBoolRenderer::Draw(wxGrid& grid,
+                                  wxGridCellAttr& attr,
+                                  wxDC& dc,
+                                  const wxRect& rect,
+                                  int row, int col,
+                                  bool isSelected)
+{
+    wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
+
     // draw a check mark in the centre (ignoring alignment - TODO)
+    wxSize size = GetBestSize(grid, attr, dc, row, col);
     wxRect rectMark;
-    rectMark.x = rect.x + rect.width/2 - s_checkSize/2;
-    rectMark.y = rect.y + rect.height/2 - s_checkSize/2;
-    rectMark.width = rectMark.height = s_checkSize;
+    rectMark.x = rect.x + rect.width/2 - size.x/2;
+    rectMark.y = rect.y + rect.height/2 - size.y/2;
+    rectMark.width = size.x;
+    rectMark.height = size.y;
 
     dc.SetBrush(*wxTRANSPARENT_BRUSH);
     dc.SetPen(wxPen(attr.GetTextColour(), 1, wxSOLID));
     dc.DrawRectangle(rectMark);
 
-    rectMark.Inflate(-margin);
+    rectMark.Inflate(-wxGRID_CHECKMARK_MARGIN);
 
     bool value;
     if (grid.GetTable()->CanGetValueAs(row, col, wxT("bool")))
@@ -6599,6 +6663,62 @@ int wxGrid::GetColMinimalWidth(int col) const
     return obj ? (int)obj : WXGRID_MIN_COL_WIDTH;
 }
 
+void wxGrid::AutoSizeColumn( int col, bool setAsMin )
+{
+    wxClientDC dc(m_gridWin);
+
+    wxCoord width, widthMax = 0;
+    for ( int row = 0; row < m_numRows; row++ )
+    {
+        wxGridCellAttr* attr = GetCellAttr(row, col);
+        wxGridCellRenderer* renderer = attr->GetRenderer(GetDefaultRendererForCell(row,col));
+        if ( renderer )
+        {
+            width = renderer->GetBestSize(*this, *attr, dc, row, col).x;
+            if ( width > widthMax )
+            {
+                widthMax = width;
+            }
+        }
+
+        attr->DecRef();
+    }
+
+    // now also compare with the column label width
+    dc.SetFont( GetLabelFont() );
+    dc.GetTextExtent( GetColLabelValue(col), &width, NULL );
+    if ( width > widthMax )
+    {
+        widthMax = width;
+    }
+
+    if ( !widthMax )
+    {
+        // empty column - give default width (notice that if widthMax is less
+        // than default width but != 0, it's ok)
+        widthMax = m_defaultColWidth;
+    }
+    else
+    {
+        // leave some space around text
+        widthMax += 10;
+    }
+
+    SetColSize(col, widthMax);
+    if ( setAsMin )
+    {
+        SetColMinimalWidth(col, widthMax);
+    }
+}
+
+void wxGrid::AutoSizeColumns( bool setAsMin )
+{
+    for ( int col = 0; col < m_numCols; col++ )
+    {
+        AutoSizeColumn(col, setAsMin);
+    }
+}
+
 //
 // ------ cell value accessor functions
 //