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:
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