00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #pragma once
00025
00026 #include "cinder/Cinder.h"
00027 #include "cinder/Display.h"
00028 #include "cinder/app/Renderer.h"
00029 #include "cinder/Vector.h"
00030 #include "cinder/Function.h"
00031 #include "cinder/app/MouseEvent.h"
00032 #include "cinder/app/TouchEvent.h"
00033 #include "cinder/app/KeyEvent.h"
00034 #include "cinder/app/FileDropEvent.h"
00035
00036 namespace cinder { namespace app {
00037
00038 class Window;
00039 struct FullScreenOptions;
00040 typedef std::shared_ptr<Window> WindowRef;
00041
00042 } }
00043
00044 #if defined( CINDER_COCOA ) && defined( __OBJC__ )
00045 #import <Foundation/Foundation.h>
00046 #if defined( CINDER_COCOA_TOUCH )
00047 @class UIViewController;
00048 #endif
00049
00050 @protocol WindowImplCocoa
00051 @required
00052 - (BOOL)isFullScreen;
00053 - (void)setFullScreen:(BOOL)fullScreen options:(const cinder::app::FullScreenOptions *)options;
00054 - (cinder::Vec2i)getSize;
00055 - (void)setSize:(cinder::Vec2i)size;
00056 - (cinder::Vec2i)getPos;
00057 - (void)setPos:(cinder::Vec2i)pos;
00058 - (float)getContentScale;
00059 - (void)close;
00060 - (NSString *)getTitle;
00061 - (void)setTitle:(NSString *)title;
00062 - (BOOL)isBorderless;
00063 - (void)setBorderless:(BOOL)borderless;
00064 - (BOOL)isAlwaysOnTop;
00065 - (void)setAlwaysOnTop:(BOOL)alwaysOnTop;
00066 - (void)hide;
00067 - (void)show;
00068 - (BOOL)isHidden;
00069 - (cinder::DisplayRef)getDisplay;
00070 - (cinder::app::RendererRef)getRenderer;
00071 - (const std::vector<cinder::app::TouchEvent::Touch>&)getActiveTouches;
00072 - (void*)getNative;
00073 #if defined( CINDER_COCOA_TOUCH )
00074 - (UIViewController *)getNativeViewController;
00075 #endif
00076 @end
00077 #elif defined( CINDER_COCOA )
00078 class WindowImplCocoa;
00079 #if defined( CINDER_COCOA_TOUCH )
00080 class UIViewController;
00081 #endif
00082 #elif defined( CINDER_MSW )
00083 namespace cinder { namespace app {
00084 class WindowImplMsw;
00085 } }
00086 #endif
00087
00088 namespace cinder { namespace app {
00089
00090 typedef signals::signal<void(MouseEvent&),EventCombiner<MouseEvent> > EventSignalMouse;
00091 typedef signals::signal<void(TouchEvent&),EventCombiner<TouchEvent> > EventSignalTouch;
00092 typedef signals::signal<void(KeyEvent&),EventCombiner<KeyEvent> > EventSignalKey;
00093 typedef signals::signal<void(FileDropEvent&),EventCombiner<FileDropEvent> > EventSignalFileDrop;
00094 typedef signals::signal<void()> EventSignalWindow;
00095
00097 class ExcInvalidWindow : public cinder::Exception {
00098 virtual const char * what() const throw() { return "Invalid Window"; }
00099 };
00100
00102 struct FullScreenOptions {
00103 FullScreenOptions() : mKioskMode( true ), mSecondaryDisplayBlanking( false ), mExclusive( false )
00104 {}
00105
00107 FullScreenOptions& kioskMode( bool enable = true ) { mKioskMode = enable; return *this; }
00109 FullScreenOptions& secondaryDisplayBlanking( bool enable = true ) { mSecondaryDisplayBlanking = enable; return *this; }
00111 FullScreenOptions& exclusive( bool enable = true ) { mExclusive = enable; return *this; }
00113 FullScreenOptions& display( DisplayRef display ) { mDisplay = display; return *this; }
00114
00116 DisplayRef getDisplay() const { return mDisplay; }
00118 bool isKioskModeEnabled() const { return mKioskMode; }
00120 bool isSecondaryDisplayBlankingEnabled() const { return mSecondaryDisplayBlanking; }
00122 bool isExclusive() const { return mExclusive; }
00123
00124 private:
00125 DisplayRef mDisplay;
00126 bool mKioskMode, mSecondaryDisplayBlanking, mExclusive;
00127 };
00128
00129 class Window : public std::enable_shared_from_this<Window> {
00130 public:
00131
00132 struct Format {
00133 Format( RendererRef renderer = RendererRef(), DisplayRef display = Display::getMainDisplay(), bool fullScreen = false, Vec2i size = Vec2i( 640, 480 ), Vec2i pos = Vec2i::zero() )
00134 : mRenderer( renderer ), mFullScreen( fullScreen ), mDisplay( display ), mSize( size ), mPos( pos ), mPosSpecified( false ),
00135 mResizable( true ), mBorderless( false ), mAlwaysOnTop( false ), mFullScreenButtonEnabled( false )
00136 #if defined( CINDER_COCOA_TOUCH )
00137 , mRootViewController( NULL )
00138 #endif
00139 {
00140 mFullScreenOptions.kioskMode( true );
00141 }
00142
00144 DisplayRef getDisplay() const { return mDisplay; }
00146 void setDisplay( DisplayRef display ) { mDisplay = display; }
00148 Format& display( DisplayRef displayRef ) { mDisplay = displayRef; return *this; }
00150 bool isFullScreen() const { return mFullScreen; }
00152 const FullScreenOptions& getFullScreenOptions() const { return mFullScreenOptions; }
00154 void setFullScreen( bool fullScreen = true, const FullScreenOptions &options = FullScreenOptions() ) { mFullScreen = fullScreen; mFullScreenOptions = options; }
00156 Format& fullScreen( bool fs = true ) { mFullScreen = fs; return *this; }
00158 Vec2i getSize() const { return mSize; }
00160 void setSize( const Vec2i &size ) { mSize = size; }
00162 void setSize( int32_t width, int32_t height ) { mSize = Vec2i( width, height ); }
00164 Format& size( const Vec2i &s ) { mSize = s; return *this; }
00166 Format& size( int32_t width, int32_t height ) { mSize = Vec2i( width, height ); return *this; }
00167
00169 Vec2i getPos() const { return mPos; }
00171 void setPos( const Vec2i &pos ) { mPos = pos; mPosSpecified = true; }
00173 void setPos( int32_t x, int32_t y ) { mPos = Vec2i( x, y ); mPosSpecified = true; }
00175 Format& pos( const Vec2i &pos ) { mPos = pos; mPosSpecified = true; return *this; }
00177 Format& pos( int32_t x, int32_t y ) { mPos = Vec2i( x, y ); mPosSpecified = true; return *this; }
00179 bool isPosSpecified() const { return mPosSpecified; }
00181 void unspecifyPos() { mPosSpecified = false; }
00182
00184 RendererRef getRenderer() const { return mRenderer; }
00186 void setRenderer( RendererRef renderer ) { mRenderer = renderer; }
00188 Format& renderer( RendererRef r ) { mRenderer = r; return *this; }
00189
00190 #if defined( CINDER_COCOA_TOUCH )
00191
00192 UIViewController* getRootViewController() { return mRootViewController;}
00194 void setRootViewController( UIViewController *v ) { mRootViewController = v; }
00196 Format& rootViewController( UIViewController *v ) { mRootViewController = v; return *this; }
00197 #endif
00198
00200 bool isResizable() const { return mResizable; }
00202 void setResizable( bool resizable = true ) { mResizable = resizable; }
00204 Format& resizable( bool res = true ) { mResizable = res; return *this; }
00206 bool isBorderless() const { return mBorderless; }
00208 void setBorderless( bool borderless = true ) { mBorderless = borderless; }
00210 Format& borderless( bool border = true ) { mBorderless = border; return *this; }
00212 bool isAlwaysOnTop() const { return mAlwaysOnTop; }
00214 void setAlwaysOnTop( bool alwaysOnTop = true ) { mAlwaysOnTop = alwaysOnTop; }
00216 Format& alwaysOnTop( bool top = true ) { mAlwaysOnTop = top; return *this; }
00218 void enableFullScreenButton( bool enabled = true ) { mFullScreenButtonEnabled = enabled; }
00220 Format& fullScreenButton( bool enabled = true ) { mFullScreenButtonEnabled = enabled; return *this; }
00222 bool isFullScreenButtonEnabled() const { return mFullScreenButtonEnabled; }
00223
00225 std::string getTitle() const { return mTitle; }
00227 void setTitle( const std::string &title ) { mTitle = title; }
00229 Format& title( const std::string &t ) { mTitle = t; return *this; }
00230
00231 private:
00232 RendererRef mRenderer;
00233 bool mFullScreen;
00234 FullScreenOptions mFullScreenOptions;
00235 DisplayRef mDisplay;
00236 Vec2i mSize, mPos;
00237 bool mPosSpecified;
00238 bool mResizable, mBorderless, mAlwaysOnTop, mFullScreenButtonEnabled;
00239 std::string mTitle;
00240
00241 #if defined( CINDER_COCOA_TOUCH )
00242 UIViewController *mRootViewController;
00243 #endif
00244 };
00245
00247 bool isFullScreen() const;
00249 void setFullScreen( bool fullScreen = true, const FullScreenOptions& options = FullScreenOptions() );
00251 int32_t getWidth() const { return getSize().x; }
00253 int32_t getHeight() const { return getSize().y; }
00255 float getAspectRatio() const { return getSize().x / (float)getSize().y; }
00257 Area getBounds() const { return Area( 0, 0, getSize().x, getSize().y ); }
00259 virtual Vec2i getSize() const;
00261 void setSize( int32_t width, int32_t height ) { setSize( Vec2i( width, height ) ); }
00263 void setSize( const Vec2i &size );
00265 Vec2i getPos() const;
00267 void setPos( int32_t x, int32_t y ) const { setPos( Vec2i( x, y ) ); }
00269 void setPos( const Vec2i &pos ) const;
00271 Vec2f getCenter() const { return Vec2f( getWidth() / 2.0f, getHeight() / 2.0f ); }
00273 void spanAllDisplays();
00274
00276 float getContentScale() const;
00278 float toPixels( float s ) const { return s * getContentScale(); }
00280 Vec2f toPixels( Vec2f s ) const { return s * getContentScale(); }
00282 Vec2i toPixels( Vec2i s ) const { return Vec2i( (int32_t)(s.x * getContentScale()), (int32_t)(s.y * getContentScale()) ); }
00284 Area toPixels( const Area &a ) const { const float s = getContentScale(); return Area( (int32_t)(a.x1 * s), (int32_t)(a.y1 * s), (int32_t)(a.x2 * s), (int32_t)(a.y2 * s) ); }
00286 Rectf toPixels( const Rectf &a ) const { return a * getContentScale(); }
00288 float toPoints( float s ) const { return s / getContentScale(); }
00290 Vec2f toPoints( Vec2f s ) const { return s / getContentScale(); }
00292 Vec2i toPoints( Vec2i s ) const { return Vec2i( (int32_t)(s.x / getContentScale()), (int32_t)(s.y / getContentScale()) ); }
00294 Area toPoints( const Area &a ) const { const float s = 1.0f / getContentScale(); return Area( (int32_t)(a.x1 * s), (int32_t)(a.y1 * s), (int32_t)(a.x2 * s), (int32_t)(a.y2 * s) ); }
00296 Rectf toPoints( const Rectf &a ) const { return a / getContentScale(); }
00297
00299 std::string getTitle() const;
00301 void setTitle( const std::string &title );
00302
00304 bool isBorderless() const;
00306 void setBorderless( bool borderless = true );
00308 bool isAlwaysOnTop() const;
00310 void setAlwaysOnTop( bool alwaysOnTop = true );
00311
00313 void hide();
00315 void show();
00317 bool isHidden() const;
00318
00320 void close();
00321
00323 DisplayRef getDisplay() const;
00325 RendererRef getRenderer() const;
00327 void* getNative() const;
00328 #if defined( CINDER_COCOA_TOUCH )
00329
00330 UIViewController* getNativeViewController();
00331 #endif
00332 #if defined( CINDER_MSW )
00333
00334 HDC getDc() const { return getRenderer()->getDc(); }
00335 #endif
00336
00337 EventSignalMouse& getSignalMouseDown() { return mSignalMouseDown; }
00338 void emitMouseDown( MouseEvent *event );
00339 template<typename T, typename Y>
00340 signals::connection connectMouseDown( T fn, Y *inst ) { return getSignalMouseDown().connect( std::bind( fn, inst, std::_1 ) ); }
00341
00342 EventSignalMouse& getSignalMouseDrag() { return mSignalMouseDrag; }
00343 void emitMouseDrag( MouseEvent *event );
00344 template<typename T, typename Y>
00345 signals::connection connectMouseDrag( T fn, Y *inst ) { return getSignalMouseDrag().connect( std::bind( fn, inst, std::_1 ) ); }
00346
00347 EventSignalMouse& getSignalMouseUp() { return mSignalMouseUp; }
00348 void emitMouseUp( MouseEvent *event );
00349 template<typename T, typename Y>
00350 signals::connection connectMouseUp( T fn, Y *inst ) { return getSignalMouseUp().connect( std::bind( fn, inst, std::_1 ) ); }
00351
00352 EventSignalMouse& getSignalMouseMove() { return mSignalMouseMove; }
00353 void emitMouseMove( MouseEvent *event );
00354 template<typename T, typename Y>
00355 signals::connection connectMouseMove( T fn, Y *inst ) { return getSignalMouseMove().connect( std::bind( fn, inst, std::_1 ) ); }
00356
00357 EventSignalMouse& getSignalMouseWheel() { return mSignalMouseWheel; }
00358 void emitMouseWheel( MouseEvent *event );
00359 template<typename T, typename Y>
00360 signals::connection connectMouseWheel( T fn, Y *inst ) { return getSignalMouseWheel().connect( std::bind( fn, inst, std::_1 ) ); }
00361
00362 EventSignalTouch& getSignalTouchesBegan() { return mSignalTouchesBegan; }
00363 void emitTouchesBegan( TouchEvent *event );
00364 template<typename T, typename Y>
00365 signals::connection connectTouchesBegan( T fn, Y *inst ) { return getSignalTouchesBegan().connect( std::bind( fn, inst, std::_1 ) ); }
00366
00367 EventSignalTouch& getSignalTouchesMoved() { return mSignalTouchesMoved; }
00368 void emitTouchesMoved( TouchEvent *event );
00369 template<typename T, typename Y>
00370 signals::connection connectTouchesMoved( T fn, Y *inst ) { return getSignalTouchesMoved().connect( std::bind( fn, inst, std::_1 ) ); }
00371
00372 EventSignalTouch& getSignalTouchesEnded() { return mSignalTouchesEnded; }
00373 void emitTouchesEnded( TouchEvent *event );
00374 template<typename T, typename Y>
00375 signals::connection connectTouchesEnded( T fn, Y *inst ) { return getSignalTouchesEnded().connect( std::bind( fn, inst, std::_1 ) ); }
00376
00378 const std::vector<TouchEvent::Touch>& getActiveTouches() const;
00379
00380 EventSignalKey& getSignalKeyDown() { return mSignalKeyDown; }
00381 void emitKeyDown( KeyEvent *event );
00382 template<typename T, typename Y>
00383 signals::connection connectKeyDown( T fn, Y *inst ) { return getSignalKeyDown().connect( std::bind( fn, inst, std::_1 ) ); }
00384
00385 EventSignalKey& getSignalKeyUp() { return mSignalKeyUp; }
00386 void emitKeyUp( KeyEvent *event );
00387 template<typename T, typename Y>
00388 signals::connection connectKeyUp( T fn, Y *inst ) { return getSignalKeyUp().connect( std::bind( fn, inst, std::_1 ) ); }
00389
00390 EventSignalWindow& getSignalDraw() { return mSignalDraw; }
00392 void emitDraw();
00393 template<typename T, typename Y>
00394 signals::connection connectDraw( T fn, Y *inst ) { return getSignalDraw().connect( std::bind( fn, inst ) ); }
00395
00397 EventSignalWindow& getSignalPostDraw() { return mSignalPostDraw; }
00398 template<typename T, typename Y>
00399 signals::connection connectPostDraw( T fn, Y *inst ) { return getSignalPostDraw().connect( std::bind( fn, inst ) ); }
00400
00401 EventSignalWindow& getSignalMove() { return mSignalMove; }
00402 void emitMove();
00403 template<typename T, typename Y>
00404 signals::connection connectMove( T fn, Y *inst ) { return getSignalMove().connect( std::bind( fn, inst ) ); }
00405
00406 EventSignalWindow& getSignalResize() { return mSignalResize; }
00407 void emitResize();
00408 template<typename T, typename Y>
00409 signals::connection connectResize( T fn, Y *inst ) { return getSignalResize().connect( std::bind( fn, inst ) ); }
00410
00411 EventSignalWindow& getSignalDisplayChange() { return mSignalDisplayChange; }
00412 void emitDisplayChange();
00413 template<typename T, typename Y>
00414 signals::connection connectDisplayChange( T fn, Y *inst ) { return getSignalDisplayChange().connect( std::bind( fn, inst ) ); }
00415
00417 EventSignalWindow& getSignalClose() { return mSignalClose; }
00419 void emitClose();
00420 template<typename T, typename Y>
00421 signals::connection connectClose( T fn, Y *inst ) { return getSignalClose().connect( std::bind( fn, inst ) ); }
00422
00423 EventSignalFileDrop& getSignalFileDrop() { return mSignalFileDrop; }
00424 void emitFileDrop( FileDropEvent *event );
00425 template<typename T, typename Y>
00426 signals::connection connectFileDrop( T fn, Y *inst ) { return getSignalFileDrop().connect( std::bind( fn, inst, std::_1 ) ); }
00427
00429 template<typename T>
00430 T* getUserData() { return static_cast<T*>( mUserData.get() ); }
00432 template<typename T>
00433 void setUserData( T *userData ) { mUserData = std::shared_ptr<void>( std::shared_ptr<T>( userData ) ); }
00434
00436 bool isValid() const { return ! mValid; }
00437 void setInvalid() { mValid = false; }
00438
00440
00441 #if defined( CINDER_COCOA ) && defined( __OBJC__ )
00442 static WindowRef privateCreate__( id<WindowImplCocoa> impl, App *app )
00443 #elif defined( CINDER_MSW )
00444 static WindowRef privateCreate__( WindowImplMsw *impl, App *app )
00445 #else
00446 static WindowRef privateCreate__( WindowImplCocoa *impl, App *app )
00447 #endif
00448 {
00449 WindowRef result( new Window );
00450 result->setImpl( impl );
00451 result->setApp( app );
00452
00453 return result;
00454 }
00456
00457 App* getApp() const { return mApp; }
00458
00459 protected:
00460 Window() : mValid( true ), mImpl( 0 ) {}
00461
00462 void testValid() const {
00463 if( ! mValid )
00464 throw ExcInvalidWindow();
00465 }
00466
00467 void setApp( App *app ) { mApp = app; }
00468
00469 #if defined( CINDER_COCOA )
00470 #if defined( __OBJC__ )
00471 void setImpl( id<WindowImplCocoa> impl ) { mImpl = impl; }
00472 #else
00473 void setImpl( WindowImplCocoa *impl ) { mImpl = impl; }
00474 #endif
00475 #elif defined( CINDER_MSW )
00476 void setImpl( WindowImplMsw *impl ) { mImpl = impl; }
00477 #endif
00478
00479 App *mApp;
00480 bool mValid;
00481 std::shared_ptr<void> mUserData;
00482
00483 EventSignalMouse mSignalMouseDown, mSignalMouseDrag, mSignalMouseUp, mSignalMouseWheel, mSignalMouseMove;
00484 EventSignalTouch mSignalTouchesBegan, mSignalTouchesMoved, mSignalTouchesEnded;
00485 EventSignalKey mSignalKeyDown, mSignalKeyUp;
00486 EventSignalWindow mSignalDraw, mSignalPostDraw, mSignalMove, mSignalResize, mSignalDisplayChange, mSignalClose;
00487 EventSignalFileDrop mSignalFileDrop;
00488
00489 #if defined( CINDER_COCOA )
00490 #if defined( __OBJC__ )
00491 id<WindowImplCocoa> mImpl;
00492 #else
00493 WindowImplCocoa *mImpl;
00494 #endif
00495 #elif defined( CINDER_MSW )
00496 WindowImplMsw *mImpl;
00497 #endif
00498 };
00499
00500 } }