diff options
Diffstat (limited to 'src/sensorsquick/qmlsensor.cpp')
-rw-r--r-- | src/sensorsquick/qmlsensor.cpp | 529 |
1 files changed, 529 insertions, 0 deletions
diff --git a/src/sensorsquick/qmlsensor.cpp b/src/sensorsquick/qmlsensor.cpp new file mode 100644 index 00000000..d507e919 --- /dev/null +++ b/src/sensorsquick/qmlsensor.cpp @@ -0,0 +1,529 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#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)->size(); +} + +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) +{ +} + +QmlSensor::~QmlSensor() +{ +} + +/*! + \qmlproperty string Sensor::identifier + This property holds the backend identifier for the sensor. + + Please see QSensor::identifier for information about this property. +*/ + +QByteArray QmlSensor::identifier() const +{ + return sensor()->identifier(); +} + +void QmlSensor::setIdentifier(const QByteArray &identifier) +{ + sensor()->setIdentifier(identifier); +} + +/*! + \qmlproperty string Sensor::type + This property holds the type of the sensor. +*/ + +QByteArray QmlSensor::type() const +{ + return 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) +{ + if (!m_componentComplete) { + m_activateOnComplete = active; + return; + } + if (active) + sensor()->start(); + else + sensor()->stop(); +} + +bool QmlSensor::isActive() const +{ + return sensor()->isActive(); +} + +/*! + \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; +} + +QBindable<QmlSensorReading*> QmlSensor::bindableReading() const +{ + return &m_reading; +} + +/*! + \qmlmethod bool Sensor::isFeatureSupported(feature) + \since QtSensors 6.7 + Checks if a specific feature is supported by the backend. + Returns \c true if the \a feature is supported, and \c false otherwise. + For feature descriptions see \l {QSensor::Feature}. + + Please see QSensor::isFeatureSupported for information. +*/ + +bool QmlSensor::isFeatureSupported(Feature feature) const +{ + return sensor()->isFeatureSupported(static_cast<QSensor::Feature>(feature)); +} + +/*! + \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() +{ + return sensor()->start(); +} + +/*! + \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_componentComplete = 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))); + connect(sensor(), &QSensor::busyChanged, this, &QmlSensor::busyChanged); + connect(sensor(), &QSensor::identifierChanged, this, &QmlSensor::identifierChanged); + + // These can change! + int oldDataRate = dataRate(); + int oldOutputRange = outputRange(); + + if (sensor()->connectToBackend()) + Q_EMIT connectedToBackendChanged(); + + m_reading.setValueBypassingBindings(createReading()); + m_reading->setParent(this); + 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.size()) + Q_EMIT availableDataRatesChanged(); + if (output.size()) + Q_EMIT outputRangesChanged(); + + connect(sensor(), SIGNAL(readingChanged()), this, SLOT(updateReading())); + if (m_activateOnComplete) + start(); +} + +void QmlSensor::updateReading() +{ + if (m_reading) { + m_reading->update(); + m_reading.notify(); + 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. +*/ + +/*! + \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; +} + +QBindable<quint64> QmlSensorReading::bindableTimestamp() const +{ + return &m_timestamp; +} + + +void QmlSensorReading::update() +{ + m_timestamp = reading()->timestamp(); + readingUpdate(); +} + +QT_END_NAMESPACE |