Symbian3/PDK/Source/GUID-C60DC070-572B-5960-B394-550426FDB909.dita
author Dominic Pinkman <dominic.pinkman@nokia.com>
Fri, 02 Jul 2010 12:51:36 +0100
changeset 11 5072524fcc79
parent 9 59758314f811
child 12 80ef3a206772
permissions -rw-r--r--
Fixing terminology

<?xml version="1.0" encoding="UTF-8"?>
<!--Arbortext, Inc., 1988-2008, v.4002-->
<!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA Concept//EN"
 "concept.dtd">
<concept id="GUID-C60DC070-572B-5960-B394-550426FDB909" xml:lang="en">
<title> Advanced Pointer Tutorial</title>
<shortdesc>This tutorial provides step-by-step instructions and sample
code to help you write applications using advanced pointers. </shortdesc>
<prolog>
<metadata><keywords></keywords></metadata>
</prolog>
<conbody>
<p> <b>Variant</b>: <xref
href="GUID-D93978BE-11A3-5CE3-B110-1DEAA5AD566C.dita">ScreenPlay</xref
>. <b>Target audience</b>: Application developers. </p>
<section><title>Required background </title> <p>This topic builds
on the material in the following topics: </p> <ul>
<li id="GUID-C4209FBD-3860-5F4B-8458-87D22D483953"><p><xref
href="GUID-9C269F45-F160-5A4B-ABF8-896D2A538E3B.dita">Advanced Pointer
Overview</xref>  </p> </li>
<li id="GUID-9D3C3B31-F43A-5201-A1EC-A1F2848CFF43"><p><xref
href="GUID-9AD75103-CD56-5279-B639-5CA2BBF979B5.dita">Advanced Pointer
States and Event Communication</xref>  </p> </li>
</ul> </section>
<section><title>Using advanced pointers</title> <p>This topic covers
the following: </p> <ul>
<li id="GUID-C3AD43AA-09C0-5BA2-8496-5B87D40C89F5"><p><xref
href="GUID-C60DC070-572B-5960-B394-550426FDB909.dita#GUID-C60DC070-572B-5960-B394-550426FDB909/GUID-8CBE862B-0C1D-5088-89B7-9B3EC898E4FC"
>Enabling multiple pointers in a window</xref>  </p> </li>
<li id="GUID-177323F2-55C6-56D9-B3D2-A8DDACF69E10"><p><xref
href="GUID-C60DC070-572B-5960-B394-550426FDB909.dita#GUID-C60DC070-572B-5960-B394-550426FDB909/GUID-C026DAB9-C11C-5D29-A1EA-6730E914250F"
>Getting Z coordinates from TPointerEvent</xref>  </p> </li>
<li id="GUID-91CEA92C-A692-5853-96F0-625A76B7DC8D"><p><xref
href="GUID-C60DC070-572B-5960-B394-550426FDB909.dita#GUID-C60DC070-572B-5960-B394-550426FDB909/GUID-B7057F69-191F-5AA4-8C61-EBECE66D92F6"
> Pinch zooming</xref>  </p> </li>
</ul> </section>
<section id="GUID-8CBE862B-0C1D-5088-89B7-9B3EC898E4FC"><title>Enabling
multiple pointers in a window</title> <ol
id="GUID-210D17A8-4869-5F9B-B71C-672101AC591C">
<li id="GUID-81A2AC5C-7837-5216-8F47-FC5959C27522"><p> <xref
href="GUID-637F82AF-0CF9-3C85-834D-7C1A0866DF87.dita"><apiname>RWindow</apiname
></xref> provides a handle to a standard window. Call <codeph>RWindow</codeph
> to create an instance of a window. </p> <codeblock
id="GUID-0E31C3F6-3719-5F16-9F74-C405850604B8" xml:space="preserve"
>
RWindow window(ws);

User::LeaveIfError(window.Construct(wg, reinterpret_cast&lt;TUint32>(&amp;wg) + 1));
</codeblock> </li>
<li id="GUID-B67D3702-1A8F-5C6A-AB0F-FEA7C4D04A07"><p>Call <xref
href="GUID-683603DD-F3D3-3193-BEB3-8236C7DE7F79.dita#GUID-683603DD-F3D3-3193-BEB3-8236C7DE7F79/GUID-05293539-F1B0-3C7D-BB14-3FD42F23D5C8"
><apiname>RWindow::EnableAdvancedPointers()</apiname></xref> to enable
advanced pointers. Then call <xref
href="GUID-1460DD8F-9AA1-3B99-8FFD-F309959CCA34.dita#GUID-1460DD8F-9AA1-3B99-8FFD-F309959CCA34/GUID-4E02165A-DFCC-3D18-BB18-18726B28E90A"
><apiname>RWindowBase::Activate()</apiname></xref> to display the
window and enable the window to receive events. <xref
href="GUID-683603DD-F3D3-3193-BEB3-8236C7DE7F79.dita"><apiname>RWindow</apiname
></xref> inherits from <xref
href="GUID-1460DD8F-9AA1-3B99-8FFD-F309959CCA34.dita"><apiname>RWindowBase</apiname
></xref>, so you can call the <codeph>Activate()</codeph> function
on <codeph>RWindow</codeph>. </p> <codeblock
id="GUID-DB2FB570-2BB0-5C5F-9E4F-076D6A0E469E" xml:space="preserve"
>
window.EnableAdvancedPointers();
window.Activate();
</codeblock> <p>When an application needs to receive advanced pointer
events in a window, it must call <codeph>RWindowBase::EnableAdvancedPointers()</codeph
> for the window <i>before</i> it is activated. </p> <p>If advanced
pointers are not enabled f<?Pub Caret?>or a window, it receives only
standard <xref href="GUID-1FFA0073-3D83-388E-A824-08C31F90CC54.dita"
><apiname>TPointerEvent</apiname></xref> information from a single
pointer with no pressure and proximity data. The single pointer environment
rules describe the way in which pointer events coming from many pointers
in the multiple pointer model are transformed into events of one pointer.
They are necessary to ensure that old single-pointer applications
work in a multiple pointer environment intuitively and as expected
by the user. </p> <p>However, the new <codeph>TPointerEvent</codeph
> types, <xref href="GUID-239D0A8B-2759-321D-AD48-976E80192239.dita"
><apiname>EEnterCloseProximity</apiname></xref>, <xref
href="GUID-8C6264B4-5E19-33A7-92B0-BB79C871BEC7.dita"><apiname>EExitCloseProximity</apiname
></xref>, <xref href="GUID-F02DB96E-1541-3223-9B7B-79D45840DB7B.dita"
><apiname>EEnterHighPressure</apiname></xref> and <xref
href="GUID-15B5991C-B075-3110-B0A4-540EC282AA56.dita"><apiname>EExitHighPressure</apiname
></xref>, are delivered to all windows, even to those that do not
enable advanced pointers. </p> </li>
</ol> </section>
<section id="GUID-C026DAB9-C11C-5D29-A1EA-6730E914250F"><title>Getting
Z coordinates from TPointerEvent</title> <ol
id="GUID-4CC2271D-1798-51B3-9A9D-E7E0B9A33DAE">
<li id="GUID-184B5B63-4EFC-55CD-8D1F-E015EEBACBE2"><p>Call <xref
href="GUID-1FFA0073-3D83-388E-A824-08C31F90CC54.dita#GUID-1FFA0073-3D83-388E-A824-08C31F90CC54/GUID-E961DA4D-AD38-31F0-88DD-A07D36346DCB"
><apiname>TPointerEvent::AdvancedPointerEvent()</apiname></xref> on
a <codeph>TPointerEvent</codeph> to return a pointer to a <xref
href="GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023.dita"><apiname>TAdvancedPointerEvent</apiname
></xref>. </p> <codeblock id="GUID-6E81680A-3070-546B-B575-49EA9E34FAF9"
xml:space="preserve">
TZType aZType;
TPointerEvent&amp; aPointerEvent;
TInt* aZ; 
TInt* aPoint3D;

TAdvancedPointerEvent *advancedP = aPointerEvent.AdvancedPointerEvent();
</codeblock> <p> <codeph>TPointerEvent</codeph> is a struct that contains
details of a pointer event. <codeph>TZType</codeph> is a struct provided
by the programmer containing members to hold proximity, pressure,
and "proximity and pressure" data. </p> </li>
<li id="GUID-ABA8FA09-5F57-51BC-8CAE-43649B5ED6D3"><p>Now we need
to test whether the pointer event contains advanced pointer data.
If it is not an advanced pointer, the code leaves. </p> <p>If it is
an advanced pointer, we call functions to detect proximity, pressure,
"proximity and pressure" data and coordinates. </p> <codeblock
id="GUID-DF109643-2564-51A0-B0F6-33BF4DA1F6E3" xml:space="preserve"
>
if(!advancedP)
    {
    // The TPointerEvent isn't an instance of TAdvancedPointerEvent
    User::Leave(KErrArgument);
    }

switch(aZType)
    {
    case EZTypeProximity:
        aZ = advancedP->Proximity();
        aPoint3D = advancedP->Proximity3D(); 
        break;
    case EZTypePressure:
        aZ = advancedP->Pressure();
        aPoint3D = advancedP->Pressure3D();
        break;
    case EZTypeProximityAndPressure:
        aZ = advancedP->ProximityAndPressure();
        aPoint3D = advancedP->ProximityAndPressure3D();
        break;
    default: 
        User::Leave(KErrArgument);
        break;
    }
</codeblock> <ul>
<li id="GUID-40C01884-AC86-5882-935D-2EC2E27C9004"><p> <xref
href="GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023.dita#GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023/GUID-0ED4B1CC-0655-3246-8645-AAC9E0C27298"
><apiname>TAdvancedPointerEvent::Proximity()</apiname></xref> returns
the proximity. </p> </li>
<li id="GUID-16A9A86B-A837-5E43-BB3A-F5A04A7F4552"><p> <xref
href="GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023.dita#GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023/GUID-15DEBFBF-7B7D-3FCF-9929-C973824A5FD3"
><apiname>TAdvancedPointerEvent::Pressure()</apiname></xref> returns
the pressure. </p> </li>
<li id="GUID-3E614890-C317-596E-A5B9-FD76426DBD12"><p> <xref
href="GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023.dita#GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023/GUID-114AE77E-D0BD-321E-BFCB-1388B35582EC"
><apiname>TAdvancedPointerEvent::ProximityAndPressure()</apiname></xref
> returns the proximity and pressure combined. </p> </li>
<li id="GUID-6F62C0D1-FAE4-5F8F-B451-68ABA404A369"><p> <xref
href="GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023.dita#GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023/GUID-E5AA7737-D217-3FDE-9E4D-AAA7F5D2C300"
><apiname>TAdvancedPointerEvent:: Position3D()</apiname></xref> returns
the proximity and the X, Y and Z coordinates. </p> </li>
<li id="GUID-5AD1811D-BCBF-5A44-B6E7-EB71BF254BCA"><p> <xref
href="GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023.dita#GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023/GUID-2F30A8F5-75BA-3FE3-84B7-3C772ED75857"
><apiname>TAdvancedPointerEvent::Pressure3D()</apiname></xref> returns
the pressure and the X and Y coordinates. </p> </li>
</ul> <p>Proximity is <i>always</i> negative and pressure is <i>always</i
> positive. Internally they are combined together as a Z coordinate.
When Z > 0, the proximity is 0 and the Z value represents the pressure.
When Z &lt; 0, the pressure is 0 and the Z value represents the proximity.
Some APIs use only a Z coordinate (such as the threshold getters and
setters and <xref
href="GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023.dita#GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023/GUID-114AE77E-D0BD-321E-BFCB-1388B35582EC"
><apiname>TAdvancedPointerEvent::ProximityAndPressure()</apiname></xref
>). In these, the Z coordinate is interpreted in terms of pressure
and proximity. </p> </li>
</ol> <fig id="GUID-7A49B143-5458-5916-B937-55D98B77BB2C">
<title> Relationships between the pointer proximity, pressure and
Z              coordinate            </title>
<image
href="GUID-1A0FB98B-8DB3-5067-9B71-FF838F6AE402_d0e241047_href.png"
placement="inline"></image></fig> </section>
<section id="GUID-B7057F69-191F-5AA4-8C61-EBECE66D92F6"><title>Pinch
zooming</title> <p>This example shows an easy way to pinch zoom an
image when the screen receives pointer events from two pointers. There
are two functions in this code that must be implemented by the programmer: <codeph
>BitmapCoordinates()</codeph> and <codeph>MoveBitmap()</codeph>. They
are not included in the example because they involve complex calculations
that are not related to advanced pointers. </p> <p>The high-level
steps to perform pinch zooming are: </p> <ol
id="GUID-AEF3917C-AAFE-5C25-9609-396D08478AC0">
<li id="GUID-7839E665-C4E1-59C8-BA89-22A62615EFA3"><p>Define the coordinates,
equivalent to the given on-screen coordinates. In the code example,
this is done using the function <codeph>BitmapCoordinates()</codeph
>. </p> </li>
<li id="GUID-FC4B1BDA-8120-53C9-9C88-BEFEF1AD54B4"><p>Define the ID
of the pointer by using <xref
href="GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023.dita#GUID-FADA3278-FF8B-308F-90AD-3DCF8911A023/GUID-67593D7E-CE40-303F-B847-81D6FC0578B1"
><apiname>TAdvancedPointerEvent::PointerNumber()</apiname></xref>.
If the device can handle two pointers (two fingers) at the same time,
their numbers are 0 and 1. The pointer number enables you to distinguish
a given pointer from other pointers. </p> </li>
<li id="GUID-1E8F7D23-EEAD-5EA5-8863-276076D6B54E"><p>For each pointer
assign its coordinates to a local variable. We assume there are only
two pointers handled by the system here. </p> </li>
<li id="GUID-E44B3D9B-560A-5959-996D-A63CBD4C3786"><p>Use the <codeph
>MoveBitmap()</codeph> function to achieve the zoom effect. </p> <codeblock
id="GUID-D85CCFDD-8F65-530A-ACD7-93DD1D435FC6" xml:space="preserve"
>
/**
Receives pointer events from two pointers to perform Pinch Zoom of the image.
Function will finish when EButton1Up is received for any of the pointers.
@param aPointer1    Coordinates of pointer number 1 when zoom is started
@param aPointer2    Coordinates of pointer number 2 when zoom is started
*/

void PinchZoom(TPoint aPointer1, TPoint aPointer2)
    {
    TPoint actualP1 = aPointer1;
    TPoint actualP2 = aPointer2;
    
    // translate on-screen pointer coordinates to coordinates of displayed bitmap
    TPoint bitmapCatching1 = BitmapCoordinates(aPointer1);
    TPoint bitmapCatching2 = BitmapCoordinates(aPointer2);
    
    TBool repaint = EFalse;
                                
    while (ETrue)
        {
        TAdvancedPointerEvent event = GetNextPointerEvent();
        
        if (event.iType == TPointerEvent::EDrag)
            { 
            if (event.PointerNumber() == 1)
                { 
                actualP1 = event.iPosition;
                repaint = ETrue;
                }
            else if (event.PointerNumber() == 2)
                {
                actualP2 = event.iPosition;
                repaint = ETrue;
                }
            }
        else if (event.iType == TPointerEvent::EButton1Up)
            {
            break;
            }
        
        if (repaint)
            {
            // move bitmap on the screen in the way that
            // bitmapCatching1 point of the bitmap will be displayed at actualP1 screen coordinate,
            // bitmapCatching2 point of the bitmap will be displayed at actualP2 screen coordinate.
            MoveBitmap(bitmapCatching1, actualP1, bitmapCatching2, actualP2);
            repaint = EFalse;
            }
        }
    }
</codeblock> </li>
</ol> </section>
</conbody>
<related-links>
<link href="GUID-9C269F45-F160-5A4B-ABF8-896D2A538E3B.dita"><linktext
>Advanced Pointer                 Overview</linktext></link>
<link href="GUID-9AD75103-CD56-5279-B639-5CA2BBF979B5.dita"><linktext
>Advanced Pointer States and                 Event Communication</linktext>
</link>
</related-links>
</concept>
<?Pub *0000013536?>