Merge branch 'generic-listctrl-improv'

Fix margins in generic wxListCtrl and modernize its code.

See #23156.
This commit is contained in:
Vadim Zeitlin 2023-01-19 21:48:51 +01:00
commit 38bc9c2a8d
2 changed files with 153 additions and 263 deletions

View file

@ -19,6 +19,8 @@
#include "wx/timer.h"
#include "wx/settings.h"
#include <memory>
// ============================================================================
// private classes
// ============================================================================
@ -40,7 +42,7 @@ struct wxColWidthInfo
}
};
WX_DEFINE_ARRAY_PTR(wxColWidthInfo *, ColWidthArray);
using ColWidthArray = std::vector<wxColWidthInfo>;
//-----------------------------------------------------------------------------
// wxListItemData (internal)
@ -50,6 +52,10 @@ class wxListItemData
{
public:
wxListItemData(wxListMainWindow *owner);
wxListItemData(const wxListItemData&) = delete;
wxListItemData(wxListItemData&&);
wxListItemData& operator=(const wxListItemData&) = delete;
wxListItemData& operator=(wxListItemData&&);
~wxListItemData();
void SetItem( const wxListItem &info );
@ -90,25 +96,22 @@ public:
public:
// the item image or -1
int m_image;
int m_image = -1;
// user data associated with the item
wxUIntPtr m_data;
wxUIntPtr m_data = 0;
// the item coordinates are not used in report mode; instead this pointer is
// null and the owner window is used to retrieve the item position and size
wxRect *m_rect;
wxRect *m_rect = nullptr;
// the list ctrl we are in
wxListMainWindow *m_owner;
// custom attributes or nullptr
wxItemAttr *m_attr;
wxItemAttr *m_attr = nullptr;
protected:
// common part of all ctors
void Init();
wxString m_text;
};
@ -133,7 +136,7 @@ public:
const wxString& GetText() const { return m_text; }
void SetText(const wxString& text) { m_text = text; }
void GetItem( wxListItem &item );
void GetItem( wxListItem &item ) const;
bool IsHit( int x, int y ) const;
int GetImage() const;
@ -160,13 +163,11 @@ private:
// wxListLineData (internal)
//-----------------------------------------------------------------------------
WX_DECLARE_LIST(wxListItemData, wxListItemDataList);
class wxListLineData
{
public:
// the list of subitems: only may have more than one item in report mode
wxListItemDataList m_items;
std::vector<wxListItemData> m_items;
// this is not used in report view
struct GeometryInfo
@ -194,8 +195,9 @@ public:
m_rectIcon.x += (w - m_rectIcon.width) / 2;
m_rectHighlight.x += (w - m_rectHighlight.width) / 2;
}
}
*m_gi;
};
std::unique_ptr<GeometryInfo> m_gi;
// is this item selected? [NB: not used in virtual mode]
bool m_highlighted;
@ -207,26 +209,19 @@ public:
public:
wxListLineData(wxListMainWindow *owner);
wxListLineData(const wxListLineData&) = delete;
wxListLineData(wxListLineData&& other) = default;
~wxListLineData()
{
WX_CLEAR_LIST(wxListItemDataList, m_items);
delete m_gi;
}
wxListLineData& operator=(const wxListLineData&) = delete;
wxListLineData& operator=(wxListLineData&&) = default;
~wxListLineData() = default;
// called by the owner when it toggles report view
void SetReportView(bool inReportView)
{
// we only need m_gi when we're not in report view so update as needed
if ( inReportView )
{
delete m_gi;
m_gi = nullptr;
}
else
{
m_gi = new GeometryInfo;
}
m_gi.reset( inReportView ? nullptr : new GeometryInfo );
}
// are we in report mode?
@ -313,19 +308,6 @@ private:
int width);
};
class wxListLineDataArray : public wxVector<wxListLineData*>
{
public:
void Clear()
{
for ( size_t n = 0; n < size(); ++n )
delete (*this)[n];
clear();
}
~wxListLineDataArray() { Clear(); }
};
//-----------------------------------------------------------------------------
// wxListHeaderWindow (internal)
//-----------------------------------------------------------------------------
@ -486,8 +468,6 @@ private:
// wxListMainWindow (internal)
//-----------------------------------------------------------------------------
WX_DECLARE_LIST(wxListHeaderData, wxListHeaderDataList);
class wxListMainWindow : public wxWindow
{
public:
@ -648,7 +628,7 @@ public:
void SetColumnWidth( int col, int width );
void GetColumn( int col, wxListItem &item ) const;
int GetColumnWidth( int col ) const;
int GetColumnCount() const { return m_columns.GetCount(); }
int GetColumnCount() const { return m_columns.size(); }
// returns the sum of the heights of all columns
int GetHeaderWidth() const;
@ -792,10 +772,10 @@ public:
protected:
// the array of all line objects for a non virtual list control (for the
// virtual list control we only ever use m_lines[0])
wxListLineDataArray m_lines;
std::vector<wxListLineData> m_lines;
// the list of column objects
wxListHeaderDataList m_columns;
std::vector<wxListHeaderData> m_columns;
// currently focused item or -1
size_t m_current;
@ -867,13 +847,15 @@ protected:
{
wxASSERT_MSG( n != (size_t)-1, wxT("invalid line index") );
wxListMainWindow *self = wxConstCast(this, wxListMainWindow);
if ( IsVirtual() )
{
wxConstCast(this, wxListMainWindow)->CacheLineData(n);
self->CacheLineData(n);
n = 0;
}
return m_lines[n];
return &self->m_lines[n];
}
// get a dummy line which can be used for geometry calculations and such:

View file

@ -63,30 +63,14 @@ static const int SCROLL_UNIT_X = 15;
static const int LINE_SPACING = 0;
// extra margins around the text label
#ifdef __WXGTK__
static const int EXTRA_WIDTH = 6;
#else
static const int EXTRA_WIDTH = 4;
#endif
#ifdef __WXGTK__
static const int EXTRA_HEIGHT = 6;
#else
static const int EXTRA_HEIGHT = 4;
#endif
// margin between the window and the items
static const int EXTRA_BORDER_X = 2;
static const int EXTRA_BORDER_Y = 2;
#ifdef __WXGTK__
// This probably needs to be done
// on all platforms as the icons
// otherwise nearly touch the border
static const int ICON_OFFSET_X = 2;
#else
static const int ICON_OFFSET_X = 0;
#endif
static const int ICON_OFFSET_X = 2;
// offset for the header window
static const int HEADER_OFFSET_X = 0;
@ -107,22 +91,32 @@ static const int HEADER_IMAGE_MARGIN_IN_REPORT_MODE = 2;
// space after a checkbox
static const int MARGIN_AROUND_CHECKBOX = 5;
// ----------------------------------------------------------------------------
// arrays/list implementations
// ----------------------------------------------------------------------------
#include "wx/listimpl.cpp"
WX_DEFINE_LIST(wxListItemDataList)
#include "wx/listimpl.cpp"
WX_DEFINE_LIST(wxListHeaderDataList)
// ----------------------------------------------------------------------------
// wxListItemData
// ----------------------------------------------------------------------------
wxListItemData::wxListItemData(wxListItemData&& other)
{
m_owner = other.m_owner;
// Take ownership of the pointers from the other object and reset them.
std::swap(m_attr, other.m_attr);
std::swap(m_rect, other.m_rect);
}
wxListItemData& wxListItemData::operator=(wxListItemData&& other)
{
m_image = other.m_image;
m_data = other.m_data;
m_owner = other.m_owner;
// Swap them to let our pointers be deleted by the other object if necessary.
std::swap(m_attr, other.m_attr);
std::swap(m_rect, other.m_rect);
return *this;
}
wxListItemData::~wxListItemData()
{
// in the virtual list control the attributes are managed by the main
@ -133,23 +127,11 @@ wxListItemData::~wxListItemData()
delete m_rect;
}
void wxListItemData::Init()
{
m_image = -1;
m_data = 0;
m_attr = nullptr;
}
wxListItemData::wxListItemData(wxListMainWindow *owner)
{
Init();
m_owner = owner;
if ( owner->InReportView() )
m_rect = nullptr;
else
if ( !owner->InReportView() )
m_rect = new wxRect;
}
@ -363,7 +345,7 @@ bool wxListHeaderData::IsHit( int x, int y ) const
return ((x >= m_xpos) && (x <= m_xpos+m_width) && (y >= m_ypos) && (y <= m_ypos+m_height));
}
void wxListHeaderData::GetItem( wxListItem& item )
void wxListHeaderData::GetItem( wxListItem& item ) const
{
long mask = item.m_mask;
if ( !mask )
@ -427,10 +409,7 @@ wxListLineData::wxListLineData( wxListMainWindow *owner )
{
m_owner = owner;
if ( InReportView() )
m_gi = nullptr;
else // !report
m_gi = new GeometryInfo;
SetReportView(InReportView());
m_highlighted = false;
m_checked = false;
@ -440,10 +419,9 @@ wxListLineData::wxListLineData( wxListMainWindow *owner )
void wxListLineData::CalculateSize( wxDC *dc, int spacing )
{
wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
wxCHECK_RET( node, wxT("no subitems at all??") );
wxCHECK_RET( !m_items.empty(), wxT("no subitems at all??") );
wxListItemData *item = node->GetData();
wxListItemData* const item = &m_items[0];
wxString s;
wxCoord lw, lh;
@ -542,10 +520,9 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing )
void wxListLineData::SetPosition( int x, int y, int spacing )
{
wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
wxCHECK_RET( node, wxT("no subitems at all??") );
wxCHECK_RET( !m_items.empty(), wxT("no subitems at all??") );
wxListItemData *item = node->GetData();
wxListItemData* const item = &m_items[0];
switch ( GetMode() )
{
@ -610,86 +587,47 @@ void wxListLineData::SetPosition( int x, int y, int spacing )
void wxListLineData::InitItems( int num )
{
for (int i = 0; i < num; i++)
m_items.Append( new wxListItemData(m_owner) );
m_items.emplace_back( m_owner );
}
void wxListLineData::SetItem( int index, const wxListItem &info )
{
wxListItemDataList::compatibility_iterator node = m_items.Item( index );
wxCHECK_RET( node, wxT("invalid column index in SetItem") );
wxListItemData *item = node->GetData();
item->SetItem( info );
m_items.at(index).SetItem( info );
}
void wxListLineData::GetItem( int index, wxListItem &info ) const
{
wxListItemDataList::compatibility_iterator node = m_items.Item( index );
if (node)
{
wxListItemData *item = node->GetData();
item->GetItem( info );
}
m_items.at(index).GetItem( info );
}
wxString wxListLineData::GetText(int index) const
{
wxString s;
wxListItemDataList::compatibility_iterator node = m_items.Item( index );
if (node)
{
wxListItemData *item = node->GetData();
s = item->GetText();
}
return s;
return m_items.at(index).GetText();
}
void wxListLineData::SetText( int index, const wxString& s )
{
wxListItemDataList::compatibility_iterator node = m_items.Item( index );
if (node)
{
wxListItemData *item = node->GetData();
item->SetText( s );
}
m_items.at(index).SetText(s);
}
void wxListLineData::SetImage( int index, int image )
{
wxListItemDataList::compatibility_iterator node = m_items.Item( index );
wxCHECK_RET( node, wxT("invalid column index in SetImage()") );
wxListItemData *item = node->GetData();
item->SetImage(image);
m_items.at(index).SetImage(image);
}
int wxListLineData::GetImage( int index ) const
{
wxListItemDataList::compatibility_iterator node = m_items.Item( index );
wxCHECK_MSG( node, -1, wxT("invalid column index in GetImage()") );
wxListItemData *item = node->GetData();
return item->GetImage();
return m_items.at(index).GetImage();
}
wxItemAttr *wxListLineData::GetAttr() const
{
wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
wxCHECK_MSG( node, nullptr, wxT("invalid column index in GetAttr()") );
wxListItemData *item = node->GetData();
return item->GetAttr();
return m_items.at(0).GetAttr();
}
void wxListLineData::SetAttr(wxItemAttr *attr)
{
wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
wxCHECK_RET( node, wxT("invalid column index in SetAttr()") );
wxListItemData *item = node->GetData();
item->SetAttr(attr);
m_items.at(0).SetAttr(attr);
}
void wxListLineData::ApplyAttributes(wxDC *dc,
@ -772,12 +710,11 @@ void wxListLineData::ApplyAttributes(wxDC *dc,
void wxListLineData::Draw(wxDC *dc, bool current)
{
wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
wxCHECK_RET( node, wxT("no subitems at all??") );
wxCHECK_RET( !m_items.empty(), wxT("no subitems at all??") );
ApplyAttributes(dc, m_gi->m_rectHighlight, IsHighlighted(), current);
wxListItemData *item = node->GetData();
wxListItemData* const item = &m_items[0];
if (item->HasImage())
{
// centre the image inside our rectangle, this looks nicer when items
@ -829,12 +766,8 @@ void wxListLineData::DrawInReportMode( wxDC *dc,
}
size_t col = 0;
for ( wxListItemDataList::compatibility_iterator node = m_items.GetFirst();
node;
node = node->GetNext(), col++ )
for ( const auto& item : m_items )
{
wxListItemData *item = node->GetData();
int width = m_owner->GetColumnWidth(col);
if (col == 0 && m_owner->HasCheckBoxes())
width -= x;
@ -845,11 +778,11 @@ void wxListLineData::DrawInReportMode( wxDC *dc,
const int wText = width;
wxDCClipper clipper(*dc, xOld, rect.y, wText, rect.height);
if ( item->HasImage() )
if ( item.HasImage() )
{
int ix, iy;
m_owner->GetImageSize( item->GetImage(), ix, iy );
m_owner->DrawImage( item->GetImage(), dc, xOld, yMid - iy/2 );
m_owner->GetImageSize( item.GetImage(), ix, iy );
m_owner->DrawImage( item.GetImage(), dc, xOld, yMid - iy/2 );
ix += IMAGE_MARGIN_IN_REPORT_MODE;
@ -857,8 +790,10 @@ void wxListLineData::DrawInReportMode( wxDC *dc,
width -= ix;
}
if ( item->HasText() )
DrawTextFormatted(dc, item->GetText(), col, xOld, yMid, width);
if ( item.HasText() )
DrawTextFormatted(dc, item.GetText(), col, xOld, yMid, width);
++col;
}
}
@ -1667,8 +1602,6 @@ wxListMainWindow::~wxListMainWindow()
m_textctrlWrapper->EndEdit(wxListTextCtrlWrapper::End_Destroy);
DoDeleteAllItems();
WX_CLEAR_LIST(wxListHeaderDataList, m_columns);
WX_CLEAR_ARRAY(m_aColWidths);
delete m_highlightBrush;
delete m_highlightUnfocusedBrush;
@ -1678,10 +1611,9 @@ wxListMainWindow::~wxListMainWindow()
void wxListMainWindow::SetReportView(bool inReportView)
{
const size_t count = m_lines.size();
for ( size_t n = 0; n < count; n++ )
for ( auto& line : m_lines )
{
m_lines[n]->SetReportView(inReportView);
line.SetReportView(inReportView);
}
}
@ -1717,22 +1649,21 @@ wxListLineData *wxListMainWindow::GetDummyLine() const
// control changed as it would have the incorrect number of fields
// otherwise
if ( !m_lines.empty() &&
m_lines[0]->m_items.GetCount() != (size_t)GetColumnCount() )
m_lines[0].m_items.size() != (size_t)GetColumnCount() )
{
self->m_lines.Clear();
self->m_lines.clear();
}
if ( m_lines.empty() )
{
wxListLineData *line = new wxListLineData(self);
self->m_lines.push_back(line);
self->m_lines.emplace_back(self);
// don't waste extra memory -- there never going to be anything
// else/more in this array
self->m_lines.shrink_to_fit();
}
return m_lines[0];
return &self->m_lines[0];
}
// ----------------------------------------------------------------------------
@ -1794,10 +1725,9 @@ wxRect wxListMainWindow::GetLineLabelRect(size_t line) const
int image_x = 0;
wxListLineData *data = GetLine(line);
wxListItemDataList::compatibility_iterator node = data->m_items.GetFirst();
if (node)
if ( !data->m_items.empty() )
{
wxListItemData *item = node->GetData();
wxListItemData *item = &data->m_items[0];
if ( item->HasImage() )
{
int ix, iy;
@ -3412,11 +3342,10 @@ wxListMainWindow::ComputeMinHeaderWidth(const wxListHeaderData* column) const
void wxListMainWindow::SetColumn( int col, const wxListItem &item )
{
wxListHeaderDataList::compatibility_iterator node = m_columns.Item( col );
wxCHECK_RET( col >= 0 && col < (int)m_columns.size(),
"invalid column index in SetColumn" );
wxCHECK_RET( node, wxT("invalid column index in SetColumn") );
wxListHeaderData *column = node->GetData();
wxListHeaderData* const column = &m_columns[col];
column->SetItem( item );
if ( item.m_width == wxLIST_AUTOSIZE_USEHEADER )
@ -3444,14 +3373,9 @@ public:
virtual void UpdateWithRow(int row) override
{
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);
line->m_items.at(GetColumn()).GetItem(item);
UpdateWithWidth(m_listmain->GetItemWidthWithImage(&item));
}
@ -3475,10 +3399,10 @@ void wxListMainWindow::SetColumnWidth( int col, int width )
if ( headerWin )
headerWin->m_dirty = true;
wxListHeaderDataList::compatibility_iterator node = m_columns.Item( col );
wxCHECK_RET( node, wxT("no column?") );
wxCHECK_RET( col >= 0 && col < (int)m_columns.size(),
"invalid column index in SetColumnWidth" );
wxListHeaderData *column = node->GetData();
wxListHeaderData* const column = &m_columns[col];
if ( width == wxLIST_AUTOSIZE_USEHEADER || width == wxLIST_AUTOSIZE )
{
@ -3490,20 +3414,20 @@ void wxListMainWindow::SetColumnWidth( int col, int width )
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 )
wxColWidthInfo& widthInfo = m_aColWidths[col];
if ( widthInfo.bNeedsUpdate )
{
size_t first_visible, last_visible;
GetVisibleLinesRange(&first_visible, &last_visible);
calculator.ComputeBestColumnWidth(GetItemCount(),
first_visible, last_visible);
pWidthInfo->nMaxWidth = calculator.GetMaxWidth();
pWidthInfo->bNeedsUpdate = false;
widthInfo.nMaxWidth = calculator.GetMaxWidth();
widthInfo.bNeedsUpdate = false;
}
else
{
calculator.UpdateWithWidth(pWidthInfo->nMaxWidth);
calculator.UpdateWithWidth(widthInfo.nMaxWidth);
}
width = calculator.GetMaxWidth() + AUTOSIZE_COL_MARGIN;
@ -3521,7 +3445,7 @@ void wxListMainWindow::SetColumnWidth( int col, int width )
{
int margin = GetClientSize().GetX();
for ( int i = 0; i < col && margin > 0; ++i )
margin -= m_columns.Item(i)->GetData()->GetWidth();
margin -= m_columns.at(i).GetWidth();
if ( margin > width )
width = margin;
@ -3552,20 +3476,18 @@ int wxListMainWindow::GetHeaderWidth() const
void wxListMainWindow::GetColumn( int col, wxListItem &item ) const
{
wxListHeaderDataList::compatibility_iterator node = m_columns.Item( col );
wxCHECK_RET( node, wxT("invalid column index in GetColumn") );
wxCHECK_RET( col >= 0 && col < (int)m_columns.size(),
"invalid column index in GetColumn" );
wxListHeaderData *column = node->GetData();
column->GetItem( item );
m_columns[col].GetItem( item );
}
int wxListMainWindow::GetColumnWidth( int col ) const
{
wxListHeaderDataList::compatibility_iterator node = m_columns.Item( col );
wxCHECK_MSG( node, 0, wxT("invalid column index") );
wxCHECK_MSG( col >= 0 && col < (int)m_columns.size(), 0,
"invalid column index in GetColumnWidth" );
wxListHeaderData *column = node->GetData();
return column->GetWidth();
return m_columns[col].GetWidth();
}
// ----------------------------------------------------------------------------
@ -3592,11 +3514,11 @@ void wxListMainWindow::SetItem( wxListItem &item )
// update the Max Width Cache if needed
int width = GetItemWidthWithImage(&item);
wxColWidthInfo* const pWidthInfo = m_aColWidths.Item(item.m_col);
if ( width > pWidthInfo->nMaxWidth )
wxColWidthInfo& widthInfo = m_aColWidths.at(item.m_col);
if ( width > widthInfo.nMaxWidth )
{
pWidthInfo->nMaxWidth = width;
pWidthInfo->bNeedsUpdate = true;
widthInfo.nMaxWidth = width;
widthInfo.bNeedsUpdate = true;
}
}
}
@ -4316,22 +4238,19 @@ void wxListMainWindow::DeleteItem( long lindex )
// mark the Column Max Width cache as dirty if the items in the line
// we're deleting contain the Max Column Width
wxListLineData * const line = GetLine(index);
wxListItemDataList::compatibility_iterator n;
wxListItem item;
for (size_t i = 0; i < m_columns.GetCount(); i++)
size_t i = 0;
for ( const auto& it : line->m_items )
{
n = line->m_items.Item( i );
wxListItemData* itemData;
itemData = n->GetData();
itemData->GetItem(item);
it.GetItem(item);
int itemWidth;
itemWidth = GetItemWidthWithImage(&item);
wxColWidthInfo *pWidthInfo = m_aColWidths.Item(i);
if ( itemWidth >= pWidthInfo->nMaxWidth )
pWidthInfo->bNeedsUpdate = true;
wxColWidthInfo& widthInfo = m_aColWidths.at(i++);
if ( itemWidth >= widthInfo.nMaxWidth )
widthInfo.bNeedsUpdate = true;
}
ResetVisibleLinesRange();
@ -4346,7 +4265,6 @@ void wxListMainWindow::DeleteItem( long lindex )
}
else
{
delete m_lines[index];
m_lines.erase( m_lines.begin() + index );
}
@ -4365,21 +4283,17 @@ void wxListMainWindow::DeleteItem( long lindex )
void wxListMainWindow::DeleteColumn( int col )
{
wxListHeaderDataList::compatibility_iterator node = m_columns.Item( col );
wxCHECK_RET( node, wxT("invalid column index in DeleteColumn()") );
wxCHECK_RET( col >= 0 && col < (int)m_columns.size(),
"invalid column index in DeleteColumn()" );
m_dirty = true;
delete node->GetData();
m_columns.Erase( node );
m_columns.erase( m_columns.begin() + col );
if ( !IsVirtual() )
{
// update all the items
for ( size_t i = 0; i < m_lines.size(); i++ )
for ( auto& line : m_lines )
{
wxListLineData * const line = GetLine(i);
// In the following atypical but possible scenario it can be
// legal to call DeleteColumn() but the items may not have any
// values for it:
@ -4391,19 +4305,16 @@ void wxListMainWindow::DeleteColumn( int col )
// 6. Call DeleteColumn().
// So we need to check for this as otherwise we would simply crash
// if this happens.
if ( line->m_items.GetCount() <= static_cast<unsigned>(col) )
if ( line.m_items.size() <= static_cast<unsigned>(col) )
continue;
wxListItemDataList::compatibility_iterator n = line->m_items.Item( col );
delete n->GetData();
line->m_items.Erase(n);
line.m_items.erase(line.m_items.begin() + col);
}
}
if ( InReportView() ) // we only cache max widths when in Report View
{
delete m_aColWidths.Item(col);
m_aColWidths.RemoveAt(col);
m_aColWidths.erase(m_aColWidths.begin() + col);
}
// invalidate it as it has to be recalculated
@ -4415,8 +4326,8 @@ 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;
for ( auto& widthInfo : m_aColWidths )
widthInfo.bNeedsUpdate = true;
}
if ( IsEmpty() )
@ -4447,7 +4358,7 @@ void wxListMainWindow::DoDeleteAllItems()
if ( InReportView() )
ResetVisibleLinesRange();
m_lines.Clear();
m_lines.clear();
}
void wxListMainWindow::DeleteAllItems()
@ -4459,8 +4370,8 @@ void wxListMainWindow::DeleteAllItems()
void wxListMainWindow::DeleteEverything()
{
WX_CLEAR_LIST(wxListHeaderDataList, m_columns);
WX_CLEAR_ARRAY(m_aColWidths);
m_columns.clear();
m_aColWidths.clear();
DeleteAllItems();
}
@ -4605,19 +4516,19 @@ void wxListMainWindow::InsertItem( wxListItem &item )
wxCHECK_RET( col < m_aColWidths.size(), "invalid item column" );
// calculate the width of the item and adjust the max column width
wxColWidthInfo *pWidthInfo = m_aColWidths.Item(col);
wxColWidthInfo& widthInfo = m_aColWidths[col];
int width = GetItemWidthWithImage(&item);
item.SetWidth(width);
if (width > pWidthInfo->nMaxWidth)
if (width > widthInfo.nMaxWidth)
{
pWidthInfo->nMaxWidth = width;
pWidthInfo->bNeedsUpdate = true;
widthInfo.nMaxWidth = width;
widthInfo.bNeedsUpdate = true;
}
}
wxListLineData *line = new wxListLineData(this);
wxListLineData line(this);
line->SetItem( item.m_col, item );
line.SetItem( item.m_col, item );
if ( item.m_mask & wxLIST_MASK_IMAGE )
{
// Reset the buffered height if it's not big enough for the new image.
@ -4632,7 +4543,7 @@ void wxListMainWindow::InsertItem( wxListItem &item )
}
}
m_lines.insert( m_lines.begin() + id, line );
m_lines.insert( m_lines.begin() + id, std::move(line) );
m_dirty = true;
@ -4654,39 +4565,36 @@ long wxListMainWindow::InsertColumn( long col, const wxListItem &item )
m_dirty = true;
if ( InReportView() )
{
wxListHeaderData *column = new wxListHeaderData( item );
wxListHeaderData column( item );
if (item.m_width == wxLIST_AUTOSIZE_USEHEADER)
column->SetWidth(ComputeMinHeaderWidth(column));
column.SetWidth(ComputeMinHeaderWidth(&column));
wxColWidthInfo *colWidthInfo = new wxColWidthInfo(0, IsVirtual());
wxColWidthInfo colWidthInfo(0, IsVirtual());
bool insert = (col >= 0) && ((size_t)col < m_columns.GetCount());
bool insert = (col >= 0) && ((size_t)col < m_columns.size());
if ( insert )
{
wxListHeaderDataList::compatibility_iterator
node = m_columns.Item( col );
m_columns.Insert( node, column );
m_aColWidths.Insert( colWidthInfo, col );
m_columns.insert( m_columns.begin() + col, column );
m_aColWidths.insert( m_aColWidths.begin() + col, colWidthInfo );
idx = col;
}
else
{
idx = m_aColWidths.GetCount();
m_columns.Append( column );
m_aColWidths.Add( colWidthInfo );
idx = m_aColWidths.size();
m_columns.push_back( column );
m_aColWidths.push_back( colWidthInfo );
}
if ( !IsVirtual() )
{
// update all the items
for ( size_t i = 0; i < m_lines.size(); i++ )
for ( auto& line : m_lines )
{
wxListLineData * const line = GetLine(i);
wxListItemData * const data = new wxListItemData(this);
auto& items = line.m_items;
if ( insert )
line->m_items.Insert(col, data);
items.emplace(items.begin() + col, this);
else
line->m_items.Append(data);
items.emplace_back(this);
}
}
@ -4732,13 +4640,13 @@ struct wxListLineComparator
{
}
bool operator()(wxListLineData* const& line1,
wxListLineData* const& line2) const
bool operator()(const wxListLineData& line1,
const wxListLineData& line2) const
{
wxListItem item;
line1->GetItem( 0, item );
line1.GetItem( 0, item );
wxUIntPtr data1 = item.m_data;
line2->GetItem( 0, item );
line2.GetItem( 0, item );
wxUIntPtr data2 = item.m_data;
return m_f(data1, data2, m_data) < 0;
}
@ -5474,7 +5382,7 @@ bool wxGenericListCtrl::DeleteAllItems()
bool wxGenericListCtrl::DeleteAllColumns()
{
size_t count = m_mainWin->m_columns.GetCount();
size_t count = m_mainWin->m_columns.size();
for ( size_t n = 0; n < count; n++ )
DeleteColumn( 0 );
return true;