1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qmlsensor_p.h"
5#include <QtSensors/QSensor>
6#include <QDebug>
7#include <QtCore/private/qobject_p.h>
8
9QT_BEGIN_NAMESPACE
10
11class QmlSensorPrivate : public QObjectPrivate
12{
13 Q_DECLARE_PUBLIC(QmlSensor)
14public:
15
16 QList<QmlSensorRange *> availableRanges;
17 QList<QmlSensorOutputRange *> outputRanges;
18};
19
20template<typename Item>
21qsizetype readonlyListCount(QQmlListProperty<Item> *p)
22{
23 return static_cast<const QList<Item *> *>(p->data)->size();
24}
25
26template<typename Item>
27Item *readonlyListAt(QQmlListProperty<Item> *p, qsizetype idx)
28{
29 return static_cast<const QList<Item *> *>(p->data)->at(idx);
30};
31
32template<typename Item>
33QQmlListProperty<Item> readonlyListProperty(const QObject *o, const QList<Item *> *list)
34{
35 // Unfortunately QQmlListProperty won't accept a const object, even on the readonly ctor.
36 return QQmlListProperty<Item>(const_cast<QObject *>(o), const_cast<QList<Item *> *>(list),
37 readonlyListCount<Item>, readonlyListAt<Item>);
38}
39
40/*!
41 \qmltype Sensor
42//! \instantiates QmlSensor
43 \inqmlmodule QtSensors
44 \since QtSensors 5.0
45 \brief The Sensor element serves as a base type for sensors.
46
47 The Sensor element serves as a base type for sensors.
48
49 This element wraps the QSensor class. Please see the documentation for
50 QSensor for details.
51
52 This element cannot be directly created. Please use one of the sub-classes instead.
53*/
54
55QmlSensor::QmlSensor(QObject *parent)
56 : QObject(*(new QmlSensorPrivate), parent)
57{
58}
59
60QmlSensor::~QmlSensor()
61{
62}
63
64/*!
65 \qmlproperty string Sensor::identifier
66 This property holds the backend identifier for the sensor.
67
68 Please see QSensor::identifier for information about this property.
69*/
70
71QByteArray QmlSensor::identifier() const
72{
73 return sensor()->identifier();
74}
75
76void QmlSensor::setIdentifier(const QByteArray &identifier)
77{
78 sensor()->setIdentifier(identifier);
79}
80
81/*!
82 \qmlproperty string Sensor::type
83 This property holds the type of the sensor.
84*/
85
86QByteArray QmlSensor::type() const
87{
88 return sensor()->type();
89}
90
91/*!
92 \qmlproperty bool Sensor::connectedToBackend
93 This property holds a value indicating if the sensor has connected to a backend.
94
95 Please see QSensor::connectedToBackend for information about this property.
96*/
97
98bool QmlSensor::isConnectedToBackend() const
99{
100 return sensor()->isConnectedToBackend();
101}
102
103/*!
104 \qmlproperty bool Sensor::busy
105 This property holds a value to indicate if the sensor is busy.
106
107 Please see QSensor::busy for information about this property.
108*/
109
110bool QmlSensor::isBusy() const
111{
112 return sensor()->isBusy();
113}
114
115/*!
116 \qmlproperty bool Sensor::active
117 This property holds a value to indicate if the sensor is active.
118
119 Please see QSensor::active for information about this property.
120*/
121
122void QmlSensor::setActive(bool active)
123{
124 if (!m_componentComplete) {
125 m_activateOnComplete = active;
126 return;
127 }
128 if (active)
129 sensor()->start();
130 else
131 sensor()->stop();
132}
133
134bool QmlSensor::isActive() const
135{
136 return sensor()->isActive();
137}
138
139/*!
140 \qmlproperty bool Sensor::alwaysOn
141 This property holds a value to indicate if the sensor should remain running when the screen is off.
142
143 Please see QSensor::alwaysOn for information about this property.
144*/
145
146bool QmlSensor::isAlwaysOn() const
147{
148 return sensor()->isAlwaysOn();
149}
150
151void QmlSensor::setAlwaysOn(bool alwaysOn)
152{
153 sensor()->setAlwaysOn(alwaysOn);
154}
155
156/*!
157 \qmlproperty bool Sensor::skipDuplicates
158 \since QtSensors 5.1
159
160 This property indicates whether duplicate reading values should be omitted.
161
162 Please see QSensor::skipDuplicates for information about this property.
163*/
164
165bool QmlSensor::skipDuplicates() const
166{
167 return sensor()->skipDuplicates();
168}
169
170void QmlSensor::setSkipDuplicates(bool skipDuplicates)
171{
172 sensor()->setSkipDuplicates(skipDuplicates);
173}
174
175/*!
176 \qmlproperty list<Range> Sensor::availableDataRates
177 This property holds the data rates that the sensor supports.
178
179 Please see QSensor::availableDataRates for information about this property.
180*/
181QQmlListProperty<QmlSensorRange> QmlSensor::availableDataRates() const
182{
183 Q_D(const QmlSensor);
184 return readonlyListProperty<QmlSensorRange>(o: this, list: &d->availableRanges);
185}
186
187/*!
188 \qmlproperty int Sensor::dataRate
189 This property holds the data rate that the sensor should be run at.
190
191 Please see QSensor::dataRate for information about this property.
192*/
193
194int QmlSensor::dataRate() const
195{
196 return sensor()->dataRate();
197}
198
199void QmlSensor::setDataRate(int rate)
200{
201 if (rate != dataRate()) {
202 sensor()->setDataRate(rate);
203 Q_EMIT dataRateChanged();
204 }
205}
206
207/*!
208 \qmlproperty list<OutputRange> Sensor::outputRanges
209 This property holds a list of output ranges the sensor supports.
210
211 Please see QSensor::outputRanges for information about this property.
212*/
213
214QQmlListProperty<QmlSensorOutputRange> QmlSensor::outputRanges() const
215{
216 Q_D(const QmlSensor);
217 return readonlyListProperty<QmlSensorOutputRange>(o: this, list: &d->outputRanges);
218}
219
220/*!
221 \qmlproperty int Sensor::outputRange
222 This property holds the output range in use by the sensor.
223
224 Please see QSensor::outputRange for information about this property.
225*/
226
227int QmlSensor::outputRange() const
228{
229 return sensor()->outputRange();
230}
231
232void QmlSensor::setOutputRange(int index)
233{
234 int oldRange = outputRange();
235 if (oldRange == index) return;
236 sensor()->setOutputRange(index);
237 if (sensor()->outputRange() == index)
238 Q_EMIT outputRangeChanged();
239}
240
241/*!
242 \qmlproperty string Sensor::description
243 This property holds a descriptive string for the sensor.
244*/
245
246QString QmlSensor::description() const
247{
248 return sensor()->description();
249}
250
251/*!
252 \qmlproperty int Sensor::error
253 This property holds the last error code set on the sensor.
254*/
255
256int QmlSensor::error() const
257{
258 return sensor()->error();
259}
260
261/*!
262 \qmlproperty SensorReading Sensor::reading
263 This property holds the reading class.
264
265 Please see QSensor::reading for information about this property.
266 \sa {QML Reading types}
267*/
268
269QmlSensorReading *QmlSensor::reading() const
270{
271 return m_reading;
272}
273
274QBindable<QmlSensorReading*> QmlSensor::bindableReading() const
275{
276 return &m_reading;
277}
278
279/*!
280 \qmlproperty Sensor::AxesOrientationMode Sensor::axesOrientationMode
281 \since QtSensors 5.1
282 This property holds the mode that affects how the screen orientation changes reading values.
283
284 Please see QSensor::axesOrientationMode for information about this property.
285*/
286
287QmlSensor::AxesOrientationMode QmlSensor::axesOrientationMode() const
288{
289 return static_cast<QmlSensor::AxesOrientationMode>(sensor()->axesOrientationMode());
290}
291
292void QmlSensor::setAxesOrientationMode(QmlSensor::AxesOrientationMode axesOrientationMode)
293{
294 sensor()->setAxesOrientationMode(static_cast<QSensor::AxesOrientationMode>(axesOrientationMode));
295}
296
297/*!
298 \qmlproperty int Sensor::currentOrientation
299 \since QtSensors 5.1
300 This property holds the current orientation that is used for rotating the reading values.
301
302 Please see QSensor::currentOrientation for information about this property.
303*/
304
305int QmlSensor::currentOrientation() const
306{
307 return sensor()->currentOrientation();
308}
309
310/*!
311 \qmlproperty int Sensor::userOrientation
312 \since QtSensors 5.1
313 This property holds the angle used for rotating the reading values in the UserOrientation mode.
314
315 Please see QSensor::userOrientation for information about this property.
316*/
317
318int QmlSensor::userOrientation() const
319{
320 return sensor()->userOrientation();
321}
322
323void QmlSensor::setUserOrientation(int userOrientation)
324{
325 sensor()->setUserOrientation(userOrientation);
326}
327
328/*!
329 \qmlproperty int Sensor::maxBufferSize
330 \since QtSensors 5.1
331 This property holds the maximum buffer size.
332
333 Please see QSensor::maxBufferSize for information about this property.
334*/
335
336int QmlSensor::maxBufferSize() const
337{
338 return sensor()->maxBufferSize();
339}
340
341/*!
342 \qmlproperty int Sensor::efficientBufferSize
343 \since QtSensors 5.1
344 The property holds the most efficient buffer size.
345
346 Please see QSensor::efficientBufferSize for information about this property.
347*/
348
349int QmlSensor::efficientBufferSize() const
350{
351 return sensor()->efficientBufferSize();
352}
353
354/*!
355 \qmlproperty int Sensor::bufferSize
356 \since QtSensors 5.1
357 This property holds the size of the buffer.
358
359 Please see QSensor::bufferSize for information about this property.
360*/
361
362int QmlSensor::bufferSize() const
363{
364 return sensor()->bufferSize();
365}
366
367void QmlSensor::setBufferSize(int bufferSize)
368{
369 sensor()->setBufferSize(bufferSize);
370}
371
372/*!
373 \qmlmethod bool Sensor::start()
374 Start retrieving values from the sensor. Returns true if the sensor
375 was started, false otherwise.
376
377 Please see QSensor::start() for information.
378*/
379
380bool QmlSensor::start()
381{
382 return sensor()->start();
383}
384
385/*!
386 \qmlmethod bool Sensor::stop()
387 Stop retrieving values from the sensor.
388 Returns true if the sensor was stopped, false otherwise.
389
390 Please see QSensor::stop() for information.
391*/
392
393void QmlSensor::stop()
394{
395 setActive(false);
396}
397
398void QmlSensor::classBegin()
399{
400}
401
402void QmlSensor::componentComplete()
403{
404 m_componentComplete = true;
405
406 connect(sender: sensor(), SIGNAL(sensorError(int)), receiver: this, SIGNAL(errorChanged()));
407 connect(sender: sensor(), SIGNAL(activeChanged()), receiver: this, SIGNAL(activeChanged()));
408 connect(sender: sensor(), SIGNAL(alwaysOnChanged()), receiver: this, SIGNAL(alwaysOnChanged()));
409 connect(sender: sensor(), SIGNAL(skipDuplicatesChanged(bool)), receiver: this, SIGNAL(skipDuplicatesChanged(bool)));
410 connect(sender: sensor(), SIGNAL(axesOrientationModeChanged(AxesOrientationMode)),
411 receiver: this, SIGNAL(axesOrientationModeChanged(AxesOrientationMode)));
412 connect(sender: sensor(), SIGNAL(userOrientationChanged(int)), receiver: this, SIGNAL(userOrientationChanged(int)));
413 connect(sender: sensor(), SIGNAL(currentOrientationChanged(int)), receiver: this, SIGNAL(currentOrientationChanged(int)));
414 connect(sender: sensor(), SIGNAL(bufferSizeChanged(int)), receiver: this, SIGNAL(bufferSizeChanged(int)));
415 connect(sender: sensor(), SIGNAL(maxBufferSizeChanged(int)), receiver: this, SIGNAL(maxBufferSizeChanged(int)));
416 connect(sender: sensor(), SIGNAL(efficientBufferSizeChanged(int)), receiver: this, SIGNAL(efficientBufferSizeChanged(int)));
417 connect(sender: sensor(), signal: &QSensor::busyChanged, context: this, slot: &QmlSensor::busyChanged);
418 connect(sender: sensor(), signal: &QSensor::identifierChanged, context: this, slot: &QmlSensor::identifierChanged);
419
420 // These can change!
421 int oldDataRate = dataRate();
422 int oldOutputRange = outputRange();
423
424 if (sensor()->connectToBackend())
425 Q_EMIT connectedToBackendChanged();
426
427 m_reading.setValueBypassingBindings(createReading());
428 m_reading->setParent(this);
429 if (oldDataRate != dataRate())
430 Q_EMIT dataRateChanged();
431 if (oldOutputRange != outputRange())
432 Q_EMIT outputRangeChanged();
433
434 Q_D(QmlSensor);
435 const auto available = sensor()->availableDataRates();
436 d->availableRanges.reserve(asize: available.size());
437 for (const qrange &r : available) {
438 auto *range = new QmlSensorRange(this);
439 range->setMinumum(r.first);
440 range->setMaximum(r.second);
441 d->availableRanges.append(t: range);
442 }
443 const auto output = sensor()->outputRanges();
444 d->outputRanges.reserve(asize: output.size());
445 for (const qoutputrange &r : output) {
446 auto *range = new QmlSensorOutputRange(this);
447 range->setMinimum(r.minimum);
448 range->setMaximum(r.maximum);
449 range->setAccuracy(r.accuracy);
450 d->outputRanges.append(t: range);
451 }
452
453 // meta-data should become non-empty
454 if (!description().isEmpty())
455 Q_EMIT descriptionChanged();
456 if (available.size())
457 Q_EMIT availableDataRatesChanged();
458 if (output.size())
459 Q_EMIT outputRangesChanged();
460
461 connect(sender: sensor(), SIGNAL(readingChanged()), receiver: this, SLOT(updateReading()));
462 if (m_activateOnComplete)
463 start();
464}
465
466void QmlSensor::updateReading()
467{
468 if (m_reading) {
469 m_reading->update();
470 m_reading.notify();
471 Q_EMIT readingChanged();
472 }
473}
474
475/*!
476 \qmltype SensorReading
477//! \instantiates QmlSensorReading
478 \inqmlmodule QtSensors
479 \since QtSensors 5.0
480 \brief The SensorReading element serves as a base type for sensor readings.
481
482 The SensorReading element serves as a base type for sensor readings.
483
484 This element wraps the QSensorReading class. Please see the documentation for
485 QSensorReading for details.
486
487 This element cannot be directly created.
488*/
489
490/*!
491 \qmlproperty quint64 SensorReading::timestamp
492 A timestamp for the reading.
493
494 Please see QSensorReading::timestamp for information about this property.
495*/
496
497quint64 QmlSensorReading::timestamp() const
498{
499 return m_timestamp;
500}
501
502QBindable<quint64> QmlSensorReading::bindableTimestamp() const
503{
504 return &m_timestamp;
505}
506
507
508void QmlSensorReading::update()
509{
510 m_timestamp = reading()->timestamp();
511 readingUpdate();
512}
513
514QT_END_NAMESPACE
515

source code of qtsensors/src/sensorsquick/qmlsensor.cpp