Last active
December 20, 2015 00:38
-
-
Save paulhoux/6042854 to your computer and use it in GitHub Desktop.
Example of using signals and slots with derived classes. Sample made for Cinder. Simply create an empty Cinder application called "Signals" using TinderBox, then replace the contents of ```SignalsApp.cpp``` with this code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _SCL_SECURE_NO_WARNINGS | |
#include "cinder/app/AppNative.h" | |
#include "cinder/gl/gl.h" | |
using namespace ci; | |
using namespace ci::app; | |
using namespace std; | |
//-------------------------- | |
// Button base class | |
//-------------------------- | |
class Button | |
{ | |
public: | |
Button() : mRect( Rectf(0, 0, 300, 100) ), mIsPressed(false) {} | |
Button( const Rectf& rect ) : mRect(rect), mIsPressed(false) {} | |
virtual ~Button() {} | |
virtual void draw(); | |
virtual void mouseDown( MouseEvent event ); | |
virtual void mouseUp( MouseEvent event ); | |
public: | |
ci::signals::signal<void( Button& )> sClicked; | |
private: | |
bool mIsPressed; | |
Rectf mRect; | |
}; | |
void Button::draw() | |
{ | |
gl::color( mIsPressed ? Color(1, 0, 0) : Color(0, 1, 0) ); | |
gl::drawSolidRect( mRect ); | |
} | |
void Button::mouseDown( MouseEvent event ) | |
{ | |
mIsPressed = mRect.contains(event.getPos()); | |
} | |
void Button::mouseUp( MouseEvent event ) | |
{ | |
if (mIsPressed && mRect.contains(event.getPos())) | |
sClicked(*this); | |
mIsPressed = false; | |
} | |
//-------------------------- | |
// LoginButton derived class | |
//-------------------------- | |
class LoginButton : public Button | |
{ | |
public: | |
LoginButton() : Button( Rectf(0, 150, 300, 250) ) {} | |
LoginButton( const Rectf& rect ) : Button(rect) {} | |
~LoginButton() {} | |
}; | |
//-------------------------- | |
// Application class | |
//-------------------------- | |
class SignalsApp : public AppNative { | |
public: | |
void setup(); | |
void draw(); | |
void mouseDown( MouseEvent event ); | |
void mouseUp( MouseEvent event ); | |
void onButtonClicked( Button& button ); | |
private: | |
Button mButton; | |
LoginButton mLoginButton; | |
}; | |
void SignalsApp::setup() | |
{ | |
mButton.sClicked.connect( std::bind( &SignalsApp::onButtonClicked, this, std::_1 ) ); | |
mLoginButton.sClicked.connect( std::bind( &SignalsApp::onButtonClicked, this, std::_1 ) ); | |
} | |
void SignalsApp::draw() | |
{ | |
gl::clear(); | |
mButton.draw(); | |
mLoginButton.draw(); | |
} | |
void SignalsApp::mouseDown( MouseEvent event ) | |
{ | |
mButton.mouseDown( event ); | |
mLoginButton.mouseDown( event ); | |
} | |
void SignalsApp::mouseUp( MouseEvent event ) | |
{ | |
mButton.mouseUp( event ); | |
mLoginButton.mouseUp( event ); | |
} | |
void SignalsApp::onButtonClicked( Button& button ) | |
{ | |
try { | |
LoginButton& btn = dynamic_cast<LoginButton&>( button ); | |
console() << "LoginButton clicked" << std::endl; | |
} | |
catch( ... /*const std::bad_cast &e*/ ) { | |
// it didn't work, so it's not a LoginButton | |
console() << "Button clicked" << std::endl; | |
} | |
} | |
CINDER_APP_NATIVE( SignalsApp, RendererGl ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment