/* Copyright (c) 2015-2016, 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 "value-traits.hpp" #include "value.hpp" #include "compat/run-in-thread.hpp" #include "compat/macros.hpp" #include #include #include #include #include #include #include #include #include #include #include "export.hpp" #if defined __GNUG__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wattributes" #endif namespace options { namespace detail { template struct tie_setting_traits_helper { using traits = detail::value_traits; using value_type = typename traits::value_type; using element_type = typename traits::element_type; static element_type to_element_type(const value& v) { return static_cast(static_cast(v)); } }; template struct tie_setting_traits final : tie_setting_traits_helper { static constexpr inline bool should_bind_to_itemdata() { return false; } }; template struct tie_setting_traits>> : tie_setting_traits_helper { static constexpr inline bool should_bind_to_itemdata() { return true; } static t itemdata_to_value(int, const QVariant& var) { return static_cast(var.toInt()); } }; } // ns options::detail template> std::enable_if_t tie_setting(value& v, QComboBox* cb, const traits_type& traits = traits_type()) { using element_type = typename detail::value_traits::element_type; cb->setCurrentIndex(cb->findData(traits.to_element_type(v))); v = traits.itemdata_to_value(cb->currentIndex(), cb->currentData()); base_value::connect(cb, static_cast(&QComboBox::currentIndexChanged), &v, [&v, cb, traits](int idx) { run_in_thread_sync(cb, [&, traits]() { v = traits.itemdata_to_value(idx, cb->currentData()); }); }, v.DIRECT_CONNTYPE); base_value::connect(&v, base_value::value_changed(), cb, [cb](int x) { run_in_thread_sync(cb, [&]() { cb->setCurrentIndex(cb->findData(x)); }); }, v.DIRECT_CONNTYPE); } template void tie_setting(value& v, QLabel* lb, F&& fun) { auto closure = [=](cv_qualified x) { lb->setText(fun(x)); }; closure(v()); base_value::connect(&v, base_value::value_changed(), lb, closure, v.SAFE_CONNTYPE); } template void tie_setting(value& v, QObject* obj, F&& fun) { if (obj == nullptr) abort(); fun(v()); base_value::connect(&v, base_value::value_changed(), obj, fun, v.DIRECT_CONNTYPE); } // XXX TODO add combobox transform both ways via std::function // need for non-translated `module_settings' dylib names OTR_OPTIONS_EXPORT void tie_setting(value& v, QComboBox* cb); OTR_OPTIONS_EXPORT void tie_setting(value& v, QComboBox* cb); OTR_OPTIONS_EXPORT void tie_setting(value& v, QComboBox* cb); OTR_OPTIONS_EXPORT void tie_setting(value& v, QCheckBox* cb); OTR_OPTIONS_EXPORT void tie_setting(value& v, QDoubleSpinBox* dsb); OTR_OPTIONS_EXPORT void tie_setting(value& v, QSpinBox* sb); OTR_OPTIONS_EXPORT void tie_setting(value& v, QLineEdit* le); OTR_OPTIONS_EXPORT void tie_setting(value& v, QLabel* lb); OTR_OPTIONS_EXPORT void tie_setting(value& v, QTabWidget* t); OTR_OPTIONS_EXPORT void tie_setting(value& v, QSlider* w); } // ns options #if defined __GNUG__ # pragma GCC diagnostic pop #endif