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).
|
||||
- Fix handling of fast consecutive clicks in wxRibbonBar (atobi).
|
||||
- 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 wxPixelData<wxImage>::Offset() for alpha (Markus Rollmann).
|
||||
- Fix bug in wxImage::ClearAlpha() for shared data (Markus Rollmann).
|
||||
|
@@ -863,6 +863,7 @@ private:
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
friend class wxGenericListCtrl;
|
||||
friend class wxListCtrlMaxWidthCalculator;
|
||||
};
|
||||
|
||||
#endif // wxUSE_LISTCTRL
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "wx/defs.h"
|
||||
|
||||
#if wxUSE_DATAVIEWCTRL
|
||||
#if wxUSE_DATAVIEWCTRL || wxUSE_LISTCTRL
|
||||
|
||||
#include "wx/timer.h"
|
||||
|
||||
@@ -117,6 +117,6 @@ private:
|
||||
wxDECLARE_NO_COPY_CLASS(wxMaxWidthCalculatorBase);
|
||||
};
|
||||
|
||||
#endif // wxUSE_DATAVIEWCTRL
|
||||
#endif // wxUSE_DATAVIEWCTRL || wxUSE_LISTCTRL
|
||||
|
||||
#endif // _WX_GENERIC_PRIVATE_WIDTHCALC_H_
|
||||
|
@@ -519,11 +519,11 @@ void MyFrame::InitWithReportItems()
|
||||
itemCol.SetImage(-1);
|
||||
m_listCtrl->InsertColumn(0, itemCol);
|
||||
|
||||
itemCol.SetText(wxT("Column 2"));
|
||||
itemCol.SetText(wxT("Column 2 (auto size excluding header)"));
|
||||
itemCol.SetAlign(wxLIST_FORMAT_CENTRE);
|
||||
m_listCtrl->InsertColumn(1, itemCol);
|
||||
|
||||
itemCol.SetText(wxT("Column 3"));
|
||||
itemCol.SetText(wxT("Column 3 (auto size including header)"));
|
||||
itemCol.SetAlign(wxLIST_FORMAT_RIGHT);
|
||||
m_listCtrl->InsertColumn(2, itemCol);
|
||||
|
||||
@@ -558,10 +558,6 @@ void MyFrame::InitWithReportItems()
|
||||
|
||||
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
|
||||
m_listCtrl->SetItemColumnImage(1, 1, 0);
|
||||
|
||||
@@ -573,6 +569,10 @@ void MyFrame::InitWithReportItems()
|
||||
|
||||
// test SetItemFont too
|
||||
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)
|
||||
@@ -671,11 +671,11 @@ void MyFrame::InitWithVirtualItems()
|
||||
}
|
||||
else
|
||||
{
|
||||
m_listCtrl->AppendColumn(wxT("First Column"));
|
||||
m_listCtrl->AppendColumn(wxT("Second Column"));
|
||||
m_listCtrl->SetColumnWidth(0, 150);
|
||||
m_listCtrl->SetColumnWidth(1, 150);
|
||||
m_listCtrl->AppendColumn(wxT("First Column (size auto)"));
|
||||
m_listCtrl->AppendColumn(wxT("Second Column (150px)"));
|
||||
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/renderer.h"
|
||||
#include "wx/generic/private/listctrl.h"
|
||||
#include "wx/generic/private/widthcalc.h"
|
||||
|
||||
#ifdef __WXMAC__
|
||||
#include "wx/osx/private.h"
|
||||
@@ -3193,6 +3194,35 @@ void wxListMainWindow::SetColumn( int col, const wxListItem &item )
|
||||
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 )
|
||||
{
|
||||
wxCHECK_RET( col >= 0 && col < GetColumnCount(),
|
||||
@@ -3214,48 +3244,42 @@ void wxListMainWindow::SetColumnWidth( int col, int width )
|
||||
|
||||
size_t count = GetItemCount();
|
||||
|
||||
if (width == wxLIST_AUTOSIZE_USEHEADER)
|
||||
if ( width == wxLIST_AUTOSIZE_USEHEADER || width == wxLIST_AUTOSIZE )
|
||||
{
|
||||
width = ComputeMinHeaderWidth(column);
|
||||
}
|
||||
else if ( width == wxLIST_AUTOSIZE )
|
||||
{
|
||||
width = ComputeMinHeaderWidth(column);
|
||||
wxListCtrlMaxWidthCalculator calculator(this, col);
|
||||
|
||||
if ( !IsVirtual() )
|
||||
calculator.UpdateWithWidth(AUTOSIZE_COL_MARGIN);
|
||||
|
||||
if ( width == wxLIST_AUTOSIZE_USEHEADER )
|
||||
calculator.UpdateWithWidth(ComputeMinHeaderWidth(column));
|
||||
|
||||
// if the cached column width isn't valid then recalculate it
|
||||
wxColWidthInfo* const pWidthInfo = m_aColWidths.Item(col);
|
||||
if ( pWidthInfo->bNeedsUpdate )
|
||||
{
|
||||
wxClientDC dc(this);
|
||||
dc.SetFont( GetFont() );
|
||||
size_t first_visible, last_visible;
|
||||
GetVisibleLinesRange(&first_visible, &last_visible);
|
||||
|
||||
int max = AUTOSIZE_COL_MARGIN;
|
||||
|
||||
// if the cached column width isn't valid then recalculate it
|
||||
if (m_aColWidths.Item(col)->bNeedsUpdate)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
wxListLineData *line = GetLine( i );
|
||||
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;
|
||||
m_aColWidths.Item(col)->nMaxWidth = max;
|
||||
}
|
||||
|
||||
max = m_aColWidths.Item(col)->nMaxWidth + AUTOSIZE_COL_MARGIN;
|
||||
if ( width < max )
|
||||
width = max;
|
||||
calculator.ComputeBestColumnWidth(count, first_visible, last_visible);
|
||||
pWidthInfo->nMaxWidth = calculator.GetMaxWidth();
|
||||
pWidthInfo->bNeedsUpdate = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
calculator.UpdateWithWidth(pWidthInfo->nMaxWidth);
|
||||
}
|
||||
|
||||
// expand the last column to fit the client size
|
||||
// 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();
|
||||
}
|
||||
|
||||
width = wxMax(margin, calculator.GetMaxWidth() + AUTOSIZE_COL_MARGIN);
|
||||
}
|
||||
|
||||
column->SetWidth( width );
|
||||
@@ -3322,8 +3346,12 @@ void wxListMainWindow::SetItem( wxListItem &item )
|
||||
// update the Max Width Cache if needed
|
||||
int width = GetItemWidthWithImage(&item);
|
||||
|
||||
if (width > m_aColWidths.Item(item.m_col)->nMaxWidth)
|
||||
m_aColWidths.Item(item.m_col)->nMaxWidth = width;
|
||||
wxColWidthInfo* const pWidthInfo = m_aColWidths.Item(item.m_col);
|
||||
if ( width > pWidthInfo->nMaxWidth )
|
||||
{
|
||||
pWidthInfo->nMaxWidth = width;
|
||||
pWidthInfo->bNeedsUpdate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3966,8 +3994,9 @@ void wxListMainWindow::DeleteItem( long lindex )
|
||||
|
||||
itemWidth = GetItemWidthWithImage(&item);
|
||||
|
||||
if (itemWidth >= m_aColWidths.Item(i)->nMaxWidth)
|
||||
m_aColWidths.Item(i)->bNeedsUpdate = true;
|
||||
wxColWidthInfo *pWidthInfo = m_aColWidths.Item(i);
|
||||
if ( itemWidth >= pWidthInfo->nMaxWidth )
|
||||
pWidthInfo->bNeedsUpdate = true;
|
||||
}
|
||||
|
||||
ResetVisibleLinesRange();
|
||||
@@ -4040,6 +4069,13 @@ void wxListMainWindow::DeleteColumn( int col )
|
||||
|
||||
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() )
|
||||
// nothing to do - in particular, don't send the event
|
||||
return;
|
||||
@@ -4062,13 +4098,7 @@ void wxListMainWindow::DoDeleteAllItems()
|
||||
}
|
||||
|
||||
if ( InReportView() )
|
||||
{
|
||||
ResetVisibleLinesRange();
|
||||
for (size_t i = 0; i < m_aColWidths.GetCount(); i++)
|
||||
{
|
||||
m_aColWidths.Item(i)->bNeedsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
m_lines.Clear();
|
||||
}
|
||||
@@ -4232,7 +4262,10 @@ void wxListMainWindow::InsertItem( wxListItem &item )
|
||||
int width = GetItemWidthWithImage(&item);
|
||||
item.SetWidth(width);
|
||||
if (width > pWidthInfo->nMaxWidth)
|
||||
{
|
||||
pWidthInfo->nMaxWidth = width;
|
||||
pWidthInfo->bNeedsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
wxListLineData *line = new wxListLineData(this);
|
||||
@@ -4278,7 +4311,7 @@ long wxListMainWindow::InsertColumn( long col, const wxListItem &item )
|
||||
if (item.m_width == wxLIST_AUTOSIZE_USEHEADER)
|
||||
column->SetWidth(ComputeMinHeaderWidth(column));
|
||||
|
||||
wxColWidthInfo *colWidthInfo = new wxColWidthInfo();
|
||||
wxColWidthInfo *colWidthInfo = new wxColWidthInfo(0, IsVirtual());
|
||||
|
||||
bool insert = (col >= 0) && ((size_t)col < m_columns.GetCount());
|
||||
if ( insert )
|
||||
|
Reference in New Issue
Block a user