/* ============================================================================== This file is part of the JUCE library. Copyright (c) 2020 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. By using JUCE, you agree to the terms of both the JUCE 6 End-User License Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). End User License Agreement: www.juce.com/juce-6-licence Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE DISCLAIMED. ============================================================================== */ #include #include "../../Assets/DemoUtilities.h" #include "UI/MainComponent.h" namespace example { class SplashScreen : public TopLevelWindow { public: SplashScreen() : TopLevelWindow(TRANS("Start-up Screen"), true) { setOpaque(false); setMouseCursor(MouseCursor::WaitCursor); centreWithSize(550, 320); setVisible(true); repaint(); waitForRepaint(); } void setStartupMessage(const String& m) { if (startupMessage != m) { startupMessage = m; repaint(); waitForRepaint(); } } void waitForRepaint() { const int currentCount = repaintCount; while (repaintCount == currentCount) MessageManager::getInstance()->runDispatchLoopUntil(5); } void hide() { setVisible(false); } void paint(Graphics& g) override { g.fillAll(Colours::black); auto r = getLocalBounds().reduced(20); AttributedString att; const Colour col(Colours::white); const Font f(16.0f); g.setFont(f); att.append("\n\n" + startupMessage, f, col.withMultipliedAlpha(0.8f)); att.append("\n\n" + String(CharPointer_UTF8("\xc2\xa9")) + " " + String(Time::getCompilationDate().getYear()), 14.0f, col); att.setJustification(Justification::centredLeft); att.draw(g, r.toFloat()); ++repaintCount; } private: //============================================================================== String startupMessage; int repaintCount = 0; }; } //============================================================================== #if JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_BSD // Just add a simple icon to the Window system tray area or Mac menu bar.. struct DemoTaskbarComponent : public SystemTrayIconComponent, private Timer { DemoTaskbarComponent() { setIconImage (getImageFromAssets ("juce_icon.png"), getImageFromAssets ("juce_icon_template.png")); setIconTooltip ("JUCE demo runner!"); } void mouseDown (const MouseEvent&) override { // On OSX, there can be problems launching a menu when we're not the foreground // process, so just in case, we'll first make our process active, and then use a // timer to wait a moment before opening our menu, which gives the OS some time to // get its act together and bring our windows to the front. Process::makeForegroundProcess(); startTimer (50); } // This is invoked when the menu is clicked or dismissed static void menuInvocationCallback (int chosenItemID, DemoTaskbarComponent*) { if (chosenItemID == 1) JUCEApplication::getInstance()->systemRequestedQuit(); } void timerCallback() override { stopTimer(); PopupMenu m; m.addItem (1, "Quit"); // It's always better to open menus asynchronously when possible. m.showMenuAsync (PopupMenu::Options(), ModalCallbackFunction::forComponent (menuInvocationCallback, this)); } }; #endif std::unique_ptr sharedAudioDeviceManager; //============================================================================== class DemoRunnerApplication : public JUCEApplication { public: //============================================================================== DemoRunnerApplication() {} ~DemoRunnerApplication() override { sharedAudioDeviceManager.reset(); } const String getApplicationName() override { return ProjectInfo::projectName; } const String getApplicationVersion() override { return ProjectInfo::versionString; } bool moreThanOneInstanceAllowed() override { return true; } //============================================================================== void initialise (const String& commandLine) override { example::SplashScreen splash; splash.setStartupMessage("First message"); splash.waitForRepaint(); registerAllDemos(); splash.setStartupMessage("Second message - demos registered"); splash.waitForRepaint(); #if JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_BSD // (This function call is for one of the demos, which involves launching a child process) if (invokeChildProcessDemo (commandLine)) return; #else ignoreUnused (commandLine); #endif mainWindow.reset (new MainAppWindow (getApplicationName())); } bool backButtonPressed() override { mainWindow->getMainComponent().getSidePanel().showOrHide (false); return true; } void shutdown() override { mainWindow = nullptr; } //============================================================================== void systemRequestedQuit() override { quit(); } void anotherInstanceStarted (const String&) override {} ApplicationCommandManager& getGlobalCommandManager() { return commandManager; } private: class MainAppWindow : public DocumentWindow { public: MainAppWindow (const String& name) : DocumentWindow (name, Desktop::getInstance().getDefaultLookAndFeel() .findColour (ResizableWindow::backgroundColourId), DocumentWindow::allButtons) { setUsingNativeTitleBar (true); setResizable (true, false); setResizeLimits (400, 400, 10000, 10000); #if JUCE_IOS || JUCE_ANDROID setFullScreen (true); auto& desktop = Desktop::getInstance(); desktop.setOrientationsEnabled (Desktop::allOrientations); desktop.setKioskModeComponent (this); #else setBounds ((int) (0.1f * (float) getParentWidth()), (int) (0.1f * (float) getParentHeight()), jmax (850, (int) (0.5f * (float) getParentWidth())), jmax (600, (int) (0.7f * (float) getParentHeight()))); #endif setContentOwned (new MainComponent(), false); setVisible (true); #if JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_BSD taskbarIcon.reset (new DemoTaskbarComponent()); #endif } void closeButtonPressed() override { JUCEApplication::getInstance()->systemRequestedQuit(); } //============================================================================== MainComponent& getMainComponent() { return *dynamic_cast (getContentComponent()); } private: std::unique_ptr taskbarIcon; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainAppWindow) }; std::unique_ptr mainWindow; ApplicationCommandManager commandManager; }; ApplicationCommandManager& getGlobalCommandManager() { return dynamic_cast (JUCEApplication::getInstance())->getGlobalCommandManager(); } //============================================================================== // This macro generates the main() routine that launches the app. START_JUCE_APPLICATION (DemoRunnerApplication)