From f10d9e199f34bc6447db078a104a12266c4fc924 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 30 Apr 2020 16:47:27 +0200 Subject: [PATCH 1/8] Remove unnecessary GetColumnCount() test in wxDataViewCtrl code The presence of columns is already checked inside UpdateColumnSizes() itself, so there is no need to do it before calling it too. No real changes. --- src/generic/datavgen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 7cf49aefa4..b8249e9fbf 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -5272,7 +5272,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(); From 7a8f04302ffbd79612ab98d60e5004bd24da24d5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 1 May 2020 03:21:45 +0200 Subject: [PATCH 2/8] Use client size for calculating column sizes, not the full size We need account for the place taken by the vertical scrollbar, if any. --- src/generic/datavgen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index b8249e9fbf..2f672c664f 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -5075,7 +5075,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. From 9ed122b31f7152099717daf810654594e50600c5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 1 May 2020 03:22:40 +0200 Subject: [PATCH 3/8] Update column sizes after updating scrollbars, not before As UpdateColumnSizes() uses client size, call it after the client size is set correctly after adjusting scrollbars to the new virtual size. --- src/generic/datavgen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 2f672c664f..26407f5e66 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -3078,7 +3078,6 @@ void wxDataViewMainWindow::OnInternalIdle() if (m_dirty) { - UpdateColumnSizes(); RecalculateDisplay(); m_dirty = false; } @@ -3098,6 +3097,7 @@ void wxDataViewMainWindow::RecalculateDisplay() SetVirtualSize( width, height ); GetOwner()->SetScrollRate( 10, m_lineHeight ); + UpdateColumnSizes(); Refresh(); } From ecc58e521102d9b7d2f84d55978bfc05870f5473 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 1 May 2020 03:23:52 +0200 Subject: [PATCH 4/8] Allow shrinking last column down to its minimal size Not doing this when the last column size should have been exactly equal to its manually set size resulted in showing the horizontal scrollbar unnecessarily. --- src/generic/datavgen.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 26407f5e66..9a290ab86c 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -5112,9 +5112,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->WXGetManuallySetWidth()) ) { return; } From 6c5f3f8929bf4e70c2e8ebd89b4b401dcc1b70f9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 1 May 2020 03:25:52 +0200 Subject: [PATCH 5/8] Refactor generic wxDataViewColumn to use DoGetEffectiveWidth() This function will be used for m_manuallySetWidth too, in addition to m_width, in the next commit. No changes yet in this one. --- include/wx/generic/dataview.h | 5 +++++ src/generic/datavgen.cpp | 11 ++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/wx/generic/dataview.h b/include/wx/generic/dataview.h index a96e53db6b..4c932cfd1c 100644 --- a/include/wx/generic/dataview.h +++ b/include/wx/generic/dataview.h @@ -166,6 +166,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/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 9a290ab86c..bce892416b 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 = From d74389f9303ef0052a1541476ad026a4d7b3c572 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 1 May 2020 03:29:32 +0200 Subject: [PATCH 6/8] Fix WXGetManuallySetWidth() for columns using wxCOL_WIDTH_DEFAULT Columns without any explicitly specified width still shouldn't be shrunk down to 0 size by UpdateColumnSizes(), so handle them as if they were created using wxDVC_DEFAULT_WIDTH instead -- which is what their actual width is/would be. This is a better fix than the one in 0c90ea40c3 (Don't auto-resize wxDataViewCtrl columns below their initial size, 2019-10-03) and that commit can be reverted now, as will be done soon. See #18343. --- include/wx/generic/dataview.h | 2 +- src/generic/datavgen.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/wx/generic/dataview.h b/include/wx/generic/dataview.h index 4c932cfd1c..247a30d253 100644 --- a/include/wx/generic/dataview.h +++ b/include/wx/generic/dataview.h @@ -154,7 +154,7 @@ public: // user interactively. void WXOnResize(int width); - int WXGetManuallySetWidth() const { return m_manuallySetWidth; } + int WXGetManuallySetWidth() const; private: // common part of all ctors diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index bce892416b..0e8689765d 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -217,6 +217,15 @@ void wxDataViewColumn::WXOnResize(int width) m_owner->OnColumnResized(); } +int wxDataViewColumn::WXGetManuallySetWidth() 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) From 44578b883c99e8fdba4647dac07302727efe4504 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 1 May 2020 03:26:47 +0200 Subject: [PATCH 7/8] Don't set m_manuallySetWidth incorrectly This fix for disallowing shrinking the last column to nothing instead of showing horizontal scrollbar when it became smaller than its minimum size was wrong and is not necessary any more after the correct fix in the previous commit. This effectively reverts 0c90ea40c3 (Don't auto-resize wxDataViewCtrl columns below their initial size, 2019-10-03). See #18343. --- include/wx/generic/dataview.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/include/wx/generic/dataview.h b/include/wx/generic/dataview.h index 247a30d253..e01d681123 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(); } From aacd26c27b887b24f889828c403797fb53355da1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 1 May 2020 03:34:44 +0200 Subject: [PATCH 8/8] Save specified, not actual, col width in wxPersistentDataViewCtrl This is more correct as saving the current width of the last column would prevent the user from shrinking it under the last automatically set size, i.e. the UI behaviour would change after restarting the program, which shouldn't be the case. Doing this required making WXGetManuallySetWidth(), which previously existed in the generic version only, available in all ports, so do it and also rename it to WXGetSpecifiedWidth() in the process, as this seems a somewhat better name (it doesn't have to be manually specified, i.e. it could also be done by the program itself or even implicitly by wxPersistentDataViewCtrl). Don't make this function public, at least for now, because it's not clear how could it be useful and it might still need to be changed to behave differently in the other ports. --- include/wx/dataview.h | 6 ++++++ include/wx/generic/dataview.h | 2 +- include/wx/persist/dataview.h | 10 +++++++++- src/generic/datavgen.cpp | 6 +++--- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/include/wx/dataview.h b/include/wx/dataview.h index 99b620d84d..48bd4efe85 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 e01d681123..12ee1ce1db 100644 --- a/include/wx/generic/dataview.h +++ b/include/wx/generic/dataview.h @@ -145,7 +145,7 @@ public: // user interactively. void WXOnResize(int width); - int WXGetManuallySetWidth() const; + virtual int WXGetSpecifiedWidth() const wxOVERRIDE; private: // common part of all ctors 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 0e8689765d..0bfdc18df2 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -217,7 +217,7 @@ void wxDataViewColumn::WXOnResize(int width) m_owner->OnColumnResized(); } -int wxDataViewColumn::WXGetManuallySetWidth() const +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 @@ -5130,7 +5130,7 @@ void wxDataViewMainWindow::UpdateColumnSizes() // reduce it until this size if it's currently wider, so this // comparison needs to be strict). if ( availableWidth < wxMax(lastCol->GetMinWidth(), - lastCol->WXGetManuallySetWidth()) ) + lastCol->WXGetSpecifiedWidth()) ) { return; } @@ -5319,7 +5319,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);