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