commit 96c2dd41a8f6294df75c0d0833a914f310f449e6
parent 5184222cc501420e50d15d6dda1a6e0d19d87e1d
Author: cfillion <cfillion@users.noreply.github.com>
Date: Mon, 23 Oct 2017 06:22:18 -0400
listview: refactor sort only when required
Diffstat:
5 files changed, 59 insertions(+), 24 deletions(-)
diff --git a/src/about.cpp b/src/about.cpp
@@ -154,7 +154,7 @@ void About::setDelegate(const DelegatePtr &delegate, const bool focus)
m_delegate = delegate;
m_delegate->init(this);
- m_menu->sort();
+ m_menu->endEdit();
m_currentIndex = -255;
updateList();
@@ -271,7 +271,7 @@ void About::updateList()
m_delegate->updateList(index);
m_currentIndex = index;
- m_list->sort();
+ m_list->endEdit();
}
AboutIndexDelegate::AboutIndexDelegate(const IndexPtr &index)
diff --git a/src/browser.cpp b/src/browser.cpp
@@ -283,7 +283,7 @@ void Browser::updateDisplayLabel()
{
char btnLabel[32];
snprintf(btnLabel, sizeof(btnLabel), "%d/%zu package%s...",
- m_list->rowCount(), m_entries.size(),
+ m_list->visibleRowCount(), m_entries.size(),
m_entries.size() == 1 ? "" : "s");
Win32::setWindowText(m_displayBtn, btnLabel);
@@ -541,7 +541,7 @@ void Browser::fillList()
}
m_list->setScroll(scroll);
- m_list->sort();
+ m_list->endEdit();
// restore selection only after having sorted the table
// in order to get the same scroll position as before if possible
@@ -777,10 +777,7 @@ void Browser::selectionDo(const function<void (int)> &func)
lastSize = newSize;
}
- // re-sort here rather than doing it once per entry after updating the
- // status cell in updateAction
- if(m_list->sortColumn() == 0)
- m_list->sort();
+ m_list->endEdit(); // re-sort if required
}
auto Browser::currentView() const -> View
diff --git a/src/listview.cpp b/src/listview.cpp
@@ -31,7 +31,7 @@
using namespace std;
ListView::ListView(HWND handle, const Columns &columns)
- : Control(handle), m_customizable(false), m_sort(), m_defaultSort()
+ : Control(handle), m_customizable(false), m_sort(), m_defaultSort(), m_dirty(0)
{
for(const Column &col : columns)
addColumn(col);
@@ -94,8 +94,12 @@ void ListView::updateCell(int row, int cell)
{
const int viewRowIndex = translate(row);
const auto &&text = Win32::widen(m_rows[row]->cell(cell).value);
+
ListView_SetItemText(handle(), viewRowIndex, cell,
const_cast<Win32::char_type *>(text.c_str()));
+
+ if(m_sort && m_sort->column == cell)
+ m_dirty |= NeedSortFlag;
}
void ListView::removeRow(const int userIndex)
@@ -156,14 +160,7 @@ void ListView::sort()
ListView_SortItems(handle(), compare, (LPARAM)this);
- for(int viewIndex = 0; viewIndex < rowCount(); viewIndex++) {
- LVITEM item{};
- item.iItem = viewIndex;
- item.mask |= LVIF_PARAM;
- ListView_GetItem(handle(), &item);
-
- row(item.lParam)->viewIndex = viewIndex;
- }
+ m_dirty = (m_dirty | NeedReindexFlag) & ~NeedSortFlag;
}
void ListView::sortByColumn(const int index, const SortOrder order, const bool user)
@@ -177,6 +174,7 @@ void ListView::sortByColumn(const int index, const SortOrder order, const bool u
m_defaultSort = settings;
m_sort = settings;
+ m_dirty |= NeedSortFlag;
setSortArrow(true);
}
@@ -209,6 +207,31 @@ void ListView::setSortArrow(const bool set)
Header_SetItem(header, m_sort->column, &item);
}
+void ListView::reindexVisible()
+{
+ const int visibleCount = visibleRowCount();
+ for(int viewIndex = 0; viewIndex < visibleCount; viewIndex++) {
+ LVITEM item{};
+ item.iItem = viewIndex;
+ item.mask |= LVIF_PARAM;
+ ListView_GetItem(handle(), &item);
+
+ row(item.lParam)->viewIndex = viewIndex;
+ }
+
+ m_dirty &= ~NeedReindexFlag;
+}
+
+void ListView::endEdit()
+{
+ if(m_dirty & NeedSortFlag)
+ sort(); // sort may set NeedReindexFlag
+ if(m_dirty & NeedReindexFlag)
+ reindexVisible();
+
+ assert(!m_dirty);
+}
+
void ListView::clear()
{
ListView_DeleteAllItems(handle());
@@ -236,6 +259,11 @@ void ListView::setSelected(const int index, const bool select)
select ? LVIS_SELECTED : 0, LVIS_SELECTED);
}
+int ListView::visibleRowCount() const
+{
+ return ListView_GetItemCount(handle());
+}
+
int ListView::currentIndex() const
{
const int internalIndex = ListView_GetNextItem(handle(), -1, LVNI_SELECTED);
@@ -395,7 +423,7 @@ void ListView::handleColumnClick(LPARAM lParam)
}
sortByColumn(col, order, true);
- sort();
+ endEdit();
}
int ListView::translate(const int userIndex) const
@@ -476,7 +504,9 @@ void ListView::resetColumns()
setSortArrow(false);
m_sort = m_defaultSort;
setSortArrow(true);
- sort();
+
+ m_dirty |= NeedSortFlag;
+ endEdit();
}
}
diff --git a/src/listview.hpp b/src/listview.hpp
@@ -100,6 +100,7 @@ public:
void updateCell(int row, int cell);
void removeRow(int index);
int rowCount() const { return (int)m_rows.size(); }
+ int visibleRowCount() const;
bool empty() const { return m_rows.empty(); }
void clear();
@@ -126,9 +127,8 @@ public:
int columnWidth(int index) const;
int columnCount() const { return (int)m_cols.size(); }
- void sort();
void sortByColumn(int index, SortOrder order = AscendingOrder, bool user = false);
- int sortColumn() const { return m_sort ? m_sort->column : -1; }
+ void endEdit();
void restoreState(Serializer::Data &);
void saveState(Serializer::Data &) const;
@@ -151,6 +151,11 @@ private:
SortOrder order;
};
+ enum DirtyFlag {
+ NeedSortFlag = 1<<0,
+ NeedReindexFlag = 1<<1,
+ };
+
static int adjustWidth(int);
void setExStyle(int style, bool enable);
void setSortArrow(bool);
@@ -159,6 +164,8 @@ private:
int translate(int userIndex) const;
int translateBack(int internalIndex) const;
void headerMenu(int x, int y);
+ void sort();
+ void reindexVisible();
bool m_customizable;
std::vector<Column> m_cols;
@@ -166,6 +173,8 @@ private:
boost::optional<Sort> m_sort;
boost::optional<Sort> m_defaultSort;
+ int m_dirty;
+
VoidSignal m_onSelect;
VoidSignal m_onActivate;
MenuSignal m_onContextMenu;
diff --git a/src/manager.cpp b/src/manager.cpp
@@ -335,7 +335,7 @@ void Manager::refresh()
m_list->select(row->index());
}
- m_list->sort();
+ m_list->endEdit();
}
void Manager::updateEnabledCell(int index, const Remote &remote)
@@ -374,8 +374,7 @@ void Manager::setMods(const ModsCallback &cb, const bool updateRow)
updateEnabledCell(index, remote);
}
- if(updateRow && m_list->sortColumn() == 2)
- m_list->sort();
+ m_list->endEdit(); // re-sort if required
}
void Manager::setRemoteEnabled(const bool enabled)