X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f0630187eace810df2176bbb7f5429297ca82d4e..572f4ad212f7f5d4e1bad60d4c30a682ce3f3152:/src/generic/datavgen.cpp?ds=sidebyside diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 7c58d590b9..7fef06b83b 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -1007,11 +1007,13 @@ bool wxDataViewToggleRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state GetEnabled() == false) 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()); + // Ensure that the check boxes always have at least the minimal required + // size, otherwise DrawCheckBox() doesn't really work well. If this size is + // greater than the cell size, the checkbox will be truncated but this is a + // lesser evil. + wxSize size = cell.GetSize(); + size.IncTo(GetSize()); + cell.SetSize(size); wxRendererNative::Get().DrawCheckBox( GetOwner()->GetOwner(), @@ -2337,7 +2339,17 @@ bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent, // If this was the last child to be removed, it's possible the parent // node became a leaf. Let's ask the model about it. if ( parentNode->GetChildNodes().empty() ) - parentNode->SetHasChildren(GetModel()->IsContainer(parent)); + { + bool isContainer = GetModel()->IsContainer(parent); + parentNode->SetHasChildren(isContainer); + if ( isContainer ) + { + // If it's still a container, make sure we show "+" icon for it + // and not "-" one as there is nothing to collapse any more. + if ( parentNode->IsOpen() ) + parentNode->ToggleOpen(); + } + } // Update selection by removing 'item' and its entire children tree from the selection. if ( !m_selection.empty() ) @@ -4547,7 +4559,7 @@ bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col ) return false; m_cols.Append( col ); - m_colsBestWidths.push_back(0); + m_colsBestWidths.push_back(CachedColWidthInfo()); OnColumnsCountChanged(); return true; } @@ -4558,7 +4570,7 @@ bool wxDataViewCtrl::PrependColumn( wxDataViewColumn *col ) return false; m_cols.Insert( col ); - m_colsBestWidths.insert(m_colsBestWidths.begin(), 0); + m_colsBestWidths.insert(m_colsBestWidths.begin(), CachedColWidthInfo()); OnColumnsCountChanged(); return true; } @@ -4569,7 +4581,7 @@ bool wxDataViewCtrl::InsertColumn( unsigned int pos, wxDataViewColumn *col ) return false; m_cols.Insert( pos, col ); - m_colsBestWidths.insert(m_colsBestWidths.begin() + pos, 0); + m_colsBestWidths.insert(m_colsBestWidths.begin() + pos, CachedColWidthInfo()); OnColumnsCountChanged(); return true; } @@ -4644,8 +4656,8 @@ int wxDataViewCtrl::GetColumnIndex(const wxDataViewColumn *column) const unsigned int wxDataViewCtrl::GetBestColumnWidth(int idx) const { - if ( m_colsBestWidths[idx] != 0 ) - return m_colsBestWidths[idx]; + if ( m_colsBestWidths[idx].width != 0 ) + return m_colsBestWidths[idx].width; const int count = m_clientArea->GetRowCount(); wxDataViewColumn *column = GetColumn(idx); @@ -4795,7 +4807,7 @@ unsigned int wxDataViewCtrl::GetBestColumnWidth(int idx) const if ( max_width > 0 ) max_width += 2 * PADDING_RIGHTLEFT; - const_cast(this)->m_colsBestWidths[idx] = max_width; + const_cast(this)->m_colsBestWidths[idx].width = max_width; return max_width; } @@ -4840,12 +4852,14 @@ bool wxDataViewCtrl::ClearColumns() void wxDataViewCtrl::InvalidateColBestWidth(int idx) { - m_colsBestWidths[idx] = 0; + m_colsBestWidths[idx].width = 0; + m_colsBestWidths[idx].dirty = true; m_colsDirty = true; } void wxDataViewCtrl::InvalidateColBestWidths() { + // mark all columns as dirty: m_colsBestWidths.clear(); m_colsBestWidths.resize(m_cols.size()); m_colsDirty = true; @@ -4853,14 +4867,27 @@ void wxDataViewCtrl::InvalidateColBestWidths() void wxDataViewCtrl::UpdateColWidths() { + m_colsDirty = false; + if ( !m_headerArea ) return; const unsigned len = m_colsBestWidths.size(); for ( unsigned i = 0; i < len; i++ ) { - if ( m_colsBestWidths[i] == 0 ) + // Note that we have to have an explicit 'dirty' flag here instead of + // checking if the width==0, as is done in GetBestColumnWidth(). + // + // Testing width==0 wouldn't work correctly if some code called + // GetWidth() after col. width invalidation but before + // wxDataViewCtrl::UpdateColWidths() was called at idle time. This + // would result in the header's column width getting out of sync with + // the control itself. + if ( m_colsBestWidths[i].dirty ) + { m_headerArea->UpdateColumn(i); + m_colsBestWidths[i].dirty = false; + } } } @@ -4869,10 +4896,7 @@ void wxDataViewCtrl::OnInternalIdle() wxDataViewCtrlBase::OnInternalIdle(); if ( m_colsDirty ) - { - m_colsDirty = false; UpdateColWidths(); - } } int wxDataViewCtrl::GetColumnPosition( const wxDataViewColumn *column ) const @@ -5082,14 +5106,20 @@ void wxDataViewCtrl::Expand( const wxDataViewItem & item ) int row = m_clientArea->GetRowByItem( item ); if (row != -1) + { m_clientArea->Expand(row); + InvalidateColBestWidths(); + } } void wxDataViewCtrl::Collapse( const wxDataViewItem & item ) { int row = m_clientArea->GetRowByItem( item ); if (row != -1) + { m_clientArea->Collapse(row); + InvalidateColBestWidths(); + } } bool wxDataViewCtrl::IsExpanded( const wxDataViewItem & item ) const