Symbian3/SDK/Source/GUID-2632A013-AA87-485E-855D-C50E211057D6.dita
author Dominic Pinkman <dominic.pinkman@nokia.com>
Tue, 20 Jul 2010 12:00:49 +0100
changeset 13 48780e181b38
parent 0 89d6a7a84779
permissions -rw-r--r--
Week 28 contribution of SDK documentation content. See release notes for details. Fixes bugs Bug 1897 and Bug 1522.

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="GUID-2632A013-AA87-485E-855D-C50E211057D6" xml:lang="en"><title>Tactile
feedback implementation example</title><prolog><metadata><keywords/></metadata></prolog><conbody>
<p>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. </p>
<p>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.</p>
<p>The header file of the example control is presented below. </p>
<codeblock xml:space="preserve">#include &lt;coecntrl.h&gt;

class CMyTactileEnabledControl: public CCoeControl
    {
public:
    CMyTactileEnabledControl();
    virtual ~CMyTactileEnabledControl();

public: // from CCoeControl
    void HandlePointerEventL( const TPointerEvent&amp; aPointerEvent );
    void SizeChanged();
    void PositionChanged();
    };</codeblock>
<p>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 <codeph>PositionChanged</codeph>, 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.</p>
<p>The first part of the source file is presented below.</p>
<codeblock xml:space="preserve">#include &lt;touchfeedback.h&gt;
#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-&gt;RemoveFeedbackForControl( this );
        } 
    }

</codeblock>
<p>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 <codeph>RemoveFeedbackForControl</codeph> at the destructor
if you have added any feedback areas with the <codeph>SetFeedbackArea</codeph> function,
or disabled or enabled feedback with the <codeph>EnableFeedbackForControl</codeph> function.</p>
<p>Also notice that you must use <codeph>MTouchFeedback::Instance</codeph> 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.</p>
<p>The remaining part of the source file is displayed below.</p>
<codeblock xml:space="preserve">void CMyTactileEnabledControl::HandlePointerEventL(
    const TPointerEvent&amp; aPointerEvent )
    {
    TBool stateChanged;

    // (your code here)

    if(aPointerEvent.iType == TPointerEvent::EDrag &amp;&amp; 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-&gt;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-&gt;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();    
    }
</codeblock>
<p>You are recommended to put feedback area updates into a new <codeph>UpdateFeedbackAreas</codeph> function,
and then to call this from both the <codeph>SizeChanged</codeph> and <codeph>PositionChanged</codeph> functions.</p>
</conbody></concept>