diff --git a/include/wx/generic/dataview.h b/include/wx/generic/dataview.h index 815dfcb75b..6742e048ba 100644 --- a/include/wx/generic/dataview.h +++ b/include/wx/generic/dataview.h @@ -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 m_cols; // cached column best widths information, values are for // respective columns from m_cols and the arrays have same size struct CachedColWidthInfo diff --git a/samples/dataview/dataview.cpp b/samples/dataview/dataview.cpp index 51273a6106..9d654828d6 100644 --- a/samples/dataview/dataview.cpp +++ b/samples/dataview/dataview.cpp @@ -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 data; for (unsigned int i=0; i<10; i++) diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index f94700b072..2ea515ae00 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -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::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();