In this recipe, we will create an InteractiveObject
class for making graphical objects that interact with the mouse cursor and executes the following actions:
For each of the previous actions, a virtual method will be called, and it would change the color of the object been drawn.
This object can be used as a base class to create interactive objects with more interesting graphics, such as textures.
Create and add the following files to your project:
InteractiveObject.h
InteractiveObject.cpp
In the source file with your application class, include the InteractiveObject.h
file and add the following using
statements:
#include "InteractiveObject.h" using namespace ci; using namespace ci::app; using namespace std;
We will create an InteractiveObject
class and make it responsive to mouse events.
InteractiveObject.h
and add the #pragma once
directive and include the following files:#pragma once #include "cinder/Rect.h" #include "cinder/Color.h" #include "cinder/app/MouseEvent.h" #include "cinder/gl/gl.h" #include "cinder/app/App.h"
InteractiveObject
:class InteractiveObject{ public: InteractiveObject( const ci::Rectf& rect ); virtual ~InteractiveObject(); virtual void draw(); virtual void pressed(); virtual void pressedOutside(); virtual void released(); virtual void releasedOutside(); virtual void rolledOver(); virtual void rolledOut(); virtual void dragged(); void mouseDown( ci::app::MouseEvent& event ); void mouseUp( ci::app::MouseEvent& event ); void mouseDrag( ci::app::MouseEvent& event ); void mouseMove( ci::app::MouseEvent& event ); ci::Rectf rect; ci::Color pressedColor, idleColor, overColor, strokeColor; protected: bool mPressed, mOver; };
InteractiveObject.cpp
file, and let's begin by including the InteractiveObject.h
file and adding the following using
statements:#include "InteractiveObject.h" using namespace ci; using namespace ci::app; using namespace std;
constructor
and destructor
.InteractiveObject::InteractiveObject( const Rectf& rect ){ this->rect = rect; pressedColor = Color( 1.0f, 0.0f, 0.0f ); idleColor = Color( 0.7f, 0.7f, 0.7f ); overColor = Color( 1.0f, 1.0f, 1.0f ); strokeColor = Color( 0.0f, 0.0f, 0.0f ); mPressed = false; mOver = false; } InteractiveObject::~InteractiveObject(){ }
InteractiveObject::draw
method we will draw the rectangle using the appropriate colors:void InteractiveObject::draw(){ if( mPressed ){ gl::color( pressedColor ); } else if( mOver ){ gl::color( overColor ); } else { gl::color( idleColor ); } gl::drawSolidRect( rect ); gl::color( strokeColor ); gl::drawStrokedRect( rect ); }
pressed
, released
, rolledOver
, rolledOut
, and dragged
methods we will simply output to the console on which the action just happened:void InteractiveObject::pressed(){ console() << "pressed" << endl; } void InteractiveObject::pressedOutside(){ console() << "pressed outside" << endl; } void InteractiveObject::released(){ console() << "released" << endl; } void InteractiveObject::releasedOutside(){ console() << "released outside" << endl; } void InteractiveObject::rolledOver(){ console() << "rolled over" << endl; } void InteractiveObject::rolledOut(){ console() << "rolled out" << endl; } void InteractiveObject::dragged(){ console() << "dragged" << endl; }
mPressed
and mOver
variables accordingly. Every time the action is detected, we will also call the correspondent method.void InteractiveObject::mouseDown( MouseEvent& event ){ if( rect.contains( event.getPos() ) ){ mPressed = true; mOver = false; pressed(); }else{ pressedOutside(); } } void InteractiveObject::mouseUp( MouseEvent& event ){ if( rect.contains( event.getPos() ) ){ if( mPressed ){ mPressed = false; mOver = true; released(); } } else { mPressed = false; mOver = false; releasedOutside(); } } void InteractiveObject::mouseDrag( MouseEvent& event ){ if( mPressed && rect.contains( event.getPos() ) ){ mPressed = true; mOver = false; dragged(); } } void InteractiveObject::mouseMove( MouseEvent& event ){ if( rect.contains( event.getPos() ) ){ if( mOver == false ){ mPressed = false; mOver = true; rolledOver(); } } else { if( mOver ){ mPressed = false; mOver = false; rolledOut(); } }
InteractiveObject
class ready, let's move to our application's class source file. Let's begin by declaring an InteractiveObject
object.shared_ptr<InteractiveObject> mObject;
setup
method we will initialize mObject
.Rectf rect( 100.0f, 100.0f, 300.0f, 300.0f ); mObject = shared_ptr<InteractiveObject>( new InteractiveObject( rect ) );
void mouseDown( MouseEvent event ); void mouseUp( MouseEvent event ); void mouseDrag( MouseEvent event ); void mouseMove( MouseEvent event );
mObject
.void MyApp::mouseDown( MouseEvent event ){ mObject->mouseDown( event ); } void MyApp::mouseUp( MouseEvent event ){ mObject->mouseUp( event ); } void MyApp::mouseDrag( MouseEvent event ){ mObject->mouseDrag( event ); } void MyApp::mouseMove( MouseEvent event ){ mObject->mouseMove( event ); }
draw
method, we will clear the background with black and call the draw
method of mObject
.gl::clear( Color( 0, 0, 0 ) ); mObject->draw();
The InteractiveObject
class is to be used as a base class for interactive objects. The methods pressed
, released
, rolledOver
, rolledOut
, and dragged
are specifically designed to be overridden.
The mouse handlers of InteractiveObject
call the previous methods whenever an action is detected. By overriding the methods, it is possible to implement specific behavior.
The virtual destructor
is declared so that extending classes can have their own destructor
.
3.15.137.75