Refactoring Gestures Class
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-LongPressGestureRecognizer.cpp
1 /*
2  * Copyright (c) 2020 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 <iostream>
19 #include <thread>
20 #include <chrono>
21
22 #include <stdlib.h>
23 #include <dali/public-api/dali-core.h>
24 #include <dali/integration-api/events/touch-event-integ.h>
25 #include <dali/integration-api/render-task-list-integ.h>
26 #include <dali-test-suite-utils.h>
27
28 using namespace Dali;
29
30 ///////////////////////////////////////////////////////////////////////////////
31 namespace
32 {
33
34 struct SignalData
35 {
36   SignalData()
37   : functorCalled(false),
38     voidFunctorCalled(false),
39     receivedGesture()
40   {}
41
42   void Reset()
43   {
44     functorCalled = false;
45     voidFunctorCalled = false;
46
47     receivedGesture.Reset();
48
49     pressedActor.Reset();
50   }
51
52   bool functorCalled;
53   bool voidFunctorCalled;
54   LongPressGesture receivedGesture;
55   Actor pressedActor;
56 };
57
58 // Functor that sets the data when called
59 struct GestureReceivedFunctor
60 {
61   GestureReceivedFunctor(SignalData& data) : signalData(data) { }
62
63   void operator()(Actor actor, const LongPressGesture& pan)
64   {
65     signalData.functorCalled = true;
66     signalData.receivedGesture = pan;
67     signalData.pressedActor = actor;
68   }
69
70   void operator()()
71   {
72     signalData.voidFunctorCalled = true;
73   }
74
75   SignalData& signalData;
76 };
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.SetDeviceId(4);
85   point.SetScreenPosition( screenPosition );
86   point.SetDeviceClass( Device::Class::TOUCH );
87   point.SetDeviceSubclass( Device::Subclass::NONE );
88   touchEvent.points.push_back( point );
89   touchEvent.time = time;
90   return touchEvent;
91 }
92
93 Integration::TouchEvent GenerateDoubleTouch( PointState::Type stateA, const Vector2& screenPositionA, PointState::Type stateB, const Vector2& screenPositionB, uint32_t time )
94 {
95   Integration::TouchEvent touchEvent;
96   Integration::Point point;
97   point.SetState( stateA );
98   point.SetDeviceId(4);
99   point.SetScreenPosition( screenPositionA );
100   point.SetDeviceClass( Device::Class::TOUCH );
101   point.SetDeviceSubclass( Device::Subclass::NONE );
102   touchEvent.points.push_back( point );
103   point.SetScreenPosition( screenPositionB );
104   point.SetState( stateB);
105   point.SetDeviceId(7);
106   touchEvent.points.push_back( point );
107   touchEvent.time = time;
108   return touchEvent;
109 }
110
111
112 } // anon namespace
113
114 ///////////////////////////////////////////////////////////////////////////////
115
116
117 int UtcDaliLongPressGestureRecognizerBasicNoAction(void)
118 {
119   TestApplication application;
120
121   LongPressGestureDetector detector = LongPressGestureDetector::New();
122
123   Actor actor = Actor::New();
124   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
125   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
126   application.GetScene().Add(actor);
127
128   // Render and notify
129   application.SendNotification();
130   application.Render();
131
132   detector.Attach(actor);
133
134   SignalData data;
135   GestureReceivedFunctor functor(data);
136   detector.DetectedSignal().Connect(&application, functor);
137
138   application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
139
140   application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 200 ) );
141
142   application.SendNotification();
143
144   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
145
146   END_TEST;
147 }
148
149 int UtcDaliLongPressGestureRecognizerBasic(void)
150 {
151   TestApplication application;
152
153   LongPressGestureDetector detector = LongPressGestureDetector::New();
154
155   Actor actor = Actor::New();
156   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
157   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
158   application.GetScene().Add(actor);
159
160   // Render and notify
161   application.SendNotification();
162   application.Render();
163
164   detector.Attach(actor);
165
166   SignalData data;
167   GestureReceivedFunctor functor(data);
168   detector.DetectedSignal().Connect(&application, functor);
169
170   application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
171
172   application.GetPlatform().TriggerTimer();
173
174   application.SendNotification();
175
176   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
177
178   END_TEST;
179 }
180
181 int UtcDaliLongPressGestureRecognizerTooShortWait(void)
182 {
183   TestApplication application;
184
185   LongPressGestureDetector detector = LongPressGestureDetector::New();
186
187   Actor actor = Actor::New();
188   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
189   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
190   application.GetScene().Add(actor);
191
192   // Render and notify
193   application.SendNotification();
194   application.Render();
195
196   detector.Attach(actor);
197
198   SignalData data;
199   GestureReceivedFunctor functor(data);
200   detector.DetectedSignal().Connect(&application, functor);
201
202   application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
203
204   application.SendNotification();
205
206   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
207
208   END_TEST;
209 }
210
211 int UtcDaliLongPressGestureRecognizerTooFewPoints(void)
212 {
213   TestApplication application;
214
215   LongPressGestureDetector detector = LongPressGestureDetector::New();
216
217   detector.SetTouchesRequired(2,2);
218
219   Actor actor = Actor::New();
220   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
221   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
222   application.GetScene().Add(actor);
223
224   // Render and notify
225   application.SendNotification();
226   application.Render();
227
228   detector.Attach(actor);
229
230   SignalData data;
231   GestureReceivedFunctor functor(data);
232   detector.DetectedSignal().Connect(&application, functor);
233
234   application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
235
236   // There should be no function to call
237   application.GetPlatform().TriggerTimer();
238
239   application.SendNotification();
240
241   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
242
243   END_TEST;
244 }
245
246 int UtcDaliLongPressGestureRecognizerTooManyPoints(void)
247 {
248   TestApplication application;
249
250   LongPressGestureDetector detector = LongPressGestureDetector::New();
251
252   Actor actor = Actor::New();
253   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
254   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
255   application.GetScene().Add(actor);
256
257   // Render and notify
258   application.SendNotification();
259   application.Render();
260
261   detector.Attach(actor);
262
263   SignalData data;
264   GestureReceivedFunctor functor(data);
265   detector.DetectedSignal().Connect(&application, functor);
266
267   application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
268   application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 151 ) );
269
270   // There should be no function to call as the double touch should have cancelled it
271   application.GetPlatform().TriggerTimer();
272
273   application.SendNotification();
274
275   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
276
277   END_TEST;
278 }
279
280 int UtcDaliLongPressGestureRecognizerMultiplePointsMoving(void)
281 {
282   TestApplication application;
283
284   LongPressGestureDetector detector = LongPressGestureDetector::New();
285
286   detector.SetTouchesRequired(2,2);
287
288   Actor actor = Actor::New();
289   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
290   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
291   application.GetScene().Add(actor);
292
293   // Render and notify
294   application.SendNotification();
295   application.Render();
296
297   detector.Attach(actor);
298
299   SignalData data;
300   GestureReceivedFunctor functor(data);
301   detector.DetectedSignal().Connect(&application, functor);
302
303   application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 0.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 151 ) );
304   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 10.0f ), PointState::MOTION, Vector2( 20.0f, 80.0f ), 153 ) );
305   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 20.0f ), PointState::MOTION, Vector2( 20.0f, 70.0f ), 155 ) );
306   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 30.0f ), PointState::MOTION, Vector2( 20.0f, 60.0f ), 157 ) );
307   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), PointState::MOTION, Vector2( 20.0f, 50.0f ), 159 ) );
308   application.ProcessEvent( GenerateDoubleTouch( PointState::STATIONARY, Vector2( 20.0f, 40.0f ), PointState::UP, Vector2( 20.0f, 50.0f ), 160 ) );
309   application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 40.0f ), 161 ) );
310
311   application.GetPlatform().TriggerTimer();
312
313   application.SendNotification();
314
315   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
316
317   END_TEST;
318 }
319
320 int UtcDaliLongPressGestureRecognizerMultiplePointsLongPress(void)
321 {
322   TestApplication application;
323
324   LongPressGestureDetector detector = LongPressGestureDetector::New();
325
326   Actor actor = Actor::New();
327   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
328   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
329   application.GetScene().Add(actor);
330
331   // Render and notify
332   application.SendNotification();
333   application.Render();
334
335   detector.Attach(actor);
336   detector.SetTouchesRequired(2,2); // Set after we've attached forcing us to change things internally
337
338   SignalData data;
339   GestureReceivedFunctor functor(data);
340   detector.DetectedSignal().Connect(&application, functor);
341
342   application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 40.0f ), 140 ) );
343   application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 40.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
344
345   application.GetPlatform().TriggerTimer();
346
347   application.ProcessEvent( GenerateDoubleTouch( PointState::STATIONARY, Vector2( 20.0f, 20.0f ), PointState::UP, Vector2( 20.0f, 90.0f ), 760 ) );
348   application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 761 ) );
349
350   application.SendNotification();
351
352   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
353
354   END_TEST;
355 }
356
357 int UtcDaliLongPressGestureRecognizerMultipleDetectors(void)
358 {
359   TestApplication application;
360
361     Actor actor = Actor::New();
362     actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
363     actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
364     application.GetScene().Add(actor);
365
366     Actor actor2 = Actor::New();
367     actor2.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
368     actor2.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
369     actor2.SetProperty( Actor::Property::POSITION_X, 100.0f);
370     application.GetScene().Add(actor2);
371
372     // Render and notify
373     application.SendNotification();
374     application.Render();
375
376     LongPressGestureDetector detector = LongPressGestureDetector::New();
377     detector.Attach(actor);
378
379     LongPressGestureDetector detector2 = LongPressGestureDetector::New(2);
380     detector2.Attach(actor2);
381
382     SignalData data;
383     GestureReceivedFunctor functor(data);
384     detector.DetectedSignal().Connect(&application, functor);
385
386     SignalData data2;
387     GestureReceivedFunctor functor2(data2);
388     detector2.DetectedSignal().Connect(&application, functor2);
389
390     application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
391
392     application.GetPlatform().TriggerTimer();
393
394     application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 700 ) );
395
396     application.SendNotification();
397
398     DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
399     DALI_TEST_EQUALS(true, actor == data.pressedActor, TEST_LOCATION);
400     data.Reset();
401     DALI_TEST_EQUALS(false, data2.functorCalled, TEST_LOCATION);
402
403     application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 120.0f, 40.0f ), 800 ) );
404     application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 120.0f, 40.0f ), PointState::DOWN, Vector2( 120.0f, 90.0f ), 805 ) );
405
406     application.GetPlatform().TriggerTimer();
407
408     application.SendNotification();
409
410     DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
411     DALI_TEST_EQUALS(true, data2.functorCalled, TEST_LOCATION);
412
413     END_TEST;
414 }