X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3e60a3c1471d7573e4e05ebc97006b9274a279ae..7f08aa6ce9c7d079b247963a3cb66193780603a3:/src/generic/datavgen.cpp diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 1653ebfcca..9ae974c053 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -607,52 +607,17 @@ IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer, wxDataViewRendererBase) wxDataViewRenderer::wxDataViewRenderer( const wxString &varianttype, wxDataViewCellMode mode, int align) : - wxDataViewRendererBase( varianttype, mode, align ) + wxDataViewCustomRendererBase( varianttype, mode, align ) { - m_dc = NULL; m_align = align; m_mode = mode; + m_ellipsizeMode = wxELLIPSIZE_MIDDLE; + m_dc = NULL; } wxDataViewRenderer::~wxDataViewRenderer() { - if (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); + delete m_dc; } wxDC *wxDataViewRenderer::GetDC() @@ -679,19 +644,6 @@ int wxDataViewRenderer::GetAlignment() const return m_align; } -int wxDataViewRenderer::CalculateAlignment() const -{ - if (m_align == wxDVR_DEFAULT_ALIGNMENT) - { - if (GetOwner() == NULL) - return wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL; - - return GetOwner()->GetAlignment() | wxALIGN_CENTRE_VERTICAL; - } - - return m_align; -} - // --------------------------------------------------------- // wxDataViewCustomRenderer // --------------------------------------------------------- @@ -704,59 +656,15 @@ 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, 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), - int xoffset) -{ - wxDCTextColourChanger changeFg(dc); - if ( attr && attr->HasColour() ) - changeFg.Set(attr->GetColour()); - - wxDCFontChanger changeFont(dc); - if ( attr && attr->HasFont() ) - { - wxFont font(dc.GetFont()); - if ( attr->GetBold() ) - font.MakeBold(); - if ( attr->GetItalic() ) - font.MakeItalic(); - - changeFont.Set(font); - } - - wxRect rectText = rect; - rectText.x += xoffset; - rectText.width -= xoffset; - - dc.DrawLabel(text, rectText, align); -} - // --------------------------------------------------------- // wxDataViewTextRenderer // --------------------------------------------------------- -IMPLEMENT_CLASS(wxDataViewTextRenderer, wxDataViewCustomRenderer) +IMPLEMENT_CLASS(wxDataViewTextRenderer, wxDataViewRenderer) wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString &varianttype, wxDataViewCellMode mode, int align ) : - wxDataViewCustomRenderer( varianttype, mode, align ) + wxDataViewRenderer( varianttype, mode, align ) { } @@ -798,14 +706,9 @@ bool wxDataViewTextRenderer::GetValueFromEditorCtrl( wxControl *editor, wxVarian return true; } -bool -wxDataViewTextRenderer::RenderWithAttr(wxDC& dc, - const wxRect& rect, - int align, - const wxDataViewItemAttr *attr, - int state) +bool wxDataViewTextRenderer::Render(wxRect rect, wxDC *dc, int state) { - RenderText(dc, rect, align, m_text, attr, state); + RenderText(m_text, 0, rect, dc, state); return true; } @@ -821,11 +724,11 @@ wxSize wxDataViewTextRenderer::GetSize() const // wxDataViewBitmapRenderer // --------------------------------------------------------- -IMPLEMENT_CLASS(wxDataViewBitmapRenderer, wxDataViewCustomRenderer) +IMPLEMENT_CLASS(wxDataViewBitmapRenderer, wxDataViewRenderer) wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString &varianttype, wxDataViewCellMode mode, int align ) : - wxDataViewCustomRenderer( varianttype, mode, align ) + wxDataViewRenderer( varianttype, mode, align ) { } @@ -868,11 +771,11 @@ wxSize wxDataViewBitmapRenderer::GetSize() const // wxDataViewToggleRenderer // --------------------------------------------------------- -IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer, wxDataViewCustomRenderer) +IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer, wxDataViewRenderer) wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString &varianttype, wxDataViewCellMode mode, int align ) : - wxDataViewCustomRenderer( varianttype, mode, align ) + wxDataViewRenderer( varianttype, mode, align ) { m_toggle = false; } @@ -897,6 +800,12 @@ bool wxDataViewToggleRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state if (GetMode() != wxDATAVIEW_CELL_ACTIVATABLE) flags |= wxCONTROL_DISABLED; + // check boxes we draw must always have the same, standard size (if it's + // bigger than the cell size the checkbox will be truncated because the + // caller had set the clipping rectangle to prevent us from drawing outside + // the cell) + cell.SetSize(GetSize()); + wxRendererNative::Get().DrawCheckBox( GetOwner()->GetOwner(), *dc, @@ -910,10 +819,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; } @@ -928,11 +834,11 @@ wxSize wxDataViewToggleRenderer::GetSize() const // wxDataViewProgressRenderer // --------------------------------------------------------- -IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer, wxDataViewCustomRenderer) +IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer, wxDataViewRenderer) wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString &label, const wxString &varianttype, wxDataViewCellMode mode, int align ) : - wxDataViewCustomRenderer( varianttype, mode, align ) + wxDataViewRenderer( varianttype, mode, align ) { m_label = label; m_value = 0; @@ -954,24 +860,23 @@ bool wxDataViewProgressRenderer::GetValue( wxVariant &value ) const return true; } -bool wxDataViewProgressRenderer::RenderWithAttr(wxDC& dc, - const wxRect& rect, - int WXUNUSED(align), - const wxDataViewItemAttr *attr, - int WXUNUSED(state)) +bool +wxDataViewProgressRenderer::Render(wxRect rect, wxDC *dc, int WXUNUSED(state)) { - // deflat the rect to leave a small border between bars in adjacent rows + // deflate 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( bar ); + 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 ); + dc->SetPen( *wxTRANSPARENT_PEN ); + + const wxDataViewItemAttr& attr = GetAttr(); + dc->SetBrush( attr.HasColour() ? wxBrush(attr.GetColour()) + : *wxBLUE_BRUSH ); + dc->DrawRectangle( bar ); return true; } @@ -1028,20 +933,17 @@ 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(); } #endif // wxUSE_DATE_RENDERER_POPUP -IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer, wxDataViewCustomRenderer) +IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer, wxDataViewRenderer) wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString &varianttype, wxDataViewCellMode mode, int align ) : - wxDataViewCustomRenderer( varianttype, mode, align ) + wxDataViewRenderer( varianttype, mode, align ) { } @@ -1098,20 +1000,16 @@ bool wxDataViewDateRenderer::Activate( wxRect WXUNUSED(cell), wxDataViewModel *m // wxDataViewIconTextRenderer // --------------------------------------------------------- -IMPLEMENT_CLASS(wxDataViewIconTextRenderer, wxDataViewCustomRenderer) +IMPLEMENT_CLASS(wxDataViewIconTextRenderer, wxDataViewRenderer) wxDataViewIconTextRenderer::wxDataViewIconTextRenderer( const wxString &varianttype, wxDataViewCellMode mode, int align ) : - wxDataViewCustomRenderer( varianttype, mode, align ) + wxDataViewRenderer( varianttype, mode, align ) { SetMode(mode); SetAlignment(align); } -wxDataViewIconTextRenderer::~wxDataViewIconTextRenderer() -{ -} - bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value ) { m_value << value; @@ -1123,17 +1021,18 @@ bool wxDataViewIconTextRenderer::GetValue( wxVariant& WXUNUSED(value) ) const return false; } -bool wxDataViewIconTextRenderer::Render( wxRect cell, wxDC *dc, int state ) +bool wxDataViewIconTextRenderer::Render(wxRect rect, wxDC *dc, 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(m_value.GetText(), xoffset, rect, dc, state); return true; } @@ -1619,15 +1518,15 @@ wxBitmap wxDataViewMainWindow::CreateItemBitmap( unsigned int row, int &indent ) model->GetValue( value, item, column->GetModelColumn()); cell->SetValue( value ); + wxDataViewItemAttr attr; + model->GetAttr(item, column->GetModelColumn(), attr); + cell->SetAttr(attr); + 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, cell->CalculateAlignment(), - hasAttr ? &attr : NULL, 0); + cell->WXCallRender(item_rect, &dc, 0); // dc.DestroyClippingRegion(); x += width; @@ -1672,6 +1571,13 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) // compute which columns needs to be redrawn unsigned int cols = GetOwner()->GetColumnCount(); + if ( !cols ) + { + // we assume that we have at least one column below and painting an + // empty control is unnecessary anyhow + return; + } + unsigned int col_start = 0; unsigned int x_start; for (x_start = 0; col_start < cols; col_start++) @@ -1750,7 +1656,8 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) if (m_hasFocus) flags |= wxCONTROL_FOCUSED; - wxRect rect( x_start, GetLineStart( item ), x_last, GetLineHeight( item ) ); + wxRect rect( x_start, GetLineStart( item ), + x_last - x_start, GetLineHeight( item ) ); wxRendererNative::Get().DrawItemSelectionRect ( this, @@ -1765,7 +1672,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) if (m_dropHint) { wxRect rect( x_start, GetLineStart( m_dropHintLine ), - x_last, GetLineHeight( m_dropHintLine ) ); + x_last - x_start, GetLineHeight( m_dropHintLine ) ); dc.SetPen( *wxBLACK_PEN ); dc.SetBrush( *wxTRANSPARENT_BRUSH ); dc.DrawRectangle( rect ); @@ -1789,7 +1696,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) wxDataViewRenderer *cell = col->GetRenderer(); cell_rect.width = col->GetWidth(); - if (col->IsHidden()) + if ( col->IsHidden() || cell_rect.width <= 0 ) continue; // skip it! for (unsigned int item = item_start; item < item_last; item++) @@ -1819,44 +1726,50 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) model->GetValue( value, dataitem, col->GetModelColumn()); cell->SetValue( value ); + wxDataViewItemAttr attr; + model->GetAttr(dataitem, col->GetModelColumn(), attr); + cell->SetAttr(attr); + // update cell_rect cell_rect.y = GetLineStart( item ); cell_rect.height = GetLineHeight( item ); - // Draw the expander here. + // deal with the expander int indent = 0; if ((!IsVirtualList()) && (col == expander)) { - indent = node->GetIndentLevel(); - // Calculate the indent first - indent = cell_rect.x + GetOwner()->GetIndent() * indent; - - int expander_width = m_lineHeight - 2*EXPANDER_MARGIN; + indent = GetOwner()->GetIndent() * node->GetIndentLevel(); - // change the cell_rect.x to the appropriate pos - int expander_x = indent + EXPANDER_MARGIN; - int expander_y = cell_rect.y + EXPANDER_MARGIN + (GetLineHeight(item) / 2) - - (expander_width/2) - EXPANDER_OFFSET; + // we reserve m_lineHeight of horizontal space for the expander + // but leave EXPANDER_MARGIN around the expander itself + int exp_x = cell_rect.x + indent + EXPANDER_MARGIN; - indent = indent + m_lineHeight; - // try to use the m_lineHeight as the expander space + indent += m_lineHeight; - dc.SetPen( m_penExpander ); - dc.SetBrush( wxNullBrush ); - if( node->HasChildren() ) + // draw expander if needed and visible + if ( node->HasChildren() && exp_x < cell_rect.GetRight() ) { - wxRect rect( expander_x , expander_y, expander_width, expander_width); + dc.SetPen( m_penExpander ); + dc.SetBrush( wxNullBrush ); + + int exp_size = m_lineHeight - 2*EXPANDER_MARGIN; + int exp_y = cell_rect.y + (cell_rect.height - exp_size)/2 + + EXPANDER_MARGIN - EXPANDER_OFFSET; + + const wxRect rect(exp_x, exp_y, exp_size, exp_size); + int flag = 0; - if (m_underMouse == node) - { + if ( m_underMouse == node ) flag |= wxCONTROL_CURRENT; - } - if( node->IsOpen() ) - wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, - flag|wxCONTROL_EXPANDED ); - else - wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, flag); + if ( node->IsOpen() ) + flag |= wxCONTROL_EXPANDED; + + // ensure that we don't overflow the cell (which might + // happen if the column is very narrow) + wxDCClipper clip(dc, cell_rect); + + wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, flag); } // force the expander column to left-center align @@ -1876,6 +1789,9 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) item_rect.x += indent; item_rect.width -= indent; + if ( item_rect.width <= 0 ) + continue; + int state = 0; if (m_hasFocus && (m_selection.Index(item) != wxNOT_FOUND)) state |= wxDATAVIEW_CELL_SELECTED; @@ -1889,11 +1805,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) // make its own renderer and thus we cannot be sure of that. wxDCClipper clip(dc, item_rect); - wxDataViewItemAttr attr; - const bool - hasAttr = model->GetAttr(dataitem, col->GetModelColumn(), attr); - cell->RenderWithAttr(dc, item_rect, cell->CalculateAlignment(), - hasAttr ? &attr : NULL, state); + cell->WXCallRender(item_rect, &dc, state); } cell_rect.x += cell_rect.width; @@ -2161,6 +2073,7 @@ bool wxDataViewMainWindow::Cleared() void wxDataViewMainWindow::UpdateDisplay() { m_dirty = true; + m_underMouse = NULL; } void wxDataViewMainWindow::OnInternalIdle() @@ -3643,12 +3556,15 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) { if ((!ignore_other_columns) && (cell->GetMode() == wxDATAVIEW_CELL_ACTIVATABLE)) { - wxVariant value; - model->GetValue( value, item, col->GetModelColumn() ); - cell->SetValue( value ); - wxRect cell_rect( xpos, GetLineStart( current ), - col->GetWidth(), GetLineHeight( current ) ); - cell->Activate( cell_rect, model, item, col->GetModelColumn() ); + if ( wxDataViewCustomRenderer *custom = cell->WXGetAsCustom() ) + { + wxVariant value; + model->GetValue( value, item, col->GetModelColumn() ); + custom->SetValue( value ); + wxRect cell_rect( xpos, GetLineStart( current ), + col->GetWidth(), GetLineHeight( current ) ); + custom->Activate( cell_rect, model, item, col->GetModelColumn() ); + } } else { @@ -3778,7 +3694,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) { ChangeCurrentRow(current); ReverseRowSelection(m_currentRow); - SendSelectionChangedEvent(GetItemByRow(m_selection[0]) ); + SendSelectionChangedEvent(GetItemByRow(m_currentRow)); } else if (event.ShiftDown()) { @@ -3817,14 +3733,17 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) // Call LeftClick after everything else as under GTK+ if (cell->GetMode() & wxDATAVIEW_CELL_ACTIVATABLE) { - // notify cell about right click - wxVariant value; - model->GetValue( value, item, col->GetModelColumn() ); - cell->SetValue( value ); - wxRect cell_rect( xpos, GetLineStart( current ), - col->GetWidth(), GetLineHeight( current ) ); - /* ignore ret */ cell->LeftClick( event.GetPosition(), cell_rect, - model, item, col->GetModelColumn()); + if ( wxDataViewCustomRenderer *custom = cell->WXGetAsCustom() ) + { + // notify cell about click + wxVariant value; + model->GetValue( value, item, col->GetModelColumn() ); + custom->SetValue( value ); + wxRect cell_rect( xpos, GetLineStart( current ), + col->GetWidth(), GetLineHeight( current ) ); + /* ignore ret */ custom->LeftClick( event.GetPosition(), cell_rect, + model, item, col->GetModelColumn()); + } } } } @@ -4206,7 +4125,11 @@ void wxDataViewCtrl::Select( const wxDataViewItem & item ) // Unselect all rows before select another in the single select mode if (m_clientArea->IsSingleSel()) m_clientArea->SelectAllRows(false); + m_clientArea->SelectRow(row, true); + + // Also set focus to the selected item + m_clientArea->ChangeCurrentRow( row ); } }