reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

commit 2c2244d4589b46603ab5cb2c87d81cf0fe11dd6e
parent aeb112c07e76d70acdb72a1908527a47a85bebc5
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Sat,  5 Mar 2016 16:03:47 -0500

implement multi selection in the remote manager dialog

Diffstat:
Msrc/listview.cpp | 54+++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/listview.hpp | 6+++++-
Msrc/manager.cpp | 68++++++++++++++++++++++++++++++++++++++------------------------------
Msrc/manager.hpp | 3++-
Msrc/resource.rc | 4++--
5 files changed, 90 insertions(+), 45 deletions(-)

diff --git a/src/listview.cpp b/src/listview.cpp @@ -185,7 +185,7 @@ void ListView::clear() bool ListView::hasSelection() const { - return currentIndex() > -1; + return selectionSize() > 0; } int ListView::currentIndex() const @@ -194,13 +194,35 @@ int ListView::currentIndex() const if(internalIndex < 0) return -1; + else + return translateBack(internalIndex); +} - LVITEM item{}; - item.iItem = internalIndex; - item.mask |= LVIF_PARAM; - ListView_GetItem(handle(), &item); +vector<int> ListView::selection() const +{ + int index = -1; + vector<int> indexes; - return (int)item.lParam; + while((index = ListView_GetNextItem(handle(), index, LVNI_SELECTED)) != -1) { + indexes.push_back(translateBack(index)); + } + + return indexes; +} + +int ListView::selectionSize() const +{ + return ListView_GetSelectedCount(handle()); +} + +int ListView::itemUnderMouse() const +{ + LVHITTESTINFO info{}; + GetCursorPos(&info.pt); + ScreenToClient(handle(), &info.pt); + ListView_HitTest(handle(), &info); + + return translateBack(info.iItem); } void ListView::onNotify(LPNMHDR info, LPARAM lParam) @@ -220,13 +242,10 @@ void ListView::onNotify(LPNMHDR info, LPARAM lParam) void ListView::handleDoubleClick() { - LVHITTESTINFO info{}; - GetCursorPos(&info.pt); - ScreenToClient(handle(), &info.pt); - ListView_HitTest(handle(), &info); + const int index = itemUnderMouse(); // user double clicked on an item - if(info.iItem > -1) + if(index > -1) m_onActivate(); } @@ -267,3 +286,16 @@ int ListView::translate(const int userIndex) const return -1; } + +int ListView::translateBack(const int internalIndex) const +{ + if(m_sortColumn < 0) + return internalIndex; + + LVITEM item{}; + item.iItem = internalIndex; + item.mask |= LVIF_PARAM; + ListView_GetItem(handle(), &item); + + return (int)item.lParam; +} diff --git a/src/listview.hpp b/src/listview.hpp @@ -47,8 +47,11 @@ public: void sortByColumn(int index, SortOrder order = AscendingOrder); void clear(); + int selectionSize() const; bool hasSelection() const; int currentIndex() const; + std::vector<int> selection() const; + int itemUnderMouse() const; int rowCount() const { return (int)m_rows.size(); } void onSelect(const Callback &callback) { m_onSelect.connect(callback); } @@ -63,7 +66,8 @@ private: void setSortArrow(bool); void handleDoubleClick(); void handleColumnClick(LPARAM lpnmlistview); - int translate(int index) const; + int translate(int userIndex) const; + int translateBack(int internalIndex) const; int m_columnSize; int m_sortColumn; diff --git a/src/manager.cpp b/src/manager.cpp @@ -29,7 +29,7 @@ using namespace std; -enum { ACTION_ENABLE = 300, ACTION_DISABLE, ACTION_UNINSTALL, ACTION_ABOUT }; +enum { ACTION_ENABLE = 80, ACTION_DISABLE, ACTION_UNINSTALL, ACTION_ABOUT }; Manager::Manager(ReaPack *reapack) : Dialog(IDD_CONFIG_DIALOG), m_reapack(reapack), m_list(0) @@ -51,7 +51,7 @@ void Manager::onInit() {AUTO_STR("State"), 60}, }); - m_list->onActivate(bind(&Manager::about, this)); + m_list->onActivate([=] { about(m_list->currentIndex()); }); } void Manager::onCommand(const int id) @@ -69,12 +69,9 @@ void Manager::onCommand(const int id) case ACTION_UNINSTALL: uninstall(); break; - case ACTION_ABOUT: - about(); - break; case IDOK: if(confirm()) - apply(); + apply(); // continue to next case (IDCANCEL) else { m_uninstall.clear(); refresh(); @@ -84,6 +81,10 @@ void Manager::onCommand(const int id) reset(); close(); break; + default: + if(id >> 8 == ACTION_ABOUT) + about(id & 0xff); + break; } } @@ -92,7 +93,8 @@ void Manager::onContextMenu(HWND target, const int x, const int y) if(target != m_list->handle()) return; - const Remote &remote = currentRemote(); + const int index = m_list->itemUnderMouse(); + const Remote &remote = getRemote(index); if(remote.isNull()) return; @@ -115,7 +117,7 @@ void Manager::onContextMenu(HWND target, const int x, const int y) const auto_string &name = make_autostring(remote.name()); auto_snprintf(aboutLabel, sizeof(aboutLabel), AUTO_STR("&About %s..."), name.c_str()); - menu.addAction(aboutLabel, ACTION_ABOUT); + menu.addAction(aboutLabel, index | (ACTION_ABOUT << 8)); menu.disable(enableAction); menu.disable(disableAction); @@ -153,21 +155,22 @@ void Manager::refresh() void Manager::setRemoteEnabled(const bool enabled) { - const Remote &remote = currentRemote(); + for(const int index : m_list->selection()) { + const Remote &remote = getRemote(index); - if(remote.isNull()) - return; + auto it = m_enableOverrides.find(remote); - auto it = m_enableOverrides.find(remote); - - if(it == m_enableOverrides.end()) - m_enableOverrides.insert({remote, enabled}); - else if(remote.isEnabled() == enabled) - m_enableOverrides.erase(it); - else - it->second = enabled; + if(it == m_enableOverrides.end()) { + if(remote.isEnabled() != enabled) + m_enableOverrides.insert({remote, enabled}); + } + else if(remote.isEnabled() == enabled) + m_enableOverrides.erase(it); + else + it->second = enabled; - m_list->replaceRow(m_list->currentIndex(), makeRow(remote)); + m_list->replaceRow(index, makeRow(remote)); + } } bool Manager::isRemoteEnabled(const Remote &remote) const @@ -182,20 +185,22 @@ bool Manager::isRemoteEnabled(const Remote &remote) const void Manager::uninstall() { - const Remote &remote = currentRemote(); - m_uninstall.insert(remote); + while(m_list->selectionSize() > 0) { + const Remote &remote = currentRemote(); + m_uninstall.insert(remote); - const auto it = m_enableOverrides.find(remote); + const auto it = m_enableOverrides.find(remote); - if(it != m_enableOverrides.end()) - m_enableOverrides.erase(it); + if(it != m_enableOverrides.end()) + m_enableOverrides.erase(it); - m_list->removeRow(m_list->currentIndex()); + m_list->removeRow(m_list->currentIndex()); + } } -void Manager::about() +void Manager::about(const int index) { - m_reapack->about(currentRemote(), handle()); + m_reapack->about(getRemote(index), handle()); } bool Manager::confirm() const @@ -253,9 +258,12 @@ ListView::Row Manager::makeRow(const Remote &remote) const Remote Manager::currentRemote() const { - const int index = m_list->currentIndex(); + return getRemote(m_list->currentIndex()); +} - if(index < 0) +Remote Manager::getRemote(const int index) const +{ + if(index < 0 || index > m_list->rowCount() - 1) return {}; const ListView::Row &row = m_list->row(index); diff --git a/src/manager.hpp b/src/manager.hpp @@ -43,10 +43,11 @@ private: ListView::Row makeRow(const Remote &) const; Remote currentRemote() const; + Remote getRemote(int index) const; void setRemoteEnabled(bool); bool isRemoteEnabled(const Remote &) const; void uninstall(); - void about(); + void about(int index); bool confirm() const; void apply(); diff --git a/src/resource.rc b/src/resource.rc @@ -31,8 +31,8 @@ FONT DIALOG_FONT CAPTION "ReaPack Configuration" BEGIN LTEXT "Remote repositories:", IDC_LABEL, 5, 5, 320, 10 - CONTROL "", IDC_LIST, WC_LISTVIEW, LVS_REPORT | LVS_SINGLESEL | - LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 5, 18, 320, 136 + CONTROL "", IDC_LIST, WC_LISTVIEW, LVS_REPORT | LVS_SHOWSELALWAYS | + WS_BORDER | WS_TABSTOP, 5, 18, 320, 136 PUSHBUTTON "&Import...", IDC_IMPORT, 5, 160, 45, 14 DEFPUSHBUTTON "&OK", IDOK, 240, 160, 40, 14 PUSHBUTTON "&Cancel", IDCANCEL, 284, 160, 40, 14