]> git.saurik.com Git - wxWidgets.git/commitdiff
Handle cell alignment in the renderer itself in generic wxDVC.
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 12 Oct 2009 22:44:03 +0000 (22:44 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 12 Oct 2009 22:44:03 +0000 (22:44 +0000)
Instead of using wxDataViewRenderer::GetSize() and rendering the cell into the
appropriate part of the rectangle, pass the full rectangle and the alignment
of the cell contents in it to the renderer itself.

This fixes the bug with bold text being truncated in the "attributes" column
of the dataview sample and is also generally more flexible as the renderer may
decide itself what to do with the extra space.

It also somewhat reduces the code duplication between CreateItemBitmap() and
OnPaint().

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62393 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/generic/dataview.h
src/generic/datavgen.cpp

index c5351892ac2111a898fd4466112ecf449195efe6..3e32fa8ffac9e0d0e7976e3b031d4d1a46206507 100644 (file)
@@ -48,11 +48,9 @@ public:
     virtual bool
     RenderWithAttr(wxDC& dc,
                    const wxRect& rect,
-                   const wxDataViewItemAttr * WXUNUSED(attr), // NULL if none
-                   int state)
-    {
-        return Render(rect, &dc, state);
-    }
+                   int align,   // combination of horizontal and vertical
+                   const wxDataViewItemAttr *attr, // may be NULL if none
+                   int state);
 
     virtual wxSize GetSize() const = 0;
 
@@ -118,6 +116,7 @@ public:
     // Draw the text using the provided attributes
     void RenderText(wxDC& dc,
                     const wxRect& rect,
+                    int align,
                     const wxString& text,
                     const wxDataViewItemAttr *attr, // may be NULL if none
                     int state,
@@ -147,11 +146,15 @@ public:
 
     virtual bool RenderWithAttr(wxDC& dc,
                                 const wxRect& rect,
+                                int align,
                                 const wxDataViewItemAttr *attr,
                                 int state);
-    virtual bool Render( wxRect cell, wxDC *dc, int state )
+    virtual bool Render(wxRect WXUNUSED(cell),
+                        wxDC * WXUNUSED(dc),
+                        int WXUNUSED(state))
     {
-        return RenderWithAttr(*dc, cell, NULL, state);
+        wxFAIL_MSG("only RenderWithAttr() should be called");
+        return false;
     }
 
     wxSize GetSize() const;
index 7221c51138ded06de2d7c4ad034667df898e4089..d407c8228561094cfaa5b7deebe9b6fc3e62292b 100644 (file)
@@ -620,6 +620,41 @@ wxDataViewRenderer::~wxDataViewRenderer()
         delete m_dc;
 }
 
+bool
+wxDataViewRenderer::RenderWithAttr(wxDC& dc,
+                                   const wxRect& cell_rect,
+                                   int align,
+                                   const wxDataViewItemAttr *WXUNUSED(attr),
+                                   int state)
+{
+    // adjust the rectangle ourselves to account for the alignment
+
+    wxRect item_rect = cell_rect;
+    if ( align )
+    {
+        const wxSize size = GetSize();
+
+        // horizontal alignment:
+        if (align & wxALIGN_CENTER_HORIZONTAL)
+            item_rect.x = cell_rect.x + (cell_rect.width / 2) - (size.x / 2);
+        else if (align & wxALIGN_RIGHT)
+            item_rect.x = cell_rect.x + cell_rect.width - size.x;
+        // else: wxALIGN_LEFT is the default
+
+        // vertical alignment:
+        item_rect.y = cell_rect.y;
+        if (align & wxALIGN_CENTER_VERTICAL)
+            item_rect.y = cell_rect.y + (cell_rect.height / 2) - (size.y / 2);
+        else if (align & wxALIGN_BOTTOM)
+            item_rect.y = cell_rect.y + cell_rect.height - size.y;
+        // else: wxALIGN_TOP is the default
+
+        item_rect.SetSize(size);
+    }
+
+    return Render(item_rect, &dc, state);
+}
+
 wxDC *wxDataViewRenderer::GetDC()
 {
     if (m_dc == NULL)
@@ -678,12 +713,13 @@ void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset,
 
     wxDataViewItemAttr attr;
     attr.SetColour(col);
-    RenderText(*dc, cell, text, &attr, state, xoffset);
+    RenderText(*dc, cell, wxALIGN_NOT, text, &attr, state, xoffset);
 }
 
 void
 wxDataViewCustomRenderer::RenderText(wxDC& dc,
                                      const wxRect& rect,
+                                     int align,
                                      const wxString& text,
                                      const wxDataViewItemAttr *attr,
                                      int WXUNUSED(state),
@@ -705,9 +741,11 @@ wxDataViewCustomRenderer::RenderText(wxDC& dc,
         changeFont.Set(font);
     }
 
-    dc.DrawText(text,
-                rect.x + xoffset,
-                rect.y + ((rect.height - dc.GetCharHeight()) / 2));
+    wxRect rectText = rect;
+    rectText.x += xoffset;
+    rectText.width -= xoffset;
+
+    dc.DrawLabel(text, rectText, align);
 }
 
 // ---------------------------------------------------------
@@ -763,10 +801,11 @@ bool wxDataViewTextRenderer::GetValueFromEditorCtrl( wxControl *editor, wxVarian
 bool
 wxDataViewTextRenderer::RenderWithAttr(wxDC& dc,
                                        const wxRect& rect,
+                                       int align,
                                        const wxDataViewItemAttr *attr,
                                        int state)
 {
-    RenderText(dc, rect, m_text, attr, state);
+    RenderText(dc, rect, align, m_text, attr, state);
     return true;
 }
 
@@ -1578,37 +1617,15 @@ wxBitmap wxDataViewMainWindow::CreateItemBitmap( unsigned int row, int &indent )
         model->GetValue( value, item, column->GetModelColumn());
         cell->SetValue( value );
 
-        wxSize size = cell->GetSize();
-        size.x = wxMin( 2*PADDING_RIGHTLEFT + size.x, width );
-        size.y = height;
-        wxRect item_rect(x, 0, size.x, size.y);
-
-        int align = cell->CalculateAlignment();
-        // horizontal alignment:
-        item_rect.x = x;
-        if (align & wxALIGN_CENTER_HORIZONTAL)
-            item_rect.x = x + (width / 2) - (size.x / 2);
-        else if (align & wxALIGN_RIGHT)
-            item_rect.x = x + width - size.x;
-        // else: wxALIGN_LEFT is the default
-
-        // vertical alignment:
-        item_rect.y = 0;
-        if (align & wxALIGN_CENTER_VERTICAL)
-            item_rect.y = (height / 2) - (size.y / 2);
-        else if (align & wxALIGN_BOTTOM)
-            item_rect.y = height - size.y;
-        // else: wxALIGN_TOP is the default
-
-        // add padding
-        item_rect.x += PADDING_RIGHTLEFT;
-        item_rect.width = size.x - 2 * PADDING_RIGHTLEFT;
+        wxRect item_rect(x, 0, width, height);
+        item_rect.Deflate(PADDING_RIGHTLEFT, 0);
 
         // dc.SetClippingRegion( item_rect );
         wxDataViewItemAttr attr;
         const bool
             hasAttr = model->GetAttr(item, column->GetModelColumn(), attr);
-        cell->RenderWithAttr(dc, item_rect, hasAttr ? &attr : NULL, 0);
+        cell->RenderWithAttr(dc, item_rect, cell->CalculateAlignment(),
+                                hasAttr ? &attr : NULL, 0);
         // dc.DestroyClippingRegion();
 
         x += width;
@@ -1850,40 +1867,12 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
                 wxDELETE(node);
             }
 
-            // cannot be bigger than allocated space
-            wxSize size = cell->GetSize();
-
-            // Because of the tree structure indent, here we should minus the width
-            // of the cell for drawing
-            size.x = wxMin( size.x + 2*PADDING_RIGHTLEFT, cell_rect.width - indent );
-            // size.y = wxMin( size.y, cell_rect.height );
-            size.y = cell_rect.height;
-
-            wxRect item_rect(cell_rect.GetTopLeft(), size);
-            int align = cell->CalculateAlignment();
-
-            // horizontal alignment:
-            item_rect.x = cell_rect.x;
-            if (align & wxALIGN_CENTER_HORIZONTAL)
-                item_rect.x = cell_rect.x + (cell_rect.width / 2) - (size.x / 2);
-            else if (align & wxALIGN_RIGHT)
-                item_rect.x = cell_rect.x + cell_rect.width - size.x;
-            // else: wxALIGN_LEFT is the default
-
-            // vertical alignment:
-            item_rect.y = cell_rect.y;
-            if (align & wxALIGN_CENTER_VERTICAL)
-                item_rect.y = cell_rect.y + (cell_rect.height / 2) - (size.y / 2);
-            else if (align & wxALIGN_BOTTOM)
-                item_rect.y = cell_rect.y + cell_rect.height - size.y;
-            // else: wxALIGN_TOP is the default
-
-            // add padding
-            item_rect.x += PADDING_RIGHTLEFT;
-            item_rect.width = size.x - 2 * PADDING_RIGHTLEFT;
-
-            // Here we add the tree indent
+            wxRect item_rect = cell_rect;
+            item_rect.Deflate(PADDING_RIGHTLEFT, 0);
+
+            // account for the tree indent (harmless if we're not indented)
             item_rect.x += indent;
+            item_rect.width -= indent;
 
             int state = 0;
             if (m_hasFocus && (m_selection.Index(item) != wxNOT_FOUND))
@@ -1896,14 +1885,13 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
             //       respect the given wxRect's top & bottom coords, eventually
             //       violating only the left & right coords - however the user can
             //       make its own renderer and thus we cannot be sure of that.
-            dc.SetClippingRegion( item_rect );
+            wxDCClipper clip(dc, item_rect);
 
             wxDataViewItemAttr attr;
             const bool
                 hasAttr = model->GetAttr(dataitem, col->GetModelColumn(), attr);
-            cell->RenderWithAttr(dc, item_rect, hasAttr ? &attr : NULL, state);
-
-            dc.DestroyClippingRegion();
+            cell->RenderWithAttr(dc, item_rect, cell->CalculateAlignment(),
+                                    hasAttr ? &attr : NULL, state);
         }
 
         cell_rect.x += cell_rect.width;