Merge branch 'dvc-last-col-resize'

Improve resizing of the last column in generic wxDataViewCtrl.

See https://github.com/wxWidgets/wxWidgets/pull/1077

Closes #18295.
This commit is contained in:
Vadim Zeitlin 2018-12-20 18:57:48 +01:00
commit 9877f207d1
3 changed files with 52 additions and 28 deletions

View File

@ -12,7 +12,6 @@
#include "wx/defs.h"
#include "wx/object.h"
#include "wx/list.h"
#include "wx/control.h"
#include "wx/scrolwin.h"
#include "wx/icon.h"
@ -74,6 +73,11 @@ public:
// UpdateWidth() if the width didn't really change, even if we don't
// care about its return value.
(void)WXUpdateWidth(width);
// Do remember the last explicitly set width: this is used to prevent
// UpdateColumnSizes() from resizing the last column to be smaller than
// this size.
m_manuallySetWidth = width;
}
virtual int GetWidth() const wxOVERRIDE;
@ -137,9 +141,15 @@ public:
m_width = width;
UpdateWidth();
// We must not update m_manuallySetWidth here as this method is called by
// UpdateColumnSizes() which resizes the column automatically, and not
// "manually".
return true;
}
int WXGetManuallySetWidth() const { return m_manuallySetWidth; }
private:
// common part of all ctors
void Init(int width, wxAlignment align, int flags);
@ -152,6 +162,7 @@ private:
wxString m_title;
int m_width,
m_manuallySetWidth,
m_minWidth;
wxAlignment m_align;
int m_flags;
@ -167,9 +178,6 @@ private:
// wxDataViewCtrl
// ---------------------------------------------------------
WX_DECLARE_LIST_WITH_DECL(wxDataViewColumn, wxDataViewColumnList,
class WXDLLIMPEXP_CORE);
class WXDLLIMPEXP_CORE wxDataViewCtrl : public wxDataViewCtrlBase,
public wxScrollHelper
{
@ -354,7 +362,9 @@ private:
void InvalidateColBestWidth(int idx);
void UpdateColWidths();
wxDataViewColumnList m_cols;
void DoClearColumns();
wxVector<wxDataViewColumn*> m_cols;
// cached column best widths information, values are for
// respective columns from m_cols and the arrays have same size
struct CachedColWidthInfo

View File

@ -793,7 +793,7 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l
lc->AppendColumn(colRadio, "bool");
lc->AppendTextColumn( "Text" );
lc->AppendProgressColumn( "Progress" );
lc->AppendProgressColumn( "Progress" )->SetMinWidth(100);
wxVector<wxVariant> data;
for (unsigned int i=0; i<10; i++)

View File

@ -180,7 +180,8 @@ wxTextCtrl *CreateEditorTextCtrl(wxWindow *parent, const wxRect& labelRect, cons
void wxDataViewColumn::Init(int width, wxAlignment align, int flags)
{
m_width = width;
m_width =
m_manuallySetWidth = width;
m_minWidth = 0;
m_align = align;
m_flags = flags;
@ -5022,20 +5023,25 @@ void wxDataViewMainWindow::UpdateColumnSizes()
int lastColX = colswidth - lastCol->GetWidth();
if ( lastColX < fullWinWidth )
{
int desiredWidth = wxMax(fullWinWidth - lastColX, lastCol->GetMinWidth());
if ( !lastCol->WXUpdateWidth(desiredWidth) )
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()) )
{
// The column width didn't change, no need to do anything else.
return;
}
lastCol->WXUpdateWidth(availableWidth);
// All columns fit on screen, so we don't need horizontal scrolling.
// To prevent flickering scrollbar when resizing the window to be
// narrower, force-set the virtual width to 0 here. It will eventually
// be corrected at idle time.
SetVirtualSize(0, m_virtualSize.y);
RefreshRect(wxRect(lastColX, 0, fullWinWidth - lastColX, GetSize().y));
RefreshRect(wxRect(lastColX, 0, availableWidth, GetSize().y));
}
else
{
@ -5048,8 +5054,6 @@ void wxDataViewMainWindow::UpdateColumnSizes()
// wxDataViewCtrl
//-----------------------------------------------------------------------------
WX_DEFINE_LIST(wxDataViewColumnList)
wxIMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl, wxDataViewCtrlBase);
wxBEGIN_EVENT_TABLE(wxDataViewCtrl, wxDataViewCtrlBase)
EVT_SIZE(wxDataViewCtrl::OnSize)
@ -5060,8 +5064,7 @@ wxDataViewCtrl::~wxDataViewCtrl()
if (m_notifier)
GetModel()->RemoveNotifier( m_notifier );
m_cols.Clear();
m_colsBestWidths.clear();
DoClearColumns();
#if wxUSE_ACCESSIBILITY
SetAccessible(NULL);
@ -5071,7 +5074,6 @@ wxDataViewCtrl::~wxDataViewCtrl()
void wxDataViewCtrl::Init()
{
m_cols.DeleteContents(true);
m_notifier = NULL;
m_headerArea = NULL;
@ -5172,9 +5174,6 @@ wxSize wxDataViewCtrl::GetSizeAvailableForScrollTarget(const wxSize& size)
void wxDataViewCtrl::OnSize( wxSizeEvent &WXUNUSED(event) )
{
if ( m_clientArea && GetColumnCount() )
m_clientArea->UpdateColumnSizes();
// We need to override OnSize so that our scrolled
// window a) does call Layout() to use sizers for
// positioning the controls but b) does not query
@ -5186,6 +5185,11 @@ void wxDataViewCtrl::OnSize( wxSizeEvent &WXUNUSED(event) )
AdjustScrollbars();
// 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() )
m_clientArea->UpdateColumnSizes();
// We must redraw the headers if their height changed. Normally this
// shouldn't happen as the control shouldn't let itself be resized beneath
// its minimal height but avoid the display artefacts that appear if it
@ -5321,7 +5325,7 @@ bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col )
if (!wxDataViewCtrlBase::AppendColumn(col))
return false;
m_cols.Append( col );
m_cols.push_back( col );
m_colsBestWidths.push_back(CachedColWidthInfo());
OnColumnsCountChanged();
return true;
@ -5332,7 +5336,7 @@ bool wxDataViewCtrl::PrependColumn( wxDataViewColumn *col )
if (!wxDataViewCtrlBase::PrependColumn(col))
return false;
m_cols.Insert( col );
m_cols.insert(m_cols.begin(), col);
m_colsBestWidths.insert(m_colsBestWidths.begin(), CachedColWidthInfo());
OnColumnsCountChanged();
return true;
@ -5343,7 +5347,7 @@ bool wxDataViewCtrl::InsertColumn( unsigned int pos, wxDataViewColumn *col )
if (!wxDataViewCtrlBase::InsertColumn(pos,col))
return false;
m_cols.Insert( pos, col );
m_cols.insert(m_cols.begin() + pos, col);
m_colsBestWidths.insert(m_colsBestWidths.begin() + pos, CachedColWidthInfo());
OnColumnsCountChanged();
return true;
@ -5392,7 +5396,7 @@ void wxDataViewCtrl::DoSetIndent()
unsigned int wxDataViewCtrl::GetColumnCount() const
{
return m_cols.GetCount();
return m_cols.size();
}
bool wxDataViewCtrl::SetRowHeight( int lineHeight )
@ -5544,12 +5548,12 @@ void wxDataViewCtrl::ColumnMoved(wxDataViewColumn *col, unsigned int new_pos)
bool wxDataViewCtrl::DeleteColumn( wxDataViewColumn *column )
{
wxDataViewColumnList::compatibility_iterator ret = m_cols.Find( column );
if (!ret)
const int idx = GetColumnIndex(column);
if ( idx == wxNOT_FOUND )
return false;
m_colsBestWidths.erase(m_colsBestWidths.begin() + GetColumnIndex(column));
m_cols.Erase(ret);
m_colsBestWidths.erase(m_colsBestWidths.begin() + idx);
m_cols.erase(m_cols.begin() + idx);
if ( m_clientArea->GetCurrentColumn() == column )
m_clientArea->ClearCurrentColumn();
@ -5559,10 +5563,20 @@ bool wxDataViewCtrl::DeleteColumn( wxDataViewColumn *column )
return true;
}
void wxDataViewCtrl::DoClearColumns()
{
typedef wxVector<wxDataViewColumn*>::const_iterator citer;
for ( citer it = m_cols.begin(); it != m_cols.end(); ++it )
delete *it;
}
bool wxDataViewCtrl::ClearColumns()
{
SetExpanderColumn(NULL);
m_cols.Clear();
DoClearColumns();
m_cols.clear();
m_sortingColumnIdxs.clear();
m_colsBestWidths.clear();