00001 /* 00002 Copyright (c) 2010, The Barbarian Group 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that 00006 the following conditions are met: 00007 00008 * Redistributions of source code must retain the above copyright notice, this list of conditions and 00009 the following disclaimer. 00010 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 00011 the following disclaimer in the documentation and/or other materials provided with the distribution. 00012 00013 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 00014 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00015 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00016 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00017 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00018 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00019 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00020 POSSIBILITY OF SUCH DAMAGE. 00021 */ 00022 00023 #pragma once 00024 00025 #include "cinder/Cinder.h" 00026 #include "cinder/app/Renderer.h" 00027 #include "cinder/Vector.h" 00028 #include "cinder/app/MouseEvent.h" 00029 #include "cinder/app/KeyEvent.h" 00030 #include "cinder/app/FileDropEvent.h" 00031 #include "cinder/Stream.h" 00032 #include "cinder/Display.h" 00033 #include "cinder/DataSource.h" 00034 #include "cinder/Timer.h" 00035 #if defined( CINDER_COCOA ) 00036 #if defined( CINDER_COCOA_TOUCH ) 00037 #if defined( __OBJC__ ) 00038 #import <UIKit/UIKit.h> 00039 #import <CoreFoundation/CoreFoundation.h> 00040 #endif 00041 #else 00042 #include <ApplicationServices/ApplicationServices.h> 00043 #endif 00044 #if defined __OBJC__ 00045 @class CinderView; 00046 @class AppImplCocoaRendererQuartz; 00047 @class AppImplCocoaRendererGl; 00048 #else 00049 class AppImplCocoaRendererQuartz; 00050 class AppImplCocoaRendererGl; 00051 #endif 00052 // class CinderView; 00053 #elif defined( CINDER_MSW ) 00054 #include "cinder/msw/OutputDebugStringStream.h" 00055 #endif 00056 00057 #include <vector> 00058 00059 namespace cinder { namespace app { 00060 00061 class App { 00062 public: 00063 class Settings { 00064 public: 00065 // whether or not the app should terminate prior to launching 00066 bool isPrepared() const { return !mShouldQuit; }; 00067 00069 void setWindowSize( int aWindowSizeX, int aWindowSizeY ); 00070 00072 void setFrameRate( float aFrameRate ); 00073 00075 void enablePowerManagement( bool aPowerManagement = true ); 00076 00078 bool isFullScreen() const { return mFullScreen; } 00080 int getWindowWidth() const { return mWindowSizeX; } 00082 int getWindowHeight() const { return mWindowSizeY; } 00084 Vec2i getWindowSize() const { return Vec2i( mWindowSizeX, mWindowSizeY ); } 00086 Area getWindowBounds() const { return Area( 0, 0, mWindowSizeX, mWindowSizeY ); } 00088 void setTitle( const std::string &title ) { mTitle = title; } 00089 00091 float getFrameRate() const { return mFrameRate; } 00093 bool isResizable() const { return mResizable; } 00095 bool getPowerManagement() const { return mPowerManagement; } 00096 00097 protected: 00098 Settings(); 00099 virtual ~Settings() {} 00100 00101 bool mShouldQuit; // defaults to false, facilitates early termination 00102 int mWindowSizeX, mWindowSizeY; // default: 640x480 00103 bool mFullScreen; // window covers screen. default: false 00104 float mFrameRate; 00105 bool mResizable; // window is Resizable. default: true 00106 bool mPowerManagement; // allow screensavers or power management to hide app. default: false 00107 std::string mTitle; 00108 }; 00109 00110 00111 public: 00112 // interface 00113 App(); 00114 virtual ~App(); 00115 00117 virtual void setup() {} 00119 virtual void shutdown() {} 00120 00122 virtual void update() {} 00124 virtual void draw() {} 00125 00127 virtual void mouseDown( MouseEvent event ) {} 00129 virtual void mouseUp( MouseEvent event ) {} 00131 virtual void mouseWheel( MouseEvent event ) {} 00133 virtual void mouseMove( MouseEvent event ) {} 00135 virtual void mouseDrag( MouseEvent event ) {} 00137 virtual void keyDown( KeyEvent event ) {} 00139 virtual void keyUp( KeyEvent event ) {} 00141 virtual void resize( int width, int height ) {} 00143 virtual void fileDrop( FileDropEvent event ) {} 00144 00146 virtual void quit() = 0; 00147 00148 class Listener { 00149 public: 00150 virtual bool mouseDown( MouseEvent event ) { return false; } 00151 virtual bool mouseUp( MouseEvent event ) { return false; } 00152 virtual bool mouseWheel( MouseEvent event ) { return false; } 00153 virtual bool mouseMove( MouseEvent event ) { return false; } 00154 virtual bool mouseDrag( MouseEvent event ) { return false; } 00155 virtual bool keyDown( KeyEvent event ) { return false; } 00156 virtual bool keyUp( KeyEvent event ) { return false; } 00157 virtual bool resize( int width, int height ) { return false; } 00158 virtual bool fileDrop( FileDropEvent event ) { return false; } 00159 }; 00160 00162 void addListener( Listener *listener ); 00164 void removeListener( Listener *listener ); 00165 00166 // Accessors 00167 virtual const Settings& getSettings() const { return getSettings(); } 00168 Renderer* getRenderer() const { return mRenderer.get(); } 00169 00171 virtual int getWindowWidth() const = 0; 00173 virtual void setWindowWidth( int windowWidth ) = 0; 00175 virtual int getWindowHeight() const = 0; 00177 virtual void setWindowHeight( int windowHeight ) = 0; 00179 virtual void setWindowSize( int windowWidth, int windowHeight ) = 0; 00181 void setWindowSize( const Vec2i &size ) { setWindowSize( size.x, size.y ); } 00183 00184 Vec2f getWindowCenter() const { return Vec2f( (float)getWindowWidth(), (float)getWindowHeight() ) * 0.5f; } 00186 Vec2i getWindowSize() const { return Vec2i( getWindowWidth(), getWindowHeight() ); } 00188 float getWindowAspectRatio() const { return getWindowWidth() / (float)getWindowHeight(); } 00190 00191 Area getWindowBounds() const { return Area( 0, 0, getWindowWidth(), getWindowHeight() ); } 00193 virtual float getFrameRate() const = 0; 00195 virtual void setFrameRate( float aFrameRate ) = 0; 00197 float getAverageFps() const { return mAverageFps; } 00199 double getFpsSampleInterval() const { return mFpsSampleInterval; } 00201 void setFpsSampleInterval( double sampleInterval ) { mFpsSampleInterval = sampleInterval; } 00202 00204 virtual bool isFullScreen() const = 0; 00206 virtual void setFullScreen( bool aFullScreen ) = 0; 00207 00209 double getElapsedSeconds() const { return mTimer.getSeconds(); } 00211 uint32_t getElapsedFrames() const { return mFrameCount; } 00212 00213 // utilities 00214 static DataSourceRef loadResource( const std::string &macPath, int mswID, const std::string &mswType ); 00215 #if defined( CINDER_COCOA ) 00216 static DataSourcePathRef loadResource( const std::string &macPath ); 00217 std::string getResourcePath( const std::string &rsrcRelativePath ); 00218 #else 00219 static DataSourceBufferRef loadResource( int mswID, const std::string &mswType ); 00220 #endif 00221 00223 virtual std::string getAppPath() = 0; 00225 00228 std::string getOpenFilePath( const std::string &initialPath = "", std::vector<std::string> extensions = std::vector<std::string>() ); 00230 00233 std::string getSaveFilePath( const std::string &initialPath = "", std::vector<std::string> extensions = std::vector<std::string>() ); 00234 00236 std::ostream& console(); 00237 00239 Surface copyWindowSurface(); 00241 Surface copyWindowSurface( const Area &area ); 00243 void restoreWindowContext(); 00244 00245 00246 // DO NOT CALL - should be private but aren't for esoteric reasons 00248 // Internal handlers - these are called into by AppImpl's. If you are calling one of these, you have likely strayed far off the path. 00249 void privateMouseDown__( const MouseEvent &event ); 00250 void privateMouseUp__( const MouseEvent &event ); 00251 void privateMouseWheel__( const MouseEvent &event ); 00252 void privateMouseMove__( const MouseEvent &event ); 00253 void privateMouseDrag__( const MouseEvent &event ); 00254 void privateKeyDown__( const KeyEvent &event ); 00255 void privateKeyUp__( const KeyEvent &event ); 00256 void privateFileDrop__( const FileDropEvent &event ); 00257 00258 virtual void privateSetup__(); 00259 virtual void privateResize__( int width, int height ); 00260 virtual void privateUpdate__(); 00261 virtual void privateDraw__(); 00262 virtual void privateShutdown__(); 00264 00265 #if defined( CINDER_MSW ) 00266 // Not all Windows target types receive paint events, and the AppImplMswRenderer* needs to know that. 00267 virtual bool getsWindowsPaintEvents() = 0; 00268 #endif 00269 00270 virtual bool receivesEvents() const { return true; } 00271 00273 static App* get() { return sInstance; } 00274 00275 protected: 00277 // These are called by application instantation macros and are only used in the launch process 00278 static void prepareLaunch(); 00279 static void executeLaunch( App *app, class Renderer *renderer, const char *title, int argc, char * const argv[] ); 00280 static void cleanupLaunch(); 00281 00282 virtual void launch( const char *title, int argc, char * const argv[] ) = 0; 00284 00285 private: 00286 00287 #if defined( CINDER_MSW ) 00288 friend class AppImplMsw; 00289 shared_ptr<cinder::msw::dostream> mOutputStream; 00290 #else 00291 static void *sAutoReleasePool; 00292 #endif 00293 00294 Timer mTimer; 00295 uint32_t mFrameCount; 00296 float mAverageFps; 00297 uint32_t mFpsLastSampleFrame; 00298 double mFpsLastSampleTime; 00299 double mFpsSampleInterval; 00300 00301 shared_ptr<Renderer> mRenderer; 00302 std::vector<Listener*> mListeners; 00303 00304 static App* sInstance; 00305 }; 00306 00311 00312 inline int getWindowWidth() { return App::get()->getWindowWidth(); } 00314 inline void setWindowWidth( int windowWidth ) { App::get()->setWindowWidth( windowWidth ); } 00316 inline int getWindowHeight() { return App::get()->getWindowHeight(); } 00318 inline void setWindowHeight( int windowHeight ) { App::get()->setWindowHeight( windowHeight ); } 00320 inline void setWindowSize( int windowWidth, int windowHeight ) { App::get()->setWindowSize( windowWidth, windowHeight ); } 00322 00323 inline Vec2f getWindowCenter() { return App::get()->getWindowCenter(); } 00325 inline Vec2i getWindowSize() { return App::get()->getWindowSize(); } 00327 inline float getWindowAspectRatio() { return App::get()->getWindowAspectRatio(); } 00329 00330 inline Area getWindowBounds() { return App::get()->getWindowBounds(); } 00332 inline float getFrameRate() { return App::get()->getFrameRate(); } 00334 inline void setFrameRate( float frameRate ) { App::get()->setFrameRate( frameRate ); } 00336 inline bool isFullScreen() { return App::get()->isFullScreen(); } 00338 inline void setFullScreen( bool fullScreen = true ) { App::get()->setFullScreen( fullScreen ); } 00339 00341 inline double getElapsedSeconds() { return App::get()->getElapsedSeconds(); } 00343 inline uint32_t getElapsedFrames() { return App::get()->getElapsedFrames(); } 00344 00345 inline DataSourceRef loadResource( const std::string &macPath, int mswID, const std::string &mswType ) { return App::get()->loadResource( macPath, mswID, mswType ); } 00346 #if defined( CINDER_COCOA ) 00347 inline DataSourcePathRef loadResource( const std::string &macPath ) { return App::get()->loadResource( macPath ); } 00348 inline std::string getResourcePath( const std::string &rsrcRelativePath ) { return App::get()->getResourcePath( rsrcRelativePath ); } 00349 #else 00350 inline DataSourceBufferRef loadResource( int mswID, const std::string &mswType ) { return App::get()->loadResource( mswID, mswType ); } 00351 #endif 00352 00354 inline std::string getAppPath() { return App::get()->getAppPath(); } 00356 00359 inline std::string getOpenFilePath( const std::string &initialPath = "", std::vector<std::string> extensions = std::vector<std::string>() ) { return App::get()->getOpenFilePath( initialPath, extensions ); } 00361 00364 inline std::string getSaveFilePath( const std::string &initialPath = "", std::vector<std::string> extensions = std::vector<std::string>() ) { return App::get()->getSaveFilePath( initialPath, extensions ); } 00365 00367 00370 inline std::ostream& console() { return App::get()->console(); } 00371 00373 inline Surface copyWindowSurface() { return App::get()->copyWindowSurface(); } 00375 inline Surface copyWindowSurface( const Area &area ) { return App::get()->copyWindowSurface( area ); } 00377 inline void restoreWindowContext() { return App::get()->restoreWindowContext(); } 00378 00379 #if defined( CINDER_COCOA ) 00380 00381 inline ::CGContextRef createWindowCgContext() { return ((Renderer2d*)(App::get()->getRenderer()))->getCgContext(); } 00382 #endif 00383 00385 00386 } } // namespace cinder::app