|
1 /* |
|
2 * Copyright (c) 2008 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 the License "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: Gesture helper implementation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "gesturehelperimpl.h" |
|
20 |
|
21 #include <e32base.h> |
|
22 #include <w32std.h> |
|
23 |
|
24 #include "gesture.h" |
|
25 #include "gesturedefs.h" |
|
26 #include "utils.h" |
|
27 #include "gestureeventfilter.h" |
|
28 #include "gesturehelpereventsender.h" |
|
29 #include "flogger.h" |
|
30 |
|
31 using namespace RT_GestureHelper; |
|
32 |
|
33 namespace RT_GestureHelper |
|
34 { |
|
35 |
|
36 /// type of function in gesture helper to be called by the timer |
|
37 /// when timer triggers |
|
38 typedef void (CGestureHelperImpl::*CallbackFunctionL)(); |
|
39 |
|
40 NONSHARABLE_CLASS( CCallbackTimer ) : public CTimer |
|
41 { |
|
42 public: |
|
43 /** Two-phase constructor */ |
|
44 static CCallbackTimer* NewL( CGestureHelperImpl& aHelper, |
|
45 CallbackFunctionL aCallbackFunctionL, TInt aDelay, TBool aIsEnabled ) |
|
46 { |
|
47 CCallbackTimer* self = new ( ELeave ) CCallbackTimer( aHelper, |
|
48 aCallbackFunctionL, aDelay, aIsEnabled ); |
|
49 CleanupStack::PushL( self ); |
|
50 self->ConstructL(); // construct base class |
|
51 CActiveScheduler::Add( self ); |
|
52 CleanupStack::Pop( self ); |
|
53 return self; |
|
54 } |
|
55 |
|
56 /** Destructor */ |
|
57 ~CCallbackTimer() |
|
58 { |
|
59 Cancel(); |
|
60 } |
|
61 |
|
62 /** Set whether sending holding events is currently enabled */ |
|
63 void SetEnabled( TBool aEnabled ) |
|
64 { |
|
65 iIsEnabled = aEnabled; |
|
66 // cancel in case hold timer is already running |
|
67 Cancel(); |
|
68 } |
|
69 |
|
70 /** @return whether sending holding events is currently enabled */ |
|
71 TBool IsEnabled() const |
|
72 { |
|
73 return iIsEnabled; |
|
74 } |
|
75 |
|
76 /** Start the timer. Calls CGestureHelperImpl::StartHoldingL upon completion */ |
|
77 void Start() |
|
78 { |
|
79 // if sending hold events is disabled, do not ever start the hold timer, and |
|
80 // hence hold events will never be triggered |
|
81 if ( iIsEnabled ) |
|
82 { |
|
83 Cancel(); |
|
84 After( iDelay ); |
|
85 } |
|
86 } |
|
87 void SetDelay(TInt aDelay) { iDelay = aDelay; } |
|
88 TInt GetDelay() { return iDelay; } |
|
89 |
|
90 private: |
|
91 /** Constructor */ |
|
92 CCallbackTimer( CGestureHelperImpl& aHelper, |
|
93 CallbackFunctionL aCallbackFunctionL, TInt aDelay, TBool aIsEnabled ) |
|
94 : CTimer( EPriorityUserInput - 1 ), // give higher priority to new pointer events with - 1 |
|
95 iHelper( aHelper ), iCallbackFunctionL( aCallbackFunctionL ), |
|
96 iDelay( aDelay ), iIsEnabled( aIsEnabled ) |
|
97 { |
|
98 } |
|
99 |
|
100 void RunL() // From CActive |
|
101 { |
|
102 (iHelper.*iCallbackFunctionL)(); |
|
103 } |
|
104 |
|
105 private: |
|
106 /// helper object that will be called back when timer is triggered |
|
107 CGestureHelperImpl& iHelper; |
|
108 /// Function in the iHelper object call |
|
109 CallbackFunctionL iCallbackFunctionL; |
|
110 /// How long a time to wait befor calling back after Start() |
|
111 TInt iDelay; |
|
112 /// whether sending holding events is currently enabled |
|
113 TBool iIsEnabled; |
|
114 }; |
|
115 |
|
116 } // namespace GestureHelper |
|
117 |
|
118 /** |
|
119 * @return position from event. Use this instead of using aEvent direction to |
|
120 * avoid accidentally using TPointerEvent::iPosition |
|
121 */ |
|
122 inline TPoint Position( const TPointerEvent& aEvent ) |
|
123 { |
|
124 // use parent position, since the capturer is using full screen area, |
|
125 // and because the (Alfred) drag events are not local to visual even when |
|
126 // coming from the client |
|
127 |
|
128 return aEvent.iPosition; |
|
129 } |
|
130 |
|
131 // ---------------------------------------------------------------------------- |
|
132 // Two-phase constructor |
|
133 // ---------------------------------------------------------------------------- |
|
134 // |
|
135 CGestureHelperImpl* CGestureHelperImpl::NewL( MGestureObserver& aObserver ) |
|
136 { |
|
137 CGestureHelperImpl* self = new ( ELeave ) CGestureHelperImpl( aObserver ); |
|
138 CleanupStack::PushL( self ); |
|
139 self->iEventSender = CGestureEventSender::NewL( aObserver ); |
|
140 self->iDoubleTapTimer = CCallbackTimer::NewL( *self, &CGestureHelperImpl::EmitFirstTapEvent, |
|
141 KMaxTapDuration, EFalse ); // double tap is disabled by default |
|
142 self->iHoldingTimer = CCallbackTimer::NewL( *self, &CGestureHelperImpl::StartHoldingL, |
|
143 KHoldDuration, EFalse ); // holding is enabled by default |
|
144 |
|
145 self->iLongTouchTimer = CCallbackTimer::NewL( *self, &CGestureHelperImpl::HandleLongTouch, |
|
146 KLongTapDuration, ETrue ); // holding is enabled by default |
|
147 |
|
148 self->iGesture = new ( ELeave ) CGesture(); |
|
149 self->iUnusedGesture = new ( ELeave ) CGesture(); |
|
150 TInt tapLimit = Mm2Pixels(KFingerSize_mm) / 2; |
|
151 self->iEventFilter = new (ELeave) CGestureEventFilter(tapLimit); |
|
152 CleanupStack::Pop( self ); |
|
153 return self; |
|
154 } |
|
155 |
|
156 // ---------------------------------------------------------------------------- |
|
157 // Constructor |
|
158 // ---------------------------------------------------------------------------- |
|
159 // |
|
160 CGestureHelperImpl::CGestureHelperImpl( MGestureObserver& aObserver ) |
|
161 : iObserver( aObserver ) |
|
162 { |
|
163 } |
|
164 |
|
165 // ---------------------------------------------------------------------------- |
|
166 // Destructor |
|
167 // ---------------------------------------------------------------------------- |
|
168 // |
|
169 CGestureHelperImpl::~CGestureHelperImpl() |
|
170 { |
|
171 delete iDoubleTapTimer; |
|
172 delete iHoldingTimer; |
|
173 delete iGesture; |
|
174 delete iPreviousTapGesture; |
|
175 delete iUnusedGesture; |
|
176 delete iLongTouchTimer; |
|
177 delete iEventFilter; |
|
178 delete iEventSender; |
|
179 } |
|
180 |
|
181 |
|
182 // ---------------------------------------------------------------------------- |
|
183 // SetHoldingEnabled |
|
184 // ---------------------------------------------------------------------------- |
|
185 // |
|
186 void CGestureHelperImpl::SetHoldingEnabled( TBool aEnabled ) |
|
187 { |
|
188 iHoldingTimer->SetEnabled( aEnabled ); |
|
189 } |
|
190 |
|
191 // ---------------------------------------------------------------------------- |
|
192 // IsHoldingEnabled |
|
193 // ---------------------------------------------------------------------------- |
|
194 // |
|
195 TBool CGestureHelperImpl::IsHoldingEnabled() const |
|
196 { |
|
197 return iHoldingTimer->IsEnabled(); |
|
198 } |
|
199 |
|
200 // ---------------------------------------------------------------------------- |
|
201 // SetHoldingEnabled |
|
202 // ---------------------------------------------------------------------------- |
|
203 // |
|
204 void CGestureHelperImpl::SetDoubleTapEnabled( TBool aEnabled ) |
|
205 { |
|
206 iDoubleTapTimer->SetEnabled( aEnabled ); |
|
207 } |
|
208 |
|
209 // ---------------------------------------------------------------------------- |
|
210 // IsHoldingEnabled |
|
211 // ---------------------------------------------------------------------------- |
|
212 // |
|
213 TBool CGestureHelperImpl::IsDoubleTapEnabled() const |
|
214 { |
|
215 return iDoubleTapTimer->IsEnabled(); |
|
216 } |
|
217 |
|
218 |
|
219 |
|
220 // ---------------------------------------------------------------------------- |
|
221 // Reset state |
|
222 // ---------------------------------------------------------------------------- |
|
223 // |
|
224 void CGestureHelperImpl::Reset() |
|
225 { |
|
226 iHoldingTimer->Cancel(); |
|
227 iLongTouchTimer->Cancel(); |
|
228 iGesture->Reset(); |
|
229 } |
|
230 |
|
231 /** |
|
232 * Helper function that calls Reset on the pointer to CGestureHelperImpl |
|
233 */ |
|
234 static void ResetHelper( TAny* aHelper ) |
|
235 { |
|
236 static_cast< CGestureHelperImpl* >( aHelper )->Reset(); |
|
237 } |
|
238 |
|
239 // ---------------------------------------------------------------------------- |
|
240 // Handle a pointer event |
|
241 // ---------------------------------------------------------------------------- |
|
242 // |
|
243 TBool CGestureHelperImpl::HandlePointerEventL( const TPointerEvent& aEvent ) |
|
244 { |
|
245 TInt filterReason; |
|
246 SetLastEventTime(); |
|
247 if (!iEventFilter->FilterDrag(aEvent, iLastEventTime, filterReason)) |
|
248 { |
|
249 return noneAlf_HandlePointerEventL( aEvent ); |
|
250 } |
|
251 else |
|
252 { |
|
253 /* |
|
254 TBuf<10> num; |
|
255 num.Num( filterReason ); |
|
256 TBuf<128> str; |
|
257 str.AppendFormat(_L("Filter reason: %d"), filterReason); |
|
258 RFileLogger::Write( _L("gh"), _L("gh.txt"), EFileLoggingModeAppend, str); |
|
259 */ |
|
260 return EFalse; |
|
261 } |
|
262 } |
|
263 |
|
264 |
|
265 TBool CGestureHelperImpl::noneAlf_HandlePointerEventL( const TPointerEvent& aEvent) |
|
266 { |
|
267 switch ( aEvent.iType ) |
|
268 { |
|
269 case TPointerEvent::EButton1Down: |
|
270 { |
|
271 HandleTouchDownL(aEvent); |
|
272 break; |
|
273 } |
|
274 case TPointerEvent::EDrag: |
|
275 { |
|
276 HandleMoveL(aEvent); |
|
277 break; |
|
278 } |
|
279 case TPointerEvent::EButton1Up: |
|
280 { |
|
281 if (KErrNone == AddPoint( aEvent )) |
|
282 { |
|
283 HandleTouchUp(aEvent); |
|
284 } |
|
285 else |
|
286 { |
|
287 EmitCancelEvent(); |
|
288 } |
|
289 Reset(); |
|
290 break; |
|
291 } |
|
292 default: |
|
293 break; |
|
294 } |
|
295 return ETrue; |
|
296 } |
|
297 |
|
298 TBool CGestureHelperImpl::IsMovementGesture(TGestureCode aCode) |
|
299 { |
|
300 return (aCode == EGestureDrag || aCode == EGestureFlick || aCode == EGestureSwipeUp || |
|
301 aCode == EGestureSwipeDown || aCode == EGestureSwipeRight || aCode == EGestureSwipeLeft); |
|
302 } |
|
303 |
|
304 void CGestureHelperImpl::HandleLongTouch() |
|
305 { |
|
306 iDoubleTapTimer->Cancel(); |
|
307 iGesture->SetLongTap(ETrue); |
|
308 iGesture->SetComplete(); |
|
309 TPoint startPos = iGesture->StartPos(); |
|
310 EmitEvent(*iGesture); |
|
311 iGesture->Reset(); |
|
312 iGesture->AddPoint( startPos, GetLastEventTime() ); |
|
313 } |
|
314 |
|
315 void CGestureHelperImpl::HandleTouchDownL(const TPointerEvent& aEvent) |
|
316 { |
|
317 TGestureCode prevCode = iGesture->PreviousGestureCode(); |
|
318 if (prevCode == EGestureStart) return; |
|
319 if (prevCode == EGestureDrag) |
|
320 { |
|
321 iGesture->Reset(); |
|
322 } |
|
323 AddPointL( aEvent ); |
|
324 |
|
325 if (!iLongTouchTimer->IsActive()) |
|
326 { |
|
327 iLongTouchTimer->Start(); |
|
328 } |
|
329 if (!iDoubleTapTimer->IsActive()) |
|
330 { |
|
331 EmitEvent( *iGesture ); |
|
332 } |
|
333 } |
|
334 |
|
335 void CGestureHelperImpl::HandleMoveL(const TPointerEvent& aEvent) |
|
336 { |
|
337 if (iGesture->IsLatestPoint( Position(aEvent))) return; // I'm not sure we need this |
|
338 //Cancel double tap time - it's neither tap nor double tap |
|
339 iDoubleTapTimer->Cancel(); |
|
340 iLongTouchTimer->Cancel(); |
|
341 |
|
342 TBool isFirstPoint = IsIdle(); |
|
343 |
|
344 AddPointL( aEvent ); |
|
345 |
|
346 if (iPreviousTapGesture) |
|
347 { |
|
348 RecycleGesture(iPreviousTapGesture); |
|
349 } |
|
350 |
|
351 if (!isFirstPoint) |
|
352 { |
|
353 EmitEvent( *iGesture ); |
|
354 } |
|
355 } |
|
356 |
|
357 void CGestureHelperImpl::HandleTouchUp(const TPointerEvent& /*aEvent*/) |
|
358 { |
|
359 TGestureCode prevCode = iGesture->PreviousGestureCode(); |
|
360 iLongTouchTimer->Cancel(); |
|
361 iDoubleTapTimer->Cancel(); |
|
362 TInt64 fromLastTouchUp = iLastEventTime.MicroSecondsFrom(iLastTouchUpTime).Int64(); |
|
363 TInt64 fromLastDoubleTap = iLastEventTime.MicroSecondsFrom(iLastDoubleTapTime).Int64(); |
|
364 /* |
|
365 TBuf<1024> str; |
|
366 str.AppendFormat(_L("fromLastTouchUp: %d, "), fromLastTouchUp); |
|
367 str.AppendFormat(_L("fromLastDoubleTap: %d, "), fromLastTouchUp); |
|
368 str.AppendFormat(_L("iPreviousTapGesture: %d, "), iPreviousTapGesture); |
|
369 RFileLogger::Write( _L("gh"), _L("gh.txt"), EFileLoggingModeAppend, str); |
|
370 */ |
|
371 if ( prevCode == EGestureLongTap ) |
|
372 { |
|
373 EmitReleasedEvent(); |
|
374 } |
|
375 else if (IsMovementGesture(prevCode) || |
|
376 !iDoubleTapTimer->IsEnabled() /* || !iGesture->IsTap()*/ ) |
|
377 { |
|
378 iGesture->SetComplete(); |
|
379 EmitEvent(*iGesture); |
|
380 } |
|
381 |
|
382 else |
|
383 { |
|
384 if ( iPreviousTapGesture && |
|
385 (fromLastTouchUp > KDoubleTapMinActivationInterval) && |
|
386 (fromLastTouchUp < KDoubleTapMaxActivationInterval) && |
|
387 (fromLastDoubleTap > KDoubleTapIdleInterval)) |
|
388 { |
|
389 // it's a double tap |
|
390 iLastTouchUpTime = iLastEventTime; |
|
391 iLastDoubleTapTime = iLastEventTime; |
|
392 EmitDoubleTapEvent(); |
|
393 } |
|
394 else |
|
395 { |
|
396 // it's a first tap |
|
397 iLastTouchUpTime = iLastEventTime; |
|
398 if (iPreviousTapGesture) |
|
399 { |
|
400 RecycleGesture(iPreviousTapGesture); |
|
401 } |
|
402 |
|
403 iPreviousTapGesture = iGesture; |
|
404 iGesture = NewGesture(); |
|
405 iDoubleTapTimer->Start(); |
|
406 } |
|
407 } |
|
408 } |
|
409 |
|
410 |
|
411 |
|
412 void CGestureHelperImpl::EmitDoubleTapEvent() |
|
413 { |
|
414 iPreviousTapGesture->SetDoubleTap(); |
|
415 EmitFirstTapEvent(); |
|
416 } |
|
417 |
|
418 |
|
419 void CGestureHelperImpl::EmitReleasedEvent() |
|
420 { |
|
421 iGesture->SetComplete(); |
|
422 iGesture->SetReleased(); |
|
423 EmitEvent(*iGesture); |
|
424 } |
|
425 |
|
426 |
|
427 // ---------------------------------------------------------------------------- |
|
428 // Is the helper idle? |
|
429 // inline ok in cpp file for a private member function |
|
430 // ---------------------------------------------------------------------------- |
|
431 // |
|
432 inline TBool CGestureHelperImpl::IsIdle() const |
|
433 { |
|
434 return iGesture->IsEmpty(); |
|
435 } |
|
436 |
|
437 // ---------------------------------------------------------------------------- |
|
438 // Add a point to the sequence of points that together make up the gesture |
|
439 // inline ok in cpp file for a private member function |
|
440 // ---------------------------------------------------------------------------- |
|
441 // |
|
442 inline void CGestureHelperImpl::AddPointL( const TPointerEvent& aEvent ) |
|
443 { |
|
444 User::LeaveIfError( AddPoint( aEvent ) ); |
|
445 } |
|
446 |
|
447 // ---------------------------------------------------------------------------- |
|
448 // Add a point to the sequence of points that together make up the gesture |
|
449 // inline ok in cpp file for a private member function |
|
450 // ---------------------------------------------------------------------------- |
|
451 // |
|
452 inline TInt CGestureHelperImpl::AddPoint( const TPointerEvent& aEvent ) |
|
453 { |
|
454 TPoint pos = Position ( aEvent ); |
|
455 return iGesture->AddPoint( pos, GetLastEventTime() ); |
|
456 } |
|
457 |
|
458 // ---------------------------------------------------------------------------- |
|
459 // StartHoldingTimer |
|
460 // ---------------------------------------------------------------------------- |
|
461 // |
|
462 void CGestureHelperImpl::StartHoldingTimer( const TPointerEvent& aNewEvent ) |
|
463 { |
|
464 if ( !( iGesture->IsHolding() || |
|
465 iGesture->IsNearHoldingPoint( Position( aNewEvent ) ) ) ) |
|
466 { |
|
467 // restart hold timer, since pointer has moved |
|
468 iHoldingTimer->Start(); |
|
469 // Remember the point in which holding was started |
|
470 iGesture->SetHoldingPoint(); |
|
471 } |
|
472 } |
|
473 |
|
474 /** |
|
475 * Helper function that calls ContinueHolding on the pointer to TGesture |
|
476 */ |
|
477 static void ContinueHolding( TAny* aGesture ) |
|
478 { |
|
479 static_cast< CGesture* >( aGesture )->ContinueHolding(); |
|
480 } |
|
481 |
|
482 // ---------------------------------------------------------------------------- |
|
483 // Add a point to the sequence of points that together make up the gesture |
|
484 // ---------------------------------------------------------------------------- |
|
485 // |
|
486 void CGestureHelperImpl::StartHoldingL() |
|
487 { |
|
488 // hold & tap event is specifically filtered out. Use case: in list fast |
|
489 // scrolling activation (e.g. enhanced coverflow), tap & hold should not |
|
490 // start fast scroll. In addition, after long tap on start position, |
|
491 // drag and drag & hold swiping should emit normal swipe and swipe&hold |
|
492 // events. Therefore, tap & hold is not supported. |
|
493 __ASSERT_DEBUG( !iGesture->IsTap() && !iPreviousTapGesture, Panic( EGesturePanicIllegalLogic ) ); |
|
494 |
|
495 // holding has just started, and gesture code should be provided to client. |
|
496 // set gesture state so that it produces a gesture code (other than drag) |
|
497 iGesture->StartHolding(); |
|
498 |
|
499 // create an item in the cleanup stack that will set the gesture state |
|
500 // to holding-was-started-earlier state. NotifyL may leave, but the |
|
501 // holding-was-started-earlier state must still be successfully set, |
|
502 // otherwise, the holding gesture code will be sent twice |
|
503 CleanupStack::PushL( TCleanupItem( &ContinueHolding, iGesture ) ); |
|
504 |
|
505 EmitEvent( *iGesture ); |
|
506 |
|
507 // set holding state to "post holding" |
|
508 CleanupStack::PopAndDestroy( iGesture ); |
|
509 } |
|
510 |
|
511 // ---------------------------------------------------------------------------- |
|
512 // RecyclePreviousTapGesture |
|
513 // ---------------------------------------------------------------------------- |
|
514 // |
|
515 void CGestureHelperImpl::RecyclePreviousTapGesture( TAny* aSelf ) |
|
516 { |
|
517 CGestureHelperImpl& self = *reinterpret_cast<CGestureHelperImpl*>( aSelf ); |
|
518 self.RecycleGesture( self.iPreviousTapGesture ); |
|
519 } |
|
520 |
|
521 // ---------------------------------------------------------------------------- |
|
522 // Emit the remainder of the previous tap event (tap + released) |
|
523 // ---------------------------------------------------------------------------- |
|
524 // |
|
525 void CGestureHelperImpl::EmitFirstTapEvent() |
|
526 { |
|
527 // when this function is called, a tap has turned out to _not_ be a double tap |
|
528 __ASSERT_DEBUG( IsDoubleTapEnabled(), Panic( EGesturePanicIllegalLogic ) ); |
|
529 __ASSERT_DEBUG( iPreviousTapGesture, Panic( EGesturePanicIllegalLogic ) ); |
|
530 |
|
531 iDoubleTapTimer->Cancel(); |
|
532 CompleteAndEmit( *iPreviousTapGesture ); |
|
533 RecycleGesture(iPreviousTapGesture); |
|
534 |
|
535 } |
|
536 |
|
537 // ---------------------------------------------------------------------------- |
|
538 // EmitStartEventL |
|
539 // ---------------------------------------------------------------------------- |
|
540 // |
|
541 void CGestureHelperImpl::EmitStartEventL( const CGesture& aGesture ) |
|
542 { |
|
543 CGesture* startGesture = aGesture.AsStartEventLC(); |
|
544 EmitEvent( *startGesture ); |
|
545 CleanupStack::PopAndDestroy( startGesture ); |
|
546 } |
|
547 |
|
548 // ---------------------------------------------------------------------------- |
|
549 // EmitCompletionEventsL |
|
550 // ---------------------------------------------------------------------------- |
|
551 // |
|
552 void CGestureHelperImpl::CompleteAndEmit( CGesture& aGesture ) |
|
553 { |
|
554 aGesture.SetComplete(); |
|
555 // send gesture code if holding has not been started. If holding has |
|
556 // been started, client has already received a "hold swipe left" e.g. event, in which |
|
557 // case don't another "swipe left" event |
|
558 if ( !aGesture.IsHolding() ) |
|
559 { |
|
560 // if client leaves, the state is automatically reset. |
|
561 // In this case the client will not get the released event |
|
562 EmitEvent( aGesture ); |
|
563 } |
|
564 |
|
565 // send an event that stylus was lifted |
|
566 aGesture.SetReleased(); |
|
567 EmitEvent( aGesture ); |
|
568 } |
|
569 |
|
570 // ---------------------------------------------------------------------------- |
|
571 // EmitCancelEventL |
|
572 // ---------------------------------------------------------------------------- |
|
573 // |
|
574 void CGestureHelperImpl::EmitCancelEvent() |
|
575 { |
|
576 iDoubleTapTimer->Cancel(); |
|
577 |
|
578 |
|
579 CGesture& gestureToCancel = iPreviousTapGesture ? *iPreviousTapGesture : *iGesture; |
|
580 gestureToCancel.SetCancelled(); |
|
581 EmitEvent( gestureToCancel ); |
|
582 RecycleGesture(iPreviousTapGesture); |
|
583 |
|
584 } |
|
585 |
|
586 // ---------------------------------------------------------------------------- |
|
587 // Notify observer |
|
588 // ---------------------------------------------------------------------------- |
|
589 // |
|
590 void CGestureHelperImpl::EmitEvent( const CGesture& aGesture ) |
|
591 { |
|
592 // deallocation of the event is happening in CGestureEventSender::RunL() |
|
593 TGestureEvent event; |
|
594 event.SetCode(const_cast<CGesture&>(aGesture).Code(EAxisBoth)); |
|
595 event.SetCurrentPos(aGesture.CurrentPos()); |
|
596 event.SetDistance(aGesture.Distance()); |
|
597 event.SetStartPos(aGesture.StartPos()); |
|
598 event.SetIsHolding(aGesture.IsHolding()); |
|
599 event.SetSpeed(aGesture.Speed()); |
|
600 iEventSender->AddEvent(event); |
|
601 } |
|
602 |
|
603 // ---------------------------------------------------------------------------- |
|
604 // Return a fresh gesture from the gesture pool (pool of one gesture) |
|
605 // ---------------------------------------------------------------------------- |
|
606 // |
|
607 CGesture* CGestureHelperImpl::NewGesture() |
|
608 { |
|
609 __ASSERT_DEBUG( iUnusedGesture, Panic( EGesturePanicIllegalLogic ) ); // pool should no be empty |
|
610 |
|
611 iUnusedGesture->Reset(); |
|
612 CGesture* freshGesture = iUnusedGesture; |
|
613 iUnusedGesture = NULL; |
|
614 return freshGesture; |
|
615 } |
|
616 |
|
617 // ---------------------------------------------------------------------------- |
|
618 // Return a fresh gesture from the gesture pool (pool of one gesture) |
|
619 // ---------------------------------------------------------------------------- |
|
620 // |
|
621 void CGestureHelperImpl::RecycleGesture( CGesture*& aGesturePointer ) |
|
622 { |
|
623 // only one object fits into the pool, and that should currently be enough |
|
624 // one pointer must be null, one non-null |
|
625 __ASSERT_DEBUG( !iUnusedGesture != !aGesturePointer, Panic( EGesturePanicIllegalLogic ) ); |
|
626 if ( aGesturePointer ) |
|
627 { |
|
628 iUnusedGesture = aGesturePointer; |
|
629 aGesturePointer = NULL; |
|
630 } |
|
631 } |