|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-2632A013-AA87-485E-855D-C50E211057D6" xml:lang="en"><title>Tactile |
|
13 feedback implementation example</title><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <p>This is an implementation example of a simple tactile feedback enabled |
|
15 control. This example can help give you an overall understanding |
|
16 of what methods to implement and what are the typical actions in each function. </p> |
|
17 <p>The example control uses area registry for producing basic feedback on |
|
18 pointer down events, and instant feedback for producing sensitive feedback |
|
19 on drag events when the control’s state changes.</p> |
|
20 <p>The header file of the example control is presented below. </p> |
|
21 <codeblock xml:space="preserve">#include <coecntrl.h> |
|
22 |
|
23 class CMyTactileEnabledControl: public CCoeControl |
|
24 { |
|
25 public: |
|
26 CMyTactileEnabledControl(); |
|
27 virtual ~CMyTactileEnabledControl(); |
|
28 |
|
29 public: // from CCoeControl |
|
30 void HandlePointerEventL( const TPointerEvent& aPointerEvent ); |
|
31 void SizeChanged(); |
|
32 void PositionChanged(); |
|
33 };</codeblock> |
|
34 <p>Note that you do not necessarily need to implement any new functions for |
|
35 supporting tactile feedback. But for non-window-owning controls that use area |
|
36 registry, you have to override <codeph>PositionChanged</codeph>, because otherwise |
|
37 you may end up with a situation where the control has been moved, but the |
|
38 feedback area still remains in its original place.</p> |
|
39 <p>The first part of the source file is presented below.</p> |
|
40 <codeblock xml:space="preserve">#include <touchfeedback.h> |
|
41 #include "mytactileenabledcontrol.h" |
|
42 |
|
43 CMyTactileEnabledControl::CMyTactileEnabledControl() |
|
44 { |
|
45 // No Tactile Feedback related actions needed |
|
46 // when the control is created. |
|
47 } |
|
48 |
|
49 CMyTactileEnabledControl::~CMyTactileEnabledControl() |
|
50 { |
|
51 // Before destroying the control, you need to call |
|
52 // RemoveFeedbackForControl, first, for removing all remaining |
|
53 // feedback areas, and, second, for clearing this control's |
|
54 // state information stored by the Tactile Feedback Client API. |
|
55 MTouchFeedback* feedback = MTouchFeedback::Instance(); |
|
56 if ( feedback ) |
|
57 { |
|
58 feedback->RemoveFeedbackForControl( this ); |
|
59 } |
|
60 } |
|
61 |
|
62 </codeblock> |
|
63 <p>The code above illustrates that usually nothing needs to be done (from |
|
64 the tactile feedback point of view) when a control is constructed, but you |
|
65 must always call <codeph>RemoveFeedbackForControl</codeph> at the destructor |
|
66 if you have added any feedback areas with the <codeph>SetFeedbackArea</codeph> function, |
|
67 or disabled or enabled feedback with the <codeph>EnableFeedbackForControl</codeph> function.</p> |
|
68 <p>Also notice that you must use <codeph>MTouchFeedback::Instance</codeph> in |
|
69 the destructor (and not any stored pointer), because in some rare cases the |
|
70 feedback system may already have been destroyed before the last controls are |
|
71 deleted.</p> |
|
72 <p>The remaining part of the source file is displayed below.</p> |
|
73 <codeblock xml:space="preserve">void CMyTactileEnabledControl::HandlePointerEventL( |
|
74 const TPointerEvent& aPointerEvent ) |
|
75 { |
|
76 TBool stateChanged; |
|
77 |
|
78 // (your code here) |
|
79 |
|
80 if(aPointerEvent.iType == TPointerEvent::EDrag && stateChanged) |
|
81 { |
|
82 // Producing sensitive feedback when dragging causes a state |
|
83 // change (this kind of feedback triggering is not possible |
|
84 // by using area registry). |
|
85 MTouchFeedback* feedback = MTouchFeedback::Instance(); |
|
86 if ( feedback ) |
|
87 { |
|
88 feedback->InstantFeedback( ETouchFeedbackSensitive ); |
|
89 } |
|
90 } |
|
91 } |
|
92 |
|
93 void CMyTactileEnabledControl::SizeChanged() |
|
94 { |
|
95 // (your code here) |
|
96 |
|
97 // We have to update all feedback areas when control is resized. |
|
98 // This is also enough for adding the feedback area in the first |
|
99 // place, because SizeChanged is always called after control has |
|
100 // been created and positioned on screen. |
|
101 MTouchFeedback* feedback = MTouchFeedback::Instance(); |
|
102 if ( feedback ) |
|
103 { |
|
104 feedback->SetFeedbackArea( |
|
105 this, |
|
106 0, // Area index, use 0 when only one area in this control |
|
107 Rect(), |
|
108 ETouchFeedbackBasic, |
|
109 ETouchEventStylusDown ); |
|
110 } |
|
111 } |
|
112 |
|
113 void CMyTactileEnabledControl::PositionChanged() |
|
114 { |
|
115 // We have to update our feedback area when this control |
|
116 // is moved. One way to do this is to call SizeChanged here. |
|
117 SizeChanged(); |
|
118 } |
|
119 </codeblock> |
|
120 <p>You are recommended to put feedback area updates into a new <codeph>UpdateFeedbackAreas</codeph> function, |
|
121 and then to call this from both the <codeph>SizeChanged</codeph> and <codeph>PositionChanged</codeph> functions.</p> |
|
122 </conbody></concept> |