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
7QT_BEGIN_NAMESPACE
8
9class QVirtualKeyboardTracePrivate : public QObjectPrivate
10{
11public:
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 */
154QVirtualKeyboardTrace::QVirtualKeyboardTrace(QObject *parent) :
155 QObject(*new QVirtualKeyboardTracePrivate(), parent)
156{
157 Q_ASSERT(parent);
158}
159
160/*! \internal */
161QVirtualKeyboardTrace::~QVirtualKeyboardTrace()
162{
163}
164
165int QVirtualKeyboardTrace::traceId() const
166{
167 Q_D(const QVirtualKeyboardTrace);
168 return d->traceId;
169}
170
171void 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
180QStringList QVirtualKeyboardTrace::channels() const
181{
182 Q_D(const QVirtualKeyboardTrace);
183 return d->channels.keys();
184}
185
186void 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
200int 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
228QVariantList 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
254int 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
284void 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
314QVariantList 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
320bool QVirtualKeyboardTrace::isFinal() const
321{
322 Q_D(const QVirtualKeyboardTrace);
323 return d->final;
324}
325
326void 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
335bool QVirtualKeyboardTrace::isCanceled() const
336{
337 Q_D(const QVirtualKeyboardTrace);
338 return d->canceled;
339}
340
341void 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
350qreal QVirtualKeyboardTrace::opacity() const
351{
352 Q_D(const QVirtualKeyboardTrace);
353 return d->opacity;
354}
355
356void 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
387void 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
396void 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
484QT_END_NAMESPACE
485

source code of qtvirtualkeyboard/src/virtualkeyboard/qvirtualkeyboardtrace.cpp