|
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: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <coemain.h> |
|
19 #include <aknutils.h> |
|
20 #include <aknappui.h> |
|
21 |
|
22 #include "statemachine.h" |
|
23 #include "stateengine.h" |
|
24 #include "rt_uievent.h" |
|
25 #include "callbacktimer.h" |
|
26 #include "stateengineconfiguration.h" |
|
27 |
|
28 #include "filelogger.h" |
|
29 #include "utils.h" |
|
30 |
|
31 using namespace stmUiEventEngine ; |
|
32 |
|
33 GLREF_D const char* stateNames[8] ; |
|
34 |
|
35 #ifdef GESTURE_LOGGING |
|
36 const char* const ttypeNames[] = { // for debugging purposes define the names of the pointer events |
|
37 "EButton1Down ", |
|
38 "EButton1Up ", |
|
39 "EButton2Down ", |
|
40 "EButton2Up ", |
|
41 "EButton3Down ", |
|
42 "EButton3Up ", |
|
43 "EDrag ", |
|
44 "EMove ", |
|
45 "EButtonRepeat ", |
|
46 "ESwitchOn ", |
|
47 "EOutOfRange ", |
|
48 "EEnterCloseProximity ", |
|
49 "EExitCloseProximity ", |
|
50 "EEnterHighPressure ", |
|
51 "EExitHighPressure " |
|
52 }; |
|
53 #endif |
|
54 |
|
55 /// Fast integer distance |
|
56 int stmUiEventEngine::Distance(int x, int y) |
|
57 { |
|
58 /* |
|
59 double d = dx * dx + dy * dy; |
|
60 double dist ; |
|
61 Math::Sqrt(dist, d) ; |
|
62 return dist; |
|
63 */ |
|
64 if(x<0) x=-x; |
|
65 if(y<0) y=-y; |
|
66 if(x < y) |
|
67 { |
|
68 int t = x; |
|
69 x = y; |
|
70 y = t; // ensures that x >= y |
|
71 } |
|
72 int dist = (y < ((13107 * x)>>15)) ? // * (.4) |
|
73 (x + ((y * 6310)>>15)) : // * (.192582403) |
|
74 (((x * 27926)>>15) // * (.852245894) |
|
75 + ((y * 18414)>>15)); // * (.561967668) |
|
76 return dist; |
|
77 } |
|
78 |
|
79 |
|
80 /*! |
|
81 CStateMachine implements the state machine and the integration fo the |
|
82 state machine to the OS. The CStateEngine handles the actual processing of the |
|
83 finite state machine but CStateMachine provides the OS specific things like timers |
|
84 and message conversion. |
|
85 |
|
86 The CStateMachine implements the MAknWsEventObserver interface so it adds |
|
87 itself to be the observer to the event monitor of the application UI. |
|
88 |
|
89 It handles the pointer events either by using the monitoring interface or |
|
90 lets the application call the HandlePointerEventL method. |
|
91 |
|
92 If MAknWsEventObserver interface is used then all the events passed to the |
|
93 application are seen. The target of the gesture starting event is stored |
|
94 so that the generated UI event contains the target as a void pointer. (should it just be CoeControl*?) |
|
95 |
|
96 There is possibility to adjust the Y coordinate of the touch point. |
|
97 In capacitive touch (Alvin) it seems that the perceived touch point is |
|
98 below the middle part of the fingertip. The user however tries to use the |
|
99 finger to point so that the touch point should correspond to the tip of the finger. |
|
100 It seems that this illusion can be achieved by adjusting the Y position about 3 mm up. |
|
101 However, this adjustment can properly be done only when the touch point is far enough |
|
102 from the window borders up or down. When close to top or bottom of window, the adjustment |
|
103 makes it impossible touch points near the edge, unless adjustment depends on the distance from |
|
104 window border. |
|
105 So in practice it should be the window server doing the adjustment, and after adjustment |
|
106 deciding the target window. At application level the adjustment can only be done properly |
|
107 if window borders do not need to be crossed. |
|
108 |
|
109 */ |
|
110 CStateMachine::CStateMachine() |
|
111 { |
|
112 m_WasMessageFiltered = false ; |
|
113 m_wseventmonitoringenabled = false ; // NB: enabled only if really used by application |
|
114 m_loggingenabled = false ; |
|
115 m_capacitiveup = false ; |
|
116 m_adjustYposition = false ; |
|
117 } |
|
118 /*!Destructor |
|
119 */ |
|
120 CStateMachine::~CStateMachine() |
|
121 { |
|
122 for (int i = 0; i < KMaxNumberOfPointers; i++) |
|
123 { |
|
124 delete m_holdTimer[i] ; |
|
125 delete m_touchTimer[i] ; |
|
126 delete m_suppressTimer[i] ; |
|
127 delete m_impl[i] ; |
|
128 } |
|
129 delete m_config ; |
|
130 } |
|
131 |
|
132 CStateMachine* CStateMachine::NewLC() |
|
133 { |
|
134 CStateMachine* self = new (ELeave) CStateMachine(); |
|
135 CleanupStack::PushL(self); |
|
136 self->ConstructL(); |
|
137 return self; |
|
138 } |
|
139 |
|
140 CStateMachine* CStateMachine::NewL() |
|
141 { |
|
142 CStateMachine* self = CStateMachine::NewLC(); |
|
143 CleanupStack::Pop(self); |
|
144 return self; |
|
145 } |
|
146 /*! |
|
147 Construct the actual state machine implemented in CStateEngine and |
|
148 creates the timers. It also adds itself to the observer list of |
|
149 CAknWsEventMonitor of the application. |
|
150 |
|
151 */ |
|
152 void CStateMachine::ConstructL() |
|
153 { |
|
154 m_config = new(ELeave)CStateEngineConfiguration() ; |
|
155 m_config->ConstructL(); |
|
156 |
|
157 for (int i = 0; i < KMaxNumberOfPointers; i++) |
|
158 { |
|
159 m_impl[i] = new(ELeave) CStateEngine(m_config, this, i) ; |
|
160 m_holdTimer[i] = CCallbackTimer::NewL(*this, handleholdTimer, 0, i, ETrue); |
|
161 m_touchTimer[i] = CCallbackTimer::NewL(*this, handletouchTimer, 0, i, ETrue); |
|
162 m_suppressTimer[i] = CCallbackTimer::NewL(*this, handlesuppressTimer, 0, i, ETrue); |
|
163 } |
|
164 |
|
165 m_coeEnv = CCoeEnv::Static(); |
|
166 |
|
167 /* IMEX: monitor added only if enabled |
|
168 add us to see the WsEvents so that we are able to interpret them; |
|
169 |
|
170 CAknAppUi* pui = (CAknAppUi*)m_coeEnv->AppUi() ; |
|
171 pui->EventMonitor()->AddObserverL(this) ; |
|
172 pui->EventMonitor()->Enable(ETrue) ; |
|
173 */ |
|
174 |
|
175 m_3mminpixels = Mm2Pixels(1.5) ; |
|
176 } |
|
177 /*! |
|
178 * Process one pointer event in the state machine. |
|
179 * \return true, if the event did not generate a UI event immediately. |
|
180 */ |
|
181 bool CStateMachine::HandleStateEvent(const TPointerEvent& aPointerEvent, |
|
182 void* aTarget, |
|
183 const TTime& aTime) |
|
184 { |
|
185 TInt index = PointerIndex(aPointerEvent); |
|
186 CStateEngine* engine = m_impl[index]; |
|
187 CreateHwEvent(engine->initEvent(), aPointerEvent, aTarget, aTime) ; |
|
188 if (m_loggingenabled) |
|
189 { |
|
190 LOGARG("HandleStateEvent: ptr %d", index) ; |
|
191 } |
|
192 m_WasMessageFiltered = engine->handleStateEvent() ; |
|
193 return m_WasMessageFiltered ; |
|
194 } |
|
195 /*! |
|
196 * wrapper method for the actual implementation in the CStateEngine. |
|
197 */ |
|
198 bool CStateMachine::wasLastMessageFiltered(TInt aPointerNumber) |
|
199 { |
|
200 return m_impl[aPointerNumber]->wasLastMessageFiltered() ; |
|
201 } |
|
202 /*! |
|
203 * wrapper method for the actual implementation in the CStateEngine. |
|
204 */ |
|
205 TRect CStateMachine::getTouchArea(TInt aPointerNumber) |
|
206 { |
|
207 return m_impl[aPointerNumber]->getTouchArea() ; |
|
208 } |
|
209 /*! |
|
210 * wrapper method for the actual implementation in the CStateEngine. |
|
211 */ |
|
212 void CStateMachine::setTouchTimeArea(long fingersize_mm) |
|
213 { |
|
214 m_config->setTouchTimeArea(fingersize_mm) ; |
|
215 } |
|
216 /*! |
|
217 * wrapper method for the actual implementation in the CStateEngine. |
|
218 */ |
|
219 void CStateMachine::setTouchArea(long fingersize_mm) |
|
220 { |
|
221 m_config->setTouchArea(fingersize_mm) ; |
|
222 } |
|
223 /*! |
|
224 * wrapper method for the actual implementation in the CStateEngine. |
|
225 */ |
|
226 TAreaShape CStateMachine::getTouchAreaShape() |
|
227 { |
|
228 return m_config->getTouchAreaShape() ; |
|
229 } |
|
230 /*! |
|
231 * wrapper method for the actual implementation in the CStateEngine. |
|
232 */ |
|
233 void CStateMachine::setTouchAreaShape(const TAreaShape aShape) |
|
234 { |
|
235 m_config->setTouchAreaShape(aShape) ; |
|
236 } |
|
237 /*! |
|
238 * wrapper method for the actual implementation in the CStateEngine. |
|
239 */ |
|
240 unsigned int CStateMachine::getTouchTimeout() |
|
241 { |
|
242 return m_config->getTouchTimeout() ; |
|
243 } |
|
244 /*! |
|
245 * wrapper method for the actual implementation in the CStateEngine. |
|
246 */ |
|
247 void CStateMachine::setTouchTimeout(unsigned int aDelay) |
|
248 { |
|
249 m_config->setTouchTimeout(aDelay) ; |
|
250 } |
|
251 /*! |
|
252 * wrapper method for the actual implementation in the CStateEngine. |
|
253 */ |
|
254 TRect CStateMachine::getHoldArea(TInt aPointerNumber) |
|
255 { |
|
256 return m_impl[aPointerNumber]->getHoldArea() ; |
|
257 } |
|
258 /*! |
|
259 * wrapper method for the actual implementation in the CStateEngine. |
|
260 */ |
|
261 void CStateMachine::setHoldArea(long fingersize_mm) |
|
262 { |
|
263 m_config->setHoldArea(fingersize_mm) ; |
|
264 } |
|
265 /*! |
|
266 * wrapper method for the actual implementation in the CStateEngine. |
|
267 */ |
|
268 TAreaShape CStateMachine::getHoldAreaShape() |
|
269 { |
|
270 return m_config->getHoldAreaShape() ; |
|
271 } |
|
272 /*! |
|
273 * wrapper method for the actual implementation in the CStateEngine. |
|
274 */ |
|
275 void CStateMachine::setHoldAreaShape(const TAreaShape aShape) |
|
276 { |
|
277 m_config->setHoldAreaShape(aShape) ; |
|
278 } |
|
279 /*! |
|
280 * wrapper method for the actual implementation in the CStateEngine. |
|
281 */ |
|
282 unsigned int CStateMachine::getHoldTimeout() |
|
283 { |
|
284 return m_config->getHoldTimeout() ; |
|
285 } |
|
286 /*! |
|
287 * wrapper method for the actual implementation in the CStateEngine. |
|
288 */ |
|
289 void CStateMachine::setHoldTimeout(unsigned int a) |
|
290 { |
|
291 m_config->setHoldTimeout(a) ; |
|
292 } |
|
293 /*! |
|
294 * wrapper method for the actual implementation in the CStateEngine. |
|
295 */ |
|
296 unsigned int CStateMachine::getTouchSuppressTimeout() |
|
297 { |
|
298 return m_config->getTouchSuppressTimeout() ; |
|
299 } |
|
300 /*! |
|
301 * wrapper method for the actual implementation in the CStateEngine. |
|
302 */ |
|
303 void CStateMachine::setTouchSuppressTimeout(unsigned int a) |
|
304 { |
|
305 m_config->setTouchSuppressTimeout(a) ; |
|
306 } |
|
307 /*! |
|
308 * wrapper method for the actual implementation in the CStateEngine. |
|
309 */ |
|
310 unsigned int CStateMachine::getMoveSuppressTimeout() |
|
311 { |
|
312 return m_config->getMoveSuppressTimeout() ; |
|
313 } |
|
314 /*! |
|
315 * wrapper method for the actual implementation in the CStateEngine. |
|
316 */ |
|
317 void CStateMachine::setMoveSuppressTimeout(unsigned int a) |
|
318 { |
|
319 m_config->setMoveSuppressTimeout(a) ; |
|
320 } |
|
321 /*! |
|
322 * wrapper method for the actual implementation in the CStateEngine. |
|
323 */ |
|
324 bool CStateMachine::addUiEventObserver(MUiEventObserver* observer) |
|
325 { |
|
326 return m_config->addUiEventObserver(observer) ; |
|
327 } |
|
328 /*! |
|
329 * wrapper method for the actual implementation in the CStateEngine. |
|
330 */ |
|
331 bool CStateMachine::removeUiEventObserver(MUiEventObserver* observer) |
|
332 { |
|
333 return m_config->removeUiEventObserver(observer) ; |
|
334 } |
|
335 /*! |
|
336 * wrapper method for the actual implementation in the CStateEngine. |
|
337 */ |
|
338 void CStateMachine::enableLogging(bool aEnable) |
|
339 { |
|
340 m_loggingenabled = aEnable ; |
|
341 m_config->enableLogging(aEnable) ; |
|
342 } |
|
343 |
|
344 TInt CStateMachine::PointerIndex(const TPointerEvent& aPointerEvent) |
|
345 { |
|
346 TInt index = 0; |
|
347 #if defined(ADVANCED_POINTER_EVENTS) |
|
348 if (aPointerEvent.IsAdvancedPointerEvent()) |
|
349 { |
|
350 const TAdvancedPointerEvent* tadvp = aPointerEvent.AdvancedPointerEvent() ; |
|
351 index = tadvp->PointerNumber() ; |
|
352 } |
|
353 #endif |
|
354 return index; |
|
355 } |
|
356 |
|
357 /*! |
|
358 * Convert pointer event (TPointerEvent) into THwEvent into the variable m_hwe. |
|
359 * THwEvent contains the position and simplified event type |
|
360 * but also has the target window and timestamp included. |
|
361 */ |
|
362 void CStateMachine::CreateHwEvent(THwEvent& aEvent, |
|
363 const TPointerEvent& aPointerEvent, |
|
364 void* aTarget, |
|
365 const TTime& aTime) |
|
366 { |
|
367 /* should be set by this moment by CStateEngine with that index in CStateEngine::initEvent() |
|
368 aEvent.iPointerNumber = PointerIndex(aPointerEvent); |
|
369 */ |
|
370 aEvent.iTarget = aTarget ; |
|
371 aEvent.iTime = aTime; |
|
372 // Change to screen coordinates here while the window is still existing.... |
|
373 aEvent.iPosition = screenCoordinates(aPointerEvent.iPosition, aTarget) ; |
|
374 switch (aPointerEvent.iType) |
|
375 { |
|
376 case TPointerEvent::EButton1Down: |
|
377 case TPointerEvent::EButton2Down: |
|
378 case TPointerEvent::EButton3Down: |
|
379 { |
|
380 aEvent.iType = stmUiEventEngine::EDown ; |
|
381 break ; |
|
382 } |
|
383 case TPointerEvent::EButton1Up: |
|
384 case TPointerEvent::EButton2Up: |
|
385 case TPointerEvent::EButton3Up: |
|
386 { |
|
387 if (m_capacitiveup) |
|
388 { |
|
389 aEvent.iType = stmUiEventEngine::ECapacitiveUP ; // How could this be checked automagically? |
|
390 } |
|
391 else |
|
392 { |
|
393 aEvent.iType = stmUiEventEngine::EResistiveUP ; // How could this be checked automagically? |
|
394 } |
|
395 |
|
396 break ; |
|
397 } |
|
398 case TPointerEvent::EDrag: |
|
399 { |
|
400 aEvent.iType = stmUiEventEngine::EDrag ; |
|
401 break ; |
|
402 } |
|
403 } |
|
404 } |
|
405 //////////////////////////////////////////////////////////////////////////////////////////// |
|
406 /*! |
|
407 * Start the hold timer if it is not already active. |
|
408 */ |
|
409 void CStateMachine::startholdTimer(TInt aPointerNumber) |
|
410 { |
|
411 if (!m_holdTimer[aPointerNumber]->IsActive()) |
|
412 { |
|
413 m_holdTimer[aPointerNumber]->Start(); |
|
414 } |
|
415 } |
|
416 |
|
417 /*! |
|
418 * The hold timer expiration: create a timer event and call the state machine |
|
419 */ |
|
420 void CStateMachine::handleholdTimer(TInt aPointerNumber) |
|
421 { |
|
422 // We get an event, lets kick the state machine |
|
423 CStateEngine* engine = m_impl[aPointerNumber]; |
|
424 CreateTimerEvent(engine->initEvent(), stmUiEventEngine::EHoldTimer) ; |
|
425 engine->handleStateEvent() ; |
|
426 } |
|
427 /*! |
|
428 * Stop the hold timer |
|
429 */ |
|
430 void CStateMachine::cancelholdTimer(TInt aPointerNumber) |
|
431 { |
|
432 m_holdTimer[aPointerNumber]->Cancel(); |
|
433 } |
|
434 /*! |
|
435 * Start suppress timer. The timeout has been set beforehand. |
|
436 */ |
|
437 void CStateMachine::startsuppressTimer(TInt aPointerNumber) |
|
438 { |
|
439 m_suppressTimer[aPointerNumber]->Start(); |
|
440 } |
|
441 /*! |
|
442 * The suppress timer expiration, create a timer event and call the state machine. |
|
443 */ |
|
444 void CStateMachine::handlesuppressTimer(TInt aPointerNumber) |
|
445 { |
|
446 // We get an event, lets kick the state machine |
|
447 CStateEngine* engine = m_impl[aPointerNumber]; |
|
448 CreateTimerEvent(engine->initEvent(), stmUiEventEngine::ESuppressTimer) ; |
|
449 engine->handleStateEvent() ; |
|
450 } |
|
451 /*! |
|
452 * stop the suppress timer |
|
453 */ |
|
454 void CStateMachine::cancelsuppressTimer(TInt aPointerNumber) |
|
455 { |
|
456 m_suppressTimer[aPointerNumber]->Cancel(); |
|
457 } |
|
458 /*! |
|
459 * start the touch timer if it is not already active. |
|
460 */ |
|
461 void CStateMachine::starttouchTimer(TInt aPointerNumber) |
|
462 { |
|
463 if (!m_touchTimer[aPointerNumber]->IsActive()) |
|
464 { |
|
465 m_touchTimer[aPointerNumber]->Start(); |
|
466 } |
|
467 } |
|
468 |
|
469 /*! |
|
470 * The touch timer expiration, create timer event and call the state machine. |
|
471 */ |
|
472 void CStateMachine::handletouchTimer(TInt aPointerNumber) |
|
473 { |
|
474 // We get an event, lets kick the state machine |
|
475 CStateEngine* engine = m_impl[aPointerNumber]; |
|
476 CreateTimerEvent(engine->initEvent(), stmUiEventEngine::ETouchTimer) ; |
|
477 engine->handleStateEvent() ; |
|
478 } |
|
479 /*! |
|
480 * stop the touch timer |
|
481 */ |
|
482 void CStateMachine::canceltouchTimer(TInt aPointerNumber) |
|
483 { |
|
484 if (m_touchTimer[aPointerNumber]->IsActive()) // we were waiting for additional events |
|
485 { |
|
486 m_touchTimer[aPointerNumber]->Cancel(); |
|
487 } |
|
488 } |
|
489 /*! |
|
490 * CreateTimerEvent creates a timer event to the m_hwe variable. |
|
491 */ |
|
492 void CStateMachine::CreateTimerEvent(THwEvent& aEvent, TStateMachineEvent aEventCode) |
|
493 { |
|
494 aEvent.iType = aEventCode ; |
|
495 // m_hwe.iPosition = TPos(0, 0) ; should we just leave the previous pos |
|
496 TTime now ; |
|
497 now.HomeTime() ; |
|
498 aEvent.iTime = now ; |
|
499 } |
|
500 /*! |
|
501 * Events are processed either using the MAknWsEventObserver interface |
|
502 * or letting the view/container pass the pointer events to the state machine. |
|
503 * The member variable m_wseventmonitoringenabled defines which method is used. |
|
504 * If handlePoingterEventL is called, the calling CCoeCOntrol must provide itself |
|
505 * as the target. |
|
506 */ |
|
507 void CStateMachine::HandlePointerEventL(const TPointerEvent& aPointerEvent, void *target) |
|
508 { |
|
509 if (m_wseventmonitoringenabled) return ; // events are handled in the event monitor |
|
510 if (m_loggingenabled) |
|
511 { |
|
512 #if defined(ADVANCED_POINTER_EVENTS) |
|
513 TInt pointerNumber = PointerIndex(aPointerEvent) ; |
|
514 LOGARG("Pointer %d event %s at (%d %d)", pointerNumber, |
|
515 ttypeNames[aPointerEvent.iType], aPointerEvent.iPosition.iX, aPointerEvent.iPosition.iY) ; |
|
516 #else |
|
517 LOGARG("Pointer event %s at (%d %d)", |
|
518 ttypeNames[aPointerEvent.iType], aPointerEvent.iPosition.iX, aPointerEvent.iPosition.iY) ; |
|
519 #endif |
|
520 } |
|
521 TTime time = m_coeEnv->LastEvent().Time(); |
|
522 HandleStateEvent(aPointerEvent, target, time) ; // target needs to be there to convert from window to screen coordinates |
|
523 } |
|
524 /** |
|
525 * One possibility to implement gesture recognition is to intercept the events |
|
526 * using the event monitoring interface. The HandleWsEventL method will get all events |
|
527 * passed to the application. The aDestination parameter defines the window where the event |
|
528 * was targeted to. The gesture recognition should use the target information |
|
529 * to determine how the gesture should be interpreted. |
|
530 * In the current implementation the aDestination needs to be one of the UI event observers |
|
531 * in order to process the message, but later when gesture recognition is added, this check |
|
532 * needs to be removed and the gesture recognition should handle the target of the gesture. |
|
533 */ |
|
534 void CStateMachine::HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination) |
|
535 { |
|
536 // Check which processing type we have for events. |
|
537 // If WsEvent monitoring, then process the message, otherwise return |
|
538 if (!m_wseventmonitoringenabled) return ; |
|
539 |
|
540 // Log the events passing trough to see what kind of stuff there goes... |
|
541 // and could the gesture recogniser grab them from here? |
|
542 TInt type=aEvent.Type(); |
|
543 switch (type) |
|
544 { |
|
545 case EEventKey: |
|
546 case EEventKeyUp: |
|
547 case EEventKeyDown: |
|
548 { |
|
549 if (m_loggingenabled) |
|
550 { |
|
551 TKeyEvent* tke = aEvent.Key() ; |
|
552 LOGARG("Key event %d %d to %u", tke->iCode, tke->iScanCode, aDestination) ; |
|
553 } |
|
554 break; |
|
555 } |
|
556 case EEventPointer: |
|
557 { |
|
558 TPointerEvent* tpe = aEvent.Pointer() ; |
|
559 if (m_loggingenabled) |
|
560 { |
|
561 TRect rcd = aDestination->Rect() ; |
|
562 TPoint org = aDestination->PositionRelativeToScreen() ; |
|
563 TRect rcd2 = rcd ; |
|
564 rcd2.Move(org) ; |
|
565 TPoint screenpos = tpe->iPosition ; |
|
566 screenpos += org ; |
|
567 |
|
568 #if defined(ADVANCED_POINTER_EVENTS) |
|
569 TInt pointerNumber = PointerIndex(*tpe) ; |
|
570 LOGARG("Pointer %d event %s at (%d %d)[%d,%d] to 0x%x ((%d,%d)(%d,%d)): screen: ((%d,%d)(%d,%d))", |
|
571 pointerNumber, |
|
572 ttypeNames[tpe->iType], |
|
573 tpe->iPosition.iX, tpe->iPosition.iY, |
|
574 screenpos.iX, screenpos.iY, |
|
575 aDestination, |
|
576 rcd.iTl.iX, rcd.iTl.iY, rcd.iBr.iX, rcd.iBr.iY, |
|
577 rcd2.iTl.iX, rcd2.iTl.iY, rcd2.iBr.iX, rcd2.iBr.iY) ; |
|
578 #else |
|
579 LOGARG("Pointer event %s at (%d %d)[%d,%d] to 0x%x ((%d,%d)(%d,%d)): screen: ((%d,%d)(%d,%d))", |
|
580 ttypeNames[tpe->iType], tpe->iPosition.iX, tpe->iPosition.iY, |
|
581 screenpos.iX, screenpos.iY, |
|
582 aDestination, |
|
583 rcd.iTl.iX, rcd.iTl.iY, rcd.iBr.iX, rcd.iBr.iY, |
|
584 rcd2.iTl.iX, rcd2.iTl.iY, rcd2.iBr.iX, rcd2.iBr.iY) ; |
|
585 #endif |
|
586 } |
|
587 HandleStateEvent(*tpe, aDestination, aEvent.Time()) ; |
|
588 break; |
|
589 } |
|
590 case EEventPointerBufferReady: |
|
591 if (m_loggingenabled) |
|
592 { |
|
593 LOGARG("Pointer buffer ready event to %u", aDestination) ; |
|
594 } |
|
595 break; |
|
596 case EEventFocusLost: |
|
597 case EEventFocusGained: |
|
598 if (m_loggingenabled) |
|
599 { |
|
600 LOGARG("Focus message event to %u", aDestination) ; |
|
601 } |
|
602 break; |
|
603 case EEventSwitchOn: |
|
604 if (m_loggingenabled) |
|
605 { |
|
606 LOGARG("Switch On event to %u", aDestination) ; |
|
607 } |
|
608 break; |
|
609 case EEventUser: |
|
610 if (m_loggingenabled) |
|
611 { |
|
612 LOGARG("User event to %u", aDestination) ; |
|
613 } |
|
614 break; |
|
615 case EEventPowerMgmt: |
|
616 if (m_loggingenabled) |
|
617 { |
|
618 LOGARG("Power Mgmnt event to %u", aDestination) ; |
|
619 } |
|
620 break; |
|
621 case EEventMessageReady: |
|
622 if (m_loggingenabled) |
|
623 { |
|
624 LOGARG("Message Ready event to %u", aDestination) ; |
|
625 } |
|
626 break; |
|
627 case EEventScreenDeviceChanged: |
|
628 if (m_loggingenabled) |
|
629 { |
|
630 LOGARG("Screen device changed event to %u", aDestination) ; |
|
631 } |
|
632 break; |
|
633 |
|
634 default: |
|
635 if (m_loggingenabled) |
|
636 { |
|
637 LOGARG("default changed event %d to %u", type, aDestination) ; |
|
638 } |
|
639 break; |
|
640 } |
|
641 } |
|
642 /*! |
|
643 * Start the touch timer using a specified delay |
|
644 */ |
|
645 void CStateMachine::startTouchTimer(TInt aDelay, TInt aPointerNumber) |
|
646 { |
|
647 m_touchTimer[aPointerNumber]->SetDelay(aDelay) ; |
|
648 starttouchTimer(aPointerNumber) ; |
|
649 } |
|
650 /*! |
|
651 * Stop the touch timer. |
|
652 */ |
|
653 void CStateMachine::cancelTouchTimer(TInt aPointerNumber) |
|
654 { |
|
655 canceltouchTimer(aPointerNumber) ; |
|
656 } |
|
657 /*! |
|
658 * Start hold timer using specified delay |
|
659 */ |
|
660 void CStateMachine::startHoldTimer(TInt aDelay, TInt aPointerNumber) |
|
661 { |
|
662 m_holdTimer[aPointerNumber]->SetDelay(aDelay) ; |
|
663 startholdTimer(aPointerNumber) ; |
|
664 } |
|
665 /*! |
|
666 * Stop the hold timer |
|
667 */ |
|
668 void CStateMachine::cancelHoldTimer(TInt aPointerNumber) |
|
669 { |
|
670 cancelholdTimer(aPointerNumber) ; |
|
671 } |
|
672 /*! |
|
673 * Start suppress timer using specified delay. |
|
674 */ |
|
675 void CStateMachine::startSuppressTimer(TInt aDelay, TInt aPointerNumber) |
|
676 { |
|
677 m_suppressTimer[aPointerNumber]->SetDelay(aDelay) ; |
|
678 startsuppressTimer(aPointerNumber) ; |
|
679 } |
|
680 /*! |
|
681 * Stop the suppress timer. |
|
682 */ |
|
683 void CStateMachine::cancelSuppressTimer(TInt aPointerNumber) |
|
684 { |
|
685 cancelsuppressTimer(aPointerNumber) ; |
|
686 } |
|
687 |
|
688 /*! |
|
689 * Method sets the m_wseventmonitoringenabled. If it is true, |
|
690 * then the state machine will be called from the HandleWsEventL method which |
|
691 * sees all the events passed to the application. |
|
692 * |
|
693 * Otherwise the HandlePointerEventL method call will cause the call to |
|
694 * state machine so the view/container needs to pass the pointer events to the state machine |
|
695 * in its own HandlePointerEventL -method. |
|
696 * |
|
697 */ |
|
698 void CStateMachine::EnableWsEventMonitoring(bool aEnable) |
|
699 { |
|
700 if( !m_wseventmonitoringenabled && aEnable ) |
|
701 { |
|
702 CAknAppUi* pui = (CAknAppUi*)m_coeEnv->AppUi() ; |
|
703 TRAPD(err, pui->EventMonitor()->AddObserverL(this)) ; |
|
704 if(!err) |
|
705 pui->EventMonitor()->Enable(ETrue) ; |
|
706 } |
|
707 else if( m_wseventmonitoringenabled && !aEnable ) |
|
708 { |
|
709 CAknAppUi* pui = (CAknAppUi*)m_coeEnv->AppUi() ; |
|
710 pui->EventMonitor()->RemoveObserver(this) ; |
|
711 // Should not disable since it may be not the only user |
|
712 //pui->EventMonitor()->Enable(EFalse) ; |
|
713 } |
|
714 |
|
715 m_wseventmonitoringenabled = aEnable ; |
|
716 } |
|
717 TPoint CStateMachine::screenCoordinates(const TPoint& aPos, void* aGestureTarget) |
|
718 { |
|
719 TPoint newPos = aPos ; |
|
720 if (aGestureTarget) |
|
721 { |
|
722 CCoeControl* pcc = (CCoeControl*) aGestureTarget ; |
|
723 TPoint tp(TPoint(0,0)); |
|
724 if (m_adjustYposition) |
|
725 { |
|
726 TSize sz = pcc->Size() ; |
|
727 |
|
728 // If we are running in capacitive touch device, |
|
729 // adjust the point up about 3 mm unless we are |
|
730 // near top or bottom of the window |
|
731 |
|
732 // Y position in the window |
|
733 int wY = newPos.iY - tp.iY; |
|
734 int edge = 2*m_3mminpixels; |
|
735 |
|
736 if (Rng(0, wY, edge - 1)) |
|
737 { |
|
738 // close to the top we adjust suitably so that immediately at the top adjust is 0 |
|
739 int adjust = wY / 2 ; |
|
740 newPos.iY -= adjust ; |
|
741 if (m_loggingenabled) |
|
742 { |
|
743 LOGARG("adjustment: nY %d tY %d [3mm: %d adj: %d]", |
|
744 newPos.iY, tp.iY, m_3mminpixels, adjust) ; |
|
745 } |
|
746 |
|
747 } |
|
748 else if (Rng(edge, wY, sz.iHeight - edge)) |
|
749 { |
|
750 #ifdef GESTURE_LOGGING |
|
751 int from = newPos.iY ; |
|
752 #endif |
|
753 newPos.iY -= m_3mminpixels ; |
|
754 if (m_loggingenabled) |
|
755 { |
|
756 LOGARG("adjustment: %d to %d [3mm: %d middle]", |
|
757 from, newPos.iY, m_3mminpixels) ; |
|
758 } |
|
759 |
|
760 } |
|
761 else |
|
762 { |
|
763 // similarly at the bottom we adjust less the closer we get to the edge |
|
764 int adjust = (sz.iHeight - wY) / 2 ; |
|
765 newPos.iY -= adjust ; |
|
766 if (m_loggingenabled) |
|
767 { |
|
768 LOGARG("adjustment: nY %d tY %d sH %d [3mm: %d adj: %d]", |
|
769 newPos.iY, tp.iY, sz.iHeight, m_3mminpixels, adjust) ; |
|
770 } |
|
771 |
|
772 } |
|
773 } |
|
774 else |
|
775 { |
|
776 // if the target does not own a window how can we adjust to the screen? |
|
777 } |
|
778 } |
|
779 return newPos ; |
|
780 } |
|
781 void CStateMachine::enableCapacitiveUp(bool aEnable) |
|
782 { |
|
783 m_capacitiveup = aEnable ; |
|
784 } |
|
785 void CStateMachine::enableYadjustment(bool aEnable) |
|
786 { |
|
787 m_adjustYposition = aEnable ; |
|
788 } |
|
789 int CStateMachine::getNumberOfPointers() |
|
790 { |
|
791 return KMaxNumberOfPointers ; |
|
792 } |
|
793 |