/* ============================================================================== This file is part of the JUCE library - "Jules' Utility Class Extensions" Copyright 2004-9 by Raw Material Software Ltd. ------------------------------------------------------------------------------ JUCE can be redistributed and/or modified under the terms of the GNU General Public License (Version 2), as published by the Free Software Foundation. A copy of the license is included in the JUCE distribution, or can be found online at www.gnu.org/licenses. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ------------------------------------------------------------------------------ To release a closed-source product which uses JUCE, commercial licenses are available: visit www.rawmaterialsoftware.com/juce for more information. ============================================================================== */ #include "jucedemo_headers.h" #include "MainDemoWindow.h" //============================================================================== class ContentComp : public Component, public MenuBarModel, public ApplicationCommandTarget { public: //============================================================================== ContentComp (MainDemoWindow* mainWindow_) : mainWindow (mainWindow_), currentDemoId (0) { invokeDirectly (showRendering, true); } ~ContentComp() { } //============================================================================== void resized() { if (currentDemo != 0) currentDemo->setBounds (0, 0, getWidth(), getHeight()); } //============================================================================== void showDemo (Component* demoComp) { currentDemo = demoComp; addAndMakeVisible (currentDemo); resized(); } //============================================================================== const StringArray getMenuBarNames() { const char* const names[] = { "Demo", "Look-and-feel", 0 }; return StringArray (names); } const PopupMenu getMenuForIndex (int menuIndex, const String& /*menuName*/) { ApplicationCommandManager* commandManager = &(mainWindow->commandManager); PopupMenu menu; if (menuIndex == 0) { menu.addCommandItem (commandManager, showRendering); menu.addCommandItem (commandManager, showFontsAndText); menu.addCommandItem (commandManager, showWidgets); menu.addCommandItem (commandManager, showThreading); menu.addCommandItem (commandManager, showTreeView); menu.addCommandItem (commandManager, showTable); menu.addCommandItem (commandManager, showAudio); menu.addCommandItem (commandManager, showDragAndDrop); menu.addCommandItem (commandManager, showOpenGL); menu.addCommandItem (commandManager, showQuicktime); menu.addCommandItem (commandManager, showDirectShow); menu.addCommandItem (commandManager, showInterprocessComms); menu.addCommandItem (commandManager, showCamera); menu.addCommandItem (commandManager, showWebBrowser); menu.addCommandItem (commandManager, showCodeEditor); menu.addSeparator(); menu.addCommandItem (commandManager, StandardApplicationCommandIDs::quit); } else if (menuIndex == 1) { menu.addCommandItem (commandManager, setDefaultLookAndFeel); menu.addCommandItem (commandManager, setOldSchoolLookAndFeel); menu.addSeparator(); menu.addCommandItem (commandManager, useNativeTitleBar); #if JUCE_MAC menu.addCommandItem (commandManager, useNativeMenus); #endif #if ! JUCE_LINUX menu.addCommandItem (commandManager, goToKioskMode); #endif StringArray renderingEngines (getPeer()->getAvailableRenderingEngines()); if (renderingEngines.size() > 1) { menu.addSeparator(); for (int i = 0; i < renderingEngines.size(); ++i) menu.addItem (5001 + i, "Use " + renderingEngines[i], true, i == getPeer()->getCurrentRenderingEngine()); } } return menu; } void menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/) { // most of our menu items are invoked automatically as commands, but we can handle the // other special cases here.. if (menuItemID >= 5001 && menuItemID < 5010) getPeer()->setCurrentRenderingEngine (menuItemID - 5001); } //============================================================================== // The following methods implement the ApplicationCommandTarget interface, allowing // this window to publish a set of actions it can perform, and which can be mapped // onto menus, keypresses, etc. ApplicationCommandTarget* getNextCommandTarget() { // this will return the next parent component that is an ApplicationCommandTarget (in this // case, there probably isn't one, but it's best to use this method in your own apps). return findFirstTargetParentComponent(); } void getAllCommands (Array & commands) { // this returns the set of all commands that this target can perform.. const CommandID ids[] = { showRendering, showFontsAndText, showWidgets, showThreading, showTreeView, showTable, showAudio, showDragAndDrop, showOpenGL, showQuicktime, showDirectShow, showCamera, showWebBrowser, showCodeEditor, showInterprocessComms, setDefaultLookAndFeel, setOldSchoolLookAndFeel, useNativeTitleBar #if JUCE_MAC , useNativeMenus #endif #if ! JUCE_LINUX , goToKioskMode #endif }; commands.addArray (ids, numElementsInArray (ids)); } // This method is used when something needs to find out the details about one of the commands // that this object can perform.. void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result) { const String generalCategory ("General"); const String demosCategory ("Demos"); switch (commandID) { case showRendering: result.setInfo ("Graphics Rendering", "Shows the graphics demo", demosCategory, 0); result.setTicked (currentDemoId == showRendering); result.addDefaultKeypress ('1', ModifierKeys::commandModifier); break; case showFontsAndText: result.setInfo ("Fonts and Text", "Shows the fonts & text demo", demosCategory, 0); result.setTicked (currentDemoId == showFontsAndText); result.addDefaultKeypress ('2', ModifierKeys::commandModifier); break; case showWidgets: result.setInfo ("Widgets", "Shows the widgets demo", demosCategory, 0); result.setTicked (currentDemoId == showWidgets); result.addDefaultKeypress ('3', ModifierKeys::commandModifier); break; case showThreading: result.setInfo ("Multithreading", "Shows the threading demo", demosCategory, 0); result.setTicked (currentDemoId == showThreading); result.addDefaultKeypress ('4', ModifierKeys::commandModifier); break; case showTreeView: result.setInfo ("Treeviews", "Shows the treeviews demo", demosCategory, 0); result.setTicked (currentDemoId == showTreeView); result.addDefaultKeypress ('5', ModifierKeys::commandModifier); break; case showTable: result.setInfo ("Table Components", "Shows the table component demo", demosCategory, 0); result.setTicked (currentDemoId == showTable); result.addDefaultKeypress ('6', ModifierKeys::commandModifier); break; case showAudio: result.setInfo ("Audio", "Shows the audio demo", demosCategory, 0); result.setTicked (currentDemoId == showAudio); result.addDefaultKeypress ('7', ModifierKeys::commandModifier); break; case showDragAndDrop: result.setInfo ("Drag-and-drop", "Shows the drag & drop demo", demosCategory, 0); result.setTicked (currentDemoId == showDragAndDrop); result.addDefaultKeypress ('8', ModifierKeys::commandModifier); break; case showOpenGL: result.setInfo ("OpenGL", "Shows the OpenGL demo", demosCategory, 0); result.addDefaultKeypress ('9', ModifierKeys::commandModifier); result.setTicked (currentDemoId == showOpenGL); #if ! JUCE_OPENGL result.setActive (false); #endif break; case showQuicktime: result.setInfo ("Quicktime", "Shows the Quicktime demo", demosCategory, 0); result.addDefaultKeypress ('b', ModifierKeys::commandModifier); result.setTicked (currentDemoId == showQuicktime); #if ! (JUCE_QUICKTIME && ! JUCE_LINUX) result.setActive (false); #endif break; case showDirectShow: result.setInfo ("DirectShow", "Shows the DirectShow demo", demosCategory, 0); result.addDefaultKeypress ('b', ModifierKeys::commandModifier); result.setTicked (currentDemoId == showDirectShow); #if ! JUCE_DIRECTSHOW result.setActive (false); #endif break; case showCamera: result.setInfo ("Camera Capture", "Shows the camera demo", demosCategory, 0); result.addDefaultKeypress ('c', ModifierKeys::commandModifier); result.setTicked (currentDemoId == showCamera); #if ! JUCE_USE_CAMERA result.setActive (false); #endif break; case showWebBrowser: result.setInfo ("Web Browser", "Shows the web browser demo", demosCategory, 0); result.addDefaultKeypress ('i', ModifierKeys::commandModifier); result.setTicked (currentDemoId == showWebBrowser); #if (! JUCE_WEB_BROWSER) || JUCE_LINUX result.setActive (false); #endif break; case showCodeEditor: result.setInfo ("Code Editor", "Shows the code editor demo", demosCategory, 0); result.addDefaultKeypress ('e', ModifierKeys::commandModifier); result.setTicked (currentDemoId == showCodeEditor); break; case showInterprocessComms: result.setInfo ("Interprocess Comms", "Shows the interprocess communications demo", demosCategory, 0); result.addDefaultKeypress ('0', ModifierKeys::commandModifier); result.setTicked (currentDemoId == showInterprocessComms); break; case setDefaultLookAndFeel: result.setInfo ("Use default look-and-feel", String::empty, generalCategory, 0); result.setTicked (dynamic_cast (&getLookAndFeel()) == 0); break; case setOldSchoolLookAndFeel: result.setInfo ("Use the old, original juce look-and-feel", String::empty, generalCategory, 0); result.setTicked (dynamic_cast (&getLookAndFeel()) != 0); break; case useNativeTitleBar: result.setInfo ("Use native window title bar", String::empty, generalCategory, 0); result.setTicked (mainWindow->isUsingNativeTitleBar()); break; #if JUCE_MAC case useNativeMenus: result.setInfo ("Use the native OSX menu bar", String::empty, generalCategory, 0); result.setTicked (MenuBarModel::getMacMainMenu() != 0); break; #endif #if ! JUCE_LINUX case goToKioskMode: result.setInfo ("Show full-screen kiosk mode", String::empty, generalCategory, 0); result.setTicked (Desktop::getInstance().getKioskModeComponent() != 0); break; #endif default: break; }; } // this is the ApplicationCommandTarget method that is used to actually perform one of our commands.. bool perform (const InvocationInfo& info) { switch (info.commandID) { case showRendering: showDemo (createRenderingDemo()); currentDemoId = showRendering; break; case showFontsAndText: showDemo (createFontsAndTextDemo()); currentDemoId = showFontsAndText; break; case showWidgets: showDemo (createWidgetsDemo()); currentDemoId = showWidgets; break; case showThreading: showDemo (createThreadingDemo()); currentDemoId = showThreading; break; case showTreeView: showDemo (createTreeViewDemo()); currentDemoId = showTreeView; break; case showTable: showDemo (createTableDemo()); currentDemoId = showTable; break; case showAudio: showDemo (createAudioDemo()); currentDemoId = showAudio; break; case showDragAndDrop: showDemo (createDragAndDropDemo()); currentDemoId = showDragAndDrop; break; case showOpenGL: #if JUCE_OPENGL showDemo (createOpenGLDemo()); currentDemoId = showOpenGL; #endif break; case showQuicktime: #if JUCE_QUICKTIME && ! JUCE_LINUX showDemo (createQuickTimeDemo()); currentDemoId = showQuicktime; #endif break; case showDirectShow: #if JUCE_DIRECTSHOW showDemo (createDirectShowDemo()); currentDemoId = showDirectShow; #endif break; case showCamera: #if JUCE_USE_CAMERA showDemo (createCameraDemo()); currentDemoId = showCamera; #endif break; case showWebBrowser: #if JUCE_WEB_BROWSER showDemo (createWebBrowserDemo()); currentDemoId = showWebBrowser; #endif break; case showCodeEditor: showDemo (createCodeEditorDemo()); currentDemoId = showCodeEditor; break; case showInterprocessComms: showDemo (createInterprocessCommsDemo()); currentDemoId = showInterprocessComms; break; case setDefaultLookAndFeel: LookAndFeel::setDefaultLookAndFeel (nullptr); break; case setOldSchoolLookAndFeel: LookAndFeel::setDefaultLookAndFeel (&oldLookAndFeel); break; case useNativeTitleBar: mainWindow->setUsingNativeTitleBar (! mainWindow->isUsingNativeTitleBar()); break; #if JUCE_MAC case useNativeMenus: if (MenuBarModel::getMacMainMenu() != 0) { MenuBarModel::setMacMainMenu (0); mainWindow->setMenuBar ((ContentComp*) mainWindow->getContentComponent()); } else { MenuBarModel::setMacMainMenu ((ContentComp*) mainWindow->getContentComponent()); mainWindow->setMenuBar (0); } break; #endif #if ! JUCE_LINUX case goToKioskMode: if (Desktop::getInstance().getKioskModeComponent() == 0) { Desktop::getInstance().setKioskModeComponent (getTopLevelComponent()); } else { Desktop::getInstance().setKioskModeComponent (0); } break; #endif default: return false; }; return true; } private: //============================================================================== MainDemoWindow* mainWindow; OldSchoolLookAndFeel oldLookAndFeel; ScopedPointer currentDemo; int currentDemoId; TooltipWindow tooltipWindow; // to add tooltips to an application, you // just need to create one of these and leave it // there to do its work.. enum CommandIDs { showRendering = 0x2000, showFontsAndText = 0x2001, showWidgets = 0x2002, showThreading = 0x2003, showTreeView = 0x2004, showAudio = 0x2005, showDragAndDrop = 0x2006, showOpenGL = 0x2007, showQuicktime = 0x2008, showInterprocessComms = 0x2009, showTable = 0x2010, showCamera = 0x2011, showWebBrowser = 0x2012, showCodeEditor = 0x2013, showDirectShow = 0x2014, setDefaultLookAndFeel = 0x200b, setOldSchoolLookAndFeel = 0x200c, useNativeTitleBar = 0x200d, useNativeMenus = 0x200e, goToKioskMode = 0x200f }; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentComp); }; //============================================================================== #if JUCE_WINDOWS || JUCE_LINUX // Just add a simple icon to the Window system tray area.. class DemoTaskbarComponent : public SystemTrayIconComponent { public: DemoTaskbarComponent() { // Create an icon which is just a square with a "j" in it.. Image icon (Image::RGB, 32, 32, true); Graphics g (icon); g.fillAll (Colours::lightblue); g.setColour (Colours::black); g.setFont ((float) icon.getHeight(), Font::bold); g.drawText ("j", 0, 0, icon.getWidth(), icon.getHeight(), Justification::centred, false); setIconImage (icon); setIconTooltip ("Juce Demo App!"); } ~DemoTaskbarComponent() { } void mouseDown (const MouseEvent&) { PopupMenu m; m.addItem (1, "Quit the Juce demo"); const int result = m.show(); if (result == 1) JUCEApplication::getInstance()->systemRequestedQuit(); } }; #endif //============================================================================== MainDemoWindow::MainDemoWindow() : DocumentWindow ("JUCE Demo!", Colours::azure, DocumentWindow::allButtons, true) { setResizable (true, false); // resizability is a property of ResizableWindow setResizeLimits (400, 300, 8192, 8192); ContentComp* contentComp = new ContentComp (this); commandManager.registerAllCommandsForTarget (contentComp); commandManager.registerAllCommandsForTarget (JUCEApplication::getInstance()); // this lets the command manager use keypresses that arrive in our window to send // out commands addKeyListener (commandManager.getKeyMappings()); // sets the main content component for the window to be this tabbed // panel. This will be deleted when the window is deleted. setContentOwned (contentComp, false); // this tells the DocumentWindow to automatically create and manage a MenuBarComponent // which uses our contentComp as its MenuBarModel setMenuBar (contentComp); // tells our menu bar model that it should watch this command manager for // changes, and send change messages accordingly. contentComp->setApplicationCommandManagerToWatch (&commandManager); setVisible (true); #if JUCE_WINDOWS || JUCE_LINUX taskbarIcon = new DemoTaskbarComponent(); #endif } MainDemoWindow::~MainDemoWindow() { // because we've set the content comp to be used as our menu bar model, we // have to switch this off before deleting the content comp.. setMenuBar (0); #if JUCE_MAC // ..and also the main bar if we're using that on a Mac... MenuBarModel::setMacMainMenu (0); #endif // clearing the content component will delete the current one, and // that will in turn delete all its child components. You don't always // have to do this explicitly, because the base class's destructor will // also delete the content component, but in this case we need to // make sure our content comp has gone away before deleting our command // manager. clearContentComponent(); } void MainDemoWindow::closeButtonPressed() { // The correct thing to do when you want the app to quit is to call the // JUCEApplication::systemRequestedQuit() method. // That means that requests to quit that come from your own UI, or from other // OS-specific sources (e.g. the dock menu on the mac) all get handled in the // same way. JUCEApplication::getInstance()->systemRequestedQuit(); }