|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Touch gesture framework pointer state. |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "akntouchgesturefwdefs.h" |
|
19 #include "akntouchgesturefwpointerstate.h" |
|
20 |
|
21 using namespace AknTouchGestureFw; |
|
22 |
|
23 // ======== MEMBER FUNCTIONS ======== |
|
24 |
|
25 // --------------------------------------------------------------------------- |
|
26 // Two-phased constructor. |
|
27 // --------------------------------------------------------------------------- |
|
28 // |
|
29 CAknTouchGestureFwPointerState* CAknTouchGestureFwPointerState::NewL() |
|
30 { |
|
31 CAknTouchGestureFwPointerState* self = |
|
32 CAknTouchGestureFwPointerState::NewLC(); |
|
33 CleanupStack::Pop( self ); |
|
34 return self; |
|
35 } |
|
36 |
|
37 |
|
38 // --------------------------------------------------------------------------- |
|
39 // Two-phased constructor. |
|
40 // --------------------------------------------------------------------------- |
|
41 // |
|
42 CAknTouchGestureFwPointerState* CAknTouchGestureFwPointerState::NewLC() |
|
43 { |
|
44 CAknTouchGestureFwPointerState* self |
|
45 = new ( ELeave ) CAknTouchGestureFwPointerState(); |
|
46 CleanupStack::PushL( self ); |
|
47 return self; |
|
48 } |
|
49 |
|
50 |
|
51 // --------------------------------------------------------------------------- |
|
52 // Destructor. |
|
53 // --------------------------------------------------------------------------- |
|
54 // |
|
55 CAknTouchGestureFwPointerState::~CAknTouchGestureFwPointerState() |
|
56 { |
|
57 } |
|
58 |
|
59 |
|
60 // --------------------------------------------------------------------------- |
|
61 // Resets the pointer state. |
|
62 // --------------------------------------------------------------------------- |
|
63 // |
|
64 void CAknTouchGestureFwPointerState::Reset() |
|
65 { |
|
66 iPointerCount = 0; |
|
67 iPointerData[0].iIsPressedDown = EFalse; |
|
68 iPointerData[1].iIsPressedDown = EFalse; |
|
69 iFirstPointerNumber = KInvalidPointerNumber; |
|
70 iSecondPointerNumber = KInvalidPointerNumber; |
|
71 } |
|
72 |
|
73 |
|
74 // --------------------------------------------------------------------------- |
|
75 // Updates the pointer state. |
|
76 // --------------------------------------------------------------------------- |
|
77 // |
|
78 TBool CAknTouchGestureFwPointerState::Update( |
|
79 const TPointerEventData& aPointerData ) |
|
80 { |
|
81 // Invalid events (e.g. several down events without corresponding |
|
82 // up-event) are ignored. |
|
83 iSuccessiveDownEvents = EFalse; |
|
84 |
|
85 TBool isValid( IsValidEvent( aPointerData.iPointerEvent.iType, |
|
86 aPointerData.iPointerNumber ) ); |
|
87 TBool targetedToControl( aPointerData.iTargetedToControl ); |
|
88 |
|
89 if ( isValid ) |
|
90 { |
|
91 // Updates pointer-related data |
|
92 UpdatePointerOrder( aPointerData.iPointerEvent.iType, |
|
93 aPointerData.iPointerNumber ); |
|
94 |
|
95 TPointerData& data( iPointerData[ aPointerData.iPointerNumber ] ); |
|
96 |
|
97 switch ( aPointerData.iPointerEvent.iType ) |
|
98 { |
|
99 case TPointerEvent::EButton1Down: |
|
100 // One pointer is already down outside gesture control. |
|
101 // No gesture recognition in such cases |
|
102 if ( targetedToControl |
|
103 && PointersDownOutsideControlArea() ) |
|
104 { |
|
105 targetedToControl = EFalse; |
|
106 } |
|
107 data.iPosition = aPointerData.iPointerEvent.iPosition; |
|
108 data.iStartPosition = aPointerData.iPointerEvent.iPosition; |
|
109 data.iIsPressedDown = ETrue; |
|
110 data.iTargetedToControl = targetedToControl; |
|
111 |
|
112 iPointerCount++; |
|
113 break; |
|
114 |
|
115 case TPointerEvent::EDrag: |
|
116 data.iPosition = aPointerData.iPointerEvent.iPosition; |
|
117 break; |
|
118 |
|
119 case TPointerEvent::EButton1Up: |
|
120 data.iIsPressedDown = EFalse; |
|
121 iPointerCount--; |
|
122 break; |
|
123 default: |
|
124 break; |
|
125 } |
|
126 |
|
127 targetedToControl = data.iTargetedToControl; |
|
128 } |
|
129 else |
|
130 { |
|
131 iSuccessiveDownEvents = |
|
132 aPointerData.iPointerEvent.iType == TPointerEvent::EButton1Down; |
|
133 } |
|
134 |
|
135 return isValid && targetedToControl; |
|
136 } |
|
137 |
|
138 |
|
139 // --------------------------------------------------------------------------- |
|
140 // Returns the position of the first pointer. |
|
141 // --------------------------------------------------------------------------- |
|
142 // |
|
143 TPoint* CAknTouchGestureFwPointerState::FirstPointerPosition() |
|
144 { |
|
145 __ASSERT_ALWAYS( iFirstPointerNumber != KInvalidPointerNumber, |
|
146 User::Invariant() ); |
|
147 return &iPointerData[ iFirstPointerNumber ].iPosition; |
|
148 } |
|
149 |
|
150 |
|
151 // --------------------------------------------------------------------------- |
|
152 // Returns the position of the second pointer. |
|
153 // --------------------------------------------------------------------------- |
|
154 // |
|
155 TPoint* CAknTouchGestureFwPointerState::SecondPointerPosition() |
|
156 { |
|
157 __ASSERT_ALWAYS( iSecondPointerNumber != KInvalidPointerNumber, |
|
158 User::Invariant() ); |
|
159 return &iPointerData[ iSecondPointerNumber ].iPosition; |
|
160 } |
|
161 |
|
162 |
|
163 // --------------------------------------------------------------------------- |
|
164 // Checks whether or not two pointers are currently detected. |
|
165 // --------------------------------------------------------------------------- |
|
166 // |
|
167 TBool CAknTouchGestureFwPointerState::IsDoubleTouch() const |
|
168 { |
|
169 return iPointerCount == 2; |
|
170 } |
|
171 |
|
172 |
|
173 // --------------------------------------------------------------------------- |
|
174 // Checks whether or not only one pointer is currently detected. |
|
175 // --------------------------------------------------------------------------- |
|
176 // |
|
177 TBool CAknTouchGestureFwPointerState::IsSingleTouch() const |
|
178 { |
|
179 return iPointerCount == 1; |
|
180 } |
|
181 |
|
182 |
|
183 // --------------------------------------------------------------------------- |
|
184 // Checks whether or not there are currently any pointers detected. |
|
185 // --------------------------------------------------------------------------- |
|
186 // |
|
187 TBool CAknTouchGestureFwPointerState::IsNoTouch() const |
|
188 { |
|
189 return !iPointerCount; |
|
190 } |
|
191 |
|
192 |
|
193 // --------------------------------------------------------------------------- |
|
194 // Checks if successive down events have been received. |
|
195 // --------------------------------------------------------------------------- |
|
196 // |
|
197 TBool CAknTouchGestureFwPointerState::SuccessiveDownEventsReceived() |
|
198 { |
|
199 return iSuccessiveDownEvents; |
|
200 } |
|
201 |
|
202 |
|
203 // --------------------------------------------------------------------------- |
|
204 // Default C++ constructor. |
|
205 // --------------------------------------------------------------------------- |
|
206 // |
|
207 CAknTouchGestureFwPointerState::CAknTouchGestureFwPointerState() |
|
208 { |
|
209 Reset(); |
|
210 } |
|
211 |
|
212 |
|
213 // --------------------------------------------------------------------------- |
|
214 // Updates the order in which the pointers were detected. |
|
215 // --------------------------------------------------------------------------- |
|
216 // |
|
217 void CAknTouchGestureFwPointerState::UpdatePointerOrder( |
|
218 TPointerEvent::TType aPointerType, |
|
219 TInt aPointerNumber ) |
|
220 { |
|
221 // Updates iFirstPointerNumber and iSecondPointerNumber to hold numbers |
|
222 // (=ids) of pointers that were pressed down first and secondly. |
|
223 // Possible values are 0 or 1 (or KInvalidPointerNumber if no pointers |
|
224 // are down) |
|
225 |
|
226 // for double touch |
|
227 __ASSERT_ALWAYS( aPointerNumber >= 0, User::Invariant() ); |
|
228 __ASSERT_ALWAYS( aPointerNumber <= 1, User::Invariant() ); |
|
229 |
|
230 switch ( aPointerType ) |
|
231 { |
|
232 case TPointerEvent::EButton1Down: |
|
233 { |
|
234 if ( iPointerCount == 0 ) |
|
235 { |
|
236 iFirstPointerNumber = aPointerNumber; |
|
237 } |
|
238 else if ( iPointerCount == 1 ) |
|
239 { |
|
240 iSecondPointerNumber = aPointerNumber; |
|
241 } |
|
242 break; |
|
243 } |
|
244 |
|
245 case TPointerEvent::EButton1Up: |
|
246 { |
|
247 if ( iPointerCount == 1 ) |
|
248 { |
|
249 iFirstPointerNumber = KInvalidPointerNumber; |
|
250 } |
|
251 else if ( iPointerCount == 2 ) |
|
252 { |
|
253 if ( aPointerNumber == 0 ) |
|
254 { |
|
255 iFirstPointerNumber = 1; |
|
256 iSecondPointerNumber = KInvalidPointerNumber; |
|
257 } |
|
258 else if ( aPointerNumber == 1 ) |
|
259 { |
|
260 iFirstPointerNumber = 0; |
|
261 iSecondPointerNumber = KInvalidPointerNumber; |
|
262 } |
|
263 } |
|
264 break; |
|
265 } |
|
266 |
|
267 default: |
|
268 { |
|
269 break; |
|
270 } |
|
271 } |
|
272 } |
|
273 |
|
274 |
|
275 // --------------------------------------------------------------------------- |
|
276 // Checks if the received event is valid or not. |
|
277 // --------------------------------------------------------------------------- |
|
278 // |
|
279 TBool CAknTouchGestureFwPointerState::IsValidEvent( |
|
280 TPointerEvent::TType aPointerType, |
|
281 TInt aPointerNumber ) |
|
282 { |
|
283 // In practice, event is NOT valid in the following situations: |
|
284 // |
|
285 // 1. Pointer down event is received for pointer which is already down. |
|
286 // 2. Pointer up event is received for pointer which is already up. |
|
287 // 3. Pointer drag event is received for pointer which is not down. |
|
288 // |
|
289 // In these situations this function returns EFalse, |
|
290 // corresponding event is ignored and recognition continues as earlier. |
|
291 // |
|
292 TBool isValid( ETrue ); |
|
293 if ( aPointerType == TPointerEvent::EButton1Down ) |
|
294 { |
|
295 if ( iPointerData[ aPointerNumber ].iIsPressedDown ) |
|
296 { |
|
297 isValid = EFalse; |
|
298 } |
|
299 } |
|
300 else if ( aPointerType == TPointerEvent::EButton1Up |
|
301 || aPointerType == TPointerEvent::EDrag ) |
|
302 { |
|
303 if ( !iPointerData[ aPointerNumber ].iIsPressedDown ) |
|
304 { |
|
305 isValid = EFalse; |
|
306 } |
|
307 } |
|
308 |
|
309 return isValid; |
|
310 } |
|
311 |
|
312 |
|
313 // --------------------------------------------------------------------------- |
|
314 // Checks if pointers are down outside the control area. |
|
315 // --------------------------------------------------------------------------- |
|
316 // |
|
317 TBool CAknTouchGestureFwPointerState::PointersDownOutsideControlArea() const |
|
318 { |
|
319 TBool outsideFound( EFalse ); |
|
320 for ( TInt i = 0; i < KMaxPointerCount; i++ ) |
|
321 { |
|
322 if ( !iPointerData[ i ].iTargetedToControl && |
|
323 iPointerData[ i ].iIsPressedDown ) |
|
324 { |
|
325 outsideFound = ETrue; |
|
326 break; |
|
327 } |
|
328 } |
|
329 return outsideFound; |
|
330 } |
|
331 |
|
332 // End of File |