This is an implementation example of a simple tactile feedback enabled control. This example can help give you an overall understanding of what methods to implement and what are the typical actions in each function.
The example control uses area registry for producing basic feedback on pointer down events, and instant feedback for producing sensitive feedback on drag events when the control’s state changes.
The header file of the example control is presented below.
#include <coecntrl.h> class CMyTactileEnabledControl: public CCoeControl { public: CMyTactileEnabledControl(); virtual ~CMyTactileEnabledControl(); public: // from CCoeControl void HandlePointerEventL( const TPointerEvent& aPointerEvent ); void SizeChanged(); void PositionChanged(); };
Note that you do not necessarily need to implement any new functions for
supporting tactile feedback. But for non-window-owning controls that use area
registry, you have to override PositionChanged
, because otherwise
you may end up with a situation where the control has been moved, but the
feedback area still remains in its original place.
The first part of the source file is presented below.
#include <touchfeedback.h> #include "mytactileenabledcontrol.h" CMyTactileEnabledControl::CMyTactileEnabledControl() { // No Tactile Feedback related actions needed // when the control is created. } CMyTactileEnabledControl::~CMyTactileEnabledControl() { // Before destroying the control, you need to call // RemoveFeedbackForControl, first, for removing all remaining // feedback areas, and, second, for clearing this control's // state information stored by the Tactile Feedback Client API. MTouchFeedback* feedback = MTouchFeedback::Instance(); if ( feedback ) { feedback->RemoveFeedbackForControl( this ); } }
The code above illustrates that usually nothing needs to be done (from
the tactile feedback point of view) when a control is constructed, but you
must always call RemoveFeedbackForControl
at the destructor
if you have added any feedback areas with the SetFeedbackArea
function,
or disabled or enabled feedback with the EnableFeedbackForControl
function.
Also notice that you must use MTouchFeedback::Instance
in
the destructor (and not any stored pointer), because in some rare cases the
feedback system may already have been destroyed before the last controls are
deleted.
The remaining part of the source file is displayed below.
void CMyTactileEnabledControl::HandlePointerEventL( const TPointerEvent& aPointerEvent ) { TBool stateChanged; // (your code here) if(aPointerEvent.iType == TPointerEvent::EDrag && stateChanged) { // Producing sensitive feedback when dragging causes a state // change (this kind of feedback triggering is not possible // by using area registry). MTouchFeedback* feedback = MTouchFeedback::Instance(); if ( feedback ) { feedback->InstantFeedback( ETouchFeedbackSensitive ); } } } void CMyTactileEnabledControl::SizeChanged() { // (your code here) // We have to update all feedback areas when control is resized. // This is also enough for adding the feedback area in the first // place, because SizeChanged is always called after control has // been created and positioned on screen. MTouchFeedback* feedback = MTouchFeedback::Instance(); if ( feedback ) { feedback->SetFeedbackArea( this, 0, // Area index, use 0 when only one area in this control Rect(), ETouchFeedbackBasic, ETouchEventStylusDown ); } } void CMyTactileEnabledControl::PositionChanged() { // We have to update our feedback area when this control // is moved. One way to do this is to call SizeChanged here. SizeChanged(); }
You are recommended to put feedback area updates into a new UpdateFeedbackAreas
function,
and then to call this from both the SizeChanged
and PositionChanged
functions.