| @@ -608,7 +608,7 @@ private: | |||
| stopTimer(); | |||
| delete this; | |||
| if (JUCEApplication::getInstance() != nullptr) | |||
| if (JUCEApplicationBase::getInstance() != nullptr) | |||
| getApp().closeModalCompsAndQuit(); | |||
| } | |||
| @@ -369,7 +369,7 @@ void MainWindowList::closeWindow (MainWindow* w) | |||
| #if ! JUCE_MAC | |||
| if (windows.size() == 1) | |||
| { | |||
| JUCEApplication::getInstance()->systemRequestedQuit(); | |||
| JUCEApplicationBase::getInstance()->systemRequestedQuit(); | |||
| } | |||
| else | |||
| #endif | |||
| @@ -331,7 +331,7 @@ void GeneratedCode::applyToCode (String& code, | |||
| headerGuard << String::toHexString ((className + "xx" + fileNameRoot).hashCode64()).toUpperCase() << "__"; | |||
| replaceTemplate (code, "headerGuard", headerGuard); | |||
| replaceTemplate (code, "version", JUCEApplication::getInstance()->getApplicationVersion()); | |||
| replaceTemplate (code, "version", JUCEApplicationBase::getInstance()->getApplicationVersion()); | |||
| replaceTemplate (code, "creationTime", Time::getCurrentTime().toString (true, true, true)); | |||
| replaceTemplate (code, "className", className); | |||
| @@ -75,7 +75,7 @@ public: | |||
| if (mainWindow != nullptr) | |||
| mainWindow->tryToQuitApplication(); | |||
| else | |||
| JUCEApplication::quit(); | |||
| JUCEApplicationBase::quit(); | |||
| } | |||
| const String getApplicationName() { return "Juce Plug-In Host"; } | |||
| @@ -31,7 +31,7 @@ extern AudioProcessor* JUCE_CALLTYPE createPluginFilter(); | |||
| /** | |||
| A class that can be used to run a simple standalone application containing your filter. | |||
| Just create one of these objects in your JUCEApplication::initialise() method, and | |||
| Just create one of these objects in your JUCEApplicationBase::initialise() method, and | |||
| let it do its work. It will create your filter object using the same createFilter() function | |||
| that the other plugin wrappers use. | |||
| */ | |||
| @@ -63,7 +63,7 @@ public: | |||
| if (filter == nullptr) | |||
| { | |||
| jassertfalse // Your filter didn't create correctly! In a standalone app that's not too great. | |||
| JUCEApplication::quit(); | |||
| JUCEApplicationBase::quit(); | |||
| } | |||
| filter->setPlayConfigDetails (JucePlugin_MaxNumInputChannels, | |||
| @@ -243,7 +243,7 @@ public: | |||
| /** @internal */ | |||
| void closeButtonPressed() override | |||
| { | |||
| JUCEApplication::quit(); | |||
| JUCEApplicationBase::quit(); | |||
| } | |||
| /** @internal */ | |||
| @@ -232,7 +232,7 @@ public: | |||
| ~SharedMessageThread() | |||
| { | |||
| signalThreadShouldExit(); | |||
| JUCEApplication::quit(); | |||
| JUCEApplicationBase::quit(); | |||
| waitForThreadToExit (5000); | |||
| clearSingletonInstance(); | |||
| } | |||
| @@ -1375,7 +1375,7 @@ public: | |||
| { | |||
| String hostName ("Juce VST Host"); | |||
| if (JUCEApplication* app = JUCEApplication::getInstance()) | |||
| if (JUCEApplicationBase* app = JUCEApplicationBase::getInstance()) | |||
| hostName = app->getApplicationName(); | |||
| hostName.copyToUTF8 ((char*) ptr, (size_t) jmin (kVstMaxVendorStrLen, kVstMaxProductStrLen) - 1); | |||
| @@ -119,7 +119,7 @@ | |||
| /* Config: JUCE_CATCH_UNHANDLED_EXCEPTIONS | |||
| If enabled, this will add some exception-catching code to forward unhandled exceptions | |||
| to your JUCEApplication::unhandledException() callback. | |||
| to your JUCEApplicationBase::unhandledException() callback. | |||
| */ | |||
| #ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS | |||
| //#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1 | |||
| @@ -222,17 +222,17 @@ namespace juce | |||
| #if ! JUCE_MODULE_AVAILABLE_juce_gui_basics | |||
| #define JUCE_CATCH_EXCEPTION JUCE_CATCH_ALL | |||
| #else | |||
| /** Used in try-catch blocks, this macro will send exceptions to the JUCEApplication | |||
| /** Used in try-catch blocks, this macro will send exceptions to the JUCEApplicationBase | |||
| object so they can be logged by the application if it wants to. | |||
| */ | |||
| #define JUCE_CATCH_EXCEPTION \ | |||
| catch (const std::exception& e) \ | |||
| { \ | |||
| juce::JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__); \ | |||
| juce::JUCEApplicationBase::sendUnhandledException (&e, __FILE__, __LINE__); \ | |||
| } \ | |||
| catch (...) \ | |||
| { \ | |||
| juce::JUCEApplication::sendUnhandledException (nullptr, __FILE__, __LINE__); \ | |||
| juce::JUCEApplicationBase::sendUnhandledException (nullptr, __FILE__, __LINE__); \ | |||
| } | |||
| #endif | |||
| @@ -36,7 +36,7 @@ | |||
| This contains methods for controlling the current application at the | |||
| process-level. | |||
| @see Thread, JUCEApplication | |||
| @see Thread, JUCEApplicationBase | |||
| */ | |||
| class JUCE_API Process | |||
| { | |||
| @@ -63,7 +63,7 @@ public: | |||
| immediately - it's intended only for use only when something goes | |||
| horribly wrong. | |||
| @see JUCEApplication::quit | |||
| @see JUCEApplicationBase::quit | |||
| */ | |||
| static void JUCE_CALLTYPE terminate(); | |||
| @@ -38,6 +38,7 @@ namespace juce | |||
| #include "messages/juce_DeletedAtShutdown.h" | |||
| #include "messages/juce_NotificationType.h" | |||
| #include "messages/juce_ApplicationBase.h" | |||
| #include "messages/juce_Initialisation.h" | |||
| #include "broadcasters/juce_ListenerList.h" | |||
| #include "broadcasters/juce_ActionBroadcaster.h" | |||
| #include "broadcasters/juce_ActionListener.h" | |||
| @@ -26,6 +26,8 @@ JUCEApplicationBase::CreateInstanceFunction JUCEApplicationBase::createInstance | |||
| JUCEApplicationBase* JUCEApplicationBase::appInstance = nullptr; | |||
| JUCEApplicationBase::JUCEApplicationBase() | |||
| : appReturnValue (0), | |||
| stillInitialising (true) | |||
| { | |||
| jassert (isStandaloneApp() && appInstance == nullptr); | |||
| appInstance = this; | |||
| @@ -37,6 +39,11 @@ JUCEApplicationBase::~JUCEApplicationBase() | |||
| appInstance = nullptr; | |||
| } | |||
| void JUCEApplicationBase::setApplicationReturnValue (const int newReturnValue) noexcept | |||
| { | |||
| appReturnValue = newReturnValue; | |||
| } | |||
| // This is called on the Mac and iOS where the OS doesn't allow the stack to unwind on shutdown.. | |||
| void JUCEApplicationBase::appWillTerminateByForce() | |||
| { | |||
| @@ -53,3 +60,230 @@ void JUCEApplicationBase::appWillTerminateByForce() | |||
| MessageManager::deleteInstance(); | |||
| } | |||
| } | |||
| void JUCEApplicationBase::quit() | |||
| { | |||
| MessageManager::getInstance()->stopDispatchLoop(); | |||
| } | |||
| void JUCEApplicationBase::sendUnhandledException (const std::exception* const e, | |||
| const char* const sourceFile, | |||
| const int lineNumber) | |||
| { | |||
| if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) | |||
| app->unhandledException (e, sourceFile, lineNumber); | |||
| } | |||
| //============================================================================== | |||
| #if ! (JUCE_IOS || JUCE_ANDROID) | |||
| #define JUCE_HANDLE_MULTIPLE_INSTANCES 1 | |||
| #endif | |||
| #if JUCE_HANDLE_MULTIPLE_INSTANCES | |||
| struct JUCEApplicationBase::MultipleInstanceHandler : public ActionListener | |||
| { | |||
| public: | |||
| MultipleInstanceHandler (const String& appName) | |||
| : appLock ("juceAppLock_" + appName) | |||
| { | |||
| } | |||
| bool sendCommandLineToPreexistingInstance() | |||
| { | |||
| if (appLock.enter (0)) | |||
| return false; | |||
| JUCEApplicationBase* const app = JUCEApplicationBase::getInstance(); | |||
| jassert (app != nullptr); | |||
| MessageManager::broadcastMessage (app->getApplicationName() | |||
| + "/" + app->getCommandLineParameters()); | |||
| return true; | |||
| } | |||
| void actionListenerCallback (const String& message) override | |||
| { | |||
| if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) | |||
| { | |||
| const String appName (app->getApplicationName()); | |||
| if (message.startsWith (appName + "/")) | |||
| app->anotherInstanceStarted (message.substring (appName.length() + 1)); | |||
| } | |||
| } | |||
| private: | |||
| InterProcessLock appLock; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultipleInstanceHandler) | |||
| }; | |||
| bool JUCEApplicationBase::sendCommandLineToPreexistingInstance() | |||
| { | |||
| jassert (multipleInstanceHandler == nullptr); // this must only be called once! | |||
| multipleInstanceHandler = new MultipleInstanceHandler (getApplicationName()); | |||
| return multipleInstanceHandler->sendCommandLineToPreexistingInstance(); | |||
| } | |||
| #else | |||
| struct JUCEApplicationBase::MultipleInstanceHandler {}; | |||
| #endif | |||
| //============================================================================== | |||
| #if JUCE_ANDROID | |||
| StringArray JUCEApplicationBase::getCommandLineParameterArray() { return StringArray(); } | |||
| String JUCEApplicationBase::getCommandLineParameters() { return String::empty; } | |||
| #else | |||
| #if JUCE_WINDOWS | |||
| String JUCE_CALLTYPE JUCEApplicationBase::getCommandLineParameters() | |||
| { | |||
| return CharacterFunctions::findEndOfToken (CharPointer_UTF16 (GetCommandLineW()), | |||
| CharPointer_UTF16 (L" "), | |||
| CharPointer_UTF16 (L"\"")).findEndOfWhitespace(); | |||
| } | |||
| StringArray JUCE_CALLTYPE JUCEApplicationBase::getCommandLineParameterArray() | |||
| { | |||
| StringArray s; | |||
| int argc = 0; | |||
| if (LPWSTR* const argv = CommandLineToArgvW (GetCommandLineW(), &argc)) | |||
| { | |||
| s = StringArray (argv + 1, argc - 1); | |||
| LocalFree (argv); | |||
| } | |||
| return s; | |||
| } | |||
| #else | |||
| #if JUCE_IOS | |||
| extern int juce_iOSMain (int argc, const char* argv[]); | |||
| #endif | |||
| #if JUCE_MAC | |||
| extern void initialiseNSApplication(); | |||
| #endif | |||
| extern const char* const* juce_argv; // declared in juce_core | |||
| extern int juce_argc; | |||
| String JUCEApplicationBase::getCommandLineParameters() | |||
| { | |||
| String argString; | |||
| for (int i = 1; i < juce_argc; ++i) | |||
| { | |||
| String arg (juce_argv[i]); | |||
| if (arg.containsChar (' ') && ! arg.isQuotedString()) | |||
| arg = arg.quoted ('"'); | |||
| argString << arg << ' '; | |||
| } | |||
| return argString.trim(); | |||
| } | |||
| StringArray JUCEApplicationBase::getCommandLineParameterArray() | |||
| { | |||
| return StringArray (juce_argv + 1, juce_argc - 1); | |||
| } | |||
| int JUCEApplicationBase::main (int argc, const char* argv[]) | |||
| { | |||
| JUCE_AUTORELEASEPOOL | |||
| { | |||
| juce_argc = argc; | |||
| juce_argv = argv; | |||
| #if JUCE_MAC | |||
| initialiseNSApplication(); | |||
| #endif | |||
| #if JUCE_IOS | |||
| return juce_iOSMain (argc, argv); | |||
| #else | |||
| return JUCEApplicationBase::main(); | |||
| #endif | |||
| } | |||
| } | |||
| #endif | |||
| //============================================================================== | |||
| int JUCEApplicationBase::main() | |||
| { | |||
| ScopedJuceInitialiser_GUI libraryInitialiser; | |||
| jassert (createInstance != nullptr); | |||
| const ScopedPointer<JUCEApplicationBase> app (createInstance()); | |||
| jassert (app != nullptr); | |||
| if (! app->initialiseApp()) | |||
| return 0; | |||
| JUCE_TRY | |||
| { | |||
| // loop until a quit message is received.. | |||
| MessageManager::getInstance()->runDispatchLoop(); | |||
| } | |||
| JUCE_CATCH_EXCEPTION | |||
| return app->shutdownApp(); | |||
| } | |||
| #endif | |||
| //============================================================================== | |||
| bool JUCEApplicationBase::initialiseApp() | |||
| { | |||
| #if JUCE_HANDLE_MULTIPLE_INSTANCES | |||
| if ((! moreThanOneInstanceAllowed()) && sendCommandLineToPreexistingInstance()) | |||
| { | |||
| DBG ("Another instance is running - quitting..."); | |||
| return false; | |||
| } | |||
| #endif | |||
| // let the app do its setting-up.. | |||
| initialise (getCommandLineParameters()); | |||
| stillInitialising = false; | |||
| if (MessageManager::getInstance()->hasStopMessageBeenSent()) | |||
| return false; | |||
| #if JUCE_HANDLE_MULTIPLE_INSTANCES | |||
| if (multipleInstanceHandler != nullptr) | |||
| MessageManager::getInstance()->registerBroadcastListener (multipleInstanceHandler); | |||
| #endif | |||
| return true; | |||
| } | |||
| int JUCEApplicationBase::shutdownApp() | |||
| { | |||
| jassert (JUCEApplicationBase::getInstance() == this); | |||
| #if JUCE_HANDLE_MULTIPLE_INSTANCES | |||
| if (multipleInstanceHandler != nullptr) | |||
| MessageManager::getInstance()->deregisterBroadcastListener (multipleInstanceHandler); | |||
| #endif | |||
| JUCE_TRY | |||
| { | |||
| // give the app a chance to clean up.. | |||
| shutdown(); | |||
| } | |||
| JUCE_CATCH_EXCEPTION | |||
| multipleInstanceHandler = nullptr; | |||
| return getApplicationReturnValue(); | |||
| } | |||
| @@ -30,11 +30,57 @@ | |||
| /** | |||
| Abstract base class for application classes. | |||
| This class shouldn't be used directly - you'll normally use JUCEApplication as | |||
| the base for your app, and that inherits from this, adding some more functionality | |||
| to it. | |||
| @see JUCEApplication | |||
| Note that in the juce_gui_basics module, there's a utility class JUCEApplication | |||
| which derives from JUCEApplicationBase, and takes care of a few chores. Most | |||
| of the time you'll want to derive your class from JUCEApplication rather than | |||
| using JUCEApplicationBase directly, but if you're not using the juce_gui_basics | |||
| module then you might need to go straight to this base class. | |||
| Any application that wants to run an event loop must declare a subclass of | |||
| JUCEApplicationBase, and implement its various pure virtual methods. | |||
| It then needs to use the START_JUCE_APPLICATION macro somewhere in a CPP file | |||
| to declare an instance of this class and generate suitable platform-specific | |||
| boilerplate code to launch the app. | |||
| e.g. @code | |||
| class MyJUCEApp : public JUCEApplication | |||
| { | |||
| public: | |||
| MyJUCEApp() {} | |||
| ~MyJUCEApp() {} | |||
| void initialise (const String& commandLine) | |||
| { | |||
| myMainWindow = new MyApplicationWindow(); | |||
| myMainWindow->setBounds (100, 100, 400, 500); | |||
| myMainWindow->setVisible (true); | |||
| } | |||
| void shutdown() | |||
| { | |||
| myMainWindow = nullptr; | |||
| } | |||
| const String getApplicationName() | |||
| { | |||
| return "Super JUCE-o-matic"; | |||
| } | |||
| const String getApplicationVersion() | |||
| { | |||
| return "1.0"; | |||
| } | |||
| private: | |||
| ScopedPointer<MyApplicationWindow> myMainWindow; | |||
| }; | |||
| // this generates boilerplate code to launch our app class: | |||
| START_JUCE_APPLICATION (MyJUCEApp) | |||
| @endcode | |||
| @see JUCEApplication, START_JUCE_APPLICATION | |||
| */ | |||
| class JUCE_API JUCEApplicationBase | |||
| { | |||
| @@ -51,13 +97,10 @@ public: | |||
| static JUCEApplicationBase* getInstance() noexcept { return appInstance; } | |||
| //============================================================================== | |||
| /** Returns the application's name. | |||
| An application must implement this to name itself. | |||
| */ | |||
| /** Returns the application's name. */ | |||
| virtual const String getApplicationName() = 0; | |||
| /** Returns the application's version number. | |||
| */ | |||
| /** Returns the application's version number. */ | |||
| virtual const String getApplicationVersion() = 0; | |||
| /** Checks whether multiple instances of the app are allowed. | |||
| @@ -148,24 +191,90 @@ public: | |||
| const String& sourceFilename, | |||
| int lineNumber) = 0; | |||
| //============================================================================== | |||
| /** Signals that the main message loop should stop and the application should terminate. | |||
| This isn't synchronous, it just posts a quit message to the main queue, and | |||
| when this message arrives, the message loop will stop, the shutdown() method | |||
| will be called, and the app will exit. | |||
| Note that this will cause an unconditional quit to happen, so if you need an | |||
| extra level before this, e.g. to give the user the chance to save their work | |||
| and maybe cancel the quit, you'll need to handle this in the systemRequestedQuit() | |||
| method - see that method's help for more info. | |||
| @see MessageManager | |||
| */ | |||
| static void quit(); | |||
| //============================================================================== | |||
| /** Returns the application's command line parameters as a set of strings. | |||
| @see getCommandLineParameters | |||
| */ | |||
| static StringArray JUCE_CALLTYPE getCommandLineParameterArray(); | |||
| /** Returns the application's command line parameters as a single string. | |||
| @see getCommandLineParameterArray | |||
| */ | |||
| static String JUCE_CALLTYPE getCommandLineParameters(); | |||
| //============================================================================== | |||
| /** Sets the value that should be returned as the application's exit code when the | |||
| app quits. | |||
| This is the value that's returned by the main() function. Normally you'd leave this | |||
| as 0 unless you want to indicate an error code. | |||
| @see getApplicationReturnValue | |||
| */ | |||
| void setApplicationReturnValue (int newReturnValue) noexcept; | |||
| /** Returns the value that has been set as the application's exit code. | |||
| @see setApplicationReturnValue | |||
| */ | |||
| int getApplicationReturnValue() const noexcept { return appReturnValue; } | |||
| //============================================================================== | |||
| /** Returns true if this executable is running as an app (as opposed to being a plugin | |||
| or other kind of shared library. */ | |||
| static inline bool isStandaloneApp() noexcept { return createInstance != nullptr; } | |||
| static bool isStandaloneApp() noexcept { return createInstance != nullptr; } | |||
| /** Returns true if the application hasn't yet completed its initialise() method | |||
| and entered the main event loop. | |||
| This is handy for things like splash screens to know when the app's up-and-running | |||
| properly. | |||
| */ | |||
| bool isInitialising() const noexcept { return stillInitialising; } | |||
| //============================================================================== | |||
| #ifndef DOXYGEN | |||
| // The following methods are for internal use only... | |||
| static int main(); | |||
| static int main (int argc, const char* argv[]); | |||
| static void appWillTerminateByForce(); | |||
| typedef JUCEApplicationBase* (*CreateInstanceFunction)(); | |||
| static CreateInstanceFunction createInstance; | |||
| protected: | |||
| virtual int shutdownApp() = 0; | |||
| virtual bool initialiseApp(); | |||
| static void JUCE_CALLTYPE sendUnhandledException (const std::exception*, const char* sourceFile, int lineNumber); | |||
| bool sendCommandLineToPreexistingInstance(); | |||
| #endif | |||
| private: | |||
| //============================================================================== | |||
| static JUCEApplicationBase* appInstance; | |||
| int appReturnValue; | |||
| bool stillInitialising; | |||
| struct MultipleInstanceHandler; | |||
| friend struct MultipleInstanceHandler; | |||
| friend struct ContainerDeletePolicy<MultipleInstanceHandler>; | |||
| ScopedPointer<MultipleInstanceHandler> multipleInstanceHandler; | |||
| int shutdownApp(); | |||
| JUCE_DECLARE_NON_COPYABLE (JUCEApplicationBase) | |||
| }; | |||
| @@ -30,7 +30,7 @@ | |||
| /** | |||
| Classes derived from this will be automatically deleted when the application exits. | |||
| After JUCEApplication::shutdown() has been called, any objects derived from | |||
| After JUCEApplicationBase::shutdown() has been called, any objects derived from | |||
| DeletedAtShutdown which are still in existence will be deleted in the reverse | |||
| order to that in which they were created. | |||
| @@ -55,7 +55,7 @@ public: | |||
| /** Deletes all extant objects. | |||
| This shouldn't be used by applications, as it's called automatically | |||
| in the shutdown code of the JUCEApplication class. | |||
| in the shutdown code of the JUCEApplicationBase class. | |||
| */ | |||
| static void deleteAll(); | |||
| @@ -63,28 +63,29 @@ JUCE_API void JUCE_CALLTYPE shutdownJuce_GUI(); | |||
| main() function, because it'll take care of shutting down whenever you return | |||
| from the main() call. | |||
| */ | |||
| class ScopedJuceInitialiser_GUI | |||
| class JUCE_API ScopedJuceInitialiser_GUI | |||
| { | |||
| public: | |||
| /** The constructor simply calls initialiseJuce_GUI(). */ | |||
| ScopedJuceInitialiser_GUI() { initialiseJuce_GUI(); } | |||
| ScopedJuceInitialiser_GUI(); | |||
| /** The destructor simply calls shutdownJuce_GUI(). */ | |||
| ~ScopedJuceInitialiser_GUI() { shutdownJuce_GUI(); } | |||
| ~ScopedJuceInitialiser_GUI(); | |||
| }; | |||
| //============================================================================== | |||
| /* | |||
| /** | |||
| To start a JUCE app, use this macro: START_JUCE_APPLICATION (AppSubClass) where | |||
| AppSubClass is the name of a class derived from JUCEApplication. | |||
| See the JUCEApplication class documentation (juce_Application.h) for more details. | |||
| AppSubClass is the name of a class derived from JUCEApplication or JUCEApplicationBase. | |||
| See the JUCEApplication and JUCEApplicationBase class documentation for more details. | |||
| */ | |||
| #if JUCE_ANDROID | |||
| #ifdef DOXYGEN | |||
| #define START_JUCE_APPLICATION(AppClass) | |||
| #elif JUCE_ANDROID | |||
| #define START_JUCE_APPLICATION(AppClass) \ | |||
| juce::JUCEApplication* juce_CreateApplication() { return new AppClass(); } | |||
| juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); } | |||
| #else | |||
| #if JUCE_WINDOWS | |||
| @@ -105,8 +106,8 @@ public: | |||
| static juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); } \ | |||
| extern "C" JUCE_MAIN_FUNCTION \ | |||
| { \ | |||
| juce::JUCEApplication::createInstance = &juce_CreateApplication; \ | |||
| return juce::JUCEApplication::main (JUCE_MAIN_FUNCTION_ARGS); \ | |||
| juce::JUCEApplicationBase::createInstance = &juce_CreateApplication; \ | |||
| return juce::JUCEApplicationBase::main (JUCE_MAIN_FUNCTION_ARGS); \ | |||
| } | |||
| #endif | |||
| @@ -334,3 +334,6 @@ JUCE_API void JUCE_CALLTYPE shutdownJuce_GUI() | |||
| MessageManager::deleteInstance(); | |||
| } | |||
| } | |||
| ScopedJuceInitialiser_GUI::ScopedJuceInitialiser_GUI() { initialiseJuce_GUI(); } | |||
| ScopedJuceInitialiser_GUI::~ScopedJuceInitialiser_GUI() { shutdownJuce_GUI(); } | |||
| @@ -41,7 +41,7 @@ typedef void* (MessageCallbackFunction) (void* userData); | |||
| /** | |||
| This class is in charge of the application's event-dispatch loop. | |||
| @see Message, CallbackMessage, MessageManagerLock, JUCEApplication | |||
| @see Message, CallbackMessage, MessageManagerLock, JUCEApplication, JUCEApplicationBase | |||
| */ | |||
| class JUCE_API MessageManager | |||
| { | |||
| @@ -22,104 +22,29 @@ | |||
| ============================================================================== | |||
| */ | |||
| #if JUCE_MAC | |||
| extern void juce_initialiseMacMainMenu(); | |||
| #endif | |||
| #if ! (JUCE_IOS || JUCE_ANDROID) | |||
| #define JUCE_HANDLE_MULTIPLE_INSTANCES 1 | |||
| #endif | |||
| JUCEApplication::JUCEApplication() {} | |||
| JUCEApplication::~JUCEApplication() {} | |||
| //============================================================================== | |||
| #if JUCE_HANDLE_MULTIPLE_INSTANCES | |||
| struct JUCEApplication::MultipleInstanceHandler : public ActionListener | |||
| { | |||
| public: | |||
| MultipleInstanceHandler (const String& appName) | |||
| : appLock ("juceAppLock_" + appName) | |||
| { | |||
| } | |||
| bool sendCommandLineToPreexistingInstance() | |||
| { | |||
| if (appLock.enter (0)) | |||
| return false; | |||
| JUCEApplication* const app = JUCEApplication::getInstance(); | |||
| jassert (app != nullptr); | |||
| MessageManager::broadcastMessage (app->getApplicationName() | |||
| + "/" + app->getCommandLineParameters()); | |||
| return true; | |||
| } | |||
| void actionListenerCallback (const String& message) override | |||
| { | |||
| if (JUCEApplication* const app = JUCEApplication::getInstance()) | |||
| { | |||
| const String appName (app->getApplicationName()); | |||
| if (message.startsWith (appName + "/")) | |||
| app->anotherInstanceStarted (message.substring (appName.length() + 1)); | |||
| } | |||
| } | |||
| private: | |||
| InterProcessLock appLock; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultipleInstanceHandler) | |||
| }; | |||
| #else | |||
| struct JUCEApplication::MultipleInstanceHandler {}; | |||
| #endif | |||
| //============================================================================== | |||
| JUCEApplication::JUCEApplication() | |||
| : appReturnValue (0), | |||
| stillInitialising (true) | |||
| { | |||
| } | |||
| JUCEApplication::~JUCEApplication() | |||
| JUCEApplication* JUCE_CALLTYPE JUCEApplication::getInstance() noexcept | |||
| { | |||
| return dynamic_cast <JUCEApplication*> (JUCEApplicationBase::getInstance()); | |||
| } | |||
| //============================================================================== | |||
| bool JUCEApplication::moreThanOneInstanceAllowed() { return true; } | |||
| void JUCEApplication::anotherInstanceStarted (const String&) {} | |||
| void JUCEApplication::suspended() {} | |||
| void JUCEApplication::resumed() {} | |||
| void JUCEApplication::systemRequestedQuit() | |||
| { | |||
| quit(); | |||
| } | |||
| void JUCEApplication::quit() | |||
| { | |||
| MessageManager::getInstance()->stopDispatchLoop(); | |||
| } | |||
| void JUCEApplication::setApplicationReturnValue (const int newReturnValue) noexcept | |||
| { | |||
| appReturnValue = newReturnValue; | |||
| } | |||
| void JUCEApplication::systemRequestedQuit() { quit(); } | |||
| //============================================================================== | |||
| void JUCEApplication::unhandledException (const std::exception*, const String&, int) | |||
| { | |||
| jassertfalse; | |||
| } | |||
| void JUCEApplication::sendUnhandledException (const std::exception* const e, | |||
| const char* const sourceFile, | |||
| const int lineNumber) | |||
| { | |||
| if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) | |||
| app->unhandledException (e, sourceFile, lineNumber); | |||
| } | |||
| //============================================================================== | |||
| ApplicationCommandTarget* JUCEApplication::getNextCommandTarget() | |||
| { | |||
| @@ -137,8 +62,7 @@ void JUCEApplication::getCommandInfo (const CommandID commandID, ApplicationComm | |||
| { | |||
| result.setInfo (TRANS("Quit"), | |||
| TRANS("Quits the application"), | |||
| "Application", | |||
| 0); | |||
| "Application", 0); | |||
| result.defaultKeypresses.add (KeyPress ('q', ModifierKeys::commandModifier, 0)); | |||
| } | |||
| @@ -155,148 +79,21 @@ bool JUCEApplication::perform (const InvocationInfo& info) | |||
| return false; | |||
| } | |||
| #if JUCE_HANDLE_MULTIPLE_INSTANCES | |||
| bool JUCEApplication::sendCommandLineToPreexistingInstance() | |||
| { | |||
| jassert (multipleInstanceHandler == nullptr); // this must only be called once! | |||
| multipleInstanceHandler = new MultipleInstanceHandler (getApplicationName()); | |||
| return multipleInstanceHandler->sendCommandLineToPreexistingInstance(); | |||
| } | |||
| //============================================================================== | |||
| #if JUCE_MAC | |||
| extern void juce_initialiseMacMainMenu(); | |||
| #endif | |||
| //============================================================================== | |||
| bool JUCEApplication::initialiseApp() | |||
| { | |||
| #if JUCE_HANDLE_MULTIPLE_INSTANCES | |||
| if ((! moreThanOneInstanceAllowed()) && sendCommandLineToPreexistingInstance()) | |||
| { | |||
| DBG ("Another instance is running - quitting..."); | |||
| return false; | |||
| } | |||
| #endif | |||
| // let the app do its setting-up.. | |||
| initialise (getCommandLineParameters()); | |||
| stillInitialising = false; | |||
| if (! MessageManager::getInstance()->hasStopMessageBeenSent()) | |||
| if (JUCEApplicationBase::initialiseApp()) | |||
| { | |||
| #if JUCE_MAC | |||
| juce_initialiseMacMainMenu(); // (needs to get the app's name) | |||
| #endif | |||
| #if JUCE_HANDLE_MULTIPLE_INSTANCES | |||
| if (multipleInstanceHandler != nullptr) | |||
| MessageManager::getInstance()->registerBroadcastListener (multipleInstanceHandler); | |||
| #endif | |||
| } | |||
| return true; | |||
| } | |||
| int JUCEApplication::shutdownApp() | |||
| { | |||
| jassert (JUCEApplicationBase::getInstance() == this); | |||
| #if JUCE_HANDLE_MULTIPLE_INSTANCES | |||
| if (multipleInstanceHandler != nullptr) | |||
| MessageManager::getInstance()->deregisterBroadcastListener (multipleInstanceHandler); | |||
| #endif | |||
| JUCE_TRY | |||
| { | |||
| // give the app a chance to clean up.. | |||
| shutdown(); | |||
| } | |||
| JUCE_CATCH_EXCEPTION | |||
| multipleInstanceHandler = nullptr; | |||
| return getApplicationReturnValue(); | |||
| } | |||
| //============================================================================== | |||
| #if JUCE_ANDROID | |||
| StringArray JUCEApplication::getCommandLineParameterArray() { return StringArray(); } | |||
| String JUCEApplication::getCommandLineParameters() { return String::empty; } | |||
| #else | |||
| int JUCEApplication::main() | |||
| { | |||
| ScopedJuceInitialiser_GUI libraryInitialiser; | |||
| jassert (createInstance != nullptr); | |||
| const ScopedPointer<JUCEApplication> app (dynamic_cast <JUCEApplication*> (createInstance())); | |||
| jassert (app != nullptr); | |||
| if (! app->initialiseApp()) | |||
| return 0; | |||
| JUCE_TRY | |||
| { | |||
| // loop until a quit message is received.. | |||
| MessageManager::getInstance()->runDispatchLoop(); | |||
| } | |||
| JUCE_CATCH_EXCEPTION | |||
| return app->shutdownApp(); | |||
| } | |||
| #if ! JUCE_WINDOWS | |||
| #if JUCE_IOS | |||
| extern int juce_iOSMain (int argc, const char* argv[]); | |||
| #endif | |||
| #if JUCE_MAC | |||
| extern void initialiseNSApplication(); | |||
| #endif | |||
| extern const char* const* juce_argv; // declared in juce_core | |||
| extern int juce_argc; | |||
| StringArray JUCEApplication::getCommandLineParameterArray() | |||
| { | |||
| return StringArray (juce_argv + 1, juce_argc - 1); | |||
| } | |||
| String JUCEApplication::getCommandLineParameters() | |||
| { | |||
| String argString; | |||
| for (int i = 1; i < juce_argc; ++i) | |||
| { | |||
| String arg (juce_argv[i]); | |||
| if (arg.containsChar (' ') && ! arg.isQuotedString()) | |||
| arg = arg.quoted ('"'); | |||
| argString << arg << ' '; | |||
| return true; | |||
| } | |||
| return argString.trim(); | |||
| } | |||
| int JUCEApplication::main (int argc, const char* argv[]) | |||
| { | |||
| JUCE_AUTORELEASEPOOL | |||
| { | |||
| juce_argc = argc; | |||
| juce_argv = argv; | |||
| #if JUCE_MAC | |||
| initialiseNSApplication(); | |||
| #endif | |||
| #if JUCE_IOS | |||
| return juce_iOSMain (argc, argv); | |||
| #else | |||
| return JUCEApplication::main(); | |||
| #endif | |||
| } | |||
| return false; | |||
| } | |||
| #endif | |||
| #endif | |||
| @@ -31,24 +31,27 @@ | |||
| An instance of this class is used to specify initialisation and shutdown | |||
| code for the application. | |||
| An application that wants to run in the JUCE framework needs to declare a | |||
| subclass of JUCEApplication and implement its various pure virtual methods. | |||
| Any application that wants to run an event loop must declare a subclass of | |||
| JUCEApplicationBase or JUCEApplication, and implement its various pure virtual | |||
| methods. | |||
| It then needs to use the START_JUCE_APPLICATION macro somewhere in a cpp file | |||
| to declare an instance of this class and generate a suitable platform-specific | |||
| main() function. | |||
| It then needs to use the START_JUCE_APPLICATION macro somewhere in a CPP file | |||
| to declare an instance of this class and generate suitable platform-specific | |||
| boilerplate code to launch the app. | |||
| Note that this class is derived from JUCEApplicationBase, which contains most | |||
| of the useful methods and functionality. This derived class is here simply as | |||
| a convenient way to also inherit from an ApplicationCommandTarget, and to implement | |||
| default versions of some of the pure virtual base class methods. But you can derive | |||
| your app object directly from JUCEApplicationBase if you want to, and by doing so | |||
| can avoid having a dependency on the juce_gui_basics module. | |||
| e.g. @code | |||
| class MyJUCEApp : public JUCEApplication | |||
| { | |||
| public: | |||
| MyJUCEApp() | |||
| { | |||
| } | |||
| ~MyJUCEApp() | |||
| { | |||
| } | |||
| MyJUCEApp() {} | |||
| ~MyJUCEApp() {} | |||
| void initialise (const String& commandLine) | |||
| { | |||
| @@ -59,7 +62,7 @@ | |||
| void shutdown() | |||
| { | |||
| myMainWindow = 0; | |||
| myMainWindow = nullptr; | |||
| } | |||
| const String getApplicationName() | |||
| @@ -73,19 +76,19 @@ | |||
| } | |||
| private: | |||
| ScopedPointer <MyApplicationWindow> myMainWindow; | |||
| ScopedPointer<MyApplicationWindow> myMainWindow; | |||
| }; | |||
| // this creates wrapper code to actually launch the app properly. | |||
| // this generates boilerplate code to launch our app class: | |||
| START_JUCE_APPLICATION (MyJUCEApp) | |||
| @endcode | |||
| @see MessageManager | |||
| @see JUCEApplicationBase, START_JUCE_APPLICATION | |||
| */ | |||
| class JUCE_API JUCEApplication : public JUCEApplicationBase, | |||
| public ApplicationCommandTarget | |||
| { | |||
| protected: | |||
| public: | |||
| //============================================================================== | |||
| /** Constructs a JUCE app object. | |||
| @@ -95,37 +98,23 @@ protected: | |||
| */ | |||
| JUCEApplication(); | |||
| public: | |||
| /** Destructor. | |||
| If subclasses implement a constructor or destructor, they shouldn't call any | |||
| JUCE code in there - put your startup/shutdown code in initialise() and | |||
| shutdown() instead. | |||
| */ | |||
| virtual ~JUCEApplication(); | |||
| ~JUCEApplication(); | |||
| //============================================================================== | |||
| /** Returns the global instance of the application object being run. */ | |||
| static JUCEApplication* getInstance() noexcept { return dynamic_cast <JUCEApplication*> (JUCEApplicationBase::getInstance()); } | |||
| static JUCEApplication* JUCE_CALLTYPE getInstance() noexcept; | |||
| //============================================================================== | |||
| /** Returns true if the application hasn't yet completed its initialise() method | |||
| and entered the main event loop. | |||
| This is handy for things like splash screens to know when the app's up-and-running | |||
| properly. | |||
| */ | |||
| bool isInitialising() const noexcept { return stillInitialising; } | |||
| //============================================================================== | |||
| /** Returns the application's name. | |||
| An application must implement this to name itself. | |||
| */ | |||
| /** Returns the application's name. */ | |||
| virtual const String getApplicationName() = 0; | |||
| /** Returns the application's version number. | |||
| */ | |||
| /** Returns the application's version number. */ | |||
| virtual const String getApplicationVersion() = 0; | |||
| /** Checks whether multiple instances of the app are allowed. | |||
| @@ -138,13 +127,12 @@ public: | |||
| callback to anotherInstanceStarted() to tell you about this - which | |||
| gives you a chance to react to what the user was trying to do. | |||
| */ | |||
| virtual bool moreThanOneInstanceAllowed(); | |||
| bool moreThanOneInstanceAllowed() override; | |||
| /** Indicates that the user has tried to start up another instance of the app. | |||
| This will get called even if moreThanOneInstanceAllowed() is false. | |||
| */ | |||
| virtual void anotherInstanceStarted (const String& commandLine); | |||
| void anotherInstanceStarted (const String& commandLine) override; | |||
| /** Called when the operating system is trying to close the application. | |||
| @@ -158,17 +146,17 @@ public: | |||
| in the same way as those from your own application code. So e.g. you'd | |||
| call this method from a "quit" item on a menu bar. | |||
| */ | |||
| virtual void systemRequestedQuit(); | |||
| void systemRequestedQuit() override; | |||
| /** This method is called when the application is being put into background mode | |||
| by the operating system. | |||
| */ | |||
| virtual void suspended(); | |||
| void suspended() override; | |||
| /** This method is called when the application is being woken from background mode | |||
| by the operating system. | |||
| */ | |||
| virtual void resumed(); | |||
| void resumed() override; | |||
| /** If any unhandled exceptions make it through to the message dispatch loop, this | |||
| callback will be triggered, in case you want to log them or do some other | |||
| @@ -178,54 +166,9 @@ public: | |||
| passed-in will be valid. If the exception is of unknown type, this pointer | |||
| will be null. | |||
| */ | |||
| virtual void unhandledException (const std::exception* e, | |||
| const String& sourceFilename, | |||
| int lineNumber); | |||
| //============================================================================== | |||
| /** Signals that the main message loop should stop and the application should terminate. | |||
| This isn't synchronous, it just posts a quit message to the main queue, and | |||
| when this message arrives, the message loop will stop, the shutdown() method | |||
| will be called, and the app will exit. | |||
| Note that this will cause an unconditional quit to happen, so if you need an | |||
| extra level before this, e.g. to give the user the chance to save their work | |||
| and maybe cancel the quit, you'll need to handle this in the systemRequestedQuit() | |||
| method - see that method's help for more info. | |||
| @see MessageManager | |||
| */ | |||
| static void quit(); | |||
| /** Sets the value that should be returned as the application's exit code when the | |||
| app quits. | |||
| This is the value that's returned by the main() function. Normally you'd leave this | |||
| as 0 unless you want to indicate an error code. | |||
| @see getApplicationReturnValue | |||
| */ | |||
| void setApplicationReturnValue (int newReturnValue) noexcept; | |||
| /** Returns the value that has been set as the application's exit code. | |||
| @see setApplicationReturnValue | |||
| */ | |||
| int getApplicationReturnValue() const noexcept { return appReturnValue; } | |||
| /** Returns the application's command line parameters as a set of strings. | |||
| @see getCommandLineParameters | |||
| */ | |||
| static StringArray JUCE_CALLTYPE getCommandLineParameterArray(); | |||
| /** Returns the application's command line parameters as a single string. | |||
| @see getCommandLineParameterArray | |||
| */ | |||
| static String JUCE_CALLTYPE getCommandLineParameters(); | |||
| /** Returns true if this executable is running as an app (as opposed to being a plugin | |||
| or other kind of shared library. */ | |||
| static inline bool isStandaloneApp() noexcept { return createInstance != nullptr; } | |||
| void unhandledException (const std::exception* e, | |||
| const String& sourceFilename, | |||
| int lineNumber) override; | |||
| //============================================================================== | |||
| /** @internal */ | |||
| @@ -237,28 +180,8 @@ public: | |||
| /** @internal */ | |||
| bool perform (const InvocationInfo&); | |||
| //============================================================================== | |||
| #ifndef DOXYGEN | |||
| // The following methods are internal calls - not for public use. | |||
| static int main(); | |||
| static int main (int argc, const char* argv[]); | |||
| static void sendUnhandledException (const std::exception*, const char* sourceFile, int lineNumber); | |||
| bool initialiseApp(); | |||
| int shutdownApp(); | |||
| protected: | |||
| bool sendCommandLineToPreexistingInstance(); | |||
| #endif | |||
| private: | |||
| //============================================================================== | |||
| struct MultipleInstanceHandler; | |||
| friend struct MultipleInstanceHandler; | |||
| friend struct ContainerDeletePolicy<MultipleInstanceHandler>; | |||
| ScopedPointer<MultipleInstanceHandler> multipleInstanceHandler; | |||
| int appReturnValue; | |||
| bool stillInitialising; | |||
| bool initialiseApp() override; | |||
| JUCE_DECLARE_NON_COPYABLE (JUCEApplication) | |||
| }; | |||
| @@ -55,7 +55,7 @@ namespace StandardApplicationCommandIDs | |||
| This command is recognised by the JUCEApplication class, so if it is invoked | |||
| and no other ApplicationCommandTarget handles the event first, the JUCEApplication | |||
| object will catch it and call JUCEApplication::systemRequestedQuit(). | |||
| object will catch it and call JUCEApplicationBase::systemRequestedQuit(). | |||
| */ | |||
| static const CommandID quit = 0x1001; | |||
| @@ -238,7 +238,6 @@ class ApplicationCommandManagerListener; | |||
| #include "properties/juce_SliderPropertyComponent.h" | |||
| #include "properties/juce_TextPropertyComponent.h" | |||
| #include "application/juce_Application.h" | |||
| #include "application/juce_Initialisation.h" | |||
| #include "misc/juce_BubbleComponent.h" | |||
| } | |||
| @@ -41,7 +41,7 @@ JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, launchApp, void, (JNIEnv* en | |||
| initialiseJuce_GUI(); | |||
| JUCEApplication* app = dynamic_cast <JUCEApplication*> (JUCEApplicationBase::createInstance()); | |||
| JUCEApplicationBase* app = JUCEApplicationBase::createInstance(); | |||
| if (! app->initialiseApp()) | |||
| exit (0); | |||
| @@ -41,7 +41,8 @@ | |||
| { | |||
| initialiseJuce_GUI(); | |||
| JUCEApplication* app = dynamic_cast <JUCEApplication*> (JUCEApplicationBase::createInstance()); | |||
| JUCEApplicationBase* app = JUCEApplicationBase::createInstance(); | |||
| if (! app->initialiseApp()) | |||
| exit (0); | |||
| } | |||
| @@ -53,15 +54,13 @@ | |||
| - (void) applicationDidEnterBackground: (UIApplication*) application | |||
| { | |||
| JUCEApplicationBase* const app = JUCEApplicationBase::getInstance(); | |||
| if (app != nullptr) | |||
| if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) | |||
| app->suspended(); | |||
| } | |||
| - (void) applicationWillEnterForeground: (UIApplication*) application | |||
| { | |||
| JUCEApplicationBase* const app = JUCEApplicationBase::getInstance(); | |||
| if (app != nullptr) | |||
| if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) | |||
| app->resumed(); | |||
| } | |||
| @@ -118,7 +118,7 @@ void FileChooser::showPlatformDialog (Array<File>& results, | |||
| JUCE_AUTORELEASEPOOL | |||
| { | |||
| ScopedPointer<TemporaryMainMenuWithStandardCommands> tempMenu; | |||
| if (JUCEApplication::isStandaloneApp()) | |||
| if (JUCEApplicationBase::isStandaloneApp()) | |||
| tempMenu = new TemporaryMainMenuWithStandardCommands(); | |||
| StringArray* filters = new StringArray(); | |||
| @@ -662,9 +662,9 @@ namespace MainMenuHelpers | |||
| static void rebuildMainMenu (const PopupMenu* extraItems) | |||
| { | |||
| // this can't be used in a plugin! | |||
| jassert (JUCEApplication::isStandaloneApp()); | |||
| jassert (JUCEApplicationBase::isStandaloneApp()); | |||
| if (JUCEApplication* app = JUCEApplication::getInstance()) | |||
| if (JUCEApplicationBase* app = JUCEApplicationBase::getInstance()) | |||
| { | |||
| JUCE_AUTORELEASEPOOL | |||
| { | |||
| @@ -1388,7 +1388,7 @@ private: | |||
| static void mouseDown (id self, SEL s, NSEvent* ev) | |||
| { | |||
| if (JUCEApplication::isStandaloneApp()) | |||
| if (JUCEApplicationBase::isStandaloneApp()) | |||
| asyncMouseDown (self, s, ev); | |||
| else | |||
| // In some host situations, the host will stop modal loops from working | |||
| @@ -1401,7 +1401,7 @@ private: | |||
| static void mouseUp (id self, SEL s, NSEvent* ev) | |||
| { | |||
| if (JUCEApplication::isStandaloneApp()) | |||
| if (JUCEApplicationBase::isStandaloneApp()) | |||
| asyncMouseUp (self, s, ev); | |||
| else | |||
| // In some host situations, the host will stop modal loops from working | |||
| @@ -162,7 +162,7 @@ static void setWindowZOrder (HWND hwnd, HWND insertAfter) | |||
| //============================================================================== | |||
| static void setDPIAwareness() | |||
| { | |||
| if (JUCEApplication::isStandaloneApp()) | |||
| if (JUCEApplicationBase::isStandaloneApp()) | |||
| { | |||
| if (setProcessDPIAware == nullptr) | |||
| { | |||
| @@ -2457,7 +2457,7 @@ private: | |||
| return 0; | |||
| case WM_QUERYENDSESSION: | |||
| if (JUCEApplication* const app = JUCEApplication::getInstance()) | |||
| if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) | |||
| { | |||
| app->systemRequestedQuit(); | |||
| return MessageManager::getInstance()->hasStopMessageBeenSent(); | |||
| @@ -3158,28 +3158,6 @@ String SystemClipboard::getTextFromClipboard() | |||
| return result; | |||
| } | |||
| //============================================================================== | |||
| String JUCE_CALLTYPE JUCEApplication::getCommandLineParameters() | |||
| { | |||
| return CharacterFunctions::findEndOfToken (CharPointer_UTF16 (GetCommandLineW()), | |||
| CharPointer_UTF16 (L" "), | |||
| CharPointer_UTF16 (L"\"")).findEndOfWhitespace(); | |||
| } | |||
| StringArray JUCE_CALLTYPE JUCEApplication::getCommandLineParameterArray() | |||
| { | |||
| StringArray s; | |||
| int argc = 0; | |||
| if (LPWSTR* const argv = CommandLineToArgvW (GetCommandLineW(), &argc)) | |||
| { | |||
| s = StringArray (argv + 1, argc - 1); | |||
| LocalFree (argv); | |||
| } | |||
| return s; | |||
| } | |||
| //============================================================================== | |||
| void Desktop::setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool /*allowMenusAndBars*/) | |||
| { | |||
| @@ -79,7 +79,7 @@ public: | |||
| /** Calls the refresh() method of all PropertyComponents in the panel */ | |||
| void refreshAll() const; | |||
| /** Returns true if there no properties have been added. */ | |||
| /** Returns true if the panel contains no properties. */ | |||
| bool isEmpty() const; | |||
| /** Returns the height that the panel needs in order to display all of its content | |||
| @@ -165,8 +165,8 @@ void DocumentWindow::closeButtonPressed() | |||
| If your app is centred around this window such that the whole app should quit when | |||
| the window is closed, then you will probably want to use this method as an opportunity | |||
| to call JUCEApplication::quit(), and leave the window to be deleted later by your | |||
| JUCEApplication::shutdown() method. (Doing it this way means that your window will | |||
| to call JUCEApplicationBase::quit(), and leave the window to be deleted later by your | |||
| JUCEApplicationBase::shutdown() method. (Doing it this way means that your window will | |||
| still get cleaned-up if the app is quit by some other means (e.g. a cmd-Q on the mac | |||
| or closing it via the taskbar icon on Windows). | |||
| */ | |||
| @@ -173,8 +173,8 @@ public: | |||
| If your app is centred around this window such that the whole app should quit when | |||
| the window is closed, then you will probably want to use this method as an opportunity | |||
| to call JUCEApplication::quit(), and leave the window to be deleted later by your | |||
| JUCEApplication::shutdown() method. (Doing it this way means that your window will | |||
| to call JUCEApplicationBase::quit(), and leave the window to be deleted later by your | |||
| JUCEApplicationBase::shutdown() method. (Doing it this way means that your window will | |||
| still get cleaned-up if the app is quit by some other means (e.g. a cmd-Q on the mac | |||
| or closing it via the taskbar icon on Windows). | |||
| @@ -32,7 +32,7 @@ | |||
| This will automatically position itself, and can be told to delete itself after | |||
| being on-screen for a minimum length of time. | |||
| To use it, just create one of these in your JUCEApplication::initialise() method, | |||
| To use it, just create one of these in your JUCEApplicationBase::initialise() method, | |||
| and when your initialisation tasks have finished running, call its deleteAfterDelay() | |||
| method to make it automatically get rid of itself. | |||
| @@ -78,9 +78,9 @@ public: | |||
| When called, the constructor will position the SplashScreen in the centre of the | |||
| display, and after the time specified, it will automatically delete itself. | |||
| Bear in mind that if you call this during your JUCEApplication::initialise() | |||
| Bear in mind that if you call this during your JUCEApplicationBase::initialise() | |||
| method and then block the message thread by performing some kind of task, then | |||
| obviously neither your splash screen or any other GUI won't appear until you | |||
| obviously neither your splash screen nor any other GUI will appear until you | |||
| allow the message thread to resume and do its work. So if you have time-consuming | |||
| tasks to do during startup, use a background thread for them. | |||