Merge changes I6d6c0232,I6667d1d6,I43e227fc into devel/master
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-TapGestureRecognizer.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <dali-test-suite-utils.h>
19 #include <dali/integration-api/events/touch-event-integ.h>
20 #include <dali/integration-api/render-task-list-integ.h>
21 #include <dali/public-api/dali-core.h>
22 #include <stdlib.h>
23
24 #include <iostream>
25
26 using namespace Dali;
27
28 ///////////////////////////////////////////////////////////////////////////////
29 namespace
30 {
31 struct SignalData
32 {
33   SignalData()
34   : functorCalled(false),
35     voidFunctorCalled(false),
36     receivedGesture()
37   {
38   }
39
40   void Reset()
41   {
42     functorCalled     = false;
43     voidFunctorCalled = false;
44
45     receivedGesture.Reset();
46
47     tappedActor.Reset();
48   }
49
50   bool       functorCalled;
51   bool       voidFunctorCalled;
52   TapGesture receivedGesture;
53   Actor      tappedActor;
54 };
55
56 // Functor that sets the data when called
57 struct GestureReceivedFunctor
58 {
59   GestureReceivedFunctor(SignalData& data)
60   : signalData(data)
61   {
62   }
63
64   void operator()(Actor actor, const TapGesture& tap)
65   {
66     signalData.functorCalled   = true;
67     signalData.receivedGesture = tap;
68     signalData.tappedActor     = actor;
69   }
70
71   void operator()()
72   {
73     signalData.voidFunctorCalled = true;
74   }
75
76   SignalData& signalData;
77 };
78
79 Integration::TouchEvent GenerateSingleTouch(PointState::Type state, const Vector2& screenPosition, uint32_t time)
80 {
81   Integration::TouchEvent touchEvent;
82   Integration::Point      point;
83   point.SetState(state);
84   point.SetScreenPosition(screenPosition);
85   point.SetDeviceClass(Device::Class::TOUCH);
86   point.SetDeviceSubclass(Device::Subclass::NONE);
87   touchEvent.points.push_back(point);
88   touchEvent.time = time;
89   return touchEvent;
90 }
91
92 Integration::TouchEvent GenerateDoubleTouch(PointState::Type state, const Vector2& screenPositionA, const Vector2& screenPositionB, uint32_t time)
93 {
94   Integration::TouchEvent touchEvent;
95   Integration::Point      point;
96   point.SetState(state);
97   point.SetScreenPosition(screenPositionA);
98   point.SetDeviceClass(Device::Class::TOUCH);
99   point.SetDeviceSubclass(Device::Subclass::NONE);
100   touchEvent.points.push_back(point);
101   point.SetScreenPosition(screenPositionB);
102   touchEvent.points.push_back(point);
103   touchEvent.time = time;
104   return touchEvent;
105 }
106
107 } // namespace
108
109 ///////////////////////////////////////////////////////////////////////////////
110
111 int UtcDaliTapGestureRecognizerBasic(void)
112 {
113   TestApplication application;
114
115   TapGestureDetector detector = TapGestureDetector::New();
116
117   Actor actor = Actor::New();
118   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
119   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
120   application.GetScene().Add(actor);
121
122   // Render and notify
123   application.SendNotification();
124   application.Render();
125
126   detector.Attach(actor);
127
128   SignalData             data;
129   GestureReceivedFunctor functor(data);
130   detector.DetectedSignal().Connect(&application, functor);
131
132   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
133
134   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 200));
135
136   application.SendNotification();
137
138   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
139
140   END_TEST;
141 }
142
143 int UtcDaliTapGestureRecognizerGapTooLong(void)
144 {
145   TestApplication application;
146
147   TapGestureDetector detector = TapGestureDetector::New();
148
149   Actor actor = Actor::New();
150   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
151   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
152   application.GetScene().Add(actor);
153
154   // Render and notify
155   application.SendNotification();
156   application.Render();
157
158   detector.Attach(actor);
159
160   SignalData             data;
161   GestureReceivedFunctor functor(data);
162   detector.DetectedSignal().Connect(&application, functor);
163
164   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
165
166   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 651));
167
168   application.SendNotification();
169
170   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
171
172   END_TEST;
173 }
174
175 int UtcDaliTapGestureRecognizerInterrupted(void)
176 {
177   TestApplication application;
178
179   TapGestureDetector detector = TapGestureDetector::New();
180
181   Actor actor = Actor::New();
182   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
183   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
184   application.GetScene().Add(actor);
185
186   // Render and notify
187   application.SendNotification();
188   application.Render();
189
190   detector.Attach(actor);
191
192   SignalData             data;
193   GestureReceivedFunctor functor(data);
194   detector.DetectedSignal().Connect(&application, functor);
195
196   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
197
198   application.ProcessEvent(GenerateSingleTouch(PointState::INTERRUPTED, Vector2(20.0f, 20.0f), 175));
199
200   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 200));
201
202   application.SendNotification();
203
204   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
205
206   END_TEST;
207 }
208
209 int UtcDaliTapGestureRecognizerMoveTooFar(void)
210 {
211   TestApplication application;
212
213   TapGestureDetector detector = TapGestureDetector::New();
214   detector.SetMaximumTapsRequired(2);
215
216   Actor actor = Actor::New();
217   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
218   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
219   application.GetScene().Add(actor);
220
221   // Render and notify
222   application.SendNotification();
223   application.Render();
224
225   detector.Attach(actor);
226
227   SignalData             data;
228   GestureReceivedFunctor functor(data);
229   detector.DetectedSignal().Connect(&application, functor);
230
231   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
232
233   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 20.0f), 200));
234
235   application.SendNotification();
236
237   application.GetPlatform().TriggerTimer();
238   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
239
240   END_TEST;
241 }
242
243 int UtcDaliTapGestureRecognizerStartDouble(void)
244 {
245   TestApplication application;
246
247   TapGestureDetector detector = TapGestureDetector::New();
248
249   Actor actor = Actor::New();
250   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
251   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
252   application.GetScene().Add(actor);
253
254   // Render and notify
255   application.SendNotification();
256   application.Render();
257
258   detector.Attach(actor);
259
260   SignalData             data;
261   GestureReceivedFunctor functor(data);
262   detector.DetectedSignal().Connect(&application, functor);
263
264   application.ProcessEvent(GenerateDoubleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), Vector2(25.0f, 25.0f), 150));
265
266   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 200));
267
268   application.SendNotification();
269
270   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
271
272   END_TEST;
273 }
274
275 int UtcDaliTapGestureRecognizerEndDouble(void)
276 {
277   TestApplication application;
278
279   TapGestureDetector detector = TapGestureDetector::New();
280
281   Actor actor = Actor::New();
282   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
283   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
284   application.GetScene().Add(actor);
285
286   // Render and notify
287   application.SendNotification();
288   application.Render();
289
290   detector.Attach(actor);
291
292   SignalData             data;
293   GestureReceivedFunctor functor(data);
294   detector.DetectedSignal().Connect(&application, functor);
295
296   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
297
298   application.ProcessEvent(GenerateDoubleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), Vector2(25.0f, 25.0f), 200));
299
300   application.ProcessEvent(GenerateDoubleTouch(PointState::UP, Vector2(20.0f, 20.0f), Vector2(25.0f, 25.0f), 200));
301
302   application.SendNotification();
303
304   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
305
306   END_TEST;
307 }
308
309 int UtcDaliTapGestureRecognizerDoubleTap(void)
310 {
311   TestApplication application;
312
313   TapGestureDetector detector = TapGestureDetector::New(2);
314
315   Actor actor = Actor::New();
316   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
317   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
318   application.GetScene().Add(actor);
319
320   // Render and notify
321   application.SendNotification();
322   application.Render();
323
324   detector.Attach(actor);
325
326   SignalData             data;
327   GestureReceivedFunctor functor(data);
328   detector.DetectedSignal().Connect(&application, functor);
329
330   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
331
332   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 200));
333
334   application.SendNotification();
335
336   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
337
338   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 250));
339
340   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 300));
341
342   application.SendNotification();
343
344   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
345
346   END_TEST;
347 }
348
349 int UtcDaliTapGestureRecognizerDoubleTapMoveTooFar(void)
350 {
351   TestApplication application;
352
353   TapGestureDetector detector = TapGestureDetector::New(2);
354
355   Actor actor = Actor::New();
356   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
357   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
358   application.GetScene().Add(actor);
359
360   // Render and notify
361   application.SendNotification();
362   application.Render();
363
364   detector.Attach(actor);
365
366   SignalData             data;
367   GestureReceivedFunctor functor(data);
368   detector.DetectedSignal().Connect(&application, functor);
369
370   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
371
372   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 200));
373
374   application.SendNotification();
375
376   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
377
378   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 50.0f), 250));
379
380   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 50.0f), 300));
381
382   application.SendNotification();
383
384   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
385
386   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 450));
387
388   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 500));
389
390   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 550));
391
392   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 600));
393
394   application.SendNotification();
395
396   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
397
398   END_TEST;
399 }
400
401 int UtcDaliTapGestureRecognizerDoubleTapWaitTooLong(void)
402 {
403   TestApplication application;
404
405   TapGestureDetector detector = TapGestureDetector::New(2);
406
407   Actor actor = Actor::New();
408   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
409   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
410   application.GetScene().Add(actor);
411
412   // Render and notify
413   application.SendNotification();
414   application.Render();
415
416   detector.Attach(actor);
417
418   SignalData             data;
419   GestureReceivedFunctor functor(data);
420   detector.DetectedSignal().Connect(&application, functor);
421
422   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
423
424   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 200));
425
426   application.SendNotification();
427
428   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
429
430   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 650));
431
432   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 750));
433
434   application.SendNotification();
435
436   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
437
438   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 950));
439
440   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 1000));
441
442   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 1050));
443
444   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 1000));
445
446   application.SendNotification();
447
448   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
449
450   END_TEST;
451 }
452
453 int UtcDaliTapGestureRecognizerMultipleDetectors(void)
454 {
455   TestApplication application;
456
457   Actor actor = Actor::New();
458   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
459   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
460   application.GetScene().Add(actor);
461
462   Actor actor2 = Actor::New();
463   actor2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
464   actor2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
465   actor2.SetProperty(Actor::Property::POSITION_X, 100.0f);
466   application.GetScene().Add(actor2);
467
468   // Render and notify
469   application.SendNotification();
470   application.Render();
471
472   TapGestureDetector detector = TapGestureDetector::New();
473   detector.Attach(actor);
474
475   TapGestureDetector detector2 = TapGestureDetector::New(2);
476   detector2.Attach(actor2);
477
478   SignalData             data;
479   GestureReceivedFunctor functor(data);
480   detector.DetectedSignal().Connect(&application, functor);
481
482   SignalData             data2;
483   GestureReceivedFunctor functor2(data2);
484   detector2.DetectedSignal().Connect(&application, functor2);
485
486   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
487
488   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 200));
489
490   application.SendNotification();
491
492   application.GetPlatform().TriggerTimer();
493   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
494   DALI_TEST_EQUALS(true, actor == data.tappedActor, TEST_LOCATION);
495   data.Reset();
496   DALI_TEST_EQUALS(false, data2.functorCalled, TEST_LOCATION);
497
498   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(120.0f, 20.0f), 250));
499
500   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(120.0f, 20.0f), 300));
501
502   application.SendNotification();
503
504   DALI_TEST_EQUALS(false, data2.functorCalled, TEST_LOCATION);
505
506   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(120.0f, 20.0f), 350));
507
508   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(120.0f, 20.0f), 400));
509
510   application.SendNotification();
511
512   application.GetPlatform().TriggerTimer();
513   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
514   DALI_TEST_EQUALS(true, data2.functorCalled, TEST_LOCATION);
515
516   END_TEST;
517 }
518
519 int UtcDaliTapGestureRecognizerTripleTap(void)
520 {
521   TestApplication application;
522
523   TapGestureDetector detector = TapGestureDetector::New(3);
524
525   Actor actor = Actor::New();
526   actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
527   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
528   application.GetScene().Add(actor);
529
530   // Render and notify
531   application.SendNotification();
532   application.Render();
533
534   detector.Attach(actor);
535
536   SignalData             data;
537   GestureReceivedFunctor functor(data);
538   detector.DetectedSignal().Connect(&application, functor);
539
540   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
541
542   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 200));
543
544   application.SendNotification();
545
546   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
547
548   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 250));
549
550   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 300));
551
552   application.SendNotification();
553
554   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
555
556   application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 350));
557
558   application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 400));
559
560   application.SendNotification();
561
562   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
563
564   END_TEST;
565 }