diff options
author | David Robillard <d@drobilla.net> | 2021-05-11 13:07:21 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2021-05-11 13:37:52 -0400 |
commit | c6ae340c6222240dc45e9bba714c722cebece186 (patch) | |
tree | 9721a06a4303e0fd50f31b05b143922ba8775745 | |
parent | 0f1e403b0cab6d364abfb894ed209082429a74dd (diff) | |
download | patchage-c6ae340c6222240dc45e9bba714c722cebece186.tar.gz patchage-c6ae340c6222240dc45e9bba714c722cebece186.tar.bz2 patchage-c6ae340c6222240dc45e9bba714c722cebece186.zip |
Add general configuration setting mechanism
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | src/Configuration.cpp | 59 | ||||
-rw-r--r-- | src/Configuration.hpp | 90 | ||||
-rw-r--r-- | src/Coord.hpp | 12 | ||||
-rw-r--r-- | src/Patchage.cpp | 59 | ||||
-rw-r--r-- | src/Setting.hpp | 75 |
6 files changed, 210 insertions, 88 deletions
@@ -2,10 +2,11 @@ patchage (1.0.5) unstable; * Fix ALSA sequencer port subscriptions * Fix crash on client disconnection + * Save "human names" setting in configuration * Show latency in toolbar with 2 decimal places * Switch to C++14 - -- David Robillard <d@drobilla.net> Tue, 11 May 2021 17:27:16 +0000 + -- David Robillard <d@drobilla.net> Tue, 11 May 2021 17:37:26 +0000 patchage (1.0.4) stable; diff --git a/src/Configuration.cpp b/src/Configuration.cpp index d615fba..665e66f 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -17,6 +17,7 @@ #include "Configuration.hpp" #include "PortType.hpp" +#include "Setting.hpp" #include "SignalDirection.hpp" #include "patchage_config.h" @@ -38,6 +39,9 @@ static const char* const port_type_names[N_PORT_TYPES] = {"JACK_AUDIO", Configuration::Configuration() { + std::get<setting::WindowLocation>(_settings).value = Coord{0.0, 0.0}; + std::get<setting::WindowSize>(_settings).value = Coord{960.0, 540.0}; + #ifdef PATCHAGE_USE_LIGHT_THEME _port_colors[static_cast<unsigned>(PortType::jack_audio)] = _default_port_colors[static_cast<unsigned>(PortType::jack_audio)] = @@ -108,6 +112,10 @@ Configuration::set_module_location(const std::string& name, SignalDirection type, Coord loc) { + if (name.empty()) { + return; + } + auto i = _module_settings.find(name); if (i == _module_settings.end()) { i = _module_settings @@ -149,7 +157,9 @@ Configuration::get_module_split(const std::string& name, bool default_val) const void Configuration::set_module_split(const std::string& name, bool split) { - _module_settings[name].split = split; + if (!name.empty()) { + _module_settings[name].split = split; + } } /** Return a vector of filenames in descending order by preference. */ @@ -211,23 +221,27 @@ Configuration::load() } if (key == "window_location") { - file >> _window_location.x >> _window_location.y; + auto& setting = std::get<setting::WindowLocation>(_settings); + file >> setting.value.x >> setting.value.y; } else if (key == "window_size") { - file >> _window_size.x >> _window_size.y; + auto& setting = std::get<setting::WindowSize>(_settings); + file >> setting.value.x >> setting.value.y; } else if (key == "zoom_level") { - file >> _zoom; + file >> std::get<setting::Zoom>(_settings).value; } else if (key == "font_size") { - file >> _font_size; + file >> std::get<setting::FontSize>(_settings).value; } else if (key == "show_toolbar") { - file >> _show_toolbar; + file >> std::get<setting::ToolbarVisible>(_settings).value; } else if (key == "sprung_layout") { - file >> _sprung_layout; + file >> std::get<setting::SprungLayout>(_settings).value; } else if (key == "show_messages") { - file >> _show_messages; + file >> std::get<setting::MessagesVisible>(_settings).value; } else if (key == "sort_ports") { - file >> _sort_ports; + file >> std::get<setting::SortedPorts>(_settings).value; } else if (key == "messages_height") { - file >> _messages_height; + file >> std::get<setting::MessagesHeight>(_settings).value; + } else if (key == "human_names") { + file >> std::get<setting::HumanNames>(_settings).value; } else if (key == "port_color") { std::string type_name; uint32_t rgba = 0u; @@ -319,17 +333,20 @@ Configuration::save() return; } - file << "window_location " << _window_location.x << " " << _window_location.y - << std::endl; - file << "window_size " << _window_size.x << " " << _window_size.y - << std::endl; - file << "zoom_level " << _zoom << std::endl; - file << "font_size " << _font_size << std::endl; - file << "show_toolbar " << _show_toolbar << std::endl; - file << "sprung_layout " << _sprung_layout << std::endl; - file << "show_messages " << _show_messages << std::endl; - file << "sort_ports " << _sort_ports << std::endl; - file << "messages_height " << _messages_height << std::endl; + file << "window_location " << get<setting::WindowLocation>().x << " " + << get<setting::WindowLocation>().y << std::endl; + + file << "window_size " << get<setting::WindowSize>().x << " " + << get<setting::WindowSize>().y << std::endl; + + file << "zoom_level " << get<setting::Zoom>() << std::endl; + file << "font_size " << get<setting::FontSize>() << std::endl; + file << "show_toolbar " << get<setting::ToolbarVisible>() << std::endl; + file << "sprung_layout " << get<setting::SprungLayout>() << std::endl; + file << "show_messages " << get<setting::MessagesVisible>() << std::endl; + file << "sort_ports " << get<setting::SortedPorts>() << std::endl; + file << "messages_height " << get<setting::MessagesHeight>() << std::endl; + file << "human_names " << get<setting::HumanNames>() << std::endl; file << std::hex << std::uppercase; for (int i = 0; i < N_PORT_TYPES; ++i) { diff --git a/src/Configuration.hpp b/src/Configuration.hpp index 75fdcfc..110a4fb 100644 --- a/src/Configuration.hpp +++ b/src/Configuration.hpp @@ -19,6 +19,7 @@ #include "Coord.hpp" #include "PortType.hpp" +#include "Setting.hpp" #include "SignalDirection.hpp" #include <boost/optional/optional.hpp> @@ -26,6 +27,7 @@ #include <cstdint> #include <map> #include <string> +#include <tuple> #define N_PORT_TYPES 5 @@ -34,7 +36,7 @@ namespace patchage { class Configuration { public: - Configuration(); + explicit Configuration(); void load(); void save(); @@ -50,44 +52,54 @@ public: void set_module_split(const std::string& name, bool split); bool get_module_split(const std::string& name, bool default_val) const; - float get_zoom() const { return _zoom; } - void set_zoom(float zoom) { _zoom = zoom; } - float get_font_size() const { return _font_size; } - void set_font_size(float font_size) { _font_size = font_size; } - - float get_show_toolbar() const { return _show_toolbar; } - void set_show_toolbar(float show_toolbar) { _show_toolbar = show_toolbar; } - - float get_sprung_layout() const { return _sprung_layout; } - void set_sprung_layout(float sprung_layout) + uint32_t get_port_color(PortType type) const { - _sprung_layout = sprung_layout; + return _port_colors[static_cast<unsigned>(type)]; } - bool get_show_messages() const { return _show_messages; } - void set_show_messages(bool show_messages) { _show_messages = show_messages; } + void set_port_color(PortType type, uint32_t rgba) + { + _port_colors[static_cast<unsigned>(type)] = rgba; + } - bool get_sort_ports() const { return _sort_ports; } - void set_sort_ports(bool sort_ports) { _sort_ports = sort_ports; } + // Set a global configuration setting + template<class S> + void set(typename S::Value value) + { + S& setting = std::get<S>(_settings); - int get_messages_height() const { return _messages_height; } - void set_messages_height(int height) { _messages_height = height; } + if (setting.value != value) { + setting.value = std::move(value); + } + } - uint32_t get_port_color(PortType type) const + // Get a global configuration setting + template<class S> + typename S::Value get() const { - return _port_colors[static_cast<unsigned>(type)]; + return std::get<S>(_settings).value; } - void set_port_color(PortType type, uint32_t rgba) + /// Call `visitor` once with each configuration setting + template<class Visitor> + void each(Visitor visitor) { - _port_colors[static_cast<unsigned>(type)] = rgba; + visitor(std::get<setting::FontSize>(_settings)); + visitor(std::get<setting::HumanNames>(_settings)); + visitor(std::get<setting::MessagesHeight>(_settings)); + visitor(std::get<setting::MessagesVisible>(_settings)); + visitor(std::get<setting::SortedPorts>(_settings)); + visitor(std::get<setting::SprungLayout>(_settings)); + visitor(std::get<setting::ToolbarVisible>(_settings)); + visitor(std::get<setting::WindowLocation>(_settings)); + visitor(std::get<setting::WindowSize>(_settings)); + visitor(std::get<setting::Zoom>(_settings)); + + for (auto i = 0u; i < N_PORT_TYPES; ++i) { + visitor(setting::PortColor{static_cast<PortType>(i), _port_colors[i]}); + } } - Coord get_window_location() { return _window_location; } - void set_window_location(Coord loc) { _window_location = loc; } - Coord get_window_size() { return _window_size; } - void set_window_size(Coord size) { _window_size = size; } - private: struct ModuleSettings { explicit ModuleSettings(bool s = false) @@ -105,16 +117,20 @@ private: uint32_t _default_port_colors[N_PORT_TYPES] = {}; uint32_t _port_colors[N_PORT_TYPES] = {}; - Coord _window_location{0.0, 0.0}; - Coord _window_size{960.0, 540.0}; - - float _zoom = 1.0f; - float _font_size = 12.0f; - int _messages_height = 0; - bool _show_toolbar = true; - bool _sprung_layout = false; - bool _show_messages = false; - bool _sort_ports = true; + using Settings = std::tuple<setting::AlsaAttached, + setting::FontSize, + setting::HumanNames, + setting::JackAttached, + setting::MessagesHeight, + setting::MessagesVisible, + setting::SortedPorts, + setting::SprungLayout, + setting::ToolbarVisible, + setting::WindowLocation, + setting::WindowSize, + setting::Zoom>; + + Settings _settings; }; } // namespace patchage diff --git a/src/Coord.hpp b/src/Coord.hpp index f77bc40..2d6a85a 100644 --- a/src/Coord.hpp +++ b/src/Coord.hpp @@ -24,6 +24,18 @@ struct Coord { double y{0.0}; }; +inline bool +operator==(const Coord& lhs, const Coord& rhs) +{ + return lhs.x == rhs.x && lhs.y == rhs.y; +} + +inline bool +operator!=(const Coord& lhs, const Coord& rhs) +{ + return !(lhs == rhs); +} + } // namespace patchage #endif // PATCHAGE_COORD_HPP diff --git a/src/Patchage.cpp b/src/Patchage.cpp index a4bb960..9c346f2 100644 --- a/src/Patchage.cpp +++ b/src/Patchage.cpp @@ -26,6 +26,7 @@ #include "Driver.hpp" #include "Event.hpp" #include "Legend.hpp" +#include "Setting.hpp" #include "UIFile.hpp" #include "event_to_string.hpp" #include "handle_event.hpp" @@ -285,19 +286,19 @@ Patchage::Patchage(Options options) _canvas->widget().show(); _main_win->present(); - _conf.set_font_size(_canvas->get_default_font_size()); + _conf.set<setting::FontSize>(_canvas->get_default_font_size()); _conf.load(); - _canvas->set_zoom(_conf.get_zoom()); - _canvas->set_font_size(_conf.get_font_size()); - if (_conf.get_sort_ports()) { + _canvas->set_zoom(_conf.get<setting::Zoom>()); + _canvas->set_font_size(_conf.get<setting::FontSize>()); + if (_conf.get<setting::SortedPorts>()) { _canvas->set_port_order(port_order, nullptr); } - _main_win->resize(static_cast<int>(_conf.get_window_size().x), - static_cast<int>(_conf.get_window_size().y)); + _main_win->resize(static_cast<int>(_conf.get<setting::WindowSize>().x), + static_cast<int>(_conf.get<setting::WindowSize>().y)); - _main_win->move(static_cast<int>(_conf.get_window_location().x), - static_cast<int>(_conf.get_window_location().y)); + _main_win->move(static_cast<int>(_conf.get<setting::WindowLocation>().x), + static_cast<int>(_conf.get<setting::WindowLocation>().y)); _legend = new Legend(_conf); _legend->signal_color_changed.connect( @@ -337,9 +338,9 @@ Patchage::Patchage(Options options) _menu_alsa_disconnect->set_sensitive(false); } - _menu_view_toolbar->set_active(_conf.get_show_toolbar()); - _menu_view_sprung_layout->set_active(_conf.get_sprung_layout()); - _menu_view_sort_ports->set_active(_conf.get_sort_ports()); + _menu_view_toolbar->set_active(_conf.get<setting::ToolbarVisible>()); + _menu_view_sprung_layout->set_active(_conf.get<setting::SprungLayout>()); + _menu_view_sort_ports->set_active(_conf.get<setting::SortedPorts>()); g_signal_connect( _main_win->gobj(), "configure-event", G_CALLBACK(configure_cb), this); @@ -398,7 +399,7 @@ Patchage::idle_callback() // Initial run, attach if (_attach) { attach(); - _menu_view_messages->set_active(_conf.get_show_messages()); + _menu_view_messages->set_active(_conf.get<setting::MessagesVisible>()); _attach = false; } @@ -552,8 +553,8 @@ Patchage::store_window_location() int size_y = 0; _main_win->get_size(size_x, size_y); - _conf.set_window_location({double(loc_x), double(loc_y)}); - _conf.set_window_size({double(size_x), double(size_y)}); + _conf.set<setting::WindowLocation>({double(loc_x), double(loc_y)}); + _conf.set<setting::WindowSize>({double(size_x), double(size_y)}); } void @@ -601,7 +602,7 @@ Patchage::on_sprung_layout_toggled() const bool sprung = _menu_view_sprung_layout->get_active(); _canvas->set_sprung_layout(sprung); - _conf.set_sprung_layout(sprung); + _conf.set<setting::SprungLayout>(sprung); } void @@ -641,7 +642,7 @@ Patchage::on_view_sort_ports() { const bool sort_ports = this->sort_ports(); _canvas->set_port_order(sort_ports ? port_order : nullptr, nullptr); - _conf.set_sort_ports(sort_ports); + _conf.set<setting::SortedPorts>(sort_ports); refresh(); } @@ -650,7 +651,7 @@ Patchage::on_zoom_in() { const float zoom = _canvas->get_zoom() * 1.25; _canvas->set_zoom(zoom); - _conf.set_zoom(zoom); + _conf.set<setting::Zoom>(zoom); } void @@ -658,21 +659,21 @@ Patchage::on_zoom_out() { const float zoom = _canvas->get_zoom() * 0.75; _canvas->set_zoom(zoom); - _conf.set_zoom(zoom); + _conf.set<setting::Zoom>(zoom); } void Patchage::on_zoom_normal() { _canvas->set_zoom(1.0); - _conf.set_zoom(1.0); + _conf.set<setting::Zoom>(1.0); } void Patchage::on_zoom_full() { _canvas->zoom_full(); - _conf.set_zoom(_canvas->get_zoom()); + _conf.set<setting::Zoom>(_canvas->get_zoom()); } void @@ -680,7 +681,7 @@ Patchage::on_increase_font_size() { const float points = _canvas->get_font_size() + 1.0; _canvas->set_font_size(points); - _conf.set_font_size(points); + _conf.set<setting::FontSize>(points); } void @@ -688,14 +689,14 @@ Patchage::on_decrease_font_size() { const float points = _canvas->get_font_size() - 1.0; _canvas->set_font_size(points); - _conf.set_font_size(points); + _conf.set<setting::FontSize>(points); } void Patchage::on_normal_font_size() { _canvas->set_font_size(_canvas->get_default_font_size()); - _conf.set_font_size(_canvas->get_default_font_size()); + _conf.set<setting::FontSize>(_canvas->get_default_font_size()); } static inline guint @@ -758,13 +759,13 @@ void Patchage::on_messages_resized(Gtk::Allocation&) { const int max_pos = _main_paned->get_allocation().get_height(); - _conf.set_messages_height(max_pos - _main_paned->get_position()); + _conf.set<setting::MessagesHeight>(max_pos - _main_paned->get_position()); } void Patchage::save() { - _conf.set_zoom(_canvas->get_zoom()); // Can be changed by ganv + _conf.set<setting::Zoom>(_canvas->get_zoom()); // Can be changed by ganv _conf.save(); } @@ -844,7 +845,7 @@ Patchage::on_view_messages() if (!_pane_initialized) { const int min_height = _log.min_height(); const int max_pos = _main_paned->get_allocation().get_height(); - const int conf_height = _conf.get_messages_height(); + const int conf_height = _conf.get<setting::MessagesHeight>(); _main_paned->set_position(max_pos - std::max(conf_height, min_height)); _pane_initialized = true; @@ -852,10 +853,10 @@ Patchage::on_view_messages() _log_scrolledwindow->show(); _status_text->scroll_to_mark(_status_text->get_buffer()->get_insert(), 0); - _conf.set_show_messages(true); + _conf.set<setting::MessagesVisible>(true); } else { _log_scrolledwindow->hide(); - _conf.set_show_messages(false); + _conf.set<setting::MessagesVisible>(false); } } @@ -868,7 +869,7 @@ Patchage::on_view_toolbar() _toolbar->hide(); } - _conf.set_show_toolbar(_menu_view_toolbar->get_active()); + _conf.set<setting::ToolbarVisible>(_menu_view_toolbar->get_active()); } bool diff --git a/src/Setting.hpp b/src/Setting.hpp new file mode 100644 index 0000000..ce4bd62 --- /dev/null +++ b/src/Setting.hpp @@ -0,0 +1,75 @@ +/* This file is part of Patchage. + * Copyright 2007-2021 David Robillard <d@drobilla.net> + * + * Patchage is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Patchage is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License + * along with Patchage. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef PATCHAGE_SETTING_HPP +#define PATCHAGE_SETTING_HPP + +#include "ClientID.hpp" +#include "Coord.hpp" +#include "PortID.hpp" +#include "PortType.hpp" +#include "SignalDirection.hpp" + +#include <boost/variant/variant.hpp> + +namespace patchage { +namespace setting { + +template<class T> +struct Setting { + using Value = T; + + Value value{}; +}; + +struct PortColor { + PortType type{}; + uint32_t value{}; +}; + +struct AlsaAttached : Setting<bool> {}; +struct FontSize : Setting<float> {}; +struct HumanNames : Setting<bool> {}; +struct JackAttached : Setting<bool> {}; +struct MessagesHeight : Setting<int> {}; +struct MessagesVisible : Setting<bool> {}; +struct SortedPorts : Setting<bool> {}; +struct SprungLayout : Setting<bool> {}; +struct ToolbarVisible : Setting<bool> {}; +struct WindowLocation : Setting<Coord> {}; +struct WindowSize : Setting<Coord> {}; +struct Zoom : Setting<float> {}; + +} // namespace setting + +/// A configuration setting +using Setting = boost::variant<setting::AlsaAttached, + setting::FontSize, + setting::HumanNames, + setting::JackAttached, + setting::MessagesHeight, + setting::MessagesVisible, + setting::PortColor, + setting::SortedPorts, + setting::SprungLayout, + setting::ToolbarVisible, + setting::WindowLocation, + setting::WindowSize, + setting::Zoom>; + +} // namespace patchage + +#endif // PATCHAGE_SETTING_HPP |