210 |
210 |
211 // ---------------------------------------------------------------------------- |
211 // ---------------------------------------------------------------------------- |
212 // Handle a pointer event |
212 // Handle a pointer event |
213 // ---------------------------------------------------------------------------- |
213 // ---------------------------------------------------------------------------- |
214 // |
214 // |
215 TSwipeResult CXnGestureHelper::HandlePointerEventL( const TPointerEvent& aEvent ) |
215 TXnGestureCode CXnGestureHelper::HandlePointerEventL( |
216 { |
216 const TPointerEvent& aEvent ) |
217 TSwipeResult ret = ESwipeNone; |
217 { |
|
218 TXnGestureCode ret( EGestureUnknown ); |
|
219 |
218 switch ( aEvent.iType ) |
220 switch ( aEvent.iType ) |
219 { |
221 { |
220 case TPointerEvent::EButton1Down: |
222 case TPointerEvent::EButton1Down: |
221 // If no up event was received during previous gesture, cancel |
223 // If no up event was received during previous gesture, cancel |
222 // previous event and reset state |
224 // previous event and reset state |
236 // types, hence further pointer events will be ignored. |
238 // types, hence further pointer events will be ignored. |
237 // Therefore, holding will NOT be started if AddPointL leaves, |
239 // Therefore, holding will NOT be started if AddPointL leaves, |
238 // since the callback would trigger a gesture callback, and that |
240 // since the callback would trigger a gesture callback, and that |
239 // would access an empty points array. |
241 // would access an empty points array. |
240 iHoldingTimer->Start(); |
242 iHoldingTimer->Start(); |
|
243 iDirection = EGestureUnknown; |
241 break; |
244 break; |
242 |
245 |
243 case TPointerEvent::EDrag: |
246 case TPointerEvent::EDrag: |
244 // ignore the event in case not in "recording" state. this may |
247 // ignore the event in case not in "recording" state. this may |
245 // happen if holding was triggered, or client sends up event after |
248 // happen if holding was triggered, or client sends up event after |
246 // down event was received in a different *client* state, and |
249 // down event was received in a different *client* state, and |
247 // client did not forward the down event to here. |
250 // client did not forward the down event to here. |
248 // Also, while stylus down, the same event is received repeatedly |
251 // Also, while stylus down, the same event is received repeatedly |
249 // even if stylus does not move. Filter out by checking if point |
252 // even if stylus does not move. Filter out by checking if point |
250 // is the same as the latest point |
253 // is the same as the latest point |
251 if ( !IsIdle() && !iGesture->IsLatestPoint( Position( aEvent ) ) ) |
254 if ( iDirection != EGestureCanceled ) |
252 { |
255 { |
253 AddPointL( aEvent ); |
256 if ( iDirection == EGestureUnknown ) |
254 if ( !( iGesture->IsHolding() || |
|
255 iGesture->IsNearHoldingPoint( Position( aEvent ) ) ) ) |
|
256 { |
257 { |
257 // restart hold timer, since pointer has moved |
258 // check current direction |
258 iHoldingTimer->Start(); |
259 iDirection = iGesture->CodeFromPoints( CXnGesture::EAxisBoth ); |
259 // Remember the point in which holding was started |
260 } |
260 iGesture->SetHoldingPoint(); |
261 else |
|
262 { |
|
263 // check if direction has changed |
|
264 if ( iDirection != iGesture->LastDirection( CXnGesture::EAxisBoth ) ) |
|
265 { |
|
266 // cancel swipe |
|
267 iDirection = EGestureCanceled; |
|
268 } |
|
269 } |
|
270 |
|
271 if ( !IsIdle() && !iGesture->IsLatestPoint( Position( aEvent ) ) ) |
|
272 { |
|
273 AddPointL( aEvent ); |
|
274 if ( !( iGesture->IsHolding() || |
|
275 iGesture->IsNearHoldingPoint( Position( aEvent ) ) ) ) |
|
276 { |
|
277 // restart hold timer, since pointer has moved |
|
278 iHoldingTimer->Start(); |
|
279 // Remember the point in which holding was started |
|
280 iGesture->SetHoldingPoint(); |
|
281 } |
261 } |
282 } |
262 } |
283 } |
263 break; |
284 break; |
264 |
285 |
265 case TPointerEvent::EButton1Up: |
286 case TPointerEvent::EButton1Up: |
270 // in client, and instead drag or up events are received. |
291 // in client, and instead drag or up events are received. |
271 // reset via cleanup stack to ensure Reset is run even if |
292 // reset via cleanup stack to ensure Reset is run even if |
272 // observer leaves |
293 // observer leaves |
273 CleanupStack::PushL( TCleanupItem( &ResetHelper, this ) ); |
294 CleanupStack::PushL( TCleanupItem( &ResetHelper, this ) ); |
274 iGesture->SetComplete(); |
295 iGesture->SetComplete(); |
275 // if adding of the point fails, notify client with a |
296 if ( iDirection != EGestureCanceled ) |
276 // cancelled event. It would be wrong to send another |
|
277 // gesture code when the up point is not known |
|
278 if ( AddPoint( aEvent ) != KErrNone ) |
|
279 { |
297 { |
280 iGesture->SetCancelled(); |
298 // if adding of the point fails, notify client with a |
281 } |
299 // cancelled event. It would be wrong to send another |
282 else |
300 // gesture code when the up point is not known |
283 { |
301 if ( AddPoint( aEvent ) != KErrNone ) |
284 // send gesture code if holding has not been started |
|
285 if ( !iGesture->IsHolding() ) |
|
286 { |
302 { |
287 // if client leaves, the state is automatically reset. |
303 iGesture->SetCancelled(); |
288 // In this case the client will not get the released event |
|
289 ret = ValidSwipe(); |
|
290 } |
304 } |
291 // send an event that stylus was lifted |
305 else |
292 iGesture->SetReleased(); |
306 { |
|
307 // send gesture code if holding has not been started |
|
308 if ( !iGesture->IsHolding() ) |
|
309 { |
|
310 // if client leaves, the state is automatically reset. |
|
311 // In this case the client will not get the released event |
|
312 ret = iDirection; |
|
313 } |
|
314 // send an event that stylus was lifted |
|
315 iGesture->SetReleased(); |
|
316 } |
293 } |
317 } |
294 // reset state |
318 // reset state |
295 CleanupStack::PopAndDestroy( this ); |
319 CleanupStack::PopAndDestroy( this ); |
296 } |
320 } |
297 break; |
321 break; |
298 |
322 |
299 default: |
323 default: |
300 break; |
324 break; |
301 } |
325 } |
|
326 |
302 return ret; |
327 return ret; |
303 } |
328 } |
304 |
329 |
305 // ---------------------------------------------------------------------------- |
330 // ---------------------------------------------------------------------------- |
306 // Is the helper idle? |
331 // Is the helper idle? |
370 |
395 |
371 // ---------------------------------------------------------------------------- |
396 // ---------------------------------------------------------------------------- |
372 // Check if swipe is valid |
397 // Check if swipe is valid |
373 // ---------------------------------------------------------------------------- |
398 // ---------------------------------------------------------------------------- |
374 // |
399 // |
375 TSwipeResult CXnGestureHelper::ValidSwipe() |
400 TXnGestureCode CXnGestureHelper::ValidSwipe() const |
376 { |
401 { |
377 TSwipeResult ret = ESwipeNone; |
402 return iGesture->Code( CXnGesture::EAxisBoth ); |
378 TBool validSwipe(ETrue); |
403 } |
379 |
|
380 // check if swipe is between defined values |
|
381 TInt distanceX = Abs( iGesture->Distance().iX ); |
|
382 TInt speedX = Abs( static_cast< TInt >( iGesture->Speed().iX ) ); |
|
383 |
|
384 TInt minLength( iOwner.MarginRect().Width() / 2 ); |
|
385 |
|
386 TInt dy( Abs( iGesture->StartPos().iY - iGesture->CurrentPos().iY ) ); |
|
387 |
|
388 if ( distanceX < minLength ) |
|
389 { |
|
390 validSwipe = EFalse; |
|
391 } |
|
392 |
|
393 if ( speedX < KGestureMinSpeedX ) |
|
394 { |
|
395 validSwipe = EFalse; |
|
396 } |
|
397 |
|
398 if ( dy > KGestureMaxDeltaY ) |
|
399 { |
|
400 validSwipe = EFalse; |
|
401 } |
|
402 |
|
403 // check the direction of swipe |
|
404 if ( validSwipe ) |
|
405 { |
|
406 switch ( iGesture->Code( CXnGesture::EAxisHorizontal ) ) |
|
407 { |
|
408 case EGestureSwipeLeft: |
|
409 ret = ESwipeLeft; |
|
410 break; |
|
411 case EGestureSwipeRight: |
|
412 ret = ESwipeRight; |
|
413 break; |
|
414 default: // fall through |
|
415 break; |
|
416 } |
|
417 } |
|
418 |
|
419 return ret; |
|
420 } |
|