1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include <QtVirtualKeyboard/qvirtualkeyboardtrace.h> |
5 | #include <QtCore/private/qobject_p.h> |
6 | |
7 | QT_BEGIN_NAMESPACE |
8 | |
9 | class QVirtualKeyboardTracePrivate : public QObjectPrivate |
10 | { |
11 | public: |
12 | QVirtualKeyboardTracePrivate() : |
13 | QObjectPrivate(), |
14 | traceId(0), |
15 | final(false), |
16 | canceled(false), |
17 | opacity(1.0), |
18 | hideTimer(0) |
19 | { } |
20 | |
21 | int traceId; |
22 | QVariantList points; |
23 | QMap<QString, QVariantList> channels; |
24 | bool final; |
25 | bool canceled; |
26 | qreal opacity; |
27 | int hideTimer; |
28 | }; |
29 | |
30 | /*! |
31 | \class QVirtualKeyboardTrace |
32 | \inmodule QtVirtualKeyboard |
33 | \ingroup qtvirtualkeyboard-cpp-for-devs |
34 | \since QtQuick.VirtualKeyboard 2.0 |
35 | \brief Trace is a data model for touch input data. |
36 | |
37 | Trace provides the data model for coordinate data and other |
38 | optional data associated with a single stroke. |
39 | |
40 | A typical use case for the trace object is as follows: |
41 | \list |
42 | \li TraceInputArea or other input device initiates |
43 | the trace event by calling \l {InputEngine::traceBegin()} |
44 | {InputEngine.traceBegin()} method. |
45 | \li If the current input method accepts the event it creates |
46 | a trace object and configures the required data channels |
47 | (if any). |
48 | \li TraceInputArea collects the data for the Trace object. |
49 | \li TraceInputArea calls the \l {InputEngine::traceEnd()} |
50 | {InputEngine.traceEnd()} method to finish the trace and |
51 | passing the trace object back to input method. |
52 | \li The input method processes the data and discards the object |
53 | when it is no longer needed. |
54 | \endlist |
55 | |
56 | The coordinate data is retrieved using the points() function. |
57 | |
58 | In addition to coordinate based data, it is possible |
59 | to attach an arbitrary data channel for each data point. |
60 | |
61 | The data channels must be defined before the points are added. |
62 | The data channels supported by the TraceInputArea are listed below: |
63 | |
64 | \list |
65 | \li \c "t" Collects time for each data point. The time is |
66 | the number of milliseconds since 1970/01/01: |
67 | \endlist |
68 | |
69 | For example, to configure the object to collect the times for |
70 | each point: |
71 | |
72 | \code |
73 | QVirtualKeyboardTrace *trace = new QVirtualKeyboardTrace(this); |
74 | trace->setChannels(QStringList() << "t"); |
75 | \endcode |
76 | |
77 | The collected data can be accessed using the channelData() function: |
78 | |
79 | \code |
80 | QVariantList timeData = trace->channelData("t"); |
81 | \endcode |
82 | |
83 | QVirtualKeyboardTrace objects are owned by their creator, which is the input method in |
84 | normal case. This means the objects are constructed in the |
85 | \l {InputMethod::traceBegin()}{InputMethod.traceBegin()} (QML) method. |
86 | |
87 | By definition, the trace object can be destroyed at earliest in the |
88 | \l {InputMethod::traceEnd()}{InputMethod.traceEnd()} (QML) method. |
89 | */ |
90 | |
91 | /*! |
92 | \qmltype Trace |
93 | \instantiates QVirtualKeyboardTrace |
94 | \inqmlmodule QtQuick.VirtualKeyboard |
95 | \ingroup qtvirtualkeyboard-internal-qml |
96 | \since QtQuick.VirtualKeyboard 2.0 |
97 | \brief Trace is a data model for touch input data. |
98 | |
99 | Trace provides the data model for coordinate data and other |
100 | optional data associated with a single stroke. |
101 | |
102 | A typical use case for the trace object is as follows: |
103 | \list |
104 | \li TraceInputArea or other input device initiates |
105 | the trace event by calling \l {InputEngine::traceBegin()} |
106 | {InputEngine.traceBegin()} method. |
107 | \li If the current input method accepts the event it creates |
108 | a trace object and configures the required data channels |
109 | (if any). |
110 | \li TraceInputArea collects the data for the trace object. |
111 | \li TraceInputArea calls the \l {InputEngine::traceEnd()} |
112 | {InputEngine.traceEnd()} method to finish the trace and |
113 | passing the trace object back to input method. |
114 | \li The input method processes the data and discards the object |
115 | when it is no longer needed. |
116 | \endlist |
117 | |
118 | The coordinate data is retrieved using the points() function. |
119 | |
120 | In addition to coordinate based data, it is possible |
121 | to attach an arbitrary data channel for each data point. |
122 | |
123 | The data channels must be defined before the points are added. |
124 | The data channels supported by the TraceInputArea are listed below: |
125 | |
126 | \list |
127 | \li \c "t" Collects time for each data point. The time is |
128 | the number of milliseconds since 1970/01/01: |
129 | \endlist |
130 | |
131 | For example, to configure the object to collect the times for |
132 | each point: |
133 | |
134 | \code |
135 | QVirtualKeyboardTrace *trace = new QVirtualKeyboardTrace(this); |
136 | trace->setChannels(QStringList() << "t"); |
137 | \endcode |
138 | |
139 | The collected data can be accessed using the channelData() function: |
140 | |
141 | \code |
142 | QVariantList timeData = trace->channelData("t"); |
143 | \endcode |
144 | |
145 | Trace objects are owned by their creator, which is the input method in |
146 | normal case. This means the objects are constructed in the |
147 | \l {InputMethod::traceBegin()}{InputMethod.traceBegin()} (QML) method. |
148 | |
149 | By definition, the trace object can be destroyed at earliest in the |
150 | \l {InputMethod::traceEnd()}{InputMethod.traceEnd()} (QML) method. |
151 | */ |
152 | |
153 | /*! \internal */ |
154 | QVirtualKeyboardTrace::QVirtualKeyboardTrace(QObject *parent) : |
155 | QObject(*new QVirtualKeyboardTracePrivate(), parent) |
156 | { |
157 | Q_ASSERT(parent); |
158 | } |
159 | |
160 | /*! \internal */ |
161 | QVirtualKeyboardTrace::~QVirtualKeyboardTrace() |
162 | { |
163 | } |
164 | |
165 | int QVirtualKeyboardTrace::traceId() const |
166 | { |
167 | Q_D(const QVirtualKeyboardTrace); |
168 | return d->traceId; |
169 | } |
170 | |
171 | void QVirtualKeyboardTrace::setTraceId(int id) |
172 | { |
173 | Q_D(QVirtualKeyboardTrace); |
174 | if (d->traceId != id) { |
175 | d->traceId = id; |
176 | emit traceIdChanged(traceId: id); |
177 | } |
178 | } |
179 | |
180 | QStringList QVirtualKeyboardTrace::channels() const |
181 | { |
182 | Q_D(const QVirtualKeyboardTrace); |
183 | return d->channels.keys(); |
184 | } |
185 | |
186 | void QVirtualKeyboardTrace::setChannels(const QStringList &channels) |
187 | { |
188 | Q_D(QVirtualKeyboardTrace); |
189 | Q_ASSERT(d->points.isEmpty()); |
190 | if (d->points.isEmpty()) { |
191 | d->channels.clear(); |
192 | for (QStringList::ConstIterator i = channels.constBegin(); |
193 | i != channels.constEnd(); i++) { |
194 | d->channels[*i] = QVariantList(); |
195 | } |
196 | emit channelsChanged(); |
197 | } |
198 | } |
199 | |
200 | int QVirtualKeyboardTrace::length() const |
201 | { |
202 | Q_D(const QVirtualKeyboardTrace); |
203 | return d->points.size(); |
204 | } |
205 | |
206 | /*! \qmlmethod var Trace::points(int pos, int count) |
207 | |
208 | Returns list of points. If no parameters are given, the |
209 | function returns all the points. |
210 | |
211 | If the \a pos parameter is given, the function returns points starting |
212 | at the position. The \a count parameter limits how many points are |
213 | returned. |
214 | |
215 | The returned list contains \c point types. |
216 | */ |
217 | |
218 | /*! Returns list of points. If no parameters are given, the |
219 | method returns all the data. |
220 | |
221 | If the \a pos parameter is given, the method returns points starting |
222 | at the position. The \a count parameter limits how many points are |
223 | returned. |
224 | |
225 | The returned list contains QPointF types. |
226 | */ |
227 | |
228 | QVariantList QVirtualKeyboardTrace::points(int pos, int count) const |
229 | { |
230 | Q_D(const QVirtualKeyboardTrace); |
231 | return d->points.mid(pos, len: count); |
232 | } |
233 | |
234 | /*! \qmlmethod int Trace::addPoint(point point) |
235 | |
236 | Adds a \a point to the Trace. |
237 | |
238 | The method returns index of the point added, or -1 if |
239 | the points cannot be added (i.e. the \l final is true). |
240 | |
241 | \note The returned index is required to associate additional |
242 | data with the point using the setChannelData() function. |
243 | */ |
244 | |
245 | /*! Adds a \a point to the QVirtualKeyboardTrace. |
246 | |
247 | The method returns index of the point added, or -1 if |
248 | the points cannot be added (i.e. the \l final is true). |
249 | |
250 | \note The returned index is required to associate additional |
251 | data with the point using the setChannelData() method. |
252 | */ |
253 | |
254 | int QVirtualKeyboardTrace::addPoint(const QPointF &point) |
255 | { |
256 | Q_D(QVirtualKeyboardTrace); |
257 | int index; |
258 | if (!d->final) { |
259 | index = d->points.size(); |
260 | d->points.append(t: point); |
261 | emit lengthChanged(length: d->points.size()); |
262 | } else { |
263 | index = -1; |
264 | } |
265 | return index; |
266 | } |
267 | |
268 | /*! \qmlmethod void Trace::setChannelData(int index, string channel, var data) |
269 | |
270 | Sets \a data for the point at \a index in the given data \a channel. |
271 | |
272 | If this method is not called for each data point, the channel data |
273 | will be padded with empty values. However, the data cannot be added at |
274 | arbitrary index, i.e., it must be added in synchronously with the point data. |
275 | */ |
276 | |
277 | /*! Sets \a data for the point at \a index in the given data \a channel. |
278 | |
279 | If this method is not called for each data point, the channel data |
280 | will be padded with empty values. However, the data cannot be added at |
281 | arbitrary index, i.e., it must be added in synchronously with the point data. |
282 | */ |
283 | |
284 | void QVirtualKeyboardTrace::setChannelData(const QString &channel, int index, const QVariant &data) |
285 | { |
286 | Q_D(QVirtualKeyboardTrace); |
287 | if (!d->final && (index + 1) == d->points.size() && d->channels.contains(key: channel)) { |
288 | QVariantList &channelData = d->channels[channel]; |
289 | while (index > channelData.size()) |
290 | channelData.append(t: QVariant()); |
291 | if (index == channelData.size()) |
292 | channelData.append(t: data); |
293 | } |
294 | } |
295 | |
296 | /*! \qmlmethod var Trace::channelData(string channel, int pos, int count) |
297 | |
298 | Returns data from the specified \a channel. If no other parameters |
299 | are given, the function returns all the data. |
300 | |
301 | If the \a pos parameter is given, the function returns data starting |
302 | at the position. The \a count parameter limits how many items are |
303 | returned. |
304 | */ |
305 | |
306 | /*! Returns data from the specified \a channel. If no other parameters |
307 | are given, the method returns all the data. |
308 | |
309 | If the \a pos parameter is given, the method returns data starting |
310 | at the position. The \a count parameter limits how many items are |
311 | returned. |
312 | */ |
313 | |
314 | QVariantList QVirtualKeyboardTrace::channelData(const QString &channel, int pos, int count) const |
315 | { |
316 | Q_D(const QVirtualKeyboardTrace); |
317 | return d->channels.value(key: channel).mid(pos, len: count); |
318 | } |
319 | |
320 | bool QVirtualKeyboardTrace::isFinal() const |
321 | { |
322 | Q_D(const QVirtualKeyboardTrace); |
323 | return d->final; |
324 | } |
325 | |
326 | void QVirtualKeyboardTrace::setFinal(bool final) |
327 | { |
328 | Q_D(QVirtualKeyboardTrace); |
329 | if (d->final != final) { |
330 | d->final = final; |
331 | emit finalChanged(isFinal: final); |
332 | } |
333 | } |
334 | |
335 | bool QVirtualKeyboardTrace::isCanceled() const |
336 | { |
337 | Q_D(const QVirtualKeyboardTrace); |
338 | return d->canceled; |
339 | } |
340 | |
341 | void QVirtualKeyboardTrace::setCanceled(bool canceled) |
342 | { |
343 | Q_D(QVirtualKeyboardTrace); |
344 | if (d->canceled != canceled) { |
345 | d->canceled = canceled; |
346 | emit canceledChanged(isCanceled: canceled); |
347 | } |
348 | } |
349 | |
350 | qreal QVirtualKeyboardTrace::opacity() const |
351 | { |
352 | Q_D(const QVirtualKeyboardTrace); |
353 | return d->opacity; |
354 | } |
355 | |
356 | void QVirtualKeyboardTrace::setOpacity(qreal opacity) |
357 | { |
358 | Q_D(QVirtualKeyboardTrace); |
359 | if (d->opacity != opacity) { |
360 | d->opacity = opacity; |
361 | emit opacityChanged(opacity); |
362 | } |
363 | } |
364 | |
365 | /*! \qmlmethod void Trace::startHideTimer(int delayMs) |
366 | |
367 | Starts a timer to set opacity to zero after \a delayMs. If called again |
368 | within \a delayMs, the timer is restarted. |
369 | |
370 | With this function the input method can hide the trace from screen before |
371 | destroying the trace object, for example, to indicate that the trace has |
372 | been processed. |
373 | |
374 | \since QtQuick.VirtualKeyboard.Styles 6.1 |
375 | */ |
376 | |
377 | /*! Starts a timer to set opacity to zero after \a delayMs. If called again |
378 | within \a delayMs, the timer is restarted. |
379 | |
380 | With this function the input method can hide the trace from screen before |
381 | destroying the trace object, for example, to indicate that the trace has |
382 | been processed. |
383 | |
384 | \since QtQuick.VirtualKeyboard.Styles 6.1 |
385 | */ |
386 | |
387 | void QVirtualKeyboardTrace::startHideTimer(int delayMs) |
388 | { |
389 | Q_D(QVirtualKeyboardTrace); |
390 | if (d->hideTimer != 0) { |
391 | killTimer(id: d->hideTimer); |
392 | } |
393 | d->hideTimer = startTimer(interval: delayMs); |
394 | } |
395 | |
396 | void QVirtualKeyboardTrace::timerEvent(QTimerEvent *event) |
397 | { |
398 | Q_UNUSED(event) |
399 | Q_D(QVirtualKeyboardTrace); |
400 | d->hideTimer = 0; |
401 | setOpacity(0); |
402 | } |
403 | |
404 | /*! \qmlproperty int Trace::traceId |
405 | |
406 | Unique id of this Trace. |
407 | */ |
408 | |
409 | /*! \property QVirtualKeyboardTrace::traceId |
410 | \brief unique id of this QVirtualKeyboardTrace. |
411 | */ |
412 | |
413 | /*! \qmlproperty list<strings> Trace::channels |
414 | |
415 | List of additional data channels in the Trace. |
416 | This property must be initialized before the data |
417 | is added. |
418 | */ |
419 | |
420 | /*! \property QVirtualKeyboardTrace::channels |
421 | \brief list of data channels in the QQTrace. |
422 | |
423 | This property must be initialized before the data |
424 | is added. |
425 | */ |
426 | |
427 | /*! \qmlproperty int QVirtualKeyboardTrace::length |
428 | |
429 | The number of points in the QVirtualKeyboardTrace. |
430 | */ |
431 | |
432 | /*! \property QVirtualKeyboardTrace::length |
433 | \brief the number of of points in the QVirtualKeyboardTrace. |
434 | */ |
435 | |
436 | /*! \qmlproperty bool Trace::final |
437 | |
438 | This property defines whether the Trace can accept more data. |
439 | If the value is \c true, no more data is accepted. |
440 | */ |
441 | |
442 | /*! \property QVirtualKeyboardTrace::final |
443 | \brief defines whether the QVirtualKeyboardTrace can accept more data. |
444 | If the value is \c true, no more data is accepted. |
445 | */ |
446 | |
447 | /*! \qmlproperty bool Trace::canceled |
448 | |
449 | This property defines whether the Trace is canceled. |
450 | The input data should not be processed from the Traces |
451 | whose \c canceled property set to true. |
452 | */ |
453 | |
454 | /*! \property QVirtualKeyboardTrace::canceled |
455 | \brief defines whether the QVirtualKeyboardTrace is canceled. |
456 | |
457 | The input data should not be processed from the Traces |
458 | whose \c canceled property set to true. |
459 | */ |
460 | |
461 | /*! \qmlproperty qreal Trace::opacity |
462 | \since QtQuick.VirtualKeyboard 2.4 |
463 | |
464 | This property defines how opaque the Trace is. |
465 | |
466 | A lower value results in a more transparent trace: \c 0.0 is fully |
467 | transparent, and \c 1.0 is fully opaque. |
468 | |
469 | This property is useful for making older traces more transparent as new |
470 | ones are added. |
471 | */ |
472 | |
473 | /*! \property QVirtualKeyboardTrace::opacity |
474 | |
475 | This property defines how opaque the QVirtualKeyboardTrace is. |
476 | |
477 | A lower value results in a more transparent trace: \c 0.0 is fully |
478 | transparent, and \c 1.0 is fully opaque. |
479 | |
480 | This property is useful for making older traces more transparent as new |
481 | ones are added. |
482 | */ |
483 | |
484 | QT_END_NAMESPACE |
485 | |