diff options
Diffstat (limited to 'src/sensorsquick/qmlsensor.cpp')
-rw-r--r-- | src/sensorsquick/qmlsensor.cpp | 577 |
1 files changed, 577 insertions, 0 deletions
diff --git a/src/sensorsquick/qmlsensor.cpp b/src/sensorsquick/qmlsensor.cpp new file mode 100644 index 00000000..0afa91ea --- /dev/null +++ b/src/sensorsquick/qmlsensor.cpp @@ -0,0 +1,577 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtSensors module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmlsensor_p.h" +#include <QtSensors/QSensor> +#include <QDebug> +#include <QtCore/private/qobject_p.h> + +QT_BEGIN_NAMESPACE + +class QmlSensorPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QmlSensor) +public: + + QList<QmlSensorRange *> availableRanges; + QList<QmlSensorOutputRange *> outputRanges; +}; + +template<typename Item> +qsizetype readonlyListCount(QQmlListProperty<Item> *p) +{ + return static_cast<const QList<Item *> *>(p->data)->count(); +} + +template<typename Item> +Item *readonlyListAt(QQmlListProperty<Item> *p, qsizetype idx) +{ + return static_cast<const QList<Item *> *>(p->data)->at(idx); +}; + +template<typename Item> +QQmlListProperty<Item> readonlyListProperty(const QObject *o, const QList<Item *> *list) +{ + // Unfortunately QQmlListProperty won't accept a const object, even on the readonly ctor. + return QQmlListProperty<Item>(const_cast<QObject *>(o), const_cast<QList<Item *> *>(list), + readonlyListCount<Item>, readonlyListAt<Item>); +} + +/*! + \qmltype Sensor + \instantiates QmlSensor + \inqmlmodule QtSensors + \since QtSensors 5.0 + \brief The Sensor element serves as a base type for sensors. + + The Sensor element serves as a base type for sensors. + + This element wraps the QSensor class. Please see the documentation for + QSensor for details. + + This element cannot be directly created. Please use one of the sub-classes instead. +*/ + +QmlSensor::QmlSensor(QObject *parent) + : QObject(*(new QmlSensorPrivate), parent) + , m_parsed(false) + , m_active(false) + , m_reading(0) +{ +} + +QmlSensor::~QmlSensor() +{ +} + +/*! + \qmlproperty string Sensor::identifier + This property holds the backend identifier for the sensor. + + Please see QSensor::identifier for information about this property. +*/ + +QString QmlSensor::identifier() const +{ + return m_identifier; +} + +void QmlSensor::setIdentifier(const QString &identifier) +{ + if (m_parsed) return; + m_identifier = identifier; + Q_EMIT identifierChanged(); +} + +/*! + \qmlproperty string Sensor::type + This property holds the type of the sensor. +*/ + +QString QmlSensor::type() const +{ + return QString::fromLatin1(sensor()->type()); +} + +/*! + \qmlproperty bool Sensor::connectedToBackend + This property holds a value indicating if the sensor has connected to a backend. + + Please see QSensor::connectedToBackend for information about this property. +*/ + +bool QmlSensor::isConnectedToBackend() const +{ + return sensor()->isConnectedToBackend(); +} + +/*! + \qmlproperty bool Sensor::busy + This property holds a value to indicate if the sensor is busy. + + Please see QSensor::busy for information about this property. +*/ + +bool QmlSensor::isBusy() const +{ + return sensor()->isBusy(); +} + +/*! + \qmlproperty bool Sensor::active + This property holds a value to indicate if the sensor is active. + + Please see QSensor::active for information about this property. +*/ + +void QmlSensor::setActive(bool active) +{ + m_active = active; + if (!m_parsed) return; // delay (it'll get called again later)! + bool wasActive = sensor()->isActive(); + if (wasActive == active) return; + if (active) { + sensor()->start(); + m_active = sensor()->isActive(); + } else { + sensor()->stop(); + } + if (m_active != wasActive) + emit activeChanged(); +} + +bool QmlSensor::isActive() const +{ + return m_active; +} + +/*! + \qmlproperty bool Sensor::alwaysOn + This property holds a value to indicate if the sensor should remain running when the screen is off. + + Please see QSensor::alwaysOn for information about this property. +*/ + +bool QmlSensor::isAlwaysOn() const +{ + return sensor()->isAlwaysOn(); +} + +void QmlSensor::setAlwaysOn(bool alwaysOn) +{ + sensor()->setAlwaysOn(alwaysOn); +} + +/*! + \qmlproperty bool Sensor::skipDuplicates + \since QtSensors 5.1 + + This property indicates whether duplicate reading values should be omitted. + + Please see QSensor::skipDuplicates for information about this property. +*/ + +bool QmlSensor::skipDuplicates() const +{ + return sensor()->skipDuplicates(); +} + +void QmlSensor::setSkipDuplicates(bool skipDuplicates) +{ + sensor()->setSkipDuplicates(skipDuplicates); +} + +/*! + \qmlproperty list<Range> Sensor::availableDataRates + This property holds the data rates that the sensor supports. + + Please see QSensor::availableDataRates for information about this property. +*/ +QQmlListProperty<QmlSensorRange> QmlSensor::availableDataRates() const +{ + Q_D(const QmlSensor); + return readonlyListProperty<QmlSensorRange>(this, &d->availableRanges); +} + +/*! + \qmlproperty int Sensor::dataRate + This property holds the data rate that the sensor should be run at. + + Please see QSensor::dataRate for information about this property. +*/ + +int QmlSensor::dataRate() const +{ + return sensor()->dataRate(); +} + +void QmlSensor::setDataRate(int rate) +{ + if (rate != dataRate()) { + sensor()->setDataRate(rate); + Q_EMIT dataRateChanged(); + } +} + +/*! + \qmlproperty list<OutputRange> Sensor::outputRanges + This property holds a list of output ranges the sensor supports. + + Please see QSensor::outputRanges for information about this property. +*/ + +QQmlListProperty<QmlSensorOutputRange> QmlSensor::outputRanges() const +{ + Q_D(const QmlSensor); + return readonlyListProperty<QmlSensorOutputRange>(this, &d->outputRanges); +} + +/*! + \qmlproperty int Sensor::outputRange + This property holds the output range in use by the sensor. + + Please see QSensor::outputRange for information about this property. +*/ + +int QmlSensor::outputRange() const +{ + return sensor()->outputRange(); +} + +void QmlSensor::setOutputRange(int index) +{ + int oldRange = outputRange(); + if (oldRange == index) return; + sensor()->setOutputRange(index); + if (sensor()->outputRange() == index) + Q_EMIT outputRangeChanged(); +} + +/*! + \qmlproperty string Sensor::description + This property holds a descriptive string for the sensor. +*/ + +QString QmlSensor::description() const +{ + return sensor()->description(); +} + +/*! + \qmlproperty int Sensor::error + This property holds the last error code set on the sensor. +*/ + +int QmlSensor::error() const +{ + return sensor()->error(); +} + +/*! + \qmlproperty SensorReading Sensor::reading + This property holds the reading class. + + Please see QSensor::reading for information about this property. + \sa {QML Reading types} +*/ + +QmlSensorReading *QmlSensor::reading() const +{ + return m_reading; +} + +/*! + \qmlproperty Sensor::AxesOrientationMode Sensor::axesOrientationMode + \since QtSensors 5.1 + This property holds the mode that affects how the screen orientation changes reading values. + + Please see QSensor::axesOrientationMode for information about this property. +*/ + +QmlSensor::AxesOrientationMode QmlSensor::axesOrientationMode() const +{ + return static_cast<QmlSensor::AxesOrientationMode>(sensor()->axesOrientationMode()); +} + +void QmlSensor::setAxesOrientationMode(QmlSensor::AxesOrientationMode axesOrientationMode) +{ + sensor()->setAxesOrientationMode(static_cast<QSensor::AxesOrientationMode>(axesOrientationMode)); +} + +/*! + \qmlproperty int Sensor::currentOrientation + \since QtSensors 5.1 + This property holds the current orientation that is used for rotating the reading values. + + Please see QSensor::currentOrientation for information about this property. +*/ + +int QmlSensor::currentOrientation() const +{ + return sensor()->currentOrientation(); +} + +/*! + \qmlproperty int Sensor::userOrientation + \since QtSensors 5.1 + This property holds the angle used for rotating the reading values in the UserOrientation mode. + + Please see QSensor::userOrientation for information about this property. +*/ + +int QmlSensor::userOrientation() const +{ + return sensor()->userOrientation(); +} + +void QmlSensor::setUserOrientation(int userOrientation) +{ + sensor()->setUserOrientation(userOrientation); +} + +/*! + \qmlproperty int Sensor::maxBufferSize + \since QtSensors 5.1 + This property holds the maximum buffer size. + + Please see QSensor::maxBufferSize for information about this property. +*/ + +int QmlSensor::maxBufferSize() const +{ + return sensor()->maxBufferSize(); +} + +/*! + \qmlproperty int Sensor::efficientBufferSize + \since QtSensors 5.1 + The property holds the most efficient buffer size. + + Please see QSensor::efficientBufferSize for information about this property. +*/ + +int QmlSensor::efficientBufferSize() const +{ + return sensor()->efficientBufferSize(); +} + +/*! + \qmlproperty int Sensor::bufferSize + \since QtSensors 5.1 + This property holds the size of the buffer. + + Please see QSensor::bufferSize for information about this property. +*/ + +int QmlSensor::bufferSize() const +{ + return sensor()->bufferSize(); +} + +void QmlSensor::setBufferSize(int bufferSize) +{ + sensor()->setBufferSize(bufferSize); +} + +/*! + \qmlmethod bool Sensor::start() + Start retrieving values from the sensor. Returns true if the sensor + was started, false otherwise. + + Please see QSensor::start() for information. +*/ + +bool QmlSensor::start() +{ + setActive(true); + return isActive(); +} + +/*! + \qmlmethod bool Sensor::stop() + Stop retrieving values from the sensor. + Returns true if the sensor was stopped, false otherwise. + + Please see QSensor::stop() for information. +*/ + +void QmlSensor::stop() +{ + setActive(false); +} + +void QmlSensor::classBegin() +{ +} + +void QmlSensor::componentComplete() +{ + m_parsed = true; + + connect(sensor(), SIGNAL(sensorError(int)), this, SIGNAL(errorChanged())); + connect(sensor(), SIGNAL(activeChanged()), this, SIGNAL(activeChanged())); + connect(sensor(), SIGNAL(alwaysOnChanged()), this, SIGNAL(alwaysOnChanged())); + connect(sensor(), SIGNAL(skipDuplicatesChanged(bool)), this, SIGNAL(skipDuplicatesChanged(bool))); + connect(sensor(), SIGNAL(axesOrientationModeChanged(AxesOrientationMode)), + this, SIGNAL(axesOrientationModeChanged(AxesOrientationMode))); + connect(sensor(), SIGNAL(userOrientationChanged(int)), this, SIGNAL(userOrientationChanged(int))); + connect(sensor(), SIGNAL(currentOrientationChanged(int)), this, SIGNAL(currentOrientationChanged(int))); + connect(sensor(), SIGNAL(bufferSizeChanged(int)), this, SIGNAL(bufferSizeChanged(int))); + connect(sensor(), SIGNAL(maxBufferSizeChanged(int)), this, SIGNAL(maxBufferSizeChanged(int))); + connect(sensor(), SIGNAL(efficientBufferSizeChanged(int)), this, SIGNAL(efficientBufferSizeChanged(int))); + + // We need to set this on the sensor object now + sensor()->setIdentifier(m_identifier.toLocal8Bit()); + + // These can change! + QByteArray oldIdentifier = sensor()->identifier(); + int oldDataRate = dataRate(); + int oldOutputRange = outputRange(); + + bool ok = sensor()->connectToBackend(); + if (ok) { + Q_EMIT connectedToBackendChanged(); + m_reading = createReading(); + m_reading->setParent(this); + } + + if (oldIdentifier != sensor()->identifier()) { + m_identifier = QString::fromLatin1(sensor()->identifier()); + Q_EMIT identifierChanged(); + } + if (oldDataRate != dataRate()) + Q_EMIT dataRateChanged(); + if (oldOutputRange != outputRange()) + Q_EMIT outputRangeChanged(); + + Q_D(QmlSensor); + const auto available = sensor()->availableDataRates(); + d->availableRanges.reserve(available.size()); + for (const qrange &r : available) { + auto *range = new QmlSensorRange(this); + range->setMinumum(r.first); + range->setMaximum(r.second); + d->availableRanges.append(range); + } + const auto output = sensor()->outputRanges(); + d->outputRanges.reserve(output.size()); + for (const qoutputrange &r : output) { + auto *range = new QmlSensorOutputRange(this); + range->setMinimum(r.minimum); + range->setMaximum(r.maximum); + range->setAccuracy(r.accuracy); + d->outputRanges.append(range); + } + + // meta-data should become non-empty + if (!description().isEmpty()) + Q_EMIT descriptionChanged(); + if (available.count()) + Q_EMIT availableDataRatesChanged(); + if (output.count()) + Q_EMIT outputRangesChanged(); + + _update(); + + connect(sensor(), SIGNAL(readingChanged()), this, SLOT(updateReading())); + if (m_active) { + m_active = false; + start(); + } +} + +void QmlSensor::_update() +{ +} + +void QmlSensor::updateReading() +{ + if (m_reading) { + m_reading->update(); + Q_EMIT readingChanged(); + } +} + +/*! + \qmltype SensorReading + \instantiates QmlSensorReading + \inqmlmodule QtSensors + \since QtSensors 5.0 + \brief The SensorReading element serves as a base type for sensor readings. + + The SensorReading element serves as a base type for sensor readings. + + This element wraps the QSensorReading class. Please see the documentation for + QSensorReading for details. + + This element cannot be directly created. +*/ + +QmlSensorReading::QmlSensorReading(QSensor *) + : QObject(0) +{ +} + +QmlSensorReading::~QmlSensorReading() +{ +} + +/*! + \qmlproperty quint64 SensorReading::timestamp + A timestamp for the reading. + + Please see QSensorReading::timestamp for information about this property. +*/ + +quint64 QmlSensorReading::timestamp() const +{ + return m_timestamp; +} + +void QmlSensorReading::update() +{ + quint64 ts = reading()->timestamp(); + if (m_timestamp != ts) { + m_timestamp = ts; + Q_EMIT timestampChanged(); + } + readingUpdate(); +} + +QT_END_NAMESPACE |