reapack

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

commit ae718b3c446f53282def59fef3749c289d520165
parent 6c57007c8d4ff1159d89aae432c03ed38f84adae
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Sun, 26 Jun 2016 17:27:36 -0400

browser: save and restore window size and position + refactoring

Diffstat:
Msrc/about.cpp | 2++
Msrc/browser.cpp | 20++++++++++++--------
Msrc/browser.hpp | 1+
Msrc/config.cpp | 6+++---
Msrc/config.hpp | 2+-
Msrc/dialog.cpp | 32++++++++++++++++++++++++++++++--
Msrc/dialog.hpp | 5+++++
Msrc/import.cpp | 2++
Msrc/listview.cpp | 19++++++++++---------
Msrc/listview.hpp | 6+++---
Msrc/manager.cpp | 4++++
Msrc/progress.cpp | 2++
Msrc/report.cpp | 2++
Msrc/serializer.cpp | 15+++++++++------
Msrc/serializer.hpp | 8++++----
Mtest/serializer.cpp | 11++++++-----
16 files changed, 96 insertions(+), 41 deletions(-)

diff --git a/src/about.cpp b/src/about.cpp @@ -45,6 +45,8 @@ About::About(IndexPtr index) void About::onInit() { + Dialog::onInit(); + m_about = createControl<RichEdit>(IDC_ABOUT); m_cats = createControl<ListView>(IDC_CATEGORIES, ListView::Columns{ diff --git a/src/browser.cpp b/src/browser.cpp @@ -108,12 +108,6 @@ void Browser::onInit() return a.latest->time().compare(b.latest->time()); }); - const auto config = m_reapack->config()->browser(); - m_list->restore(config->list, 1); - - updateDisplayLabel(); - refresh(); - m_filterTimer = startTimer(200); Dialog::onInit(); @@ -129,6 +123,14 @@ void Browser::onInit() setAnchor(getControl(IDOK), AnchorAll); setAnchor(getControl(IDCANCEL), AnchorAll); setAnchor(m_applyBtn, AnchorAll); + + auto data = m_serializer.read(m_reapack->config()->browser()->state, 1); + Dialog::restore(data); + m_list->restore(data); + assert(data.empty()); + + updateDisplayLabel(); + refresh(); } void Browser::onCommand(const int id, const int event) @@ -250,8 +252,10 @@ bool Browser::onKeyDown(const int key, const int mods) void Browser::onClose() { - auto config = m_reapack->config()->browser(); - config->list = m_list->save(); + Serializer::Data data; + Dialog::save(data); + m_list->save(data); + m_reapack->config()->browser()->state = m_serializer.write(data); } void Browser::onTimer(const int id) diff --git a/src/browser.hpp b/src/browser.hpp @@ -154,6 +154,7 @@ private: HWND m_actionsBtn; ListView *m_list; HWND m_applyBtn; + Serializer m_serializer; }; #endif diff --git a/src/config.cpp b/src/config.cpp @@ -37,7 +37,7 @@ static const auto_char *PRERELEASES_KEY = AUTO_STR("prereleases"); static const auto_char *BROWSER_GRP = AUTO_STR("browser"); static const auto_char *TYPEFILTER_KEY = AUTO_STR("typefilter"); static const auto_char *SHOWDESCS_KEY = AUTO_STR("showdescs"); -static const auto_char *LIST_KEY = AUTO_STR("list"); +static const auto_char *STATE_KEY = AUTO_STR("state"); static const auto_char *NETWORK_GRP = AUTO_STR("network"); static const auto_char *PROXY_KEY = AUTO_STR("proxy"); @@ -139,7 +139,7 @@ void Config::read(const Path &path) TYPEFILTER_KEY, m_browser.typeFilter); m_browser.showDescs = getUInt(BROWSER_GRP, SHOWDESCS_KEY, m_browser.showDescs) > 0; - m_browser.list = getString(BROWSER_GRP, LIST_KEY, m_browser.list); + m_browser.state = getString(BROWSER_GRP, STATE_KEY, m_browser.state); m_network.proxy = getString(NETWORK_GRP, PROXY_KEY, m_network.proxy); m_network.verifyPeer = getUInt(NETWORK_GRP, @@ -159,7 +159,7 @@ void Config::write() setUInt(BROWSER_GRP, TYPEFILTER_KEY, m_browser.typeFilter); setUInt(BROWSER_GRP, SHOWDESCS_KEY, m_browser.showDescs); - setString(BROWSER_GRP, LIST_KEY, m_browser.list); + setString(BROWSER_GRP, STATE_KEY, m_browser.state); setString(NETWORK_GRP, PROXY_KEY, m_network.proxy); setUInt(NETWORK_GRP, VERIFYPEER_KEY, m_network.verifyPeer); diff --git a/src/config.hpp b/src/config.hpp @@ -33,7 +33,7 @@ struct InstallOpts { struct BrowserOpts { unsigned int typeFilter; bool showDescs; - std::string list; + std::string state; }; struct NetworkOpts { diff --git a/src/dialog.cpp b/src/dialog.cpp @@ -235,7 +235,8 @@ void Dialog::center() top += verticalBias; // according to SWELL, top means bottom. #endif - SetWindowPos(m_handle, HWND_TOP, max(0, left), max(0, top), 0, 0, SWP_NOSIZE); + SetWindowPos(m_handle, HWND_TOP, max(0, left), max(0, top), + 0, 0, SWP_NOZORDER | SWP_NOSIZE); } bool Dialog::hasFocus() const @@ -327,18 +328,45 @@ void Dialog::setAnchor(HWND handle, const int flags) m_resizer.init_itemhwnd(handle, left, top, right, bottom); } +void Dialog::restore(Serializer::Data &data) +{ + if(data.size() < 2) + return; + + auto it = data.begin(); + + const auto &pos = *it++; + const auto &size = *it++; + + SetWindowPos(m_handle, HWND_TOP, pos[0], pos[1], + size[0], size[1], SWP_NOZORDER); + onResize(); + + data.erase(data.begin(), it); +} + +void Dialog::save(Serializer::Data &data) const +{ + RECT rect; + GetWindowRect(m_handle, &rect); + + data.push_back({rect.left, rect.top}); + data.push_back({rect.right - rect.left, rect.bottom - rect.top}); +} + void Dialog::onInit() { RECT rect; GetWindowRect(m_handle, &rect); m_initialSize = {rect.right - rect.left, rect.bottom - rect.top}; + center(); + m_resizer.init(m_handle); } void Dialog::onShow() { - center(); } void Dialog::onHide() diff --git a/src/dialog.hpp b/src/dialog.hpp @@ -18,6 +18,8 @@ #ifndef REAPACK_DIALOG_HPP #define REAPACK_DIALOG_HPP +#include "serializer.hpp" + #include <functional> #include <map> #include <set> @@ -107,6 +109,9 @@ public: std::string getText(HWND); void setAnchor(HWND, int flags); + void restore(Serializer::Data &); + void save(Serializer::Data &) const; + void setCloseHandler(const CloseHandler &cb) { m_closeHandler = cb; } protected: diff --git a/src/import.cpp b/src/import.cpp @@ -38,6 +38,8 @@ Import::Import(ReaPack *reapack) void Import::onInit() { + Dialog::onInit(); + SetWindowText(handle(), TITLE); m_url = getControl(IDC_URL); diff --git a/src/listview.cpp b/src/listview.cpp @@ -28,7 +28,7 @@ using namespace std; ListView::ListView(const Columns &columns, HWND handle) - : Control(handle), m_sort(), m_defaultSort() + : Control(handle), m_customizable(false), m_sort(), m_defaultSort() { for(const Column &col : columns) addColumn(col); @@ -293,7 +293,7 @@ bool ListView::onContextMenu(HWND dialog, int x, int y) #endif if(point.y < headerHeight) { - if(m_serializer) // show menu only if header is customizable + if(m_customizable) // show menu only if header is customizable headerMenu(x, y); return true; } @@ -444,18 +444,20 @@ void ListView::resetColumns() } } -void ListView::restore(const string &input, const int userVersion) +void ListView::restore(Serializer::Data &data) { + m_customizable = true; setExStyle(LVS_EX_HEADERDRAGDROP, true); // enable column reordering - const Serializer::Vector &data = m_serializer.read(input, userVersion); if(data.empty()) return; int col = -1; vector<int> order(columnCount()); - for(const auto &rec : data) { + while(!data.empty()) { + const auto &rec = data.front(); + const int left = rec[0]; const int right = rec[1]; @@ -471,6 +473,8 @@ void ListView::restore(const string &input, const int userVersion) break; } + data.pop_front(); + if(++col >= columnCount()) break; } @@ -482,17 +486,14 @@ void ListView::restore(const string &input, const int userVersion) ListView_SetColumnOrderArray(handle(), columnCount(), &order[0]); } -string ListView::save() const +void ListView::save(Serializer::Data &data) const { const Sort sort = m_sort.value_or(Sort()); vector<int> order(columnCount()); ListView_GetColumnOrderArray(handle(), columnCount(), &order[0]); - Serializer::Vector data; data.push_back({sort.column, sort.order}); for(int i = 0; i < columnCount(); i++) data.push_back({order[i], columnWidth(i)}); - - return m_serializer.write(data); } diff --git a/src/listview.hpp b/src/listview.hpp @@ -84,8 +84,8 @@ public: void sortByColumn(int index, SortOrder order = AscendingOrder, bool user = false); void setSortCallback(int i, const SortCallback &cb) { m_sortFuncs[i] = cb; } - void restore(const std::string &, int userVersion); - std::string save() const; + void restore(Serializer::Data &); + void save(Serializer::Data &) const; void resetColumns(); void onSelect(const VoidSignal::slot_type &slot) { m_onSelect.connect(slot); } @@ -114,7 +114,7 @@ private: int translateBack(int internalIndex) const; void headerMenu(int x, int y); - Serializer m_serializer; + bool m_customizable; std::vector<Column> m_cols; std::vector<Row> m_rows; boost::optional<Sort> m_sort; diff --git a/src/manager.cpp b/src/manager.cpp @@ -42,6 +42,8 @@ Manager::Manager(ReaPack *reapack) void Manager::onInit() { + Dialog::onInit(); + m_apply = getControl(IDAPPLY); disable(m_apply); @@ -489,6 +491,8 @@ NetworkConfig::NetworkConfig(NetworkOpts *opts) void NetworkConfig::onInit() { + Dialog::onInit(); + m_proxy = getControl(IDC_PROXY); SetWindowText(m_proxy, make_autostring(m_opts->proxy).c_str()); diff --git a/src/progress.cpp b/src/progress.cpp @@ -32,6 +32,8 @@ Progress::Progress(DownloadQueue *queue) void Progress::onInit() { + Dialog::onInit(); + m_label = getControl(IDC_LABEL); m_progress = GetDlgItem(handle(), IDC_PROGRESS); diff --git a/src/report.cpp b/src/report.cpp @@ -40,6 +40,8 @@ ReportDialog::ReportDialog() void ReportDialog::onInit() { + Dialog::onInit(); + fillReport(); const auto_string &str = make_autostring(m_stream.str()); diff --git a/src/serializer.cpp b/src/serializer.cpp @@ -25,14 +25,14 @@ static const char RECORD_END = ','; using namespace std; -auto Serializer::read(const string &input, const int userVersion) -> Vector +auto Serializer::read(const string &input, const int userVersion) -> Data { m_userVersion = userVersion; bool first = true; istringstream stream(input); - Vector out; + Data out; while(!stream.eof()) { string line; @@ -73,7 +73,7 @@ auto Serializer::read(const string &input, const int userVersion) -> Vector return out; } -string Serializer::write(const Vector &data) const +string Serializer::write(const Data &data) const { if(!m_userVersion) return {}; @@ -84,9 +84,10 @@ string Serializer::write(const Vector &data) const << m_userVersion << FIELD_END << VERSION << RECORD_END; - size_t i = 0; + auto it = data.begin(); + while(true) { - const Record &rec = data[i]; + const Record &rec = *it; size_t j = 0; while(true) { @@ -98,7 +99,9 @@ string Serializer::write(const Vector &data) const break; } - if(++i < data.size()) + it++; + + if(it != data.end()) stream << RECORD_END; else break; diff --git a/src/serializer.hpp b/src/serializer.hpp @@ -20,19 +20,19 @@ #include <array> #include <string> -#include <vector> +#include <list> class Serializer { public: typedef std::array<int, 2> Record; - typedef std::vector<Record> Vector; + typedef std::list<Record> Data; Serializer() : m_userVersion(0) {} int userVersion() const { return m_userVersion; } operator bool() const { return m_userVersion > 0; } - Vector read(const std::string &, int userVersion); - std::string write(const Vector &in) const; + Data read(const std::string &, int userVersion); + std::string write(const Data &in) const; private: int m_userVersion; diff --git a/test/serializer.cpp b/test/serializer.cpp @@ -12,9 +12,10 @@ TEST_CASE("read from serialized data", M) { SECTION("valid") { const auto &out = s.read("1 1,1 2,3 4,5 6", 1); REQUIRE(out.size() == 3); - REQUIRE(out[0] == (Serializer::Record{1,2})); - REQUIRE(out[1] == (Serializer::Record{3,4})); - REQUIRE(out[2] == (Serializer::Record{5,6})); + auto it = out.begin(); + REQUIRE(*it++ == (Serializer::Record{1,2})); + REQUIRE(*it++ == (Serializer::Record{3,4})); + REQUIRE(*it++ == (Serializer::Record{5,6})); REQUIRE(s.userVersion() == 1); REQUIRE(s); @@ -37,13 +38,13 @@ TEST_CASE("read from serialized data", M) { SECTION("not an integer") { const auto &out = s.read("1 1,1 2,hello world,3 4", 1); REQUIRE(out.size() == 1); - REQUIRE(out[0] == (Serializer::Record{1,2})); + REQUIRE(out.front() == (Serializer::Record{1,2})); } SECTION("single field") { const auto &out = s.read("1 1,1 2,3,4 5", 1); REQUIRE(out.size() == 1); - REQUIRE(out[0] == (Serializer::Record{1,2})); + REQUIRE(out.front() == (Serializer::Record{1,2})); } SECTION("empty string") {