Handle cell alignment in the renderer itself in generic wxDVC.
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
This commit is contained in:
@@ -48,11 +48,9 @@ public:
|
|||||||
virtual bool
|
virtual bool
|
||||||
RenderWithAttr(wxDC& dc,
|
RenderWithAttr(wxDC& dc,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
const wxDataViewItemAttr * WXUNUSED(attr), // NULL if none
|
int align, // combination of horizontal and vertical
|
||||||
int state)
|
const wxDataViewItemAttr *attr, // may be NULL if none
|
||||||
{
|
int state);
|
||||||
return Render(rect, &dc, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual wxSize GetSize() const = 0;
|
virtual wxSize GetSize() const = 0;
|
||||||
|
|
||||||
@@ -118,6 +116,7 @@ public:
|
|||||||
// Draw the text using the provided attributes
|
// Draw the text using the provided attributes
|
||||||
void RenderText(wxDC& dc,
|
void RenderText(wxDC& dc,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
|
int align,
|
||||||
const wxString& text,
|
const wxString& text,
|
||||||
const wxDataViewItemAttr *attr, // may be NULL if none
|
const wxDataViewItemAttr *attr, // may be NULL if none
|
||||||
int state,
|
int state,
|
||||||
@@ -147,11 +146,15 @@ public:
|
|||||||
|
|
||||||
virtual bool RenderWithAttr(wxDC& dc,
|
virtual bool RenderWithAttr(wxDC& dc,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
|
int align,
|
||||||
const wxDataViewItemAttr *attr,
|
const wxDataViewItemAttr *attr,
|
||||||
int state);
|
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;
|
wxSize GetSize() const;
|
||||||
|
@@ -620,6 +620,41 @@ wxDataViewRenderer::~wxDataViewRenderer()
|
|||||||
delete m_dc;
|
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()
|
wxDC *wxDataViewRenderer::GetDC()
|
||||||
{
|
{
|
||||||
if (m_dc == NULL)
|
if (m_dc == NULL)
|
||||||
@@ -678,12 +713,13 @@ void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset,
|
|||||||
|
|
||||||
wxDataViewItemAttr attr;
|
wxDataViewItemAttr attr;
|
||||||
attr.SetColour(col);
|
attr.SetColour(col);
|
||||||
RenderText(*dc, cell, text, &attr, state, xoffset);
|
RenderText(*dc, cell, wxALIGN_NOT, text, &attr, state, xoffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
wxDataViewCustomRenderer::RenderText(wxDC& dc,
|
wxDataViewCustomRenderer::RenderText(wxDC& dc,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
|
int align,
|
||||||
const wxString& text,
|
const wxString& text,
|
||||||
const wxDataViewItemAttr *attr,
|
const wxDataViewItemAttr *attr,
|
||||||
int WXUNUSED(state),
|
int WXUNUSED(state),
|
||||||
@@ -705,9 +741,11 @@ wxDataViewCustomRenderer::RenderText(wxDC& dc,
|
|||||||
changeFont.Set(font);
|
changeFont.Set(font);
|
||||||
}
|
}
|
||||||
|
|
||||||
dc.DrawText(text,
|
wxRect rectText = rect;
|
||||||
rect.x + xoffset,
|
rectText.x += xoffset;
|
||||||
rect.y + ((rect.height - dc.GetCharHeight()) / 2));
|
rectText.width -= xoffset;
|
||||||
|
|
||||||
|
dc.DrawLabel(text, rectText, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
@@ -763,10 +801,11 @@ bool wxDataViewTextRenderer::GetValueFromEditorCtrl( wxControl *editor, wxVarian
|
|||||||
bool
|
bool
|
||||||
wxDataViewTextRenderer::RenderWithAttr(wxDC& dc,
|
wxDataViewTextRenderer::RenderWithAttr(wxDC& dc,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
|
int align,
|
||||||
const wxDataViewItemAttr *attr,
|
const wxDataViewItemAttr *attr,
|
||||||
int state)
|
int state)
|
||||||
{
|
{
|
||||||
RenderText(dc, rect, m_text, attr, state);
|
RenderText(dc, rect, align, m_text, attr, state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1578,37 +1617,15 @@ wxBitmap wxDataViewMainWindow::CreateItemBitmap( unsigned int row, int &indent )
|
|||||||
model->GetValue( value, item, column->GetModelColumn());
|
model->GetValue( value, item, column->GetModelColumn());
|
||||||
cell->SetValue( value );
|
cell->SetValue( value );
|
||||||
|
|
||||||
wxSize size = cell->GetSize();
|
wxRect item_rect(x, 0, width, height);
|
||||||
size.x = wxMin( 2*PADDING_RIGHTLEFT + size.x, width );
|
item_rect.Deflate(PADDING_RIGHTLEFT, 0);
|
||||||
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;
|
|
||||||
|
|
||||||
// dc.SetClippingRegion( item_rect );
|
// dc.SetClippingRegion( item_rect );
|
||||||
wxDataViewItemAttr attr;
|
wxDataViewItemAttr attr;
|
||||||
const bool
|
const bool
|
||||||
hasAttr = model->GetAttr(item, column->GetModelColumn(), attr);
|
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();
|
// dc.DestroyClippingRegion();
|
||||||
|
|
||||||
x += width;
|
x += width;
|
||||||
@@ -1850,40 +1867,12 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
wxDELETE(node);
|
wxDELETE(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cannot be bigger than allocated space
|
wxRect item_rect = cell_rect;
|
||||||
wxSize size = cell->GetSize();
|
item_rect.Deflate(PADDING_RIGHTLEFT, 0);
|
||||||
|
|
||||||
// Because of the tree structure indent, here we should minus the width
|
// account for the tree indent (harmless if we're not indented)
|
||||||
// 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
|
|
||||||
item_rect.x += indent;
|
item_rect.x += indent;
|
||||||
|
item_rect.width -= indent;
|
||||||
|
|
||||||
int state = 0;
|
int state = 0;
|
||||||
if (m_hasFocus && (m_selection.Index(item) != wxNOT_FOUND))
|
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
|
// respect the given wxRect's top & bottom coords, eventually
|
||||||
// violating only the left & right coords - however the user can
|
// violating only the left & right coords - however the user can
|
||||||
// make its own renderer and thus we cannot be sure of that.
|
// make its own renderer and thus we cannot be sure of that.
|
||||||
dc.SetClippingRegion( item_rect );
|
wxDCClipper clip(dc, item_rect);
|
||||||
|
|
||||||
wxDataViewItemAttr attr;
|
wxDataViewItemAttr attr;
|
||||||
const bool
|
const bool
|
||||||
hasAttr = model->GetAttr(dataitem, col->GetModelColumn(), attr);
|
hasAttr = model->GetAttr(dataitem, col->GetModelColumn(), attr);
|
||||||
cell->RenderWithAttr(dc, item_rect, hasAttr ? &attr : NULL, state);
|
cell->RenderWithAttr(dc, item_rect, cell->CalculateAlignment(),
|
||||||
|
hasAttr ? &attr : NULL, state);
|
||||||
dc.DestroyClippingRegion();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cell_rect.x += cell_rect.width;
|
cell_rect.x += cell_rect.width;
|
||||||
|
Reference in New Issue
Block a user