reapack

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

commit 2b7fb71bf66b401a59def55192d3d054de80a080
parent e984df20ac2a4344ef13b887d2aaa64dc965809f
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Sun, 17 Apr 2016 00:29:06 -0400

better UI to filter by package type and make it remember the setting

Diffstat:
Msrc/browser.cpp | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Msrc/browser.hpp | 9++++++---
Msrc/config.cpp | 15+++++++++++++--
Msrc/config.hpp | 6++++++
Msrc/resource.hpp | 16+++++++---------
Msrc/resource.rc | 19++++++++-----------
6 files changed, 119 insertions(+), 55 deletions(-)

diff --git a/src/browser.cpp b/src/browser.cpp @@ -28,11 +28,14 @@ #include <boost/algorithm/string.hpp> #include <boost/range/adaptor/reversed.hpp> +#include <locale> +#include <sstream> using namespace std; enum Action { ACTION_VERSION = 80, + ACTION_FILTERTYPE, ACTION_LATEST = 300, ACTION_LATEST_ALL, ACTION_REINSTALL, @@ -56,26 +59,18 @@ void Browser::onInit() { m_apply = getControl(IDAPPLY); m_filterHandle = getControl(IDC_FILTER); + m_tabs = getControl(IDC_TABS); m_display = getControl(IDC_DISPLAY); disable(m_apply); - SendMessage(m_display, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("All")); - SendMessage(m_display, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Queued")); - SendMessage(m_display, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Installed")); - SendMessage(m_display, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Out of date")); - SendMessage(m_display, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Obsolete")); - SendMessage(m_display, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Uninstalled")); - SendMessage(m_display, CB_SETCURSEL, 0, 0); - - m_types = { - {Package::ScriptType, getControl(IDC_SCRIPTS)}, - {Package::EffectType, getControl(IDC_EFFECTS)}, - {Package::ExtensionType, getControl(IDC_EXTENSIONS)}, - }; - - for(const auto &pair : m_types) - SendMessage(pair.second, BM_SETCHECK, BST_CHECKED, 0); + SendMessage(m_tabs, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("All")); + SendMessage(m_tabs, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Queued")); + SendMessage(m_tabs, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Installed")); + SendMessage(m_tabs, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Out of date")); + SendMessage(m_tabs, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Obsolete")); + SendMessage(m_tabs, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Uninstalled")); + SendMessage(m_tabs, CB_SETCURSEL, 0, 0); m_list = createControl<ListView>(IDC_PACKAGES, ListView::Columns{ {AUTO_STR(""), 23}, @@ -99,13 +94,12 @@ void Browser::onCommand(const int id, const int event) namespace arg = std::placeholders; switch(id) { + case IDC_TABS: + if(event == CBN_SELCHANGE) + fillList(); + break; case IDC_DISPLAY: - if(event != CBN_SELCHANGE) - break; - case IDC_SCRIPTS: - case IDC_EFFECTS: - case IDC_EXTENSIONS: - fillList(); + displayButton(); break; case IDC_FILTER: m_checkFilter = true; @@ -175,6 +169,8 @@ void Browser::onCommand(const int id, const int event) default: if(id >> 8 == ACTION_VERSION) installVersion(m_currentIndex, id & 0xff); + else if(id >> 8 == ACTION_FILTERTYPE) + toggleFiltered(static_cast<Package::Type>(id & 0xff)); break; } } @@ -304,6 +300,30 @@ void Browser::actionsButton() if(!m_list->hasSelection()) menu.disableAll(); + menu.show(rect.left, rect.bottom - 1, handle()); +} + +void Browser::displayButton() +{ + RECT rect; + GetWindowRect(m_display, &rect); + + static map<const auto_char *, Package::Type> types = { + {AUTO_STR("&Scripts"), Package::ScriptType}, + {AUTO_STR("&Effects"), Package::EffectType}, + {AUTO_STR("E&xtensions"), Package::ExtensionType}, + {AUTO_STR("&Other packages"), Package::UnknownType}, + }; + + Menu menu; + for(const auto &pair : types) { + const auto index = menu.addAction(pair.first, + pair.second | (ACTION_FILTERTYPE << 8)); + + if(!isFiltered(pair.second)) + menu.check(index); + } + menu.addSeparator(); menu.addAction(AUTO_STR("Re&fresh repositories"), ACTION_REFRESH); menu.addAction(AUTO_STR("&Manage repositories..."), ACTION_MANAGE); @@ -311,6 +331,28 @@ void Browser::actionsButton() menu.show(rect.left, rect.bottom - 1, handle()); } +bool Browser::isFiltered(Package::Type type) const +{ + switch(type) { + case Package::ScriptType: + case Package::EffectType: + case Package::ExtensionType: + break; + default: + type = Package::UnknownType; + } + + auto config = m_reapack->config()->browser(); + return ((config->typeFilter >> type) & 1) == 1; +} + +void Browser::toggleFiltered(const Package::Type type) +{ + auto config = m_reapack->config()->browser(); + config->typeFilter ^= 1 << type; + fillList(); +} + void Browser::checkFilter() { if(!m_checkFilter) @@ -489,6 +531,16 @@ void Browser::fillList() } m_list->sort(); + + basic_ostringstream<auto_char> btnLabel; + btnLabel.imbue(locale("")); // enable number formatting + btnLabel << m_list->rowCount() << AUTO_STR('/') << m_entries.size() + << AUTO_STR(" package"); + + if(m_entries.size() != 1) + btnLabel << AUTO_STR('s'); + + SetWindowText(m_display, btnLabel.str().c_str()); } ListView::Row Browser::makeRow(const Entry &entry) const @@ -561,7 +613,7 @@ bool Browser::match(const Entry &entry) const { using namespace boost; - switch(getDisplay()) { + switch(currentTab()) { case All: break; case Queued: @@ -589,10 +641,7 @@ bool Browser::match(const Entry &entry) const const Package::Type type = entry.latest ? entry.package->type() : entry.regEntry.type; - const auto typeIt = m_types.find(type); - - if(typeIt != m_types.end() && - SendMessage(typeIt->second, BM_GETCHECK, 0, 0) == BST_UNCHECKED) + if(isFiltered(type)) return false; const string &name = getValue(NameColumn, entry); @@ -674,7 +723,7 @@ void Browser::resetAction(const int index) m_actions.erase(it); - if(getDisplay() == Queued) { + if(currentTab() == Queued) { m_list->removeRow(index); m_visibleEntries.erase(m_visibleEntries.begin() + index); } @@ -726,9 +775,9 @@ void Browser::selectionDo(const std::function<void (int)> &func) } } -auto Browser::getDisplay() const -> Display +auto Browser::currentTab() const -> Tab { - return (Display)SendMessage(m_display, CB_GETCURSEL, 0, 0); + return (Tab)SendMessage(m_tabs, CB_GETCURSEL, 0, 0); } bool Browser::confirm() const diff --git a/src/browser.hpp b/src/browser.hpp @@ -80,7 +80,7 @@ private: RemoteColumn, }; - enum Display { + enum Tab { All, Queued, Installed, @@ -101,11 +101,14 @@ private: const Entry *getEntry(int) const; void selectionMenu(Menu &) const; void actionsButton(); + void displayButton(); + bool isFiltered(Package::Type) const; + void toggleFiltered(Package::Type); bool hasAction(const Entry *e) const { return m_actions.count(e) > 0; } bool isTarget(const Entry *, const Version *) const; void setAction(const int index, const Version *, bool toggle = true); void selectionDo(const std::function<void (int)> &); - Display getDisplay() const; + Tab currentTab() const; bool confirm() const; void apply(); @@ -131,8 +134,8 @@ private: std::map<const Entry *, const Version *> m_actions; HWND m_filterHandle; + HWND m_tabs; HWND m_display; - std::map<int, HWND> m_types; ListView *m_list; HWND m_apply; }; diff --git a/src/config.cpp b/src/config.cpp @@ -30,7 +30,10 @@ using namespace std; static const char *GLOBAL_GRP = "reapack"; static const char *VERSION_KEY = "version"; -static const char *AUTOINSTALL_KEY = "autoInstall"; +static const char *AUTOINSTALL_KEY = "autoinstall"; + +static const char *BROWSER_GRP = "browser"; +static const char *TYPEFILTER_KEY = "typefilter"; static const char *SIZE_KEY = "size"; @@ -45,7 +48,8 @@ static string ArrayKey(const string &key, const size_t i) static const int BUFFER_SIZE = 2083; Config::Config() - : m_isFirstRun(false), m_version(0), m_autoInstall(false), m_remotesIniSize(0) + : m_isFirstRun(false), m_version(0), m_autoInstall(false), m_browser(), + m_remotesIniSize(0) { } @@ -85,6 +89,10 @@ void Config::read(const Path &path) m_autoInstall = getUInt(GLOBAL_GRP, AUTOINSTALL_KEY) > 0; + m_browser = { + getUInt(BROWSER_GRP, TYPEFILTER_KEY), + }; + readRemotes(); restoreSelfRemote(); } @@ -93,6 +101,9 @@ void Config::write() { setUInt(GLOBAL_GRP, VERSION_KEY, m_version); setUInt(GLOBAL_GRP, AUTOINSTALL_KEY, m_autoInstall); + + setUInt(BROWSER_GRP, TYPEFILTER_KEY, m_browser.typeFilter); + writeRemotes(); } diff --git a/src/config.hpp b/src/config.hpp @@ -26,6 +26,10 @@ class Path; class Config { public: + struct BrowserConfig { + size_t typeFilter; + }; + Config(); void read(const Path &); @@ -35,6 +39,7 @@ public: bool autoInstall() const { return m_autoInstall; } void setAutoInstall(const bool enable) { m_autoInstall = enable; } RemoteList *remotes() { return &m_remotes; } + BrowserConfig *browser() { return &m_browser; } private: std::string getString(const char *, const std::string &) const; @@ -51,6 +56,7 @@ private: bool m_isFirstRun; size_t m_version; bool m_autoInstall; + BrowserConfig m_browser; void readRemotes(); void restoreSelfRemote(); diff --git a/src/resource.hpp b/src/resource.hpp @@ -58,14 +58,12 @@ #define IDC_GROUPBOX 221 #define IDC_URL 222 #define IDC_SCRIPTS 223 -#define IDC_EFFECTS 224 -#define IDC_EXTENSIONS 225 -#define IDC_FILTER 226 -#define IDC_CLEAR 227 -#define IDC_DISPLAY 228 -#define IDC_SELECT 229 -#define IDC_UNSELECT 230 -#define IDC_ACTIONS 231 -#define IDC_OPTIONS 232 +#define IDC_FILTER 224 +#define IDC_CLEAR 225 +#define IDC_DISPLAY 226 +#define IDC_SELECT 227 +#define IDC_UNSELECT 228 +#define IDC_ACTIONS 229 +#define IDC_OPTIONS 230 #endif diff --git a/src/resource.rc b/src/resource.rc @@ -84,20 +84,17 @@ FONT DIALOG_FONT CAPTION "ReaPack: Package Browser" BEGIN LTEXT "Filter:", IDC_LABEL, 5, 7, 20, 10 - EDITTEXT IDC_FILTER, 25, 4, 200, 14, ES_AUTOHSCROLL | WS_TABSTOP - PUSHBUTTON "Cl&ear", IDC_CLEAR, 227, 4, 32, 14 - LTEXT "Display:", IDC_LABEL2, 266, 7, 30, 10 - COMBOBOX IDC_DISPLAY, 294, 5, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Type:", IDC_LABEL3, 356, 7, 20, 10 - CHECKBOX "&Scripts", IDC_SCRIPTS, 376, 4, 35, 14, BS_AUTOCHECKBOX | WS_TABSTOP - CHECKBOX "&Effects", IDC_EFFECTS, 413, 4, 35, 14, BS_AUTOCHECKBOX | WS_TABSTOP - CHECKBOX "&Extensions", IDC_EXTENSIONS, 450, 4, 50, 14, BS_AUTOCHECKBOX | WS_TABSTOP + EDITTEXT IDC_FILTER, 25, 4, 212, 14, ES_AUTOHSCROLL | WS_TABSTOP + PUSHBUTTON "Cl&ear", IDC_CLEAR, 239, 4, 32, 14 + LTEXT "Display:", IDC_LABEL2, 286, 7, 30, 10 + COMBOBOX IDC_TABS, 314, 5, 65, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "", IDC_DISPLAY, 385, 4, 110, 14 CONTROL "", IDC_PACKAGES, WC_LISTVIEW, LVS_REPORT | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 5, 22, 490, 204 PUSHBUTTON "&Select all", IDC_SELECT, 5, 230, 45, 14 PUSHBUTTON "&Unselect all", IDC_UNSELECT, 53, 230, 45, 14 PUSHBUTTON "&Actions...", IDC_ACTIONS, 101, 230, 45, 14 - DEFPUSHBUTTON "&OK", IDOK, 368, 230, 40, 14 - PUSHBUTTON "&Cancel", IDCANCEL, 411, 230, 40, 14 - PUSHBUTTON "&Apply", IDAPPLY, 454, 230, 40, 14 + DEFPUSHBUTTON "&OK", IDOK, 369, 230, 40, 14 + PUSHBUTTON "&Cancel", IDCANCEL, 412, 230, 40, 14 + PUSHBUTTON "&Apply", IDAPPLY, 455, 230, 40, 14 END