From a7195519a25b715a5786383450a25f0420f7aeb5 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Mon, 30 Dec 2013 08:19:24 +0100 Subject: initial ng options impl, untested --- facetracknoir/options.hpp | 200 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 facetracknoir/options.hpp diff --git a/facetracknoir/options.hpp b/facetracknoir/options.hpp new file mode 100644 index 00000000..7db75941 --- /dev/null +++ b/facetracknoir/options.hpp @@ -0,0 +1,200 @@ +/* Copyright (c) 2013 Stanislaw Halik + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace options { + template + inline T qcruft_to_t(const QVariant& t); + + template<> + inline int qcruft_to_t(const QVariant& t) + { + return t.toInt(); + } + + template<> + inline bool qcruft_to_t(const QVariant& t) + { + return t.toBool(); + } + + template<> + inline double qcruft_to_t(const QVariant& t) + { + return t.toDouble(); + } + + template<> + inline float qcruft_to_t(const QVariant& t) + { + return t.toFloat(); + } + + // snapshot of qsettings group at given time + class group { + private: + QMap map; + QString name; + public: + group(const QString& name, QSettings& s) : name(name) + { + s.beginGroup(name); + for (auto& k : s.childKeys()) + map[k] = s.value(k); + s.endGroup(); + } + static constexpr const char* org = "opentrack"; + void save() { + QSettings s(org); + s.beginGroup(name); + for (auto& k : map.keys()) + s.setValue(k, map[k]); + s.endGroup(); + } + template + T get(const QString& k) { + return qcruft_to_t(map.value(k)); + } + + void put(const QString& s, const QVariant& d) + { + map[s] = d; + } + }; + + class bundle { + private: + const QString group_name; + group saved; + group transient; + bundle(const bundle&) = delete; + bundle& operator=(const bundle&) = delete; + bool modified; + public: + bundle(const QString& group_name, QSettings& s) : + group_name(group_name), + saved(group_name, s), + transient(saved), + modified(false) + { + } + std::shared_ptr make(const QString& name, QSettings& s) { + assert(s.format() == QSettings::IniFormat); + return std::make_shared(name, s); + } + void store(QString& name, QVariant& datum) + { + modified = true; + transient.put(name, datum); + } + template + T get(QString& name) { + transient.get(name); + } + void save() + { + modified = false; + saved = transient; + transient.save(); + } + void revert() + { + modified = false; + transient = saved; + } + }; + + typedef std::shared_ptr pbundle; + + class QCruft : public QObject { + }; + + template + class value : public QCruft { + private: + const QString self_name; + pbundle b; + public: + value(const pbundle& b, const QString& name) : + self_name(name), + b(b) + { + } + operator T() { return b->get(self_name); } + T& operator=(const T& datum) { + b->store(self_name, datum); + emit valueChanged(datum); + return datum; + } + public slots: + void setValue(const T datum) { + this->operator =(datum); + } + signals: + void valueChanged(T datum); + }; + + template + inline void tie(value&, Q*); + + template<> + inline void tie(value& v, QComboBox* cb) + { + QObject::connect(cb, SIGNAL(currentIndexChanged(int)), &v, SLOT(setValue(int))); + QObject::connect(&v, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int))); + } + + template<> + inline void tie(value& v, QComboBox* cb) + { + QObject::connect(cb, SIGNAL(currentTextChanged(QString)), &v, SLOT(setValue(QString))); + QObject::connect(&v, SIGNAL(valueChanged(QString)), &v, SLOT(setValue(QString))); + } + + template<> + inline void tie(value& v, QCheckBox* cb) + { + QObject::connect(cb, SIGNAL(toggled(bool)), &v, SLOT(setValue(bool))); + QObject::connect(&v, SIGNAL(valueChanged(bool)), cb, SLOT(setChecked(bool))); + } + + template<> + inline void tie(value& v, QDoubleSpinBox* dsb) + { + QObject::connect(dsb, SIGNAL(valueChanged(double)), &v, SLOT(setValue(double))); + QObject::connect(&v, SIGNAL(valueChanged(double)), dsb, SLOT(setValue(double))); + } + + template<> + inline void tie(value& v, QSpinBox* sb) + { + QObject::connect(sb, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int))); + QObject::connect(&v, SIGNAL(valueChanged(int)), sb, SLOT(setValue(int))); + } + + template<> + inline void tie(value& v, QSlider* sl) + { + QObject::connect(sl, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int))); + QObject::connect(&v, SIGNAL(valueChanged(int)), sl, SLOT(setValue(int))); + } +} -- cgit v1.2.3