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 | |
9 | QT_BEGIN_NAMESPACE |
10 | |
11 | class QmlSensorPrivate : public QObjectPrivate |
12 | { |
13 | Q_DECLARE_PUBLIC(QmlSensor) |
14 | public: |
15 | |
16 | QList<QmlSensorRange *> availableRanges; |
17 | QList<QmlSensorOutputRange *> outputRanges; |
18 | }; |
19 | |
20 | template<typename Item> |
21 | qsizetype readonlyListCount(QQmlListProperty<Item> *p) |
22 | { |
23 | return static_cast<const QList<Item *> *>(p->data)->size(); |
24 | } |
25 | |
26 | template<typename Item> |
27 | Item *readonlyListAt(QQmlListProperty<Item> *p, qsizetype idx) |
28 | { |
29 | return static_cast<const QList<Item *> *>(p->data)->at(idx); |
30 | }; |
31 | |
32 | template<typename Item> |
33 | QQmlListProperty<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 | //! \nativetype 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 | |
55 | QmlSensor::QmlSensor(QObject *parent) |
56 | : QObject(*(new QmlSensorPrivate), parent) |
57 | { |
58 | } |
59 | |
60 | QmlSensor::~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 | |
71 | QByteArray QmlSensor::identifier() const |
72 | { |
73 | return sensor()->identifier(); |
74 | } |
75 | |
76 | void 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 | |
86 | QByteArray 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 | |
98 | bool 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 | |
110 | bool 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 | |
122 | void 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 | |
134 | bool 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 | |
146 | bool QmlSensor::isAlwaysOn() const |
147 | { |
148 | return sensor()->isAlwaysOn(); |
149 | } |
150 | |
151 | void 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 | |
165 | bool QmlSensor::skipDuplicates() const |
166 | { |
167 | return sensor()->skipDuplicates(); |
168 | } |
169 | |
170 | void 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 | */ |
181 | QQmlListProperty<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 | |
194 | int QmlSensor::dataRate() const |
195 | { |
196 | return sensor()->dataRate(); |
197 | } |
198 | |
199 | void 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 | |
214 | QQmlListProperty<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 | |
227 | int QmlSensor::outputRange() const |
228 | { |
229 | return sensor()->outputRange(); |
230 | } |
231 | |
232 | void 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 | |
246 | QString 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 | |
256 | int 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 | |
269 | QmlSensorReading *QmlSensor::reading() const |
270 | { |
271 | return m_reading; |
272 | } |
273 | |
274 | QBindable<QmlSensorReading*> QmlSensor::bindableReading() const |
275 | { |
276 | return &m_reading; |
277 | } |
278 | |
279 | /*! |
280 | \qmlmethod bool Sensor::isFeatureSupported(feature) |
281 | \since QtSensors 6.7 |
282 | Checks if a specific feature is supported by the backend. |
283 | Returns \c true if the \a feature is supported, and \c false otherwise. |
284 | For feature descriptions see \l {QSensor::Feature}. |
285 | |
286 | Please see QSensor::isFeatureSupported for information. |
287 | */ |
288 | |
289 | bool QmlSensor::isFeatureSupported(Feature feature) const |
290 | { |
291 | return sensor()->isFeatureSupported(feature: static_cast<QSensor::Feature>(feature)); |
292 | } |
293 | |
294 | /*! |
295 | \qmlproperty Sensor::AxesOrientationMode Sensor::axesOrientationMode |
296 | \since QtSensors 5.1 |
297 | This property holds the mode that affects how the screen orientation changes reading values. |
298 | |
299 | Please see QSensor::axesOrientationMode for information about this property. |
300 | */ |
301 | |
302 | QmlSensor::AxesOrientationMode QmlSensor::axesOrientationMode() const |
303 | { |
304 | return static_cast<QmlSensor::AxesOrientationMode>(sensor()->axesOrientationMode()); |
305 | } |
306 | |
307 | void QmlSensor::setAxesOrientationMode(QmlSensor::AxesOrientationMode axesOrientationMode) |
308 | { |
309 | sensor()->setAxesOrientationMode(static_cast<QSensor::AxesOrientationMode>(axesOrientationMode)); |
310 | } |
311 | |
312 | /*! |
313 | \qmlproperty int Sensor::currentOrientation |
314 | \since QtSensors 5.1 |
315 | This property holds the current orientation that is used for rotating the reading values. |
316 | |
317 | Please see QSensor::currentOrientation for information about this property. |
318 | */ |
319 | |
320 | int QmlSensor::currentOrientation() const |
321 | { |
322 | return sensor()->currentOrientation(); |
323 | } |
324 | |
325 | /*! |
326 | \qmlproperty int Sensor::userOrientation |
327 | \since QtSensors 5.1 |
328 | This property holds the angle used for rotating the reading values in the UserOrientation mode. |
329 | |
330 | Please see QSensor::userOrientation for information about this property. |
331 | */ |
332 | |
333 | int QmlSensor::userOrientation() const |
334 | { |
335 | return sensor()->userOrientation(); |
336 | } |
337 | |
338 | void QmlSensor::setUserOrientation(int userOrientation) |
339 | { |
340 | sensor()->setUserOrientation(userOrientation); |
341 | } |
342 | |
343 | /*! |
344 | \qmlproperty int Sensor::maxBufferSize |
345 | \since QtSensors 5.1 |
346 | This property holds the maximum buffer size. |
347 | |
348 | Please see QSensor::maxBufferSize for information about this property. |
349 | */ |
350 | |
351 | int QmlSensor::maxBufferSize() const |
352 | { |
353 | return sensor()->maxBufferSize(); |
354 | } |
355 | |
356 | /*! |
357 | \qmlproperty int Sensor::efficientBufferSize |
358 | \since QtSensors 5.1 |
359 | The property holds the most efficient buffer size. |
360 | |
361 | Please see QSensor::efficientBufferSize for information about this property. |
362 | */ |
363 | |
364 | int QmlSensor::efficientBufferSize() const |
365 | { |
366 | return sensor()->efficientBufferSize(); |
367 | } |
368 | |
369 | /*! |
370 | \qmlproperty int Sensor::bufferSize |
371 | \since QtSensors 5.1 |
372 | This property holds the size of the buffer. |
373 | |
374 | Please see QSensor::bufferSize for information about this property. |
375 | */ |
376 | |
377 | int QmlSensor::bufferSize() const |
378 | { |
379 | return sensor()->bufferSize(); |
380 | } |
381 | |
382 | void QmlSensor::setBufferSize(int bufferSize) |
383 | { |
384 | sensor()->setBufferSize(bufferSize); |
385 | } |
386 | |
387 | /*! |
388 | \qmlmethod bool Sensor::start() |
389 | Start retrieving values from the sensor. Returns true if the sensor |
390 | was started, false otherwise. |
391 | |
392 | Please see QSensor::start() for information. |
393 | */ |
394 | |
395 | bool QmlSensor::start() |
396 | { |
397 | return sensor()->start(); |
398 | } |
399 | |
400 | /*! |
401 | \qmlmethod bool Sensor::stop() |
402 | Stop retrieving values from the sensor. |
403 | Returns true if the sensor was stopped, false otherwise. |
404 | |
405 | Please see QSensor::stop() for information. |
406 | */ |
407 | |
408 | void QmlSensor::stop() |
409 | { |
410 | setActive(false); |
411 | } |
412 | |
413 | void QmlSensor::classBegin() |
414 | { |
415 | } |
416 | |
417 | void QmlSensor::componentComplete() |
418 | { |
419 | m_componentComplete = true; |
420 | |
421 | connect(sender: sensor(), SIGNAL(sensorError(int)), receiver: this, SIGNAL(errorChanged())); |
422 | connect(sender: sensor(), SIGNAL(activeChanged()), receiver: this, SIGNAL(activeChanged())); |
423 | connect(sender: sensor(), SIGNAL(alwaysOnChanged()), receiver: this, SIGNAL(alwaysOnChanged())); |
424 | connect(sender: sensor(), SIGNAL(skipDuplicatesChanged(bool)), receiver: this, SIGNAL(skipDuplicatesChanged(bool))); |
425 | connect(sender: sensor(), SIGNAL(axesOrientationModeChanged(AxesOrientationMode)), |
426 | receiver: this, SIGNAL(axesOrientationModeChanged(AxesOrientationMode))); |
427 | connect(sender: sensor(), SIGNAL(userOrientationChanged(int)), receiver: this, SIGNAL(userOrientationChanged(int))); |
428 | connect(sender: sensor(), SIGNAL(currentOrientationChanged(int)), receiver: this, SIGNAL(currentOrientationChanged(int))); |
429 | connect(sender: sensor(), SIGNAL(bufferSizeChanged(int)), receiver: this, SIGNAL(bufferSizeChanged(int))); |
430 | connect(sender: sensor(), SIGNAL(maxBufferSizeChanged(int)), receiver: this, SIGNAL(maxBufferSizeChanged(int))); |
431 | connect(sender: sensor(), SIGNAL(efficientBufferSizeChanged(int)), receiver: this, SIGNAL(efficientBufferSizeChanged(int))); |
432 | connect(sender: sensor(), signal: &QSensor::busyChanged, context: this, slot: &QmlSensor::busyChanged); |
433 | connect(sender: sensor(), signal: &QSensor::identifierChanged, context: this, slot: &QmlSensor::identifierChanged); |
434 | |
435 | // These can change! |
436 | int oldDataRate = dataRate(); |
437 | int oldOutputRange = outputRange(); |
438 | |
439 | if (sensor()->connectToBackend()) |
440 | Q_EMIT connectedToBackendChanged(); |
441 | |
442 | m_reading.setValueBypassingBindings(createReading()); |
443 | m_reading->setParent(this); |
444 | if (oldDataRate != dataRate()) |
445 | Q_EMIT dataRateChanged(); |
446 | if (oldOutputRange != outputRange()) |
447 | Q_EMIT outputRangeChanged(); |
448 | |
449 | Q_D(QmlSensor); |
450 | const auto available = sensor()->availableDataRates(); |
451 | d->availableRanges.reserve(asize: available.size()); |
452 | for (const qrange &r : available) { |
453 | auto *range = new QmlSensorRange(this); |
454 | range->setMinumum(r.first); |
455 | range->setMaximum(r.second); |
456 | d->availableRanges.append(t: range); |
457 | } |
458 | const auto output = sensor()->outputRanges(); |
459 | d->outputRanges.reserve(asize: output.size()); |
460 | for (const qoutputrange &r : output) { |
461 | auto *range = new QmlSensorOutputRange(this); |
462 | range->setMinimum(r.minimum); |
463 | range->setMaximum(r.maximum); |
464 | range->setAccuracy(r.accuracy); |
465 | d->outputRanges.append(t: range); |
466 | } |
467 | |
468 | // meta-data should become non-empty |
469 | if (!description().isEmpty()) |
470 | Q_EMIT descriptionChanged(); |
471 | if (available.size()) |
472 | Q_EMIT availableDataRatesChanged(); |
473 | if (output.size()) |
474 | Q_EMIT outputRangesChanged(); |
475 | |
476 | connect(sender: sensor(), SIGNAL(readingChanged()), receiver: this, SLOT(updateReading())); |
477 | if (m_activateOnComplete) |
478 | start(); |
479 | } |
480 | |
481 | void QmlSensor::updateReading() |
482 | { |
483 | if (m_reading) { |
484 | m_reading->update(); |
485 | m_reading.notify(); |
486 | Q_EMIT readingChanged(); |
487 | } |
488 | } |
489 | |
490 | /*! |
491 | \qmltype SensorReading |
492 | //! \nativetype QmlSensorReading |
493 | \inqmlmodule QtSensors |
494 | \since QtSensors 5.0 |
495 | \brief The SensorReading element serves as a base type for sensor readings. |
496 | |
497 | The SensorReading element serves as a base type for sensor readings. |
498 | |
499 | This element wraps the QSensorReading class. Please see the documentation for |
500 | QSensorReading for details. |
501 | |
502 | This element cannot be directly created. |
503 | */ |
504 | |
505 | /*! |
506 | \qmlproperty quint64 SensorReading::timestamp |
507 | A timestamp for the reading. |
508 | |
509 | Please see QSensorReading::timestamp for information about this property. |
510 | */ |
511 | |
512 | quint64 QmlSensorReading::timestamp() const |
513 | { |
514 | return m_timestamp; |
515 | } |
516 | |
517 | QBindable<quint64> QmlSensorReading::bindableTimestamp() const |
518 | { |
519 | return &m_timestamp; |
520 | } |
521 | |
522 | |
523 | void QmlSensorReading::update() |
524 | { |
525 | m_timestamp = reading()->timestamp(); |
526 | readingUpdate(); |
527 | } |
528 | |
529 | QT_END_NAMESPACE |
530 |
Definitions
- QmlSensorPrivate
- readonlyListCount
- readonlyListAt
- readonlyListProperty
- QmlSensor
- ~QmlSensor
- identifier
- setIdentifier
- type
- isConnectedToBackend
- isBusy
- setActive
- isActive
- isAlwaysOn
- setAlwaysOn
- skipDuplicates
- setSkipDuplicates
- availableDataRates
- dataRate
- setDataRate
- outputRanges
- outputRange
- setOutputRange
- description
- error
- reading
- bindableReading
- isFeatureSupported
- axesOrientationMode
- setAxesOrientationMode
- currentOrientation
- userOrientation
- setUserOrientation
- maxBufferSize
- efficientBufferSize
- bufferSize
- setBufferSize
- start
- stop
- classBegin
- componentComplete
- updateReading
- timestamp
- bindableTimestamp
Start learning QML with our Intro Training
Find out more