X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2d0d78133612ffdcc4ac498db54813fc38c64a90..0738b901b17340f09766524b8d9d79e9ed1268e7:/src/generic/datavgen.cpp diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 7221c51138..04924b89dd 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -612,6 +612,7 @@ wxDataViewRenderer::wxDataViewRenderer( const wxString &varianttype, m_dc = NULL; m_align = align; m_mode = mode; + m_ellipsizeMode = wxELLIPSIZE_MIDDLE; } wxDataViewRenderer::~wxDataViewRenderer() @@ -620,6 +621,54 @@ 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(); + + // take alignment into account only if there is enough space, otherwise + // show as much contents as possible + // + // notice that many existing renderers (e.g. wxDataViewSpinRenderer) + // return hard-coded size which can be more than they need and if we + // trusted their GetSize() we'd draw the text out of cell bounds + // entirely + + if ( size.x < cell_rect.width ) + { + if (align & wxALIGN_CENTER_HORIZONTAL) + item_rect.x += (cell_rect.width - size.x)/2; + else if (align & wxALIGN_RIGHT) + item_rect.x += cell_rect.width - size.x; + // else: wxALIGN_LEFT is the default + + item_rect.width = size.x; + } + + if ( size.y < cell_rect.height ) + { + if (align & wxALIGN_CENTER_VERTICAL) + item_rect.y += (cell_rect.height - size.y)/2; + else if (align & wxALIGN_BOTTOM) + item_rect.y += cell_rect.height - size.y; + // else: wxALIGN_TOP is the default + + item_rect.height = size.y; + } + } + + return Render(item_rect, &dc, state); +} + wxDC *wxDataViewRenderer::GetDC() { if (m_dc == NULL) @@ -669,29 +718,27 @@ wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString &varianttype, { } -void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, - wxRect cell, wxDC *dc, int state ) -{ - wxColour col = state & wxDATAVIEW_CELL_SELECTED - ? wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) - : GetOwner()->GetOwner()->GetForegroundColour(); - - wxDataViewItemAttr attr; - attr.SetColour(col); - RenderText(*dc, cell, text, &attr, state, xoffset); -} - void wxDataViewCustomRenderer::RenderText(wxDC& dc, const wxRect& rect, + int align, const wxString& text, const wxDataViewItemAttr *attr, - int WXUNUSED(state), + int state, int xoffset) { - wxDCTextColourChanger changeFg(dc); - if ( attr && attr->HasColour() ) - changeFg.Set(attr->GetColour()); + // override custom foreground with the standard one for the selected items + // because we currently don't allow changing the selection background and + // custom colours may be unreadable on it + wxColour col; + if ( state & wxDATAVIEW_CELL_SELECTED ) + col = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT); + else if ( attr && attr->HasColour() ) + col = attr->GetColour(); + else // use default foreground + col = GetOwner()->GetOwner()->GetForegroundColour(); + + wxDCTextColourChanger changeFg(dc, col); wxDCFontChanger changeFont(dc); if ( attr && attr->HasFont() ) @@ -705,9 +752,26 @@ 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; + + // check if we want to ellipsize the text if it doesn't fit + wxString ellipsizedText; + if ( GetEllipsizeMode() != wxELLIPSIZE_NONE ) + { + ellipsizedText = wxControl::Ellipsize + ( + text, + dc, + GetEllipsizeMode(), + rect.width, + wxELLIPSIZE_FLAGS_NONE + ); + } + + dc.DrawLabel(ellipsizedText.empty() ? text : ellipsizedText, + rectText, align); } // --------------------------------------------------------- @@ -763,10 +827,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; } @@ -871,10 +936,7 @@ bool wxDataViewToggleRenderer::Activate( wxRect WXUNUSED(cell), wxDataViewModel *model, const wxDataViewItem & item, unsigned int col) { - bool value = !m_toggle; - wxVariant variant = value; - model->SetValue( variant, item, col); - model->ValueChanged( item, col ); + model->ChangeValue(!m_toggle, item, col); return true; } @@ -899,10 +961,6 @@ wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString &label, m_value = 0; } -wxDataViewProgressRenderer::~wxDataViewProgressRenderer() -{ -} - bool wxDataViewProgressRenderer::SetValue( const wxVariant &value ) { m_value = (long) value; @@ -919,18 +977,24 @@ bool wxDataViewProgressRenderer::GetValue( wxVariant &value ) const return true; } -bool wxDataViewProgressRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state) ) +bool wxDataViewProgressRenderer::RenderWithAttr(wxDC& dc, + const wxRect& rect, + int WXUNUSED(align), + const wxDataViewItemAttr *attr, + int WXUNUSED(state)) { - double pct = (double)m_value / 100.0; - wxRect bar = cell; - bar.width = (int)(cell.width * pct); - dc->SetPen( *wxTRANSPARENT_PEN ); - dc->SetBrush( *wxBLUE_BRUSH ); - dc->DrawRectangle( bar ); + // deflat the rect to leave a small border between bars in adjacent rows + wxRect bar = rect.Deflate(0, 1); - dc->SetBrush( *wxTRANSPARENT_BRUSH ); - dc->SetPen( *wxBLACK_PEN ); - dc->DrawRectangle( cell ); + dc.SetBrush( *wxTRANSPARENT_BRUSH ); + dc.SetPen( *wxBLACK_PEN ); + dc.DrawRectangle( bar ); + + bar.width = (int)(bar.width * m_value / 100.); + dc.SetPen( *wxTRANSPARENT_PEN ); + dc.SetBrush( attr && attr->HasColour() ? wxBrush(attr->GetColour()) + : *wxBLUE_BRUSH ); + dc.DrawRectangle( bar ); return true; } @@ -987,10 +1051,7 @@ END_EVENT_TABLE() void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent &event ) { - wxDateTime date = event.GetDate(); - wxVariant value = date; - m_model->SetValue( value, m_item, m_col ); - m_model->ValueChanged( m_item, m_col ); + m_model->ChangeValue( event.GetDate(), m_item, m_col ); DismissAndNotify(); } @@ -1067,10 +1128,6 @@ const wxString &varianttype, wxDataViewCellMode mode, int align ) : SetAlignment(align); } -wxDataViewIconTextRenderer::~wxDataViewIconTextRenderer() -{ -} - bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value ) { m_value << value; @@ -1082,17 +1139,23 @@ bool wxDataViewIconTextRenderer::GetValue( wxVariant& WXUNUSED(value) ) const return false; } -bool wxDataViewIconTextRenderer::Render( wxRect cell, wxDC *dc, int state ) +bool +wxDataViewIconTextRenderer::RenderWithAttr(wxDC& dc, + const wxRect& rect, + int align, + const wxDataViewItemAttr *attr, + int state) { int xoffset = 0; - const wxIcon &icon = m_value.GetIcon(); - if (icon.IsOk()) + + const wxIcon& icon = m_value.GetIcon(); + if ( icon.IsOk() ) { - dc->DrawIcon( icon, cell.x, cell.y + ((cell.height - icon.GetHeight()) / 2)); - xoffset = icon.GetWidth()+4; + dc.DrawIcon(icon, rect.x, rect.y + (rect.height - icon.GetHeight())/2); + xoffset = icon.GetWidth()+4; } - RenderText( m_value.GetText(), xoffset, cell, dc, state ); + RenderText(dc, rect, align, m_value.GetText(), attr, state, xoffset); return true; } @@ -1578,37 +1641,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 +1891,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 + wxRect item_rect = cell_rect; + item_rect.Deflate(PADDING_RIGHTLEFT, 0); - // 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 + // 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 +1909,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;