[vlc-devel] [RFC 15/82] qt: provide wrapper around vlc_var with simple types
Pierre Lamot
pierre at videolabs.io
Fri Feb 1 14:01:19 CET 2019
values are accesible from Q_PROPERTIES for QML integration
---
modules/gui/qt/Makefile.am | 3 +
modules/gui/qt/util/vlc_var_observer.cpp | 59 +++++
modules/gui/qt/util/vlc_var_observer.hpp | 276 +++++++++++++++++++++++
3 files changed, 338 insertions(+)
create mode 100644 modules/gui/qt/util/vlc_var_observer.cpp
create mode 100644 modules/gui/qt/util/vlc_var_observer.hpp
diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index 0b20509bc0..1f51781643 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -146,6 +146,8 @@ libqt_plugin_la_SOURCES = \
gui/qt/util/singleton.hpp \
gui/qt/util/vlctick.cpp \
gui/qt/util/vlctick.hpp \
+ gui/qt/util/vlc_var_observer.cpp \
+ gui/qt/util/vlc_var_observer.hpp \
gui/qt/util/imagehelper.cpp gui/qt/util/imagehelper.hpp \
gui/qt/styles/seekstyle.cpp gui/qt/styles/seekstyle.hpp
if HAVE_WIN32
@@ -232,6 +234,7 @@ nodist_libqt_plugin_la_SOURCES = \
gui/qt/util/qmenuview.moc.cpp \
gui/qt/util/qvlcapp.moc.cpp \
gui/qt/util/pictureflow.moc.cpp \
+ gui/qt/util/vlc_var_observer.moc.cpp \
gui/qt/util/vlctick.moc.cpp \
gui/qt/util/validators.moc.cpp \
gui/qt/util/buttons/RoundButton.moc.cpp \
diff --git a/modules/gui/qt/util/vlc_var_observer.cpp b/modules/gui/qt/util/vlc_var_observer.cpp
new file mode 100644
index 0000000000..72785cd791
--- /dev/null
+++ b/modules/gui/qt/util/vlc_var_observer.cpp
@@ -0,0 +1,59 @@
+/*****************************************************************************
+ * Copyright (C) 2019 VLC authors and VideoLAN
+ *
+ * This program 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 2 of the License, or
+ * ( at your option ) any later version.
+ *
+ * This program 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include "vlc_var_observer.hpp"
+
+VLCVarBooleanObserver::VLCVarBooleanObserver(vlc_object_t *object, QString property, QObject *parent)
+ : VLCVarObserver<VLCVarBooleanObserver, bool>(object, property, parent)
+{
+}
+
+void VLCVarBooleanObserver::setValue(bool value)
+{
+ setValueInternal(value);
+}
+
+VLCVarStringObserver::VLCVarStringObserver(vlc_object_t *object, QString property, QObject *parent)
+ : VLCVarObserver<VLCVarStringObserver, QString>(object, property, parent)
+{
+}
+
+void VLCVarStringObserver::setValue(QString value)
+{
+ setValueInternal(value);
+}
+
+VLCVarFloatObserver::VLCVarFloatObserver(vlc_object_t *object, QString property, QObject *parent)
+ : VLCVarObserver<VLCVarFloatObserver, float>(object, property, parent)
+{
+}
+
+void VLCVarFloatObserver::setValue(float value)
+{
+ setValueInternal(value);
+}
+
+VLCVarIntObserver::VLCVarIntObserver(vlc_object_t *object, QString property, QObject *parent)
+ : VLCVarObserver<VLCVarIntObserver, int64_t>(object, property, parent)
+{
+}
+
+void VLCVarIntObserver::setValue(int64_t value)
+{
+ setValueInternal(value);
+}
diff --git a/modules/gui/qt/util/vlc_var_observer.hpp b/modules/gui/qt/util/vlc_var_observer.hpp
new file mode 100644
index 0000000000..fd3a5ed20a
--- /dev/null
+++ b/modules/gui/qt/util/vlc_var_observer.hpp
@@ -0,0 +1,276 @@
+/*****************************************************************************
+ * Copyright (C) 2019 VLC authors and VideoLAN
+ *
+ * This program 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 2 of the License, or
+ * ( at your option ) any later version.
+ *
+ * This program 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VLC_VAR_OBSERVER_HPP
+#define VLC_VAR_OBSERVER_HPP
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_variables.h>
+#include <vlc_cxx_helpers.hpp>
+
+#include <QObject>
+
+#include "qt.hpp"
+
+/*
+ * type traits to convert VLC_VAR to C++types
+ */
+template<typename T>
+struct VLCVarTypeTraits {
+};
+
+template<>
+struct VLCVarTypeTraits<QString>
+{
+ static const int var_type = VLC_VAR_STRING;
+ inline static QString fromValue(const vlc_value_t& value) {
+ return value.psz_string;
+ }
+ inline static vlc_value_t toValue(const QString& value) {
+ vlc_value_t ret;
+ ret.psz_string = strdup(qtu(value));
+ return ret;
+ }
+ inline static void releaseValue(vlc_value_t value) {
+ free(value.psz_string);
+ }
+};
+
+template<>
+struct VLCVarTypeTraits<bool>
+{
+ static const int var_type = VLC_VAR_BOOL;
+ inline static bool fromValue(const vlc_value_t& value) {
+ return value.b_bool;
+ }
+ inline static vlc_value_t toValue(bool value) {
+ vlc_value_t ret;
+ ret.b_bool = value;
+ return ret;
+ }
+ inline static void releaseValue(vlc_value_t) {}
+};
+
+template<>
+struct VLCVarTypeTraits<int64_t>
+{
+ static const int var_type = VLC_VAR_INTEGER;
+ inline static int64_t fromValue(const vlc_value_t& value) {
+ return value.i_int;
+ }
+ inline static vlc_value_t toValue(int64_t value) {
+ vlc_value_t ret;
+ ret.i_int = value;
+ return ret;
+ }
+ inline static void releaseValue(vlc_value_t) {}
+};
+
+template<>
+struct VLCVarTypeTraits<float>
+{
+ static const int var_type = VLC_VAR_FLOAT;
+ inline static float fromValue(const vlc_value_t& value) {
+ return value.f_float;
+ }
+ inline static vlc_value_t toValue(float value) {
+ vlc_value_t ret;
+ ret.f_float = value;
+ return ret;
+ }
+ inline static void releaseValue(vlc_value_t) {}
+};
+
+
+//Generic observer
+template<typename Derived, typename BaseType>
+class VLCVarObserver : public QObject
+{
+public:
+ VLCVarObserver(vlc_object_t* object, QString property, QObject* parent)
+ : QObject(parent)
+ , m_property(property)
+ {
+ resetObject(object);
+ Derived* derived = static_cast<Derived*>(this);
+ connect( derived, &Derived::valueChangedInternal, [this](vlc_object_t* object, BaseType val) {
+ this->onValueChangedInternal(object, val);
+ });
+ }
+
+ virtual ~VLCVarObserver()
+ {
+ if (m_object)
+ {
+ Derived* derived = static_cast<Derived*>(this);
+ var_DelCallback(m_object.get(), qtu(m_property), value_modified, derived);
+ }
+ }
+
+ ///change the object beeing observed
+ void resetObject( vlc_object_t* object )
+ {
+ Derived* derived = static_cast<Derived*>(this);
+ if (m_object)
+ var_DelCallback( m_object.get(), qtu(m_property), value_modified, derived );
+
+ m_object.reset( object, true );
+ if (m_object)
+ {
+ int type = var_Type(object, qtu(m_property));
+ if (type == 0) //variable not found
+ {
+ msg_Warn(m_object.get(), "variable %s not found in object", qtu(m_property));
+ m_object.reset(nullptr);
+ return;
+ }
+ assert((type & VLC_VAR_CLASS) == VLCVarTypeTraits<BaseType>::var_type);
+ vlc_value_t currentvalue;
+ if (var_Get(m_object.get(), qtu(m_property), ¤tvalue) == VLC_SUCCESS)
+ {
+ BaseType value = VLCVarTypeTraits<BaseType>::fromValue(currentvalue);
+ if (m_value != value)
+ {
+ m_value = value;
+ emit derived->valueChanged( m_value );
+ }
+ }
+
+ var_AddCallback(m_object.get(), qtu(m_property), value_modified, derived);
+ }
+ }
+
+ BaseType getValue() const
+ {
+ if (!m_object)
+ return BaseType{};
+ return m_value;
+ }
+
+protected:
+ //called by setValue in child classes
+ void setValueInternal(BaseType value)
+ {
+ if (! m_object)
+ return;
+ vlc_value_t vlcvalue = VLCVarTypeTraits<BaseType>::toValue( value );
+ var_Set(m_object.get(), qtu(m_property), vlcvalue);
+ VLCVarTypeTraits<BaseType>::releaseValue(vlcvalue);
+ }
+
+private:
+ //executed on UI thread
+ virtual void onValueChangedInternal(vlc_object_t* object, BaseType value)
+ {
+ if (m_object.get() != object)
+ return;
+ if (m_value != value) {
+ m_value = value;
+ Derived* derived = static_cast<Derived*>(this);
+ emit derived->valueChanged( m_value );
+ }
+ }
+
+
+ //executed on variable thread, this forwards the callback to the UI thread
+ static int value_modified( vlc_object_t * object, char const *, vlc_value_t, vlc_value_t newValue, void * data)
+ {
+ Derived* that = static_cast<Derived*>(data);
+ emit that->onValueChangedInternal( object, VLCVarTypeTraits<BaseType>::fromValue( newValue ) );
+ return VLC_SUCCESS;
+ }
+
+ typedef vlc_shared_data_ptr_type(vlc_object_t, vlc_object_hold, vlc_object_release) ObjectPtr;
+ ObjectPtr m_object;
+ QString m_property;
+ BaseType m_value;
+};
+
+//specialisation
+
+class VLCVarBooleanObserver : public VLCVarObserver<VLCVarBooleanObserver, bool>
+{
+ Q_OBJECT
+public:
+ Q_PROPERTY(bool value READ getValue WRITE setValue NOTIFY valueChanged)
+
+ VLCVarBooleanObserver(vlc_object_t* object, QString property, QObject* parent = nullptr);
+
+public slots:
+ void setValue(bool value);
+
+signals:
+ void valueChanged( bool );
+ void valueChangedInternal(vlc_object_t *, bool );
+};
+
+class VLCVarStringObserver : public VLCVarObserver<VLCVarStringObserver, QString>
+{
+ Q_OBJECT
+public:
+ Q_PROPERTY(QString value READ getValue WRITE setValue NOTIFY valueChanged)
+
+ VLCVarStringObserver(vlc_object_t* object, QString property, QObject* parent = nullptr);
+
+public slots:
+ void setValue(QString value);
+
+signals:
+ void valueChanged( QString );
+ void valueChangedInternal( vlc_object_t *, QString );
+};
+
+class VLCVarFloatObserver : public VLCVarObserver<VLCVarFloatObserver, float>
+{
+ Q_OBJECT
+public:
+ Q_PROPERTY(float value READ getValue WRITE setValue NOTIFY valueChanged)
+
+ VLCVarFloatObserver(vlc_object_t* object, QString property, QObject* parent = nullptr);
+
+public slots:
+ void setValue(float value);
+
+signals:
+ void valueChanged( float );
+ void valueChangedInternal( vlc_object_t *, float );
+};
+
+
+class VLCVarIntObserver : public VLCVarObserver<VLCVarIntObserver, int64_t>
+{
+ Q_OBJECT
+public:
+ Q_PROPERTY(int64_t value READ getValue WRITE setValue NOTIFY valueChanged)
+
+ VLCVarIntObserver(vlc_object_t* object, QString property, QObject* parent = nullptr);
+
+public slots:
+ void setValue(int64_t value);
+
+signals:
+ void valueChanged( int64_t );
+ void valueChangedInternal( vlc_object_t *, int64_t );
+};
+
+#endif // VLC_VAR_OBSERVER_HPP
--
2.19.1
More information about the vlc-devel
mailing list