Apply new indicator UI.
[platform/framework/native/uifw.git] / src / ui / FUi_TouchPinchGestureDetector.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file                        FUi_TouchPinchGestureDetector.cpp
19  * @brief               This is the implementation file for %_TouchPinchGestureDetector class
20  * @version     2.0
21  *
22  * This file contains the implementation of %_TouchPinchGestureDetector class.
23  *
24  */
25
26 #include <FBase.h>
27 #include <FBaseColIEnumeratorT.h>
28 #include <FUiITouchPinchGestureEventListener.h>
29 #include "FUi_TouchPinchGestureDetector.h"
30 #include "FUi_ITouchPinchGestureEventListener.h"
31 #include "FUi_TouchManager.h"
32 #include "FUi_TouchPinchGestureDetectorImpl.h"
33
34 // namespace
35 using namespace Tizen::Graphics;
36 using namespace Tizen::Base::Collection;
37 using namespace Tizen::Base::Runtime;
38
39 namespace
40 {
41 const int DEFAULT_TOUCH_COUNT = 2;
42 const int POLLING_PINCH = 16;
43 const int PINCH_THRESHOLD = 10;
44 }
45
46 namespace Tizen { namespace Ui
47 {
48 _TouchPinchGestureDetector::_TouchPinchGestureDetector(void)
49         : __MinimumPoint(0, 0)
50         , __MaximumPoint(0, 0)
51         , __centerPosition(0, 0)
52         , __pTimer(null)
53         , __threshold(PINCH_THRESHOLD)
54         , __scale(0)
55 {
56         result r = GetLastResult();
57         SysTryReturnVoidResult(NID_UI, r == E_SUCCESS, r, GetErrorMessage(r));
58
59         __pTimer = new (std::nothrow)Timer;
60         SysTryReturnVoidResult(NID_UI, __pTimer, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
61
62         r = __pTimer->Construct(*this);
63         SysTryCatch(NID_UI, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
64
65         SetDetectorType(_TOUCH_GESTURE_DETECTOR_TYPE_PINCH);
66         return;
67
68 CATCH:
69         delete __pTimer;
70         __pTimer = null;
71 }
72
73 _TouchPinchGestureDetector::~_TouchPinchGestureDetector(void)
74 {
75         delete __pTimer;
76         __pTimer = null;
77 }
78
79 bool
80 _TouchPinchGestureDetector::OnTouchPressed(const _Control& source, const _TouchInfo& touchinfo)
81 {
82         //SysLog(NID_UI, "pressId = %d, pressX = %d, pressY = %d", touchinfo.GetPointId(), touchinfo.GetCurrentPosition().x, touchinfo.GetCurrentPosition().y);
83
84         if (MeasureArea() > __threshold)
85         {
86                 SetGestureStart(true);
87                 SetDetectorState(_TOUCH_GESTURE_DETECTOR_STATE_STARTED);
88
89                 _Control* pControl = GetControl();
90                 if (pControl && !pControl->IsMultiTouchEnabled())
91                 {
92                         pControl->SetMultiTouchEnabled(true);
93                 }
94         }
95
96         return false;
97 }
98
99 bool
100 _TouchPinchGestureDetector::OnTouchMoved(const _Control& source, const _TouchInfo& touchinfo)
101 {
102         _TouchGestureDetectorState state = GetDetectorState();
103         //SysLog(NID_UI, "moveId = %d, moveX = %d, moveY = %d", touchinfo.GetPointId(), touchinfo.GetCurrentPosition().x, touchinfo.GetCurrentPosition().y);
104
105         if (state == _TOUCH_GESTURE_DETECTOR_STATE_STARTED || state == _TOUCH_GESTURE_DETECTOR_STATE_SUCCESS_AND_WAIT
106                 || state == _TOUCH_GESTURE_DETECTOR_STATE_CHANGED)
107         {
108                 //SysLog(NID_UI, "enter state ok");
109                 if (MeasureArea() > __threshold)
110                 {
111                         SetDetectorState(_TOUCH_GESTURE_DETECTOR_STATE_CHANGED);
112                 }
113         }
114
115         return false;
116 }
117
118 void
119 _TouchPinchGestureDetector::OnTimerExpired(Timer& timer)
120 {
121         SetDetectorStateChanged();
122
123         __pTimer->Start(POLLING_PINCH);
124 }
125
126 void
127 _TouchPinchGestureDetector::SetDetectorStateChanged(void)
128 {
129         _TouchGestureDetectorState state = GetDetectorState();
130
131         if ( state == _TOUCH_GESTURE_DETECTOR_STATE_CHANGED )
132         {
133                 SetDetectorState(_TOUCH_GESTURE_DETECTOR_STATE_CHANGED);
134         }
135 }
136
137 bool
138 _TouchPinchGestureDetector::OnTouchReleased(const _Control& source, const _TouchInfo& touchinfo)
139 {
140         //SysLog(NID_UI, "releaseId = %d, releaseX = %d, releaseY = %d", touchinfo.GetPointId(), touchinfo.GetCurrentPosition().x, touchinfo.GetCurrentPosition().y);
141
142         if (MeasureArea() > __threshold)
143         {
144                 return false;
145         }
146
147         __pTimer->Cancel();
148
149         _TouchGestureDetectorState state = GetDetectorState();
150
151         if (IsGestureStarted())
152         {
153                 SetGestureStart(false);
154                 if (state == _TOUCH_GESTURE_DETECTOR_STATE_STARTED || state == _TOUCH_GESTURE_DETECTOR_STATE_CHANGED || state == _TOUCH_GESTURE_DETECTOR_STATE_SUCCESS_AND_WAIT)
155                 {
156                         SetDetectorState(_TOUCH_GESTURE_DETECTOR_STATE_FINISHED);
157                 }
158         }
159
160         return false;
161 }
162
163 bool
164 _TouchPinchGestureDetector::OnTouchCanceled(const _Control& source, const _TouchInfo& touchinfo)
165 {
166         __pTimer->Cancel();
167         __centerPosition.x = 0;
168         __centerPosition.y = 0;
169         __scale = 0;
170         __MinimumPoint.x = 0;
171         __MinimumPoint.y = 0;
172         __MaximumPoint.x = 0;
173         __MaximumPoint.y = 0;
174
175         return false;
176 }
177
178 Point
179 _TouchPinchGestureDetector::GetCenterPoint(void) const
180 {
181         return Point(__centerPosition.x, __centerPosition.y);
182 }
183
184 FloatPoint
185 _TouchPinchGestureDetector::GetCenterPointF(void) const
186 {
187         return __centerPosition;
188 }
189
190 int
191 _TouchPinchGestureDetector::GetScale(void) const
192 {
193         return __scale;
194 }
195
196 float
197 _TouchPinchGestureDetector::GetScaleF(void) const
198 {
199         return __scale;
200 }
201
202 int
203 _TouchPinchGestureDetector::MeasureArea(void)
204 {
205         _TouchManager* pTouchManager = _TouchManager::GetInstance();
206         SysTryReturn(NID_UI, pTouchManager != null, null, E_SYSTEM, "[E_SYSTEM] _TouchManager does not exist.");
207
208         IListT<_FingerInfo*>* pFingerInfoList = pTouchManager->GetMultiFingerInfoListN();
209         SysTryReturn(NID_UI, pFingerInfoList, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
210
211         //SysLog(NID_UI, "GetCount = %d, minX = %d, minY = %d, maxX = %d, maxY = %d", pFingerInfoList->GetCount(), __MinimumPoint.x, __MinimumPoint.y, __MaximumPoint.x, __MaximumPoint.y);
212
213         bool initialized = false;
214
215         __MinimumPoint.x = 0;
216         __MinimumPoint.y = 0;
217         __MaximumPoint.x = 0;
218         __MaximumPoint.y = 0;
219
220         for (int i = 0; i < pFingerInfoList->GetCount(); i++)
221         {
222                 _FingerInfo* pFingerInfo = null;
223                 pFingerInfoList->GetAt(i, pFingerInfo);
224
225                 if (pFingerInfo == null || pFingerInfo->GetPointId() == INVALID_POINT_ID ||
226                         pFingerInfo->GetStatus() == _TOUCH_RELEASED || pFingerInfo->GetStatus() == _TOUCH_CANCELED)
227                 {
228                         continue;
229                 }
230
231                 //SysLog(NID_UI, "pointId = %d, x = %d, y = %d", pFingerInfo->GetPointId(), pFingerInfo->GetPoint().x, pFingerInfo->GetPoint().y);
232
233                 Tizen::Graphics::FloatPoint point = pFingerInfo->GetPoint();
234
235                 if (initialized)
236                 {
237                         if (__MinimumPoint.x > point.x)
238                         {
239                                 __MinimumPoint.x = point.x;
240                         }
241                         if (__MinimumPoint.y > point.y)
242                         {
243                                 __MinimumPoint.y = point.y;
244                         }
245                         if (__MaximumPoint.x < point.x)
246                         {
247                                 __MaximumPoint.x = point.x;
248                         }
249                         if (__MaximumPoint.y < point.y)
250                         {
251                                 __MaximumPoint.y = point.y;
252                         }
253                 }
254                 else
255                 {
256                         __MinimumPoint.x = point.x;
257                         __MinimumPoint.y = point.y;
258                         __MaximumPoint.x = point.x;
259                         __MaximumPoint.y = point.y;
260
261                         initialized = true;
262                 }
263         }
264
265         delete pFingerInfoList;
266         pFingerInfoList = null;
267
268         __centerPosition.x = (__MinimumPoint.x+__MaximumPoint.x)/2;
269         __centerPosition.y = (__MinimumPoint.y+__MaximumPoint.y)/2;
270
271         __scale =  int(sqrt(abs(__MaximumPoint.x-__MinimumPoint.x) * abs(__MaximumPoint.y-__MinimumPoint.y)));
272
273         initialized = false;
274         //SysLog(NID_UI, "centerX = %d, centerY = %d, area = %d", __centerPosition.x, __centerPosition.y, __scale);
275
276         return __scale;
277 }
278
279 } }  // Tizen::Ui