diff --git a/include/wx/dataview.h b/include/wx/dataview.h index e796ab46c7..a0ed0dc1e3 100644 --- a/include/wx/dataview.h +++ b/include/wx/dataview.h @@ -514,6 +514,12 @@ public: virtual void SetBitmap( const wxBitmap& bitmap ) wxOVERRIDE { m_bitmap = bitmap; } virtual wxBitmap GetBitmap() const wxOVERRIDE { return m_bitmap; } + // Special accessor for use by wxWidgets only returning the width that was + // explicitly set, either by the application, using SetWidth(), or by the + // user, resizing the column interactively. It is usually the same as + // GetWidth(), but can be different for the last column. + virtual int WXGetSpecifiedWidth() const { return GetWidth(); } + protected: wxDataViewRenderer *m_renderer; int m_model_column; diff --git a/include/wx/generic/dataview.h b/include/wx/generic/dataview.h index a96e53db6b..12ee1ce1db 100644 --- a/include/wx/generic/dataview.h +++ b/include/wx/generic/dataview.h @@ -137,15 +137,6 @@ public: if ( width == m_width ) return; - // Normally we don't update it here as this method is called by - // UpdateColumnSizes() which resizes the column automatically, and not - // "manually", but if it's the first time the width is being set for a - // column created with the default width, do set m_manuallySetWidth in - // order to prevent the column from becoming narrower than its initial - // size when the control is resized, as this is unexpected. - if ( m_width == -1 ) - m_manuallySetWidth = width; - m_width = width; UpdateWidth(); } @@ -154,7 +145,7 @@ public: // user interactively. void WXOnResize(int width); - int WXGetManuallySetWidth() const { return m_manuallySetWidth; } + virtual int WXGetSpecifiedWidth() const wxOVERRIDE; private: // common part of all ctors @@ -166,6 +157,11 @@ private: void UpdateDisplay(); void UpdateWidth(); + // Return the effective value corresponding to the given width, handling + // its negative values such as wxCOL_WIDTH_DEFAULT. + int DoGetEffectiveWidth(int width) const; + + wxString m_title; int m_width, m_manuallySetWidth, diff --git a/include/wx/persist/dataview.h b/include/wx/persist/dataview.h index c5f212b2ee..ee10c02480 100644 --- a/include/wx/persist/dataview.h +++ b/include/wx/persist/dataview.h @@ -61,7 +61,15 @@ public: SaveValue(columnPrefix + wxPERSIST_DVC_HIDDEN, column->IsHidden()); SaveValue(columnPrefix + wxPERSIST_DVC_POS, control->GetColumnPosition(column)); - SaveValue(columnPrefix + wxPERSIST_DVC_WIDTH, column->GetWidth()); + + // We take special care to save only the specified width instead of + // the currently used one. Usually they're one and the same, but + // they can be different for the last column, whose size can be + // greater than specified, as it's always expanded to fill the + // entire control width. + const int width = column->WXGetSpecifiedWidth(); + if ( width > 0 ) + SaveValue(columnPrefix + wxPERSIST_DVC_WIDTH, width); // Check if this column is the current sort key. if ( column->IsSortKey() ) diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 674e977aa7..613c057a96 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -188,9 +188,9 @@ void wxDataViewColumn::Init(int width, wxAlignment align, int flags) m_sortAscending = true; } -int wxDataViewColumn::GetWidth() const +int wxDataViewColumn::DoGetEffectiveWidth(int width) const { - switch ( m_width ) + switch ( width ) { case wxCOL_WIDTH_DEFAULT: return wxWindow::FromDIP(wxDVC_DEFAULT_WIDTH, m_owner); @@ -200,10 +200,15 @@ int wxDataViewColumn::GetWidth() const return m_owner->GetBestColumnWidth(m_owner->GetColumnIndex(this)); default: - return m_width; + return width; } } +int wxDataViewColumn::GetWidth() const +{ + return DoGetEffectiveWidth(m_width); +} + void wxDataViewColumn::WXOnResize(int width) { m_width = @@ -212,6 +217,15 @@ void wxDataViewColumn::WXOnResize(int width) m_owner->OnColumnResized(); } +int wxDataViewColumn::WXGetSpecifiedWidth() const +{ + // Note that we need to return valid value even if no width was initially + // specified, as otherwise the last column created without any explicit + // width could be reduced to nothing by UpdateColumnSizes() when the + // control is shrunk. + return DoGetEffectiveWidth(m_manuallySetWidth); +} + void wxDataViewColumn::UpdateDisplay() { if (m_owner) @@ -3108,7 +3122,6 @@ void wxDataViewMainWindow::OnInternalIdle() if (m_dirty) { - UpdateColumnSizes(); RecalculateDisplay(); m_dirty = false; } @@ -3128,6 +3141,7 @@ void wxDataViewMainWindow::RecalculateDisplay() SetVirtualSize( width, height ); GetOwner()->SetScrollRate( 10, m_lineHeight ); + UpdateColumnSizes(); Refresh(); } @@ -5123,7 +5137,7 @@ void wxDataViewMainWindow::UpdateColumnSizes() wxDataViewCtrl *owner = GetOwner(); - int fullWinWidth = GetSize().x; + int fullWinWidth = GetClientSize().x; // Find the last shown column: we shouldn't bother to resize the columns // that are hidden anyhow. @@ -5160,9 +5174,11 @@ void wxDataViewMainWindow::UpdateColumnSizes() const int availableWidth = fullWinWidth - lastColX; // Never make the column automatically smaller than the last width it - // was explicitly given nor its minimum width. - if ( availableWidth <= wxMax(lastCol->GetMinWidth(), - lastCol->WXGetManuallySetWidth()) ) + // was explicitly given nor its minimum width (however we do need to + // reduce it until this size if it's currently wider, so this + // comparison needs to be strict). + if ( availableWidth < wxMax(lastCol->GetMinWidth(), + lastCol->WXGetSpecifiedWidth()) ) { return; } @@ -5320,7 +5336,7 @@ void wxDataViewCtrl::OnSize( wxSizeEvent &WXUNUSED(event) ) // Update the last column size to take all the available space. Note that // this must be done after calling Layout() to update m_clientArea size. - if ( m_clientArea && GetColumnCount() ) + if ( m_clientArea ) m_clientArea->UpdateColumnSizes(); AdjustScrollbars(); @@ -5351,7 +5367,7 @@ void wxDataViewCtrl::OnDPIChanged(wxDPIChangedEvent& event) minWidth = minWidth * event.GetNewDPI().x / event.GetOldDPI().x; m_cols[i]->SetMinWidth(minWidth); - int width = m_cols[i]->WXGetManuallySetWidth(); + int width = m_cols[i]->WXGetSpecifiedWidth(); if ( width > 0 ) width = width * event.GetNewDPI().x / event.GetOldDPI().x; m_cols[i]->SetWidth(width);