Moved Gesture::State and -::Type to gesture-enumerations.h.
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-RotationGestureRecognizer.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
20 #include <stdlib.h>
21 #include <dali/public-api/dali-core.h>
22 #include <dali/integration-api/input-options.h>
23 #include <dali/integration-api/events/touch-event-integ.h>
24 #include <dali-test-suite-utils.h>
25
26 using namespace Dali;
27
28 void utc_dali_rotation_gesture_recognizer_startup(void)
29 {
30   test_return_value = TET_UNDEF;
31 }
32
33 void utc_dali_rotation_gesture_recognizer_cleanup(void)
34 {
35   test_return_value = TET_PASS;
36 }
37
38 ///////////////////////////////////////////////////////////////////////////////
39 namespace
40 {
41
42 struct SignalData
43 {
44   SignalData()
45   : functorCalled(false),
46     voidFunctorCalled(false),
47     receivedGesture()
48   {}
49
50   void Reset()
51   {
52     functorCalled = false;
53     voidFunctorCalled = false;
54
55     receivedGesture.Reset();
56
57     rotatedActor.Reset();
58   }
59
60   bool functorCalled;
61   bool voidFunctorCalled;
62   RotationGesture receivedGesture;
63   Actor rotatedActor;
64 };
65
66 // Functor that sets the data when called
67 struct GestureReceivedFunctor
68 {
69   GestureReceivedFunctor(SignalData& data) : signalData(data) { }
70
71   void operator()(Actor actor, const RotationGesture& rotation)
72   {
73     signalData.functorCalled = true;
74     signalData.receivedGesture = rotation;
75     signalData.rotatedActor = actor;
76   }
77
78   void operator()()
79   {
80     signalData.voidFunctorCalled = true;
81   }
82
83   SignalData& signalData;
84 };
85
86 Integration::TouchEvent GenerateSingleTouch( PointState::Type state, const Vector2& screenPosition, uint32_t time )
87 {
88   Integration::TouchEvent touchEvent;
89   Integration::Point point;
90   point.SetState( state );
91   point.SetScreenPosition( screenPosition );
92   point.SetDeviceClass( Device::Class::TOUCH );
93   point.SetDeviceSubclass( Device::Subclass::NONE );
94   touchEvent.points.push_back( point );
95   touchEvent.time = time;
96   return touchEvent;
97 }
98
99 Integration::TouchEvent GenerateDoubleTouch( PointState::Type stateA, const Vector2& screenPositionA, PointState::Type stateB, const Vector2& screenPositionB, uint32_t time )
100 {
101   Integration::TouchEvent touchEvent;
102   Integration::Point point;
103   point.SetState( stateA );
104   point.SetScreenPosition( screenPositionA );
105   point.SetDeviceClass( Device::Class::TOUCH );
106   point.SetDeviceSubclass( Device::Subclass::NONE );
107   touchEvent.points.push_back( point );
108   point.SetScreenPosition( screenPositionB );
109   point.SetState( stateB);
110   touchEvent.points.push_back( point );
111   touchEvent.time = time;
112   return touchEvent;
113 }
114
115
116 } // anon namespace
117
118 ///////////////////////////////////////////////////////////////////////////////
119 int UtcDaliRotationGestureRecognizerRealistic(void)
120 {
121   TestApplication application;
122
123   RotationGestureDetector detector = RotationGestureDetector::New();
124
125   Actor actor = Actor::New();
126   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
127   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
128   application.GetScene().Add( actor );
129
130   // Render and notify
131   application.SendNotification();
132   application.Render();
133
134   detector.Attach(actor);
135
136   SignalData data;
137   GestureReceivedFunctor functor(data);
138   detector.DetectedSignal().Connect(&application, functor);
139
140   application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 100 ) );
141   application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 20.0f ), 105 ) );
142   application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 110 ) );
143   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 25.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 115 ) );
144   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 30.0f ), PointState::MOTION, Vector2( 20.0f, 85.0f ), 120 ) );
145   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 35.0f ), PointState::MOTION, Vector2( 20.0f, 80.0f ), 125 ) );
146   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 40.0f ), PointState::MOTION, Vector2( 20.0f, 75.0f ), 130 ) );
147   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 45.0f ), PointState::MOTION, Vector2( 20.0f, 70.0f ), 135 ) );
148   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 50.0f ), PointState::MOTION, Vector2( 20.0f, 65.0f ), 140 ) );
149   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 55.0f ), PointState::MOTION, Vector2( 20.0f, 60.0f ), 145 ) );
150   application.ProcessEvent( GenerateSingleTouch( PointState::UP, Vector2( 20.0f, 56.0f ), 155 ) );
151
152   application.SendNotification();
153
154   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
155
156   END_TEST;
157 }
158
159 int UtcDaliRotationGestureRecognizerBasicInterrupted(void)
160 {
161   TestApplication application;
162
163   RotationGestureDetector detector = RotationGestureDetector::New();
164
165   Actor actor = Actor::New();
166   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
167   actor.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
168   application.GetScene().Add( actor );
169
170   // Render and notify
171   application.SendNotification();
172   application.Render();
173
174   detector.Attach(actor);
175
176   SignalData data;
177   GestureReceivedFunctor functor(data);
178   detector.DetectedSignal().Connect(&application, functor);
179
180   // application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
181   // application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 25.0f ), 151 ) );
182   application.ProcessEvent( GenerateSingleTouch( PointState::INTERRUPTED, Vector2( 20.0f, 30.0f ), 152 ) );
183
184   application.SendNotification();
185
186   DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
187
188   END_TEST;
189 }
190
191 int UtcDaliRotationGestureRecognizerMinimumTouchEvents(void)
192 {
193   TestApplication application;
194
195   Actor actor = Actor::New();
196   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
197   actor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
198   application.GetScene().Add( actor );
199
200   application.SendNotification();
201   application.Render();
202
203   SignalData data;
204   GestureReceivedFunctor functor( data );
205
206   RotationGestureDetector detector = RotationGestureDetector::New();
207   detector.Attach( actor );
208   detector.DetectedSignal().Connect( &application, functor );
209
210   // Case 1
211   // 2 touch events make a gesture begin
212   Integration::SetRotationGestureMinimumTouchEvents( 2 );
213   application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
214   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 20.0f ), PointState::MOTION, Vector2( 90.0f, 90.0f ), 160 ) );
215
216   DALI_TEST_EQUALS( GestureState::STARTED, data.receivedGesture.GetState(), TEST_LOCATION );
217   DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
218   data.Reset();
219
220   // Case 2
221   // 4 touch events make a gesture begin
222   Integration::SetRotationGestureMinimumTouchEvents( 4 );
223   application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
224   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 20.0f ), PointState::MOTION, Vector2( 90.0f, 90.0f ), 160 ) );
225
226   // Check the gesture is not detected unlike previous case
227   DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
228
229   END_TEST;
230 }
231
232 int UtcDaliRotationGestureRecognizerMinimumTouchEventsAfterStart(void)
233 {
234   TestApplication application;
235
236   Actor actor = Actor::New();
237   actor.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
238   actor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
239   application.GetScene().Add( actor );
240
241   application.SendNotification();
242   application.Render();
243
244   SignalData data;
245   GestureReceivedFunctor functor( data );
246
247   RotationGestureDetector detector = RotationGestureDetector::New();
248   detector.Attach( actor );
249   detector.DetectedSignal().Connect( &application, functor );
250
251   // Case 1
252   // > 2 touch events make a gesture begin
253   // > 4 touch events generate gestures after begin
254   Integration::SetRotationGestureMinimumTouchEvents(2);
255   Integration::SetRotationGestureMinimumTouchEventsAfterStart(6);
256
257   application.ProcessEvent( GenerateDoubleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), PointState::DOWN, Vector2( 20.0f, 90.0f ), 150 ) );
258   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 20.0f ), PointState::MOTION, Vector2( 90.0f, 90.0f ), 160 ) );
259
260   DALI_TEST_EQUALS(GestureState::STARTED, data.receivedGesture.GetState(), TEST_LOCATION);
261   DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
262
263   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 20.0f ), PointState::MOTION, Vector2( 20.0f, 90.0f ), 170 ) );
264   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 20.0f ), PointState::MOTION, Vector2( 20.0f, 90.0f ), 180 ) );
265   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 20.0f ), PointState::MOTION, Vector2( 20.0f, 90.0f ), 190 ) );
266   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 20.0f ), PointState::MOTION, Vector2( 20.0f, 90.0f ), 200 ) );
267   // > Test : not enough touch events to make the gesture state "CONTINUING"
268   DALI_TEST_EQUALS(GestureState::STARTED, data.receivedGesture.GetState(), TEST_LOCATION);
269
270   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 20.0f ), PointState::MOTION, Vector2( 20.0f, 90.0f ), 210 ) );
271   application.ProcessEvent( GenerateDoubleTouch( PointState::MOTION, Vector2( 20.0f, 20.0f ), PointState::MOTION, Vector2( 20.0f, 90.0f ), 220 ) );
272   // > Test : 6 touch events after start make the gesture state "CONTINUING"
273   DALI_TEST_EQUALS(GestureState::CONTINUING, data.receivedGesture.GetState(), TEST_LOCATION);
274
275   END_TEST;
276 }