Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Cinder Creative Coding Cookbook

You're reading from   Cinder Creative Coding Cookbook If you know C++ this book takes your creative potential to a whole other level. The practical recipes show you how to create interactive and visually dynamic applications using Cinder which will excite and delight your audience.

Arrow left icon
Product type Paperback
Published in May 2013
Publisher Packt
ISBN-13 9781849518703
Length 352 pages
Edition 1st Edition
Tools
Concepts
Arrow right icon
Toc

Table of Contents (19) Chapters Close

Cinder Creative Coding Cookbook
Credits
About the Authors
About the Reviewers
www.PacktPub.com
Preface
1. Getting Started 2. Preparing for Development FREE CHAPTER 3. Using Image Processing Techniques 4. Using Multimedia Content 5. Building Particle Systems 6. Rendering and Texturing Particle Systems 7. Using 2D Graphics 8. Using 3D Graphics 9. Adding Animation 10. Interacting with the User 11. Sensing and Tracking Input from the Camera 12. Using Audio Input and Output Index

Responding to touch input


A Cinder application can receive several touch events.

The available touch event handlers that get called by touch interaction are listed in the following table:

Method

Usage

touchesBegan

This is called when new touches are detected

touchesMoved

This is called when existing touches move

touchesEnded

This is called when existing touches are removed

All of the preceding methods receive a ci::app::TouchEvent object as a parameter with a std::vector of ci::app::TouchEvent::Touch objects with information about each touch detected. Since many devices can detect and respond to several touches simultaneously, it is possible and common for a touch event to contain several touches.

It is not mandatory to implement all of the preceding event handlers; you can use the ones your application requires specifically.

Cinder applications can respond to touch events on any touch-enabled device running Windows 7, OS X, or iOS.

Getting ready

Implement the necessary touch event handlers according to the touch events you want to respond to. For example, to respond to all available touch events (touches added, touches moved, and touches removed), you would need to declare and implement the following methods:

void touchesBegan( TouchEvent event );
void touchesMoved( TouchEvent event );
void touchesEnded( TouchEvent event );

How to do it…

We will learn how to work with the ci::app::TouchEvent class to understand touch events. Perform the following steps to do so:

  1. To access the list of touches, you can type in the following line of code:

    const std::vector<TouchEvent::Touch>& touches = event.getTouches();

    Iterate through the container to access each individual element.

    for( std::vector<TouchEvent::Touch>::const_iterator it = touches.begin(); it != touches.end(); ++it ){
      const TouchEvent::Touch& touch = *it;
      //do something with the touch object
    }
  2. You can get the position of a touch by calling the getPos method that returns a Vec2f value with its position or using the getX and getY methods to receive the x and y coordinates separately, for example:

    for( std::vector<TouchEvent::Touch>::const_iterator it = touches.begin(); it != touches.end(); ++it ){
      const TouchEvent::Touch& touch = *it;
      vec2f pos = touch.getPos();
      float x = touch.getX();
      float y = touch.getY(); 
    }
  3. The getId method returns a uint32_t value with a unique ID for the touch object. This ID is persistent throughout the lifecycle of the touch, which means you can use it to keep track of a specific touch as you access it on the different touch events.

    For example, to make an application where we draw lines using our fingers, we can create std::map that associates each line, in the form of a ci::PolyLine<Vec2f> object, with a uint32_t key with the unique ID of a touch.

    We need to include the file with std::map and PolyLine to our project by adding the following code snippet to the beginning of the source file:

    #include "cinder/polyline.h"
    #include <map>
  4. We can now declare the container:

    std::map< uint32_t, PolyLine<Vec2f> > mLines;
  5. In the touchesBegan method we create a new line for each detected touch and map it to the unique ID of each touch:

    const std::vector<TouchEvent::Touch>& touches = event.getTouches();
    for( std::vector<TouchEvent::Touch>::const_iterator it = touches.begin(); it != touches.end(); ++it ){
      const TouchEvent::Touch& touch = *it;
      mLines[ touch.getId() ] = PolyLine<Vec2f>();
    }
  6. In the touchesMoved method, we add the position of each touch to its corresponding line:

    const std::vector<TouchEvent::Touch>& touches = event.getTouches();
    for( std::vector<TouchEvent::Touch>::const_iterator it = touches.begin(); it != touches.end(); ++it ){
      const TouchEvent::Touch& touch = *it;
      mLines[ touch.getId() ].push_back( touch.getPos() ); 
    }
  7. In the touchesEnded method, we remove the line that corresponds to a touch being removed:

    const std::vector<TouchEvent::Touch>& touches = event.getTouches();
    for( std::vector<TouchEvent::Touch>::const_iterator it = touches.begin(); it != touches.end(); ++it ){
      const TouchEvent::Touch& touch = *it;
      mLines.erase( touch.getId() );
    }
  8. Finally, the lines can be drawn. Here we clear the background with black and draw the lines with in white. The following is the implementation of the draw method:

    gl::clear( Color::black() );
    gl::color( Color::white() );
    for( std::map<uint32_t, PolyLine<Vec2f> >::iterator it = mLines.begin(); it != mLines.end(); ++it ){
      gl::draw( it->second );
    }

    The following is a screenshot of our app running after drawing some lines:

How it works…

A Cinder application responds internally to the system calls for any touch event. It will then create a ci::app::TouchEvent object with information about the event and call the corresponding event handler in our application's class. The way to respond to touch events becomes uniform across the Windows and Mac platforms.

The ci::app::TouchEvent class contains only one accessor method that returns a const reference to a std::vector<TouchEvent::Touch> container. This container has one ci::app::TouchEvent::Touch object for each detected touch and contains information about the touch.

The ci::app::TouchEvent::Touch object contains information about the touch including position and previous position, unique ID, the time stamp, and a pointer to the native event object which maps to UITouch on Cocoa Touch and TOUCHPOINT on Windows 7.

There's more...

At any time, it is also possible to get a container with all active touches by calling the getActiveTouches method. It returns a const reference to a std::vector<TouchEvent::Touch> container. It offers flexibility when working with touch applications as it can be accessed outside the touch event methods.

For example, if you want to draw a solid red circle around each active touch, you can add the following code snippet to your draw method:

const std::vector<TouchEvent::Touch>&activeTouches = getActiveTouches();
gl::color( Color( 1.0f, 0.0f, 0.0f ) );
for( std::vector<TouchEvent::Touch>::const_iterator it = activeTouches.begin(); it != activeTouches.end(); ++it ){
  const TouchEvent::Touch& touch = *it;
gl::drawSolidCircle( touch.getPos(), 10.0f );
}
lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image