Correct implement wxLIST_AUTOSIZE_XXX in the generic wxListCtrl.
Use both the contents and the header width when wxLIST_AUTOSIZE_USEHEADER is given instead of just the latter. Also make both wxLIST_AUTOSIZE_USEHEADER and the previously implemented wxLIST_AUTOSIZE work efficiently for the virtual list controls by reusing wxMaxWidthCalculatorBase already used in the generic wxDataViewCtrl. Closes #10326. (this is a backport ofde7e315557
and0e2d9e539c
from master)
This commit is contained in:
committed by
Vadim Zeitlin
parent
c21ad5d9c2
commit
b64e030f0c
@@ -596,6 +596,7 @@ All (GUI):
|
|||||||
wxGenericFileDialog which was accidentally lost some time ago (Carl Godkin).
|
wxGenericFileDialog which was accidentally lost some time ago (Carl Godkin).
|
||||||
- Fix handling of fast consecutive clicks in wxRibbonBar (atobi).
|
- Fix handling of fast consecutive clicks in wxRibbonBar (atobi).
|
||||||
- Fix updating nested window scrollbars in some cases (sbrowne).
|
- Fix updating nested window scrollbars in some cases (sbrowne).
|
||||||
|
- Improve wxLIST_AUTOSIZE_XXX support in generic wxListCtrl (Kinaou Hervé).
|
||||||
- Fix wxPGChoices copy ctor (Snoits).
|
- Fix wxPGChoices copy ctor (Snoits).
|
||||||
- Fix wxPixelData<wxImage>::Offset() for alpha (Markus Rollmann).
|
- Fix wxPixelData<wxImage>::Offset() for alpha (Markus Rollmann).
|
||||||
- Fix bug in wxImage::ClearAlpha() for shared data (Markus Rollmann).
|
- Fix bug in wxImage::ClearAlpha() for shared data (Markus Rollmann).
|
||||||
|
@@ -863,6 +863,7 @@ private:
|
|||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
|
|
||||||
friend class wxGenericListCtrl;
|
friend class wxGenericListCtrl;
|
||||||
|
friend class wxListCtrlMaxWidthCalculator;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // wxUSE_LISTCTRL
|
#endif // wxUSE_LISTCTRL
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "wx/defs.h"
|
#include "wx/defs.h"
|
||||||
|
|
||||||
#if wxUSE_DATAVIEWCTRL
|
#if wxUSE_DATAVIEWCTRL || wxUSE_LISTCTRL
|
||||||
|
|
||||||
#include "wx/timer.h"
|
#include "wx/timer.h"
|
||||||
|
|
||||||
@@ -117,6 +117,6 @@ private:
|
|||||||
wxDECLARE_NO_COPY_CLASS(wxMaxWidthCalculatorBase);
|
wxDECLARE_NO_COPY_CLASS(wxMaxWidthCalculatorBase);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // wxUSE_DATAVIEWCTRL
|
#endif // wxUSE_DATAVIEWCTRL || wxUSE_LISTCTRL
|
||||||
|
|
||||||
#endif // _WX_GENERIC_PRIVATE_WIDTHCALC_H_
|
#endif // _WX_GENERIC_PRIVATE_WIDTHCALC_H_
|
||||||
|
@@ -519,11 +519,11 @@ void MyFrame::InitWithReportItems()
|
|||||||
itemCol.SetImage(-1);
|
itemCol.SetImage(-1);
|
||||||
m_listCtrl->InsertColumn(0, itemCol);
|
m_listCtrl->InsertColumn(0, itemCol);
|
||||||
|
|
||||||
itemCol.SetText(wxT("Column 2"));
|
itemCol.SetText(wxT("Column 2 (auto size excluding header)"));
|
||||||
itemCol.SetAlign(wxLIST_FORMAT_CENTRE);
|
itemCol.SetAlign(wxLIST_FORMAT_CENTRE);
|
||||||
m_listCtrl->InsertColumn(1, itemCol);
|
m_listCtrl->InsertColumn(1, itemCol);
|
||||||
|
|
||||||
itemCol.SetText(wxT("Column 3"));
|
itemCol.SetText(wxT("Column 3 (auto size including header)"));
|
||||||
itemCol.SetAlign(wxLIST_FORMAT_RIGHT);
|
itemCol.SetAlign(wxLIST_FORMAT_RIGHT);
|
||||||
m_listCtrl->InsertColumn(2, itemCol);
|
m_listCtrl->InsertColumn(2, itemCol);
|
||||||
|
|
||||||
@@ -558,10 +558,6 @@ void MyFrame::InitWithReportItems()
|
|||||||
|
|
||||||
m_listCtrl->SetTextColour(*wxBLUE);
|
m_listCtrl->SetTextColour(*wxBLUE);
|
||||||
|
|
||||||
m_listCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE );
|
|
||||||
m_listCtrl->SetColumnWidth( 1, wxLIST_AUTOSIZE );
|
|
||||||
m_listCtrl->SetColumnWidth( 2, wxLIST_AUTOSIZE );
|
|
||||||
|
|
||||||
// Set images in columns
|
// Set images in columns
|
||||||
m_listCtrl->SetItemColumnImage(1, 1, 0);
|
m_listCtrl->SetItemColumnImage(1, 1, 0);
|
||||||
|
|
||||||
@@ -573,6 +569,10 @@ void MyFrame::InitWithReportItems()
|
|||||||
|
|
||||||
// test SetItemFont too
|
// test SetItemFont too
|
||||||
m_listCtrl->SetItemFont(0, *wxITALIC_FONT);
|
m_listCtrl->SetItemFont(0, *wxITALIC_FONT);
|
||||||
|
|
||||||
|
m_listCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE );
|
||||||
|
m_listCtrl->SetColumnWidth( 1, wxLIST_AUTOSIZE );
|
||||||
|
m_listCtrl->SetColumnWidth( 2, wxLIST_AUTOSIZE_USEHEADER );
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyFrame::InitWithIconItems(bool withText, bool sameIcon)
|
void MyFrame::InitWithIconItems(bool withText, bool sameIcon)
|
||||||
@@ -671,11 +671,11 @@ void MyFrame::InitWithVirtualItems()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_listCtrl->AppendColumn(wxT("First Column"));
|
m_listCtrl->AppendColumn(wxT("First Column (size auto)"));
|
||||||
m_listCtrl->AppendColumn(wxT("Second Column"));
|
m_listCtrl->AppendColumn(wxT("Second Column (150px)"));
|
||||||
m_listCtrl->SetColumnWidth(0, 150);
|
|
||||||
m_listCtrl->SetColumnWidth(1, 150);
|
|
||||||
m_listCtrl->SetItemCount(1000000);
|
m_listCtrl->SetItemCount(1000000);
|
||||||
|
m_listCtrl->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
|
||||||
|
m_listCtrl->SetColumnWidth(1, 150);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
#include "wx/imaglist.h"
|
#include "wx/imaglist.h"
|
||||||
#include "wx/renderer.h"
|
#include "wx/renderer.h"
|
||||||
#include "wx/generic/private/listctrl.h"
|
#include "wx/generic/private/listctrl.h"
|
||||||
|
#include "wx/generic/private/widthcalc.h"
|
||||||
|
|
||||||
#ifdef __WXMAC__
|
#ifdef __WXMAC__
|
||||||
#include "wx/osx/private.h"
|
#include "wx/osx/private.h"
|
||||||
@@ -3193,6 +3194,35 @@ void wxListMainWindow::SetColumn( int col, const wxListItem &item )
|
|||||||
m_headerWidth = 0;
|
m_headerWidth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class wxListCtrlMaxWidthCalculator : public wxMaxWidthCalculatorBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxListCtrlMaxWidthCalculator(wxListMainWindow *listmain, unsigned int column)
|
||||||
|
: wxMaxWidthCalculatorBase(column),
|
||||||
|
m_listmain(listmain)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void UpdateWithRow(int row) wxOVERRIDE
|
||||||
|
{
|
||||||
|
wxListLineData *line = m_listmain->GetLine( row );
|
||||||
|
wxListItemDataList::compatibility_iterator n = line->m_items.Item( GetColumn() );
|
||||||
|
|
||||||
|
wxCHECK_RET( n, wxS("no subitem?") );
|
||||||
|
|
||||||
|
wxListItemData* const itemData = n->GetData();
|
||||||
|
|
||||||
|
wxListItem item;
|
||||||
|
itemData->GetItem(item);
|
||||||
|
|
||||||
|
UpdateWithWidth(m_listmain->GetItemWidthWithImage(&item));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxListMainWindow* const m_listmain;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void wxListMainWindow::SetColumnWidth( int col, int width )
|
void wxListMainWindow::SetColumnWidth( int col, int width )
|
||||||
{
|
{
|
||||||
wxCHECK_RET( col >= 0 && col < GetColumnCount(),
|
wxCHECK_RET( col >= 0 && col < GetColumnCount(),
|
||||||
@@ -3214,48 +3244,42 @@ void wxListMainWindow::SetColumnWidth( int col, int width )
|
|||||||
|
|
||||||
size_t count = GetItemCount();
|
size_t count = GetItemCount();
|
||||||
|
|
||||||
|
if ( width == wxLIST_AUTOSIZE_USEHEADER || width == wxLIST_AUTOSIZE )
|
||||||
|
{
|
||||||
|
wxListCtrlMaxWidthCalculator calculator(this, col);
|
||||||
|
|
||||||
|
calculator.UpdateWithWidth(AUTOSIZE_COL_MARGIN);
|
||||||
|
|
||||||
if ( width == wxLIST_AUTOSIZE_USEHEADER )
|
if ( width == wxLIST_AUTOSIZE_USEHEADER )
|
||||||
{
|
calculator.UpdateWithWidth(ComputeMinHeaderWidth(column));
|
||||||
width = ComputeMinHeaderWidth(column);
|
|
||||||
}
|
|
||||||
else if ( width == wxLIST_AUTOSIZE )
|
|
||||||
{
|
|
||||||
width = ComputeMinHeaderWidth(column);
|
|
||||||
|
|
||||||
if ( !IsVirtual() )
|
|
||||||
{
|
|
||||||
wxClientDC dc(this);
|
|
||||||
dc.SetFont( GetFont() );
|
|
||||||
|
|
||||||
int max = AUTOSIZE_COL_MARGIN;
|
|
||||||
|
|
||||||
// if the cached column width isn't valid then recalculate it
|
// if the cached column width isn't valid then recalculate it
|
||||||
if (m_aColWidths.Item(col)->bNeedsUpdate)
|
wxColWidthInfo* const pWidthInfo = m_aColWidths.Item(col);
|
||||||
|
if ( pWidthInfo->bNeedsUpdate )
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < count; i++)
|
size_t first_visible, last_visible;
|
||||||
|
GetVisibleLinesRange(&first_visible, &last_visible);
|
||||||
|
|
||||||
|
calculator.ComputeBestColumnWidth(count, first_visible, last_visible);
|
||||||
|
pWidthInfo->nMaxWidth = calculator.GetMaxWidth();
|
||||||
|
pWidthInfo->bNeedsUpdate = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
wxListLineData *line = GetLine( i );
|
calculator.UpdateWithWidth(pWidthInfo->nMaxWidth);
|
||||||
wxListItemDataList::compatibility_iterator n = line->m_items.Item( col );
|
|
||||||
|
|
||||||
wxCHECK_RET( n, wxT("no subitem?") );
|
|
||||||
|
|
||||||
wxListItemData *itemData = n->GetData();
|
|
||||||
wxListItem item;
|
|
||||||
|
|
||||||
itemData->GetItem(item);
|
|
||||||
int itemWidth = GetItemWidthWithImage(&item);
|
|
||||||
if (itemWidth > max)
|
|
||||||
max = itemWidth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_aColWidths.Item(col)->bNeedsUpdate = false;
|
// expand the last column to fit the client size
|
||||||
m_aColWidths.Item(col)->nMaxWidth = max;
|
// only for AUTOSIZE_USEHEADER to mimic MSW behaviour
|
||||||
|
int margin = 0;
|
||||||
|
if ( (width == wxLIST_AUTOSIZE_USEHEADER) && (col == GetColumnCount() - 1) )
|
||||||
|
{
|
||||||
|
margin = GetClientSize().GetX();
|
||||||
|
for ( int i = 0; i < col && margin > 0; ++i )
|
||||||
|
margin -= m_columns.Item(i)->GetData()->GetWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
max = m_aColWidths.Item(col)->nMaxWidth + AUTOSIZE_COL_MARGIN;
|
width = wxMax(margin, calculator.GetMaxWidth() + AUTOSIZE_COL_MARGIN);
|
||||||
if ( width < max )
|
|
||||||
width = max;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
column->SetWidth( width );
|
column->SetWidth( width );
|
||||||
@@ -3322,8 +3346,12 @@ void wxListMainWindow::SetItem( wxListItem &item )
|
|||||||
// update the Max Width Cache if needed
|
// update the Max Width Cache if needed
|
||||||
int width = GetItemWidthWithImage(&item);
|
int width = GetItemWidthWithImage(&item);
|
||||||
|
|
||||||
if (width > m_aColWidths.Item(item.m_col)->nMaxWidth)
|
wxColWidthInfo* const pWidthInfo = m_aColWidths.Item(item.m_col);
|
||||||
m_aColWidths.Item(item.m_col)->nMaxWidth = width;
|
if ( width > pWidthInfo->nMaxWidth )
|
||||||
|
{
|
||||||
|
pWidthInfo->nMaxWidth = width;
|
||||||
|
pWidthInfo->bNeedsUpdate = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3966,8 +3994,9 @@ void wxListMainWindow::DeleteItem( long lindex )
|
|||||||
|
|
||||||
itemWidth = GetItemWidthWithImage(&item);
|
itemWidth = GetItemWidthWithImage(&item);
|
||||||
|
|
||||||
if (itemWidth >= m_aColWidths.Item(i)->nMaxWidth)
|
wxColWidthInfo *pWidthInfo = m_aColWidths.Item(i);
|
||||||
m_aColWidths.Item(i)->bNeedsUpdate = true;
|
if ( itemWidth >= pWidthInfo->nMaxWidth )
|
||||||
|
pWidthInfo->bNeedsUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetVisibleLinesRange();
|
ResetVisibleLinesRange();
|
||||||
@@ -4040,6 +4069,13 @@ void wxListMainWindow::DeleteColumn( int col )
|
|||||||
|
|
||||||
void wxListMainWindow::DoDeleteAllItems()
|
void wxListMainWindow::DoDeleteAllItems()
|
||||||
{
|
{
|
||||||
|
// We will need to update all columns if any items are inserted again.
|
||||||
|
if ( InReportView() )
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < m_aColWidths.GetCount(); i++ )
|
||||||
|
m_aColWidths.Item(i)->bNeedsUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
if ( IsEmpty() )
|
if ( IsEmpty() )
|
||||||
// nothing to do - in particular, don't send the event
|
// nothing to do - in particular, don't send the event
|
||||||
return;
|
return;
|
||||||
@@ -4062,13 +4098,7 @@ void wxListMainWindow::DoDeleteAllItems()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( InReportView() )
|
if ( InReportView() )
|
||||||
{
|
|
||||||
ResetVisibleLinesRange();
|
ResetVisibleLinesRange();
|
||||||
for (size_t i = 0; i < m_aColWidths.GetCount(); i++)
|
|
||||||
{
|
|
||||||
m_aColWidths.Item(i)->bNeedsUpdate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_lines.Clear();
|
m_lines.Clear();
|
||||||
}
|
}
|
||||||
@@ -4232,7 +4262,10 @@ void wxListMainWindow::InsertItem( wxListItem &item )
|
|||||||
int width = GetItemWidthWithImage(&item);
|
int width = GetItemWidthWithImage(&item);
|
||||||
item.SetWidth(width);
|
item.SetWidth(width);
|
||||||
if (width > pWidthInfo->nMaxWidth)
|
if (width > pWidthInfo->nMaxWidth)
|
||||||
|
{
|
||||||
pWidthInfo->nMaxWidth = width;
|
pWidthInfo->nMaxWidth = width;
|
||||||
|
pWidthInfo->bNeedsUpdate = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxListLineData *line = new wxListLineData(this);
|
wxListLineData *line = new wxListLineData(this);
|
||||||
@@ -4278,7 +4311,7 @@ long wxListMainWindow::InsertColumn( long col, const wxListItem &item )
|
|||||||
if (item.m_width == wxLIST_AUTOSIZE_USEHEADER)
|
if (item.m_width == wxLIST_AUTOSIZE_USEHEADER)
|
||||||
column->SetWidth(ComputeMinHeaderWidth(column));
|
column->SetWidth(ComputeMinHeaderWidth(column));
|
||||||
|
|
||||||
wxColWidthInfo *colWidthInfo = new wxColWidthInfo();
|
wxColWidthInfo *colWidthInfo = new wxColWidthInfo(0, IsVirtual());
|
||||||
|
|
||||||
bool insert = (col >= 0) && ((size_t)col < m_columns.GetCount());
|
bool insert = (col >= 0) && ((size_t)col < m_columns.GetCount());
|
||||||
if ( insert )
|
if ( insert )
|
||||||
|
Reference in New Issue
Block a user