From 9457c35d42bc7ed09a070c7cb26b864781329065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Sun, 11 Oct 2020 18:00:39 +0200 Subject: [PATCH] Speed up wxDataViewCtrl::SetSelections() on macOS Don't make many single-item selection adjustments in SetSelections() in wxOSX and instead implement it with a single native call to selectRowIndexes:byExtendingSelection: This has a dramatic, orders of magnitude effect on this call's performance when selecting many items: selecting 10 thousand items goes from minutes of runtime and gigabytes of RAM to unobservable impact in both. --- include/wx/osx/cocoa/dataview.h | 1 + include/wx/osx/core/dataview.h | 1 + src/osx/cocoa/dataview.mm | 14 ++++++++++++++ src/osx/dataview_osx.cpp | 5 ++--- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/include/wx/osx/cocoa/dataview.h b/include/wx/osx/cocoa/dataview.h index 554dcbe0e6..41d16201d8 100644 --- a/include/wx/osx/cocoa/dataview.h +++ b/include/wx/osx/cocoa/dataview.h @@ -514,6 +514,7 @@ public: virtual int GetSelections(wxDataViewItemArray& sel) const; virtual bool IsSelected(const wxDataViewItem& item) const; virtual void Select(const wxDataViewItem& item); + virtual void Select(const wxDataViewItemArray& items); virtual void SelectAll(); virtual void Unselect(const wxDataViewItem& item); virtual void UnselectAll(); diff --git a/include/wx/osx/core/dataview.h b/include/wx/osx/core/dataview.h index b1d263ba20..f3ac6d33fd 100644 --- a/include/wx/osx/core/dataview.h +++ b/include/wx/osx/core/dataview.h @@ -90,6 +90,7 @@ public: virtual int GetSelections(wxDataViewItemArray& sel) const = 0; // returns all selected items in the native control virtual bool IsSelected (wxDataViewItem const& item) const = 0; // checks if the passed item is selected in the native control virtual void Select (wxDataViewItem const& item) = 0; // selects the passed item in the native control + virtual void Select (wxDataViewItemArray const& items) = 0; // selects the passed items in the native control virtual void SelectAll() = 0; // selects all items in the native control virtual void Unselect (wxDataViewItem const& item) = 0; // unselects the passed item in the native control virtual void UnselectAll() = 0; // unselects all items in the native control diff --git a/src/osx/cocoa/dataview.mm b/src/osx/cocoa/dataview.mm index 24577504e2..770719e4a9 100644 --- a/src/osx/cocoa/dataview.mm +++ b/src/osx/cocoa/dataview.mm @@ -2508,6 +2508,20 @@ void wxCocoaDataViewControl::Select(const wxDataViewItem& item) byExtendingSelection:GetDataViewCtrl()->HasFlag(wxDV_MULTIPLE) ? YES : NO]; } +void wxCocoaDataViewControl::Select(const wxDataViewItemArray& items) +{ + NSMutableIndexSet *selection = [[NSMutableIndexSet alloc] init]; + + for ( const auto& i: items ) + { + if ( i.IsOk() ) + [selection addIndex:[m_OutlineView rowForItem:[m_DataSource getDataViewItemFromBuffer:i]]]; + } + + [m_OutlineView selectRowIndexes:selection byExtendingSelection:NO]; + [selection release]; +} + void wxCocoaDataViewControl::SelectAll() { [m_OutlineView selectAll:m_OutlineView]; diff --git a/src/osx/dataview_osx.cpp b/src/osx/dataview_osx.cpp index c850b5052e..ad197cc85c 100644 --- a/src/osx/dataview_osx.cpp +++ b/src/osx/dataview_osx.cpp @@ -647,9 +647,8 @@ void wxDataViewCtrl::SetSelections(wxDataViewItemArray const& sel) last_parent = parent; } - // finally select the items: - for (i=0; iSelect(sel[i]); + // finally select the items: + dataViewWidgetPtr->Select(sel); } void wxDataViewCtrl::Unselect(wxDataViewItem const& item)