diff --git a/Builds/VisualStudio2005/Juce.vcproj b/Builds/VisualStudio2005/Juce.vcproj index 7d44fa08f8..9250f1d033 100644 --- a/Builds/VisualStudio2005/Juce.vcproj +++ b/Builds/VisualStudio2005/Juce.vcproj @@ -843,6 +843,7 @@ + diff --git a/Builds/VisualStudio2008/Juce.vcproj b/Builds/VisualStudio2008/Juce.vcproj index 477a1d35e8..fb5098a8a1 100644 --- a/Builds/VisualStudio2008/Juce.vcproj +++ b/Builds/VisualStudio2008/Juce.vcproj @@ -843,6 +843,7 @@ + diff --git a/Builds/VisualStudio2008_DLL/Juce.vcproj b/Builds/VisualStudio2008_DLL/Juce.vcproj index 7322381ce9..ee12f37b63 100644 --- a/Builds/VisualStudio2008_DLL/Juce.vcproj +++ b/Builds/VisualStudio2008_DLL/Juce.vcproj @@ -845,6 +845,7 @@ + diff --git a/Builds/VisualStudio2010/Juce.vcxproj b/Builds/VisualStudio2010/Juce.vcxproj index b3c4a813e7..7c69cf0228 100644 --- a/Builds/VisualStudio2010/Juce.vcxproj +++ b/Builds/VisualStudio2010/Juce.vcxproj @@ -760,6 +760,7 @@ + diff --git a/Builds/VisualStudio2010/Juce.vcxproj.filters b/Builds/VisualStudio2010/Juce.vcxproj.filters index 7409e030d8..bdc0457f2e 100644 --- a/Builds/VisualStudio2010/Juce.vcxproj.filters +++ b/Builds/VisualStudio2010/Juce.vcxproj.filters @@ -2214,6 +2214,9 @@ Juce\Source\memory + + Juce\Source\memory + Juce\Source\memory diff --git a/Juce.jucer b/Juce.jucer index ff3554e823..70492273e0 100644 --- a/Juce.jucer +++ b/Juce.jucer @@ -1259,6 +1259,8 @@ file="src/memory/juce_MemoryBlock.cpp"/> + 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, 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, - 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 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 ((typeid (LookAndFeel) == typeid (getLookAndFeel())) != 0); - break; - - case setOldSchoolLookAndFeel: - result.setInfo ("Use the old, original juce look-and-feel", String::empty, generalCategory, 0); - result.setTicked ((typeid (OldSchoolLookAndFeel) == typeid (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 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 (0); - 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, - - 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. - setContentComponent (contentComp); - - // 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 - - // setting our content component to 0 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. - setContentComponent (0, true); -} - -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(); -} +/* + ============================================================================== + + 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() + { + // (need to do this because the old school look-and-feel object is one of our members, + // so will be deleted with us, and would leave a dangling pointer if it's selected) + LookAndFeel::setDefaultLookAndFeel (0); + } + + //============================================================================== + 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, 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, + 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 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 ((typeid (LookAndFeel) == typeid (getLookAndFeel())) != 0); + break; + + case setOldSchoolLookAndFeel: + result.setInfo ("Use the old, original juce look-and-feel", String::empty, generalCategory, 0); + result.setTicked ((typeid (OldSchoolLookAndFeel) == typeid (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 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 (0); + 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, + + 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(); +} diff --git a/extras/JuceDemo/Source/demos/WidgetsDemo.cpp b/extras/JuceDemo/Source/demos/WidgetsDemo.cpp index f52b0fd714..a20ed9b860 100644 --- a/extras/JuceDemo/Source/demos/WidgetsDemo.cpp +++ b/extras/JuceDemo/Source/demos/WidgetsDemo.cpp @@ -1009,15 +1009,11 @@ public: Colours::lightgrey, true) { - setContentComponent (new ColourSelector()); + setContentOwned (new ColourSelector(), false); centreWithSize (400, 400); setResizable (true, true); } - ~ColourSelectorDialogWindow() - { - } - void closeButtonPressed() { // we expect this component to be run within a modal loop, so when the close diff --git a/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp b/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp index 4791ae4b2d..eaa2e7fd85 100644 --- a/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp +++ b/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp @@ -702,7 +702,16 @@ protected: midiTransport->GetCurrentTempo (&bpm); midiTransport->IsTransportPlaying (&isPlaying); midiTransport->GetCurrentMeter (&num, &denom); - midiTransport->GetCurrentTickPosition (&ticks); + + // (The following is a work-around because GetCurrentTickPosition() doesn't work correctly). + Cmn_Int64 sampleLocation; + + if (isPlaying) + midiTransport->GetCurrentRTASSampleLocation (&sampleLocation); + else + midiTransport->GetCurrentTDMSampleLocation (&sampleLocation); + + midiTransport->GetCustomTickPosition (&ticks, sampleLocation); } info.bpm = bpm; diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index ef90894996..f329a3fbf4 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -9995,8 +9995,7 @@ namespace BufferedInputStream::BufferedInputStream (InputStream* const sourceStream, const int bufferSize_, const bool deleteSourceWhenDestroyed) - : source (sourceStream), - sourceToDelete (deleteSourceWhenDestroyed ? sourceStream : 0), + : source (sourceStream, deleteSourceWhenDestroyed), bufferSize (calcBufferStreamBufferSize (bufferSize_, sourceStream)), position (sourceStream->getPosition()), lastReadPos (0), @@ -10007,7 +10006,7 @@ BufferedInputStream::BufferedInputStream (InputStream* const sourceStream, const } BufferedInputStream::BufferedInputStream (InputStream& sourceStream, const int bufferSize_) - : source (&sourceStream), + : source (&sourceStream, false), bufferSize (calcBufferStreamBufferSize (bufferSize_, &sourceStream)), position (sourceStream.getPosition()), lastReadPos (0), @@ -10445,13 +10444,10 @@ SubregionStream::SubregionStream (InputStream* const sourceStream, const int64 startPositionInSourceStream_, const int64 lengthOfSourceStream_, const bool deleteSourceWhenDestroyed) - : source (sourceStream), + : source (sourceStream, deleteSourceWhenDestroyed), startPositionInSourceStream (startPositionInSourceStream_), lengthOfSourceStream (lengthOfSourceStream_) { - if (deleteSourceWhenDestroyed) - sourceToDelete = source; - setPosition (0); } @@ -55213,7 +55209,7 @@ public: : DialogWindow (TRANS("Add/remove items from toolbar"), Colours::white, true, true), toolbar (toolbar_) { - setContentComponent (new CustomiserPanel (factory, toolbar, optionFlags), true, true); + setContentOwned (new CustomiserPanel (factory, toolbar, optionFlags), true); setResizable (true, true); setResizeLimits (400, 300, 1500, 1000); positionNearBar(); @@ -55222,7 +55218,6 @@ public: ~ToolbarCustomisationDialog() { toolbar->setEditingActive (false); - setContentComponent (0, true); } void closeButtonPressed() @@ -58493,7 +58488,8 @@ FileChooserDialogBox::FileChooserDialogBox (const String& name, : ResizableWindow (name, backgroundColour, true), warnAboutOverwritingExistingFiles (warnAboutOverwritingExistingFiles_) { - setContentComponent (content = new ContentComponent (name, instructions, chooserComponent)); + content = new ContentComponent (name, instructions, chooserComponent); + setContentOwned (content, false); setResizable (true, true); setResizeLimits (300, 300, 1200, 1000); @@ -62231,7 +62227,7 @@ void MultiDocumentPanel::addWindow (Component* component) MultiDocumentPanelWindow* const dw = createNewDocumentWindow(); dw->setResizable (true, false); - dw->setContentComponent (component, false, true); + dw->setContentNonOwned (component, true); dw->setName (component->getName()); const var bkg (component->getProperties() ["mdiDocumentBkg_"]); @@ -62341,8 +62337,7 @@ bool MultiDocumentPanel::closeDocument (Component* component, if (dw != 0 && dw->getContentComponent() == component) { - dw->setContentComponent (0, false); - delete dw; + ScopedPointer (dw)->clearContentComponent(); break; } } @@ -62356,13 +62351,10 @@ bool MultiDocumentPanel::closeDocument (Component* component, { for (int i = getNumChildComponents(); --i >= 0;) { - MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i)); + ScopedPointer dw (dynamic_cast (getChildComponent (i))); if (dw != 0) - { - dw->setContentComponent (0, false); - delete dw; - } + dw->clearContentComponent(); } addAndMakeVisible (components.getFirst()); @@ -62498,7 +62490,7 @@ void MultiDocumentPanel::setLayoutMode (const LayoutMode newLayoutMode) if (dw != 0) { dw->getContentComponent()->getProperties().set ("mdiDocumentPos_", dw->getWindowStateAsString()); - dw->setContentComponent (0, false); + dw->clearContentComponent(); delete dw; } } @@ -77557,16 +77549,11 @@ public: if (! JUCEApplication::isStandaloneApp()) setAlwaysOnTop (true); // for a plugin, make it always-on-top because the host windows are often top-level - setContentComponent (contentComponent, true, true); + setContentNonOwned (contentComponent, true); centreAroundComponent (componentToCentreAround, getWidth(), getHeight()); setResizable (shouldBeResizable, useBottomRightCornerResizer); } - ~TempDialogWindow() - { - setContentComponent (0, false); - } - void closeButtonPressed() { setVisible (false); @@ -77986,6 +77973,7 @@ BEGIN_JUCE_NAMESPACE ResizableWindow::ResizableWindow (const String& name, const bool addToDesktop_) : TopLevelWindow (name, addToDesktop_), + ownsContentComponent (false), resizeToFitContent (false), fullscreen (false), lastNonFullScreenPos (50, 50, 256, 256), @@ -78006,6 +77994,7 @@ ResizableWindow::ResizableWindow (const String& name, const Colour& backgroundColour_, const bool addToDesktop_) : TopLevelWindow (name, addToDesktop_), + ownsContentComponent (false), resizeToFitContent (false), fullscreen (false), lastNonFullScreenPos (50, 50, 256, 256), @@ -78032,7 +78021,7 @@ ResizableWindow::~ResizableWindow() resizableCorner = 0; resizableBorder = 0; - contentComponent.deleteAndZero(); + clearContentComponent(); // have you been adding your own components directly to this window..? tut tut tut. // Read the instructions for using a ResizableWindow! @@ -78049,31 +78038,70 @@ int ResizableWindow::getDesktopWindowStyleFlags() const return styleFlags; } -void ResizableWindow::setContentComponent (Component* const newContentComponent, - const bool deleteOldOne, - const bool resizeToFit) +void ResizableWindow::clearContentComponent() { - resizeToFitContent = resizeToFit; + if (ownsContentComponent) + { + contentComponent.deleteAndZero(); + } + else + { + removeChildComponent (contentComponent); + contentComponent = 0; + } +} - if (newContentComponent != static_cast (contentComponent)) +void ResizableWindow::setContent (Component* newContentComponent, + const bool takeOwnership, + const bool resizeToFitWhenContentChangesSize) +{ + if (newContentComponent != contentComponent) { - if (deleteOldOne) - contentComponent.deleteAndZero(); // (avoid using a scoped pointer for this, so that it survives - // external deletion of the content comp) - else - removeChildComponent (contentComponent); + clearContentComponent(); contentComponent = newContentComponent; - Component::addAndMakeVisible (contentComponent); } - if (resizeToFit) + ownsContentComponent = takeOwnership; + resizeToFitContent = resizeToFitWhenContentChangesSize; + + if (resizeToFitWhenContentChangesSize) childBoundsChanged (contentComponent); resized(); // must always be called to position the new content comp } +void ResizableWindow::setContentOwned (Component* newContentComponent, const bool resizeToFitWhenContentChangesSize) +{ + setContent (newContentComponent, true, resizeToFitWhenContentChangesSize); +} + +void ResizableWindow::setContentNonOwned (Component* newContentComponent, const bool resizeToFitWhenContentChangesSize) +{ + setContent (newContentComponent, false, resizeToFitWhenContentChangesSize); +} + +void ResizableWindow::setContentComponent (Component* const newContentComponent, + const bool deleteOldOne, + const bool resizeToFitWhenContentChangesSize) +{ + if (newContentComponent != contentComponent) + { + if (deleteOldOne) + { + contentComponent.deleteAndZero(); + } + else + { + removeChildComponent (contentComponent); + contentComponent = 0; + } + } + + setContent (newContentComponent, true, resizeToFitWhenContentChangesSize); +} + void ResizableWindow::setContentComponentSize (int width, int height) { jassert (width > 0 && height > 0); // not a great idea to give it a zero size.. @@ -98258,8 +98286,7 @@ GZIPCompressorOutputStream::GZIPCompressorOutputStream (OutputStream* const dest int compressionLevel, const bool deleteDestStream, const int windowBits) - : destStream (destStream_), - streamToDelete (deleteDestStream ? destStream_ : 0), + : destStream (destStream_, deleteDestStream), buffer ((size_t) GZIPCompressorHelper::gzipCompBufferSize) { if (compressionLevel < 1 || compressionLevel > 9) @@ -105644,8 +105671,7 @@ GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const sou const bool deleteSourceWhenDestroyed, const bool noWrap_, const int64 uncompressedStreamLength_) - : sourceStream (sourceStream_), - streamToDelete (deleteSourceWhenDestroyed ? sourceStream_ : 0), + : sourceStream (sourceStream_, deleteSourceWhenDestroyed), uncompressedStreamLength (uncompressedStreamLength_), noWrap (noWrap_), isEof (false), @@ -105658,7 +105684,7 @@ GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const sou } GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream& sourceStream_) - : sourceStream (&sourceStream_), + : sourceStream (&sourceStream_, false), uncompressedStreamLength (-1), noWrap (false), isEof (false), diff --git a/juce_amalgamated.h b/juce_amalgamated.h index eb80726d68..e58f5a4f12 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 30 +#define JUCE_BUILDNUMBER 31 /** Current Juce version number. @@ -19537,6 +19537,124 @@ private: #ifndef __JUCE_BUFFEREDINPUTSTREAM_JUCEHEADER__ #define __JUCE_BUFFEREDINPUTSTREAM_JUCEHEADER__ + +/*** Start of inlined file: juce_OptionalScopedPointer.h ***/ +#ifndef __JUCE_OPTIONALSCOPEDPOINTER_JUCEHEADER__ +#define __JUCE_OPTIONALSCOPEDPOINTER_JUCEHEADER__ + +/** + Holds a pointer to an object which can optionally be deleted when this pointer + goes out of scope. + + This acts in many ways like a ScopedPointer, but allows you to specify whether or + not the object is deleted. + + @see ScopedPointer +*/ +template +class OptionalScopedPointer +{ +public: + + /** Creates an empty OptionalScopedPointer. */ + OptionalScopedPointer() : shouldDelete (false) {} + + /** Creates an OptionalScopedPointer to point to a given object, and specifying whether + the OptionalScopedPointer will delete it. + + If takeOwnership is true, then the OptionalScopedPointer will act like a ScopedPointer, + deleting the object when it is itself deleted. If this parameter is false, then the + OptionalScopedPointer just holds a normal pointer to the object, and won't delete it. + */ + OptionalScopedPointer (ObjectType* objectToHold, bool takeOwnership) + : object (objectToHold), shouldDelete (takeOwnership) + { + } + + /** Takes ownership of the object that another OptionalScopedPointer holds. + + Like a normal ScopedPointer, the objectToTransferFrom object will become null, + as ownership of the managed object is transferred to this object. + + The flag to indicate whether or not to delete the managed object is also + copied from the source object. + */ + OptionalScopedPointer (OptionalScopedPointer& objectToTransferFrom) + : object (objectToTransferFrom.release()), + shouldDelete (objectToTransferFrom.shouldDelete) + { + } + + /** Takes ownership of the object that another OptionalScopedPointer holds. + + Like a normal ScopedPointer, the objectToTransferFrom object will become null, + as ownership of the managed object is transferred to this object. + + The ownership flag that says whether or not to delete the managed object is also + copied from the source object. + */ + OptionalScopedPointer& operator= (OptionalScopedPointer& objectToTransferFrom) + { + if (object != objectToTransferFrom.object) + { + clear(); + object = objectToTransferFrom.object; + } + + shouldDelete = objectToTransferFrom.shouldDelete; + return *this; + } + + /** The destructor may or may not delete the object that is being held, depending on the + takeOwnership flag that was specified when the object was first passed into an + OptionalScopedPointer constructor. + */ + ~OptionalScopedPointer() + { + clear(); + } + + /** Returns the object that this pointer is managing. */ + inline operator ObjectType*() const throw() { return object; } + + /** Returns the object that this pointer is managing. */ + inline ObjectType& operator*() const throw() { return *object; } + + /** Lets you access methods and properties of the object that this pointer is holding. */ + inline ObjectType* operator->() const throw() { return object; } + + /** Removes the current object from this OptionalScopedPointer without deleting it. + This will return the current object, and set this OptionalScopedPointer to a null pointer. + */ + ObjectType* release() throw() { return object.release(); } + + /** Resets this pointer to null, possibly deleting the object that it holds, if it has + ownership of it. + */ + void clear() + { + if (! shouldDelete) + object.release(); + } + + /** Swaps this object with another OptionalScopedPointer. + The two objects simply exchange their states. + */ + void swapWith (OptionalScopedPointer& other) throw() + { + object.swapWith (other.object); + swapVariables (shouldDelete, other.shouldDelete); + } + +private: + + ScopedPointer object; + bool shouldDelete; +}; + +#endif // __JUCE_OPTIONALSCOPEDPOINTER_JUCEHEADER__ +/*** End of inlined file: juce_OptionalScopedPointer.h ***/ + /** Wraps another input stream, and reads from it using an intermediate buffer If you're using an input stream such as a file input stream, and making lots of @@ -19583,8 +19701,7 @@ public: private: - InputStream* const source; - ScopedPointer sourceToDelete; + OptionalScopedPointer source; int bufferSize; int64 position, lastReadPos, bufferStart, bufferOverlap; HeapBlock buffer; @@ -19686,8 +19803,7 @@ public: private: - OutputStream* const destStream; - ScopedPointer streamToDelete; + OptionalScopedPointer destStream; HeapBlock buffer; class GZIPCompressorHelper; friend class ScopedPointer ; @@ -19754,8 +19870,7 @@ public: int read (void* destBuffer, int maxBytesToRead); private: - InputStream* const sourceStream; - ScopedPointer streamToDelete; + OptionalScopedPointer sourceStream; const int64 uncompressedStreamLength; const bool noWrap; bool isEof; @@ -19998,8 +20113,7 @@ public: bool isExhausted(); private: - InputStream* const source; - ScopedPointer sourceToDelete; + OptionalScopedPointer source; const int64 startPositionInSourceStream, lengthOfSourceStream; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SubregionStream); @@ -20381,6 +20495,9 @@ private: #endif #ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__ +#endif +#ifndef __JUCE_OPTIONALSCOPEDPOINTER_JUCEHEADER__ + #endif #ifndef __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__ @@ -55356,21 +55473,41 @@ public: You should never add components directly to a ResizableWindow (or any of its subclasses) with addChildComponent(). Instead, add them to the content component. - @param newContentComponent the new component to use (or null to not use one) - this - component will be deleted either when replaced by another call - to this method, or when the ResizableWindow is deleted. - To remove a content component without deleting it, use - setContentComponent (0, false). - @param deleteOldOne if true, the previous content component will be deleted; if - false, the previous component will just be removed without - deleting it. - @param resizeToFit if true, the ResizableWindow will maintain its size such that - it always fits around the size of the content component. If false, the - new content will be resized to fit the current space available. - */ - void setContentComponent (Component* newContentComponent, - bool deleteOldOne = true, - bool resizeToFit = false); + @param newContentComponent the new component to use - this component will be deleted when it's + no longer needed (i.e. when the window is deleted or a new content + component is set for it). To set a component that this window will not + delete, call setContentNonOwned() instead. + @param resizeToFitWhenContentChangesSize if true, then the ResizableWindow will maintain its size + such that it always fits around the size of the content component. If false, + the new content will be resized to fit the current space available. + */ + void setContentOwned (Component* newContentComponent, + bool resizeToFitWhenContentChangesSize); + + /** Changes the current content component. + + This sets a component that will be placed in the centre of the ResizableWindow, + (leaving a space around the edge for the border). + + You should never add components directly to a ResizableWindow (or any of its subclasses) + with addChildComponent(). Instead, add them to the content component. + + @param newContentComponent the new component to use - this component will NOT be deleted by this + component, so it's the caller's responsibility to manage its lifetime (it's + ok to delete it while this window is still using it). To set a content + component that the window will delete, call setContentOwned() instead. + @param resizeToFitWhenContentChangesSize if true, then the ResizableWindow will maintain its size + such that it always fits around the size of the content component. If false, + the new content will be resized to fit the current space available. + */ + void setContentNonOwned (Component* newContentComponent, + bool resizeToFitWhenContentChangesSize); + + /** Removes the current content component. + If the previous content component was added with setContentOwned(), it will also be deleted. If + it was added with setContentNonOwned(), it will simply be removed from this component. + */ + void clearContentComponent(); /** Changes the window so that the content component ends up with the specified size. @@ -55401,6 +55538,11 @@ public: backgroundColourId = 0x1005700, /**< A colour to use to fill the window's background. */ }; + /** @deprecated - use setContentOwned() and setContentNonOwned() instead. */ + JUCE_DEPRECATED (void setContentComponent (Component* newContentComponent, + bool deleteOldOne = true, + bool resizeToFit = false)); + protected: /** @internal */ @@ -55450,7 +55592,7 @@ protected: private: Component::SafePointer contentComponent; - bool resizeToFitContent, fullscreen; + bool ownsContentComponent, resizeToFitContent, fullscreen; ComponentDragger dragger; Rectangle lastNonFullScreenPos; ComponentBoundsConstrainer defaultConstrainer; @@ -55460,6 +55602,7 @@ private: #endif void updateLastPos(); + void setContent (Component* newComp, bool takeOwnership, bool resizeToFit); #if JUCE_CATCH_DEPRECATED_CODE_MISUSE // The parameters for these methods have changed - please update your code! diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 0ed14969f6..2cfc4be0ee 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 30 +#define JUCE_BUILDNUMBER 31 /** Current Juce version number. diff --git a/src/gui/components/controls/juce_Toolbar.cpp b/src/gui/components/controls/juce_Toolbar.cpp index 5746561bb6..b2e4a64bad 100644 --- a/src/gui/components/controls/juce_Toolbar.cpp +++ b/src/gui/components/controls/juce_Toolbar.cpp @@ -677,7 +677,7 @@ public: : DialogWindow (TRANS("Add/remove items from toolbar"), Colours::white, true, true), toolbar (toolbar_) { - setContentComponent (new CustomiserPanel (factory, toolbar, optionFlags), true, true); + setContentOwned (new CustomiserPanel (factory, toolbar, optionFlags), true); setResizable (true, true); setResizeLimits (400, 300, 1500, 1000); positionNearBar(); @@ -686,7 +686,6 @@ public: ~ToolbarCustomisationDialog() { toolbar->setEditingActive (false); - setContentComponent (0, true); } void closeButtonPressed() diff --git a/src/gui/components/filebrowser/juce_FileChooserDialogBox.cpp b/src/gui/components/filebrowser/juce_FileChooserDialogBox.cpp index 245899818e..2645408bac 100644 --- a/src/gui/components/filebrowser/juce_FileChooserDialogBox.cpp +++ b/src/gui/components/filebrowser/juce_FileChooserDialogBox.cpp @@ -106,7 +106,8 @@ FileChooserDialogBox::FileChooserDialogBox (const String& name, : ResizableWindow (name, backgroundColour, true), warnAboutOverwritingExistingFiles (warnAboutOverwritingExistingFiles_) { - setContentComponent (content = new ContentComponent (name, instructions, chooserComponent)); + content = new ContentComponent (name, instructions, chooserComponent); + setContentOwned (content, false); setResizable (true, true); setResizeLimits (300, 300, 1200, 1000); diff --git a/src/gui/components/layout/juce_MultiDocumentPanel.cpp b/src/gui/components/layout/juce_MultiDocumentPanel.cpp index ebfa8a0807..4f6e4c987d 100644 --- a/src/gui/components/layout/juce_MultiDocumentPanel.cpp +++ b/src/gui/components/layout/juce_MultiDocumentPanel.cpp @@ -155,7 +155,7 @@ void MultiDocumentPanel::addWindow (Component* component) MultiDocumentPanelWindow* const dw = createNewDocumentWindow(); dw->setResizable (true, false); - dw->setContentComponent (component, false, true); + dw->setContentNonOwned (component, true); dw->setName (component->getName()); const var bkg (component->getProperties() ["mdiDocumentBkg_"]); @@ -265,8 +265,7 @@ bool MultiDocumentPanel::closeDocument (Component* component, if (dw != 0 && dw->getContentComponent() == component) { - dw->setContentComponent (0, false); - delete dw; + ScopedPointer (dw)->clearContentComponent(); break; } } @@ -280,13 +279,10 @@ bool MultiDocumentPanel::closeDocument (Component* component, { for (int i = getNumChildComponents(); --i >= 0;) { - MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i)); + ScopedPointer dw (dynamic_cast (getChildComponent (i))); if (dw != 0) - { - dw->setContentComponent (0, false); - delete dw; - } + dw->clearContentComponent(); } addAndMakeVisible (components.getFirst()); @@ -423,7 +419,7 @@ void MultiDocumentPanel::setLayoutMode (const LayoutMode newLayoutMode) if (dw != 0) { dw->getContentComponent()->getProperties().set ("mdiDocumentPos_", dw->getWindowStateAsString()); - dw->setContentComponent (0, false); + dw->clearContentComponent(); delete dw; } } diff --git a/src/gui/components/windows/juce_DialogWindow.cpp b/src/gui/components/windows/juce_DialogWindow.cpp index d4bdadf3d1..efea9d6294 100644 --- a/src/gui/components/windows/juce_DialogWindow.cpp +++ b/src/gui/components/windows/juce_DialogWindow.cpp @@ -76,16 +76,11 @@ public: if (! JUCEApplication::isStandaloneApp()) setAlwaysOnTop (true); // for a plugin, make it always-on-top because the host windows are often top-level - setContentComponent (contentComponent, true, true); + setContentNonOwned (contentComponent, true); centreAroundComponent (componentToCentreAround, getWidth(), getHeight()); setResizable (shouldBeResizable, useBottomRightCornerResizer); } - ~TempDialogWindow() - { - setContentComponent (0, false); - } - void closeButtonPressed() { setVisible (false); diff --git a/src/gui/components/windows/juce_ResizableWindow.cpp b/src/gui/components/windows/juce_ResizableWindow.cpp index e2fb6a0c29..84b2ea8425 100644 --- a/src/gui/components/windows/juce_ResizableWindow.cpp +++ b/src/gui/components/windows/juce_ResizableWindow.cpp @@ -38,6 +38,7 @@ BEGIN_JUCE_NAMESPACE ResizableWindow::ResizableWindow (const String& name, const bool addToDesktop_) : TopLevelWindow (name, addToDesktop_), + ownsContentComponent (false), resizeToFitContent (false), fullscreen (false), lastNonFullScreenPos (50, 50, 256, 256), @@ -58,6 +59,7 @@ ResizableWindow::ResizableWindow (const String& name, const Colour& backgroundColour_, const bool addToDesktop_) : TopLevelWindow (name, addToDesktop_), + ownsContentComponent (false), resizeToFitContent (false), fullscreen (false), lastNonFullScreenPos (50, 50, 256, 256), @@ -84,7 +86,7 @@ ResizableWindow::~ResizableWindow() resizableCorner = 0; resizableBorder = 0; - contentComponent.deleteAndZero(); + clearContentComponent(); // have you been adding your own components directly to this window..? tut tut tut. // Read the instructions for using a ResizableWindow! @@ -102,31 +104,70 @@ int ResizableWindow::getDesktopWindowStyleFlags() const } //============================================================================== -void ResizableWindow::setContentComponent (Component* const newContentComponent, - const bool deleteOldOne, - const bool resizeToFit) +void ResizableWindow::clearContentComponent() { - resizeToFitContent = resizeToFit; + if (ownsContentComponent) + { + contentComponent.deleteAndZero(); + } + else + { + removeChildComponent (contentComponent); + contentComponent = 0; + } +} - if (newContentComponent != static_cast (contentComponent)) +void ResizableWindow::setContent (Component* newContentComponent, + const bool takeOwnership, + const bool resizeToFitWhenContentChangesSize) +{ + if (newContentComponent != contentComponent) { - if (deleteOldOne) - contentComponent.deleteAndZero(); // (avoid using a scoped pointer for this, so that it survives - // external deletion of the content comp) - else - removeChildComponent (contentComponent); + clearContentComponent(); contentComponent = newContentComponent; - Component::addAndMakeVisible (contentComponent); } - if (resizeToFit) + ownsContentComponent = takeOwnership; + resizeToFitContent = resizeToFitWhenContentChangesSize; + + if (resizeToFitWhenContentChangesSize) childBoundsChanged (contentComponent); resized(); // must always be called to position the new content comp } +void ResizableWindow::setContentOwned (Component* newContentComponent, const bool resizeToFitWhenContentChangesSize) +{ + setContent (newContentComponent, true, resizeToFitWhenContentChangesSize); +} + +void ResizableWindow::setContentNonOwned (Component* newContentComponent, const bool resizeToFitWhenContentChangesSize) +{ + setContent (newContentComponent, false, resizeToFitWhenContentChangesSize); +} + +void ResizableWindow::setContentComponent (Component* const newContentComponent, + const bool deleteOldOne, + const bool resizeToFitWhenContentChangesSize) +{ + if (newContentComponent != contentComponent) + { + if (deleteOldOne) + { + contentComponent.deleteAndZero(); + } + else + { + removeChildComponent (contentComponent); + contentComponent = 0; + } + } + + setContent (newContentComponent, true, resizeToFitWhenContentChangesSize); +} + void ResizableWindow::setContentComponentSize (int width, int height) { jassert (width > 0 && height > 0); // not a great idea to give it a zero size.. diff --git a/src/gui/components/windows/juce_ResizableWindow.h b/src/gui/components/windows/juce_ResizableWindow.h index 92fec37c16..0a98d8be14 100644 --- a/src/gui/components/windows/juce_ResizableWindow.h +++ b/src/gui/components/windows/juce_ResizableWindow.h @@ -245,21 +245,41 @@ public: You should never add components directly to a ResizableWindow (or any of its subclasses) with addChildComponent(). Instead, add them to the content component. - @param newContentComponent the new component to use (or null to not use one) - this - component will be deleted either when replaced by another call - to this method, or when the ResizableWindow is deleted. - To remove a content component without deleting it, use - setContentComponent (0, false). - @param deleteOldOne if true, the previous content component will be deleted; if - false, the previous component will just be removed without - deleting it. - @param resizeToFit if true, the ResizableWindow will maintain its size such that - it always fits around the size of the content component. If false, the - new content will be resized to fit the current space available. + @param newContentComponent the new component to use - this component will be deleted when it's + no longer needed (i.e. when the window is deleted or a new content + component is set for it). To set a component that this window will not + delete, call setContentNonOwned() instead. + @param resizeToFitWhenContentChangesSize if true, then the ResizableWindow will maintain its size + such that it always fits around the size of the content component. If false, + the new content will be resized to fit the current space available. */ - void setContentComponent (Component* newContentComponent, - bool deleteOldOne = true, - bool resizeToFit = false); + void setContentOwned (Component* newContentComponent, + bool resizeToFitWhenContentChangesSize); + + /** Changes the current content component. + + This sets a component that will be placed in the centre of the ResizableWindow, + (leaving a space around the edge for the border). + + You should never add components directly to a ResizableWindow (or any of its subclasses) + with addChildComponent(). Instead, add them to the content component. + + @param newContentComponent the new component to use - this component will NOT be deleted by this + component, so it's the caller's responsibility to manage its lifetime (it's + ok to delete it while this window is still using it). To set a content + component that the window will delete, call setContentOwned() instead. + @param resizeToFitWhenContentChangesSize if true, then the ResizableWindow will maintain its size + such that it always fits around the size of the content component. If false, + the new content will be resized to fit the current space available. + */ + void setContentNonOwned (Component* newContentComponent, + bool resizeToFitWhenContentChangesSize); + + /** Removes the current content component. + If the previous content component was added with setContentOwned(), it will also be deleted. If + it was added with setContentNonOwned(), it will simply be removed from this component. + */ + void clearContentComponent(); /** Changes the window so that the content component ends up with the specified size. @@ -291,6 +311,12 @@ public: backgroundColourId = 0x1005700, /**< A colour to use to fill the window's background. */ }; + //============================================================================== + /** @deprecated - use setContentOwned() and setContentNonOwned() instead. */ + JUCE_DEPRECATED (void setContentComponent (Component* newContentComponent, + bool deleteOldOne = true, + bool resizeToFit = false)); + protected: //============================================================================== /** @internal */ @@ -340,7 +366,7 @@ protected: private: //============================================================================== Component::SafePointer contentComponent; - bool resizeToFitContent, fullscreen; + bool ownsContentComponent, resizeToFitContent, fullscreen; ComponentDragger dragger; Rectangle lastNonFullScreenPos; ComponentBoundsConstrainer defaultConstrainer; @@ -350,6 +376,7 @@ private: #endif void updateLastPos(); + void setContent (Component* newComp, bool takeOwnership, bool resizeToFit); #if JUCE_CATCH_DEPRECATED_CODE_MISUSE // The parameters for these methods have changed - please update your code! diff --git a/src/io/streams/juce_BufferedInputStream.cpp b/src/io/streams/juce_BufferedInputStream.cpp index 81cc98b764..7b53921ffb 100644 --- a/src/io/streams/juce_BufferedInputStream.cpp +++ b/src/io/streams/juce_BufferedInputStream.cpp @@ -49,8 +49,7 @@ namespace //============================================================================== BufferedInputStream::BufferedInputStream (InputStream* const sourceStream, const int bufferSize_, const bool deleteSourceWhenDestroyed) - : source (sourceStream), - sourceToDelete (deleteSourceWhenDestroyed ? sourceStream : 0), + : source (sourceStream, deleteSourceWhenDestroyed), bufferSize (calcBufferStreamBufferSize (bufferSize_, sourceStream)), position (sourceStream->getPosition()), lastReadPos (0), @@ -61,7 +60,7 @@ BufferedInputStream::BufferedInputStream (InputStream* const sourceStream, const } BufferedInputStream::BufferedInputStream (InputStream& sourceStream, const int bufferSize_) - : source (&sourceStream), + : source (&sourceStream, false), bufferSize (calcBufferStreamBufferSize (bufferSize_, &sourceStream)), position (sourceStream.getPosition()), lastReadPos (0), diff --git a/src/io/streams/juce_BufferedInputStream.h b/src/io/streams/juce_BufferedInputStream.h index 5dbf2de0d2..501d496fe9 100644 --- a/src/io/streams/juce_BufferedInputStream.h +++ b/src/io/streams/juce_BufferedInputStream.h @@ -27,7 +27,7 @@ #define __JUCE_BUFFEREDINPUTSTREAM_JUCEHEADER__ #include "juce_InputStream.h" -#include "../../memory/juce_ScopedPointer.h" +#include "../../memory/juce_OptionalScopedPointer.h" //============================================================================== @@ -80,8 +80,7 @@ public: private: //============================================================================== - InputStream* const source; - ScopedPointer sourceToDelete; + OptionalScopedPointer source; int bufferSize; int64 position, lastReadPos, bufferStart, bufferOverlap; HeapBlock buffer; diff --git a/src/io/streams/juce_GZIPCompressorOutputStream.cpp b/src/io/streams/juce_GZIPCompressorOutputStream.cpp index b35269e6d6..c0e7919a64 100644 --- a/src/io/streams/juce_GZIPCompressorOutputStream.cpp +++ b/src/io/streams/juce_GZIPCompressorOutputStream.cpp @@ -133,8 +133,7 @@ GZIPCompressorOutputStream::GZIPCompressorOutputStream (OutputStream* const dest int compressionLevel, const bool deleteDestStream, const int windowBits) - : destStream (destStream_), - streamToDelete (deleteDestStream ? destStream_ : 0), + : destStream (destStream_, deleteDestStream), buffer ((size_t) GZIPCompressorHelper::gzipCompBufferSize) { if (compressionLevel < 1 || compressionLevel > 9) diff --git a/src/io/streams/juce_GZIPCompressorOutputStream.h b/src/io/streams/juce_GZIPCompressorOutputStream.h index d2ad2c023a..6778bb8503 100644 --- a/src/io/streams/juce_GZIPCompressorOutputStream.h +++ b/src/io/streams/juce_GZIPCompressorOutputStream.h @@ -27,7 +27,7 @@ #define __JUCE_GZIPCOMPRESSOROUTPUTSTREAM_JUCEHEADER__ #include "juce_OutputStream.h" -#include "../../memory/juce_ScopedPointer.h" +#include "../../memory/juce_OptionalScopedPointer.h" //============================================================================== @@ -79,8 +79,7 @@ public: private: //============================================================================== - OutputStream* const destStream; - ScopedPointer streamToDelete; + OptionalScopedPointer destStream; HeapBlock buffer; class GZIPCompressorHelper; friend class ScopedPointer ; diff --git a/src/io/streams/juce_GZIPDecompressorInputStream.cpp b/src/io/streams/juce_GZIPDecompressorInputStream.cpp index ba98f30c34..b997a7827f 100644 --- a/src/io/streams/juce_GZIPDecompressorInputStream.cpp +++ b/src/io/streams/juce_GZIPDecompressorInputStream.cpp @@ -161,8 +161,7 @@ GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const sou const bool deleteSourceWhenDestroyed, const bool noWrap_, const int64 uncompressedStreamLength_) - : sourceStream (sourceStream_), - streamToDelete (deleteSourceWhenDestroyed ? sourceStream_ : 0), + : sourceStream (sourceStream_, deleteSourceWhenDestroyed), uncompressedStreamLength (uncompressedStreamLength_), noWrap (noWrap_), isEof (false), @@ -175,7 +174,7 @@ GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const sou } GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream& sourceStream_) - : sourceStream (&sourceStream_), + : sourceStream (&sourceStream_, false), uncompressedStreamLength (-1), noWrap (false), isEof (false), diff --git a/src/io/streams/juce_GZIPDecompressorInputStream.h b/src/io/streams/juce_GZIPDecompressorInputStream.h index ab84c0c2b5..49922666f2 100644 --- a/src/io/streams/juce_GZIPDecompressorInputStream.h +++ b/src/io/streams/juce_GZIPDecompressorInputStream.h @@ -27,7 +27,7 @@ #define __JUCE_GZIPDECOMPRESSORINPUTSTREAM_JUCEHEADER__ #include "juce_InputStream.h" -#include "../../memory/juce_ScopedPointer.h" +#include "../../memory/juce_OptionalScopedPointer.h" //============================================================================== @@ -80,8 +80,7 @@ public: //============================================================================== private: - InputStream* const sourceStream; - ScopedPointer streamToDelete; + OptionalScopedPointer sourceStream; const int64 uncompressedStreamLength; const bool noWrap; bool isEof; diff --git a/src/io/streams/juce_SubregionStream.cpp b/src/io/streams/juce_SubregionStream.cpp index fb911f1029..7375bbbef1 100644 --- a/src/io/streams/juce_SubregionStream.cpp +++ b/src/io/streams/juce_SubregionStream.cpp @@ -35,13 +35,10 @@ SubregionStream::SubregionStream (InputStream* const sourceStream, const int64 startPositionInSourceStream_, const int64 lengthOfSourceStream_, const bool deleteSourceWhenDestroyed) - : source (sourceStream), + : source (sourceStream, deleteSourceWhenDestroyed), startPositionInSourceStream (startPositionInSourceStream_), lengthOfSourceStream (lengthOfSourceStream_) { - if (deleteSourceWhenDestroyed) - sourceToDelete = source; - setPosition (0); } diff --git a/src/io/streams/juce_SubregionStream.h b/src/io/streams/juce_SubregionStream.h index bf0552e697..6ad9010bd8 100644 --- a/src/io/streams/juce_SubregionStream.h +++ b/src/io/streams/juce_SubregionStream.h @@ -27,7 +27,7 @@ #define __JUCE_SUBREGIONSTREAM_JUCEHEADER__ #include "juce_InputStream.h" -#include "../../memory/juce_ScopedPointer.h" +#include "../../memory/juce_OptionalScopedPointer.h" //============================================================================== @@ -80,8 +80,7 @@ public: //============================================================================== private: - InputStream* const source; - ScopedPointer sourceToDelete; + OptionalScopedPointer source; const int64 startPositionInSourceStream, lengthOfSourceStream; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SubregionStream); diff --git a/src/juce_core_includes.h b/src/juce_core_includes.h index 827013e991..380c688458 100644 --- a/src/juce_core_includes.h +++ b/src/juce_core_includes.h @@ -221,6 +221,9 @@ #ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__ #include "memory/juce_MemoryBlock.h" #endif +#ifndef __JUCE_OPTIONALSCOPEDPOINTER_JUCEHEADER__ + #include "memory/juce_OptionalScopedPointer.h" +#endif #ifndef __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__ #include "memory/juce_ReferenceCountedObject.h" #endif