diff --git a/build/linux/platform_specific_code/juce_linux_Windowing.cpp b/build/linux/platform_specific_code/juce_linux_Windowing.cpp index 2f99e6f3f6..c7b3bb0c9a 100644 --- a/build/linux/platform_specific_code/juce_linux_Windowing.cpp +++ b/build/linux/platform_specific_code/juce_linux_Windowing.cpp @@ -2595,8 +2595,6 @@ void juce_windowMessageReceive (XEvent* event) { LinuxComponentPeer* const peer = LinuxComponentPeer::getPeerFor (event->xany.window); - const MessageManagerLock messLock; - if (ComponentPeer::isValidPeer (peer)) peer->handleWindowMessage (event); } diff --git a/build/macosx/Juce.xcodeproj/project.pbxproj b/build/macosx/Juce.xcodeproj/project.pbxproj index 37a92bc699..9f3b89dac1 100644 --- a/build/macosx/Juce.xcodeproj/project.pbxproj +++ b/build/macosx/Juce.xcodeproj/project.pbxproj @@ -473,6 +473,7 @@ 84A48BEB08A22E4B00752A2B /* juce_TimeSliceThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A48A2508A22E4A00752A2B /* juce_TimeSliceThread.cpp */; }; 84A48BEC08A22E4B00752A2B /* juce_TimeSliceThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A48A2608A22E4A00752A2B /* juce_TimeSliceThread.h */; }; 84A48BED08A22E4B00752A2B /* juce_WaitableEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A48A2708A22E4A00752A2B /* juce_WaitableEvent.h */; }; + 84B1C1330F6287E70068E14F /* juce_CallbackMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 84B1C1320F6287E70068E14F /* juce_CallbackMessage.h */; }; 84BC4E290C8DD38C00FA249B /* juce_AudioPlayHead.h in Headers */ = {isa = PBXBuildFile; fileRef = 84BC4E210C8DD38C00FA249B /* juce_AudioPlayHead.h */; }; 84BC4E2A0C8DD38C00FA249B /* juce_AudioProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84BC4E220C8DD38C00FA249B /* juce_AudioProcessor.cpp */; }; 84BC4E2B0C8DD38C00FA249B /* juce_AudioProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 84BC4E230C8DD38C00FA249B /* juce_AudioProcessor.h */; }; @@ -1060,6 +1061,7 @@ 84A48A2508A22E4A00752A2B /* juce_TimeSliceThread.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_TimeSliceThread.cpp; path = ../../src/juce_core/threads/juce_TimeSliceThread.cpp; sourceTree = SOURCE_ROOT; }; 84A48A2608A22E4A00752A2B /* juce_TimeSliceThread.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_TimeSliceThread.h; path = ../../src/juce_core/threads/juce_TimeSliceThread.h; sourceTree = SOURCE_ROOT; }; 84A48A2708A22E4A00752A2B /* juce_WaitableEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_WaitableEvent.h; path = ../../src/juce_core/threads/juce_WaitableEvent.h; sourceTree = SOURCE_ROOT; }; + 84B1C1320F6287E70068E14F /* juce_CallbackMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_CallbackMessage.h; sourceTree = ""; }; 84BC4E210C8DD38C00FA249B /* juce_AudioPlayHead.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_AudioPlayHead.h; sourceTree = ""; }; 84BC4E220C8DD38C00FA249B /* juce_AudioProcessor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = juce_AudioProcessor.cpp; sourceTree = ""; }; 84BC4E230C8DD38C00FA249B /* juce_AudioProcessor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_AudioProcessor.h; sourceTree = ""; }; @@ -1495,6 +1497,7 @@ 84A4886908A22E4900752A2B /* juce_ActionListenerList.h */, 84A4886A08A22E4900752A2B /* juce_AsyncUpdater.cpp */, 84A4886B08A22E4900752A2B /* juce_AsyncUpdater.h */, + 84B1C1320F6287E70068E14F /* juce_CallbackMessage.h */, 84A4886C08A22E4900752A2B /* juce_ChangeBroadcaster.cpp */, 84A4886D08A22E4900752A2B /* juce_ChangeBroadcaster.h */, 84A4886E08A22E4900752A2B /* juce_ChangeListener.h */, @@ -2547,6 +2550,7 @@ 8457783E0E8947C8006D9E4E /* juce_NSViewComponent.h in Headers */, 84E025060E94028C003E41AF /* juce_posix_SharedCode.h in Headers */, 84F8B60D0EB5B9230020D98D /* juce_mac_NativeIncludes.h in Headers */, + 84B1C1330F6287E70068E14F /* juce_CallbackMessage.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/build/macosx/platform_specific_code/juce_mac_AppleRemote.mm b/build/macosx/platform_specific_code/juce_mac_AppleRemote.mm index 71c892f02f..04c3b429d4 100644 --- a/build/macosx/platform_specific_code/juce_mac_AppleRemote.mm +++ b/build/macosx/platform_specific_code/juce_mac_AppleRemote.mm @@ -265,7 +265,6 @@ void AppleRemoteDevice::handleCallbackInternal() { if (strcmp (cookies, buttonPatterns + i) == 0) { - const MessageManagerLock mml; buttonPressed ((ButtonType) buttonNum, totalValues > 0); break; } diff --git a/build/macosx/platform_specific_code/juce_mac_AudioCDBurner.mm b/build/macosx/platform_specific_code/juce_mac_AudioCDBurner.mm index ff18fc81bc..1506ceb30b 100644 --- a/build/macosx/platform_specific_code/juce_mac_AudioCDBurner.mm +++ b/build/macosx/platform_specific_code/juce_mac_AudioCDBurner.mm @@ -161,8 +161,6 @@ END_JUCE_NAMESPACE JUCE_NAMESPACE::Thread::sleep (300); float progress = [[[burn status] objectForKey: DRStatusPercentCompleteKey] floatValue]; -NSLog ([[burn status] description]); - if (listener != 0 && listener->audioCDBurnProgress (progress)) { [burn abort]; diff --git a/build/macosx/platform_specific_code/juce_mac_Debugging.mm b/build/macosx/platform_specific_code/juce_mac_Debugging.mm index 572666cdfc..7e280d1274 100644 --- a/build/macosx/platform_specific_code/juce_mac_Debugging.mm +++ b/build/macosx/platform_specific_code/juce_mac_Debugging.mm @@ -36,8 +36,8 @@ //============================================================================== void Logger::outputDebugString (const String& text) throw() { - const ScopedAutoReleasePool pool; - NSLog (juceStringToNS (text + T("\n"))); + fputs (text.toUTF8(), stderr); + fputs ("\n", stderr); } void Logger::outputDebugPrintf (const tchar* format, ...) throw() @@ -45,7 +45,7 @@ void Logger::outputDebugPrintf (const tchar* format, ...) throw() String text; va_list args; va_start (args, format); - text.vprintf(format, args); + text.vprintf (format, args); outputDebugString (text); } diff --git a/build/macosx/platform_specific_code/juce_mac_Fonts.mm b/build/macosx/platform_specific_code/juce_mac_Fonts.mm index b51b4eb706..aac5b68b57 100644 --- a/build/macosx/platform_specific_code/juce_mac_Fonts.mm +++ b/build/macosx/platform_specific_code/juce_mac_Fonts.mm @@ -41,7 +41,7 @@ class FontHelper public: String name; - bool isBold, isItalic; + bool isBold, isItalic, needsItalicTransform; float fontSize, totalSize, ascent; int refCount; NSMutableDictionary* attributes; @@ -54,6 +54,7 @@ public: name (name_), isBold (bold_), isItalic (italic_), + needsItalicTransform (false), fontSize (size_), refCount (1) { @@ -67,10 +68,7 @@ public: NSFont* newFont = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSItalicFontMask]; if (newFont == font) - { - // couldn't find an italic version, so fake it with obliqueness.. - [attributes setObject: [NSNumber numberWithFloat: 0.16] forKey: NSObliquenessAttributeName]; - } + needsItalicTransform = true; // couldn't find a proper italic version, so fake it with a transform.. font = newFont; } @@ -155,6 +153,9 @@ public: break; } } + + if (needsItalicTransform) + path->applyTransform (AffineTransform::identity.sheared (-0.15, 0)); } return kerning != 0; diff --git a/build/macosx/platform_specific_code/juce_mac_MainMenu.mm b/build/macosx/platform_specific_code/juce_mac_MainMenu.mm index dc05c1187c..6d17317390 100644 --- a/build/macosx/platform_specific_code/juce_mac_MainMenu.mm +++ b/build/macosx/platform_specific_code/juce_mac_MainMenu.mm @@ -212,16 +212,11 @@ public: void updateMenus() { if (Time::getMillisecondCounter() > lastUpdateTime + 500) - { - const MessageManagerLock mml; menuBarItemsChanged (0); - } } void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const { - const MessageManagerLock mml; - if (currentModel != 0) { if (commandManager != 0) diff --git a/build/macosx/platform_specific_code/juce_mac_MessageManager.mm b/build/macosx/platform_specific_code/juce_mac_MessageManager.mm index f9cab0749d..9822f25d78 100644 --- a/build/macosx/platform_specific_code/juce_mac_MessageManager.mm +++ b/build/macosx/platform_specific_code/juce_mac_MessageManager.mm @@ -61,7 +61,6 @@ public: { if (JUCEApplication::getInstance() != 0) { - const MessageManagerLock mml; JUCEApplication::getInstance()->systemRequestedQuit(); return NSTerminateCancel; } @@ -73,7 +72,6 @@ public: { if (JUCEApplication::getInstance() != 0) { - const MessageManagerLock mml; JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename)); return YES; } @@ -89,14 +87,12 @@ public: if (files.size() > 0 && JUCEApplication::getInstance() != 0) { - const MessageManagerLock mml; JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" "))); } } virtual void focusChanged() { - const MessageManagerLock mml; juce_HandleProcessFocusChange(); } @@ -108,11 +104,10 @@ public: virtual void performCallback (CallbackMessagePayload* pl) { - const MessageManagerLock mml; pl->result = (*pl->function) (pl->parameter); pl->hasBeenExecuted = true; } - + virtual void deleteSelf() { delete this; @@ -357,6 +352,11 @@ void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* call } else { + // If a thread has a MessageManagerLock and then tries to call this method, it'll + // deadlock because the message manager is blocked from running, so can never + // call your function.. + jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + const ScopedAutoReleasePool pool; CallbackMessagePayload cmp; diff --git a/build/macosx/platform_specific_code/juce_mac_NSViewComponentPeer.mm b/build/macosx/platform_specific_code/juce_mac_NSViewComponentPeer.mm index 7003ce6498..34bd4928db 100644 --- a/build/macosx/platform_specific_code/juce_mac_NSViewComponentPeer.mm +++ b/build/macosx/platform_specific_code/juce_mac_NSViewComponentPeer.mm @@ -918,8 +918,6 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r) { if (constrainer != 0) { - const MessageManagerLock mml; - NSRect current = [window frame]; current.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - current.origin.y - current.size.height; @@ -1082,8 +1080,6 @@ void NSViewComponentPeer::setIcon (const Image& /*newIcon*/) //============================================================================== void NSViewComponentPeer::viewFocusGain() { - const MessageManagerLock messLock; - if (currentlyFocusedPeer != this) { if (ComponentPeer::isValidPeer (currentlyFocusedPeer)) @@ -1146,8 +1142,6 @@ void NSViewComponentPeer::textInputRequired (int /*x*/, int /*y*/) bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) { - const MessageManagerLock mml; - String unicode (nsStringToJuce ([ev characters])); String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers])); int keyCode = getKeyCodeFromEvent (ev); @@ -1187,7 +1181,6 @@ bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) { - const MessageManagerLock mml; updateKeysDown (ev, true); bool used = handleKeyEvent (ev, true); @@ -1203,14 +1196,12 @@ bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev) { - const MessageManagerLock mml; updateKeysDown (ev, false); return handleKeyEvent (ev, false); } void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); handleModifierKeysChange(); } @@ -1218,7 +1209,6 @@ void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) #if MACOS_10_4_OR_EARLIER bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) { - const MessageManagerLock mml; if ([ev type] == NSKeyDown) return redirectKeyDown (ev); else if ([ev type] == NSKeyUp) @@ -1231,7 +1221,6 @@ bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) //============================================================================== void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); int x, y; @@ -1242,7 +1231,6 @@ void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) { - const MessageManagerLock mml; const int oldMods = currentModifiers; updateModifiers (ev); currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]); @@ -1254,7 +1242,6 @@ void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); int x, y; @@ -1265,7 +1252,6 @@ void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); int x, y; getMousePos (ev, view, x, y); @@ -1275,7 +1261,6 @@ void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); int x, y; getMousePos (ev, view, x, y); @@ -1285,7 +1270,6 @@ void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); int x, y; getMousePos (ev, view, x, y); @@ -1295,7 +1279,6 @@ void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f), @@ -1306,8 +1289,6 @@ void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) //============================================================================== BOOL NSViewComponentPeer::sendDragCallback (int type, id sender) { - const MessageManagerLock mml; - NSString* bestType = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]]; @@ -1358,7 +1339,6 @@ void NSViewComponentPeer::drawRect (NSRect r) if (r.size.width < 1.0f || r.size.height < 1.0f) return; - const MessageManagerLock mml; const float y = [view frame].size.height - (r.origin.y + r.size.height); JuceNSImage temp ((int) (r.size.width + 0.5f), @@ -1392,8 +1372,6 @@ void NSViewComponentPeer::drawRect (NSRect r) bool NSViewComponentPeer::canBecomeKeyWindow() { - const MessageManagerLock mml; - // If running as a plugin, let the component decide whether it's going to allow the window to get focused. return JUCEApplication::getInstance() != 0 || (isValidPeer (this) && getComponent()->getWantsKeyboardFocus()); @@ -1401,8 +1379,6 @@ bool NSViewComponentPeer::canBecomeKeyWindow() bool NSViewComponentPeer::windowShouldClose() { - const MessageManagerLock mml; - if (! isValidPeer (this)) return YES; @@ -1412,7 +1388,6 @@ bool NSViewComponentPeer::windowShouldClose() void NSViewComponentPeer::redirectMovedOrResized() { - const MessageManagerLock mml; handleMovedOrResized(); } diff --git a/build/macosx/platform_specific_code/juce_mac_Network.mm b/build/macosx/platform_specific_code/juce_mac_Network.mm index e29ce1d1c1..7ceb5ee717 100644 --- a/build/macosx/platform_specific_code/juce_mac_Network.mm +++ b/build/macosx/platform_specific_code/juce_mac_Network.mm @@ -284,7 +284,7 @@ public: - (void) connection: (NSURLConnection*) connection didFailWithError: (NSError*) error { - NSLog ([error description]); + DBG (nsStringToJuce ([error description])); hasFailed = true; initialised = true; runLoopThread->signalThreadShouldExit(); diff --git a/build/macosx/platform_specific_code/juce_mac_WebBrowserComponent.mm b/build/macosx/platform_specific_code/juce_mac_WebBrowserComponent.mm index 0d8f8b3847..2beaedabc6 100644 --- a/build/macosx/platform_specific_code/juce_mac_WebBrowserComponent.mm +++ b/build/macosx/platform_specific_code/juce_mac_WebBrowserComponent.mm @@ -69,8 +69,6 @@ END_JUCE_NAMESPACE { NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"]; - const MessageManagerLock mml; - if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString]))) [listener use]; else diff --git a/build/win32/platform_specific_code/juce_win32_Messaging.cpp b/build/win32/platform_specific_code/juce_win32_Messaging.cpp index c074d235c9..6e7333b74c 100644 --- a/build/win32/platform_specific_code/juce_win32_Messaging.cpp +++ b/build/win32/platform_specific_code/juce_win32_Messaging.cpp @@ -101,8 +101,6 @@ bool juce_dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages if (GetMessage (&m, (HWND) 0, 0, 0) > 0) { - const MessageManagerLock mml; - if (m.message == specialId && m.hwnd == juce_messageWindowHandle) { diff --git a/build/win32/platform_specific_code/juce_win32_Windowing.cpp b/build/win32/platform_specific_code/juce_win32_Windowing.cpp index ace941ab49..3d97680e81 100644 --- a/build/win32/platform_specific_code/juce_win32_Windowing.cpp +++ b/build/win32/platform_specific_code/juce_win32_Windowing.cpp @@ -1805,8 +1805,6 @@ private: LRESULT peerWindowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) { { - const MessageManagerLock messLock; - if (isValidPeer (this)) { switch (message) diff --git a/build/win32/vc8/JUCE.vcproj b/build/win32/vc8/JUCE.vcproj index 9a04f22e8a..93d5d05ef4 100644 --- a/build/win32/vc8/JUCE.vcproj +++ b/build/win32/vc8/JUCE.vcproj @@ -43,7 +43,7 @@ Name="VCCLCompilerTool" Optimization="0" PreprocessorDefinitions="WIN32;_DEBUG;_LIB" - MinimalRebuild="true" + MinimalRebuild="false" BasicRuntimeChecks="3" RuntimeLibrary="1" RuntimeTypeInfo="true" @@ -117,6 +117,7 @@ WholeProgramOptimization="true" PreprocessorDefinitions="WIN32;NDEBUG;_LIB" StringPooling="true" + MinimalRebuild="false" RuntimeLibrary="0" RuntimeTypeInfo="true" UsePrecompiledHeader="0" @@ -184,7 +185,7 @@ Name="VCCLCompilerTool" Optimization="0" PreprocessorDefinitions="WIN32;_DEBUG;_LIB;JUCE_DLL_BUILD;JUCE_DLL" - MinimalRebuild="true" + MinimalRebuild="false" BasicRuntimeChecks="3" RuntimeLibrary="1" RuntimeTypeInfo="true" @@ -269,6 +270,7 @@ WholeProgramOptimization="true" PreprocessorDefinitions="WIN32;NDEBUG;_LIB;JUCE_DLL_BUILD;JUCE_DLL" StringPooling="true" + MinimalRebuild="false" RuntimeLibrary="0" EnableFunctionLevelLinking="true" RuntimeTypeInfo="true" @@ -1222,6 +1224,10 @@ RelativePath="..\..\..\src\juce_appframework\events\juce_AsyncUpdater.h" > + + diff --git a/extras/audio plugins/How to use this framework.txt b/extras/audio plugins/How to use this framework.txt index 37f39ff0af..142da6aca7 100644 --- a/extras/audio plugins/How to use this framework.txt +++ b/extras/audio plugins/How to use this framework.txt @@ -87,28 +87,30 @@ make it easier to update to the latest code. - From the Digidesign website, download their latest Plug-In SDK - Install the SDK and build some of the demo plugins to make sure it all works. - In Visual Studio: Add all of these to your include path: - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\common - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\common\Platform - c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public - c:\yourdirectory\PT_73_SDK\AlturaPorts\SADriver\Interfaces - c:\yourdirectory\PT_73_SDK\AlturaPorts\DigiPublic\Interfaces - c:\yourdirectory\PT_73_SDK\AlturaPorts\Fic\Interfaces\DAEClient - c:\yourdirectory\PT_73_SDK\AlturaPorts\NewFileLibs\Cmn - c:\yourdirectory\PT_73_SDK\AlturaPorts\NewFileLibs\DOA - c:\yourdirectory\PT_73_SDK\AlturaPorts\AlturaSource\PPC_H - c:\yourdirectory\PT_73_SDK\AlturaPorts\AlturaSource\AppSupport - c:\yourdirectory\PT_73_SDK\AvidCode\AVX2sdk\AVX\avx2\avx2sdk\inc + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\common + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\common\Platform + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public + C:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugIns\DSPManager\Interfaces + c:\yourdirectory\PT_80_SDK\AlturaPorts\SADriver\Interfaces + c:\yourdirectory\PT_80_SDK\AlturaPorts\DigiPublic\Interfaces + c:\yourdirectory\PT_80_SDK\AlturaPorts\Fic\Interfaces\DAEClient + c:\yourdirectory\PT_80_SDK\AlturaPorts\NewFileLibs\Cmn + c:\yourdirectory\PT_80_SDK\AlturaPorts\NewFileLibs\DOA + c:\yourdirectory\PT_80_SDK\AlturaPorts\AlturaSource\PPC_H + c:\yourdirectory\PT_80_SDK\AlturaPorts\AlturaSource\AppSupport + c:\yourdirectory\PT_80_SDK\AvidCode\AVX2sdk\AVX\avx2\avx2sdk\inc + C:\yourdirectory\PT_80_SDK\xplat\AVX\avx2\avx2sdk\inc - In Visual Studio: Using the Digidesign demo projects in the SDK, make sure you've compiled debug and release versions of the following static libraries: DAE.lib, DigiExt.lib, DSI.lib, PlugInLib.lib. @@ -267,8 +269,8 @@ If you also want to build an RTAS, then carry on reading... the "libPluginLibrary.a" item inside it. Drag this subitem down to your Target/"Link Binary With Libraries" build stage and drop it there to add it to the link process. - In your Info.plist, change the "Bundle OS Type Code" to "TDMw", and the "Bundle Creator OS Type Code" to - "PTul". -- You may need to remove the "OTHER_CFLAGS = -x c++" from the RTAS settings file to stop it complaining about + "PTul". +- You may need to remove the "OTHER_CFLAGS = -x c++" from the RTAS settings file to stop it complaining about obj-C code You should now be able to build an RTAS! Again, just renaming the finished bundle to ".dpm" and diff --git a/extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm b/extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm index 3812ee0a98..2d43b0ecf5 100644 --- a/extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm +++ b/extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm @@ -617,7 +617,6 @@ public: #endif } - OSStatus ProcessBufferLists (AudioUnitRenderActionFlags& ioActionFlags, const AudioBufferList& inBuffer, AudioBufferList& outBuffer, diff --git a/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp b/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp index 46fb99fcb2..61ae6dc8b6 100644 --- a/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp +++ b/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp @@ -29,6 +29,12 @@ ============================================================================== */ +#ifdef _MSC_VER + // (this is a workaround for a build problem in VC9) + #define _DO_NOT_DECLARE_INTERLOCKED_INTRINSICS_IN_MEMORY + #include +#endif + #include "juce_RTAS_DigiCode_Header.h" #if JucePlugin_Build_RTAS @@ -43,28 +49,30 @@ To be able to include all the Digidesign headers correctly, you'll need to add this lot to your include path: - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\common - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\common\Platform - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public - c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugIns\DSPManager\Interfaces - c:\yourdirectory\PT_711_SDK\AlturaPorts\SADriver\Interfaces - c:\yourdirectory\PT_711_SDK\AlturaPorts\DigiPublic\Interfaces - c:\yourdirectory\PT_711_SDK\AlturaPorts\Fic\Interfaces\DAEClient - c:\yourdirectory\PT_711_SDK\AlturaPorts\NewFileLibs\Cmn - c:\yourdirectory\PT_711_SDK\AlturaPorts\NewFileLibs\DOA - c:\yourdirectory\PT_711_SDK\AlturaPorts\AlturaSource\PPC_H - c:\yourdirectory\PT_711_SDK\AlturaPorts\AlturaSource\AppSupport + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\common + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\common\Platform + c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public + C:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugIns\DSPManager\Interfaces + c:\yourdirectory\PT_80_SDK\AlturaPorts\SADriver\Interfaces + c:\yourdirectory\PT_80_SDK\AlturaPorts\DigiPublic\Interfaces + c:\yourdirectory\PT_80_SDK\AlturaPorts\Fic\Interfaces\DAEClient + c:\yourdirectory\PT_80_SDK\AlturaPorts\NewFileLibs\Cmn + c:\yourdirectory\PT_80_SDK\AlturaPorts\NewFileLibs\DOA + c:\yourdirectory\PT_80_SDK\AlturaPorts\AlturaSource\PPC_H + c:\yourdirectory\PT_80_SDK\AlturaPorts\AlturaSource\AppSupport + c:\yourdirectory\PT_80_SDK\AvidCode\AVX2sdk\AVX\avx2\avx2sdk\inc + C:\yourdirectory\PT_80_SDK\xplat\AVX\avx2\avx2sdk\inc NB. If you hit a huge pile of bugs around here, make sure that you've not got the Apple QuickTime headers before the PT headers in your path, because there are @@ -983,7 +991,9 @@ void initialiseMacRTAS(); CProcessGroupInterface* CProcessGroup::CreateProcessGroup() { +#if JUCE_MAC initialiseMacRTAS(); +#endif initialiseJuce_NonGUI(); return new JucePlugInGroup(); } diff --git a/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp b/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp index 699fbfaf3d..1d8d61adad 100644 --- a/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp +++ b/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp @@ -292,12 +292,7 @@ public: Component* const c = getChildComponent (0); if (c != 0) - { -#if JUCE_LINUX - const MessageManagerLock mml; -#endif c->setBounds (0, 0, getWidth(), getHeight()); - } } void childBoundsChanged (Component* child); @@ -428,10 +423,6 @@ public: { if (editorComp == 0) { -#if JUCE_LINUX - const MessageManagerLock mml; -#endif - AudioProcessorEditor* const ed = filter->createEditorIfNeeded(); if (ed != 0) @@ -1086,8 +1077,6 @@ public: if (MessageManager::getInstance()->isThisTheMessageThread() && ! recursionCheck) { - const MessageManagerLock mml; - recursionCheck = true; juce_callAnyTimersSynchronously(); @@ -1106,10 +1095,6 @@ public: if (editorComp == 0) { -#if JUCE_LINUX - const MessageManagerLock mml; -#endif - AudioProcessorEditor* const ed = filter->createEditorIfNeeded(); if (ed != 0) @@ -1136,10 +1121,6 @@ public: jassert (! recursionCheck); recursionCheck = true; -#if JUCE_LINUX - const MessageManagerLock mml; -#endif - if (editorComp != 0) { Component* const modalComponent = Component::getCurrentlyModalComponent(); @@ -1197,10 +1178,6 @@ public: if (editorComp != 0) { -#if JUCE_LINUX - const MessageManagerLock mml; -#endif - editorComp->setOpaque (true); editorComp->setVisible (false); diff --git a/extras/juce demo/src/BinaryData.cpp b/extras/juce demo/src/BinaryData.cpp index c6640be808..88ce28235e 100644 --- a/extras/juce demo/src/BinaryData.cpp +++ b/extras/juce demo/src/BinaryData.cpp @@ -7999,4 +7999,3 @@ static const unsigned char temp17[] = {47,42,13,10,32,32,61,61,61,61,61,61,61,61 111,109,109,97,110,100,77,97,110,97,103,101,114,41,13,10,123,13,10,32,32,32,32,114,101,116,117,114,110,32,110,101,119,32,87,105,100,103,101,116, 115,68,101,109,111,32,40,99,111,109,109,97,110,100,77,97,110,97,103,101,114,41,59,13,10,125,13,10,0,0}; const char* BinaryData::widgetsdemo_cpp = (const char*) temp17; - diff --git a/extras/juce demo/src/demos/ThreadingDemo.cpp b/extras/juce demo/src/demos/ThreadingDemo.cpp index 232c317dbd..9135c67e60 100644 --- a/extras/juce demo/src/demos/ThreadingDemo.cpp +++ b/extras/juce demo/src/demos/ThreadingDemo.cpp @@ -33,13 +33,11 @@ //============================================================================== -class BouncingBallComp : public Component, - public AsyncUpdater +class BouncingBallComp : public Component { float x, y, size, dx, dy, w, h, parentWidth, parentHeight; float innerX, innerY; Colour colour; - CriticalSection lock; Thread::ThreadID threadId; public: @@ -88,25 +86,8 @@ public: parentHeight = getParentHeight() - size; } - void handleAsyncUpdate() - { - const ScopedLock sl (lock); - - setBounds (((int) x) - 2, - ((int) y) - 2, - ((int) size) + 4, - ((int) size) + 4); - - innerX = x - getX(); - innerY = y - getY(); - - repaint(); - } - void moveBall() { - const ScopedLock sl (lock); - threadId = Thread::getCurrentThreadId(); // this is so the component can print the thread ID inside the ball x += dx; @@ -124,10 +105,15 @@ public: if (y > parentHeight) dy = -fabsf (dy); - // this is called on a background thread, so we don't want to call - // any UI code from here - instead we'll trigger an event that will update - // the component's position later. This is a safe way to avoid deadlocks - triggerAsyncUpdate(); + setBounds (((int) x) - 2, + ((int) y) - 2, + ((int) size) + 4, + ((int) size) + 4); + + innerX = x - getX(); + innerY = y - getY(); + + repaint(); } juce_UseDebuggingNewOperator @@ -166,10 +152,18 @@ public: // called, so we should check it often, and exit as soon as it gets flagged. while (! threadShouldExit()) { - moveBall(); - // sleep a bit so the threads don't all grind the CPU to a halt.. wait (interval); + + // because this is a background thread, we mustn't do any UI work without + // first grabbing a MessageManagerLock.. + const MessageManagerLock mml (Thread::getCurrentThread()); + + if (! mml.lockWasGained()) // if something is trying to kill this job, the lock + return; // will fail, in which case we'd better return.. + + // now we've got the UI thread locked, we can mess about with the components + moveBall(); } } @@ -196,9 +190,18 @@ public: // this is the code that runs this job. It'll be repeatedly called until we return // jobHasFinished instead of jobNeedsRunningAgain. - moveBall(); Thread::sleep (30); + + // because this is a background thread, we mustn't do any UI work without + // first grabbing a MessageManagerLock.. + const MessageManagerLock mml (this); + + // before moving the ball, we need to check whether the lock was actually gained, because + // if something is trying to stop this job, it will have failed.. + if (mml.lockWasGained()) + moveBall(); + return jobNeedsRunningAgain; } diff --git a/extras/the jucer/src/BinaryData.cpp b/extras/the jucer/src/BinaryData.cpp index c08fddd03e..1279f531a8 100644 --- a/extras/the jucer/src/BinaryData.cpp +++ b/extras/the jucer/src/BinaryData.cpp @@ -911,4 +911,3 @@ static const unsigned char temp4[] = {137,80,78,71,13,10,26,10,0,0,0,13,73,72,68 0,98,28,9,155,95,0,2,104,68,236,11,1,8,160,17,225,73,128,0,3,0,120,52,172,151,198,78,252,63,0,0,0,0,73,69,78,68,174,66, 96,130,0,0}; const char* BinaryData::prefs_misc_png = (const char*) temp4; - diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 2900d01057..bb1fba66c7 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -15680,12 +15680,8 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app) { juce_setCurrentThreadName ("Juce Message Thread"); - { - const MessageManagerLock mml; - - // let the app do its setting-up.. - app->initialise (app->commandLineParameters); - } + // let the app do its setting-up.. + app->initialise (app->commandLineParameters); // register for broadcast new app messages MessageManager::getInstance()->registerBroadcastListener (app); @@ -15732,7 +15728,6 @@ int JUCEApplication::shutdownAppAndClearUp() JUCE_TRY { // give the app a chance to clean up.. - const MessageManagerLock mml; app->shutdown(); } #if JUCE_CATCH_UNHANDLED_EXCEPTIONS @@ -15830,7 +15825,6 @@ void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI() const ScopedAutoReleasePool pool; #endif { - const MessageManagerLock mml; DeletedAtShutdown::deleteAll(); LookAndFeel::clearDefaultLookAndFeel(); @@ -21936,6 +21930,27 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf for (int i = jmin (2, info.buffer->getNumChannels()); --i >= 0;) applyFilter (info.buffer->getSampleData (i, info.startSample), info.numSamples, filterStates[i]); } + else if (ratio <= 1.0001) + { + // if the filter's not currently being applied, keep it stoked with the last couple of samples to avoid discontinuities + for (int i = jmin (2, info.buffer->getNumChannels()); --i >= 0;) + { + const float* const endOfBuffer = info.buffer->getSampleData (i, info.startSample + info.numSamples - 1); + FilterState& fs = filterStates[i]; + + if (info.numSamples > 1) + { + fs.y2 = fs.x2 = *(endOfBuffer - 1); + } + else + { + fs.y2 = fs.y1; + fs.x2 = fs.x1; + } + + fs.y1 = fs.x1 = *endOfBuffer; + } + } jassert (sampsInBuffer >= 0); } @@ -32272,8 +32287,6 @@ VstIntPtr VSTPluginInstance::handleCallback (VstInt32 opcode, VstInt32 index, Vs if (getActiveEditor() != 0) dispatch (effEditIdle, 0, 0, 0, 0); #endif - const MessageManagerLock mml; - juce_callAnyTimersSynchronously(); handleUpdateNowIfNeeded(); @@ -36799,9 +36812,9 @@ static const int quitMessageId = 0xfffff321; MessageManager::MessageManager() throw() : broadcastListeners (0), quitMessagePosted (false), - quitMessageReceived (false) + quitMessageReceived (false), + threadWithLock (0) { - currentLockingThreadId = 0; messageThreadId = Thread::getCurrentThreadId(); } @@ -36832,26 +36845,46 @@ void MessageManager::postMessageToQueue (Message* const message) delete message; } +CallbackMessage::CallbackMessage() throw() {} +CallbackMessage::~CallbackMessage() throw() {} + +void CallbackMessage::post() +{ + if (MessageManager::instance != 0) + MessageManager::instance->postCallbackMessage (this); +} + +void MessageManager::postCallbackMessage (Message* const message) +{ + message->messageRecipient = 0; + postMessageToQueue (message); +} + // not for public use.. void MessageManager::deliverMessage (void* message) { - const MessageManagerLock lock; - Message* const m = (Message*) message; MessageListener* const recipient = m->messageRecipient; - if (messageListeners.contains (recipient)) + JUCE_TRY { - JUCE_TRY + if (messageListeners.contains (recipient)) { recipient->handleMessage (*m); } - JUCE_CATCH_EXCEPTION - } - else if (recipient == 0 && m->intParameter1 == quitMessageId) - { - quitMessageReceived = true; + else if (recipient == 0) + { + if (m->intParameter1 == quitMessageId) + { + quitMessageReceived = true; + } + else if (dynamic_cast (m) != 0) + { + (dynamic_cast (m))->messageCallback(); + } + } } + JUCE_CATCH_EXCEPTION delete m; } @@ -36926,57 +36959,136 @@ void MessageManager::setCurrentMessageThread (const Thread::ThreadID threadId) t bool MessageManager::currentThreadHasLockedMessageManager() const throw() { - return Thread::getCurrentThreadId() == currentLockingThreadId; + const Thread::ThreadID thisThread = Thread::getCurrentThreadId(); + return thisThread == messageThreadId || thisThread == threadWithLock; } -MessageManagerLock::MessageManagerLock() throw() - : lastLockingThreadId (0), - locked (false) +/* The only safe way to lock the message thread while another thread does + some work is by posting a special message, whose purpose is to tie up the event + loop until the other thread has finished its business. + + Any other approach can get horribly deadlocked if the OS uses its own hidden locks which + get locked before making an event callback, because if the same OS lock gets indirectly + accessed from another thread inside a MM lock, you're screwed. (this is exactly what happens + in Cocoa). +*/ +class SharedLockingEvents : public ReferenceCountedObject { - if (MessageManager::instance != 0) +public: + SharedLockingEvents() throw() {} + ~SharedLockingEvents() {} + + /* This class just holds a couple of events to communicate between the MMLockMessage + and the MessageManagerLock. Because both of these objects may be deleted at any time, + this shared data must be kept in a separate, ref-counted container. */ + WaitableEvent lockedEvent, releaseEvent; +}; + +class MMLockMessage : public CallbackMessage +{ +public: + MMLockMessage (SharedLockingEvents* const events_) throw() + : events (events_) + {} + + ~MMLockMessage() throw() {} + + ReferenceCountedObjectPtr events; + + void messageCallback() { - MessageManager::instance->messageDispatchLock.enter(); - lastLockingThreadId = MessageManager::instance->currentLockingThreadId; - MessageManager::instance->currentLockingThreadId = Thread::getCurrentThreadId(); - locked = true; + events->lockedEvent.signal(); + events->releaseEvent.wait(); } + + juce_UseDebuggingNewOperator + + MMLockMessage (const MMLockMessage&); + const MMLockMessage& operator= (const MMLockMessage&); +}; + +MessageManagerLock::MessageManagerLock (Thread* const threadToCheck) throw() + : locked (false), + needsUnlocking (false) +{ + init (threadToCheck, 0); } -MessageManagerLock::MessageManagerLock (Thread* const thread) throw() - : locked (false) +MessageManagerLock::MessageManagerLock (ThreadPoolJob* const jobToCheckForExitSignal) throw() + : locked (false), + needsUnlocking (false) { - jassert (thread != 0); // This will only work if you give it a valid thread! + init (0, jobToCheckForExitSignal); +} +void MessageManagerLock::init (Thread* const threadToCheck, ThreadPoolJob* const job) throw() +{ if (MessageManager::instance != 0) { - for (;;) + if (MessageManager::instance->currentThreadHasLockedMessageManager()) { - if (MessageManager::instance->messageDispatchLock.tryEnter()) + locked = true; // either we're on the message thread, or this it's a re-entrant call. + } + else + { + if (threadToCheck == 0 && job == 0) { - locked = true; - lastLockingThreadId = MessageManager::instance->currentLockingThreadId; - MessageManager::instance->currentLockingThreadId = Thread::getCurrentThreadId(); - break; + MessageManager::instance->lockingLock.enter(); } + else + { + while (! MessageManager::instance->lockingLock.tryEnter()) + { + if ((threadToCheck != 0 && threadToCheck->threadShouldExit()) + || (job != 0 && job->shouldExit())) + return; - if (thread != 0 && thread->threadShouldExit()) - break; + Thread::sleep (1); + } + } - Thread::sleep (1); + SharedLockingEvents* const events = new SharedLockingEvents(); + sharedEvents = events; + events->incReferenceCount(); + + (new MMLockMessage (events))->post(); + + while (! events->lockedEvent.wait (50)) + { + if ((threadToCheck != 0 && threadToCheck->threadShouldExit()) + || (job != 0 && job->shouldExit())) + { + events->releaseEvent.signal(); + events->decReferenceCount(); + MessageManager::instance->lockingLock.exit(); + return; + } + } + + jassert (MessageManager::instance->threadWithLock == 0); + + MessageManager::instance->threadWithLock = Thread::getCurrentThreadId(); + locked = true; + needsUnlocking = true; } } } MessageManagerLock::~MessageManagerLock() throw() { - if (locked && MessageManager::instance != 0) + if (needsUnlocking && MessageManager::instance != 0) { - MessageManager::instance->currentLockingThreadId = lastLockingThreadId; - MessageManager::instance->messageDispatchLock.exit(); + jassert (MessageManager::instance->currentThreadHasLockedMessageManager()); + + ((SharedLockingEvents*) sharedEvents)->releaseEvent.signal(); + ((SharedLockingEvents*) sharedEvents)->decReferenceCount(); + MessageManager::instance->threadWithLock = 0; + MessageManager::instance->lockingLock.exit(); } } END_JUCE_NAMESPACE + /********* End of inlined file: juce_MessageManager.cpp *********/ /********* Start of inlined file: juce_MultiTimer.cpp *********/ @@ -52429,13 +52541,19 @@ void TreeViewItem::treeHasChanged() const throw() void TreeViewItem::repaintItem() const { - if (ownerView != 0) + if (ownerView != 0 && areAllParentsOpen()) { - const Rectangle r (getItemPosition (false)); + const Rectangle r (getItemPosition (true)); ownerView->viewport->repaint (0, r.getY(), r.getRight(), r.getHeight()); } } +bool TreeViewItem::areAllParentsOpen() const throw() +{ + return parentItem == 0 + || (parentItem->isOpen() && parentItem->areAllParentsOpen()); +} + void TreeViewItem::updatePositions (int newY) { y = newY; @@ -65757,8 +65875,8 @@ void ComponentDragger::dragComponent (Component* const componentToDrag, const Mo if (componentToDrag->isValidComponent()) { - int x = originalX + e.getDistanceFromDragStartX(); - int y = originalY + e.getDistanceFromDragStartY(); + int x = originalX; + int y = originalY; int w = componentToDrag->getWidth(); int h = componentToDrag->getHeight(); @@ -65766,6 +65884,9 @@ void ComponentDragger::dragComponent (Component* const componentToDrag, const Mo if (parentComp != 0) parentComp->globalPositionToRelative (x, y); + x += e.getDistanceFromDragStartX(); + y += e.getDistanceFromDragStartY(); + if (constrainer != 0) constrainer->setBoundsForComponent (componentToDrag, x, y, w, h, false, false, false, false); @@ -119536,23 +119657,22 @@ FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); } } - else { - return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; - } - } - else { - /* - * If we never got STREAMINFO, turn off MD5 checking to save - * cycles since we don't have a sum to compare to anyway - */ - if(!decoder->private_->has_stream_info) - decoder->private_->do_md5_checking = false; - if(decoder->private_->do_md5_checking) { - if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8)) - return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; - } - return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); + + return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } + + /* + * If we never got STREAMINFO, turn off MD5 checking to save + * cycles since we don't have a sum to compare to anyway + */ + if(!decoder->private_->has_stream_info) + decoder->private_->do_md5_checking = false; + if(decoder->private_->do_md5_checking) { + if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8)) + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + } + + return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); } void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status) @@ -242235,8 +242355,6 @@ bool juce_dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages if (GetMessage (&m, (HWND) 0, 0, 0) > 0) { - const MessageManagerLock mml; - if (m.message == specialId && m.hwnd == juce_messageWindowHandle) { @@ -244127,8 +244245,6 @@ private: LRESULT peerWindowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) { { - const MessageManagerLock messLock; - if (isValidPeer (this)) { switch (message) @@ -263070,8 +263186,6 @@ void juce_windowMessageReceive (XEvent* event) { LinuxComponentPeer* const peer = LinuxComponentPeer::getPeerFor (event->xany.window); - const MessageManagerLock messLock; - if (ComponentPeer::isValidPeer (peer)) peer->handleWindowMessage (event); } @@ -264524,7 +264638,7 @@ public: - (void) connection: (NSURLConnection*) connection didFailWithError: (NSError*) error { - NSLog ([error description]); + DBG (nsStringToJuce ([error description])); hasFailed = true; initialised = true; runLoopThread->signalThreadShouldExit(); @@ -266004,8 +266118,8 @@ void juce_updateMultiMonitorInfo (Array & monitorCoords, const bool c void Logger::outputDebugString (const String& text) throw() { - const ScopedAutoReleasePool pool; - NSLog (juceStringToNS (text + T("\n"))); + fputs (text.toUTF8(), stderr); + fputs ("\n", stderr); } void Logger::outputDebugPrintf (const tchar* format, ...) throw() @@ -266013,7 +266127,7 @@ void Logger::outputDebugPrintf (const tchar* format, ...) throw() String text; va_list args; va_start (args, format); - text.vprintf(format, args); + text.vprintf (format, args); outputDebugString (text); } @@ -266914,8 +267028,6 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r) { if (constrainer != 0) { - const MessageManagerLock mml; - NSRect current = [window frame]; current.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - current.origin.y - current.size.height; @@ -267077,8 +267189,6 @@ void NSViewComponentPeer::setIcon (const Image& /*newIcon*/) void NSViewComponentPeer::viewFocusGain() { - const MessageManagerLock messLock; - if (currentlyFocusedPeer != this) { if (ComponentPeer::isValidPeer (currentlyFocusedPeer)) @@ -267141,8 +267251,6 @@ void NSViewComponentPeer::textInputRequired (int /*x*/, int /*y*/) bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) { - const MessageManagerLock mml; - String unicode (nsStringToJuce ([ev characters])); String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers])); int keyCode = getKeyCodeFromEvent (ev); @@ -267182,7 +267290,6 @@ bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) { - const MessageManagerLock mml; updateKeysDown (ev, true); bool used = handleKeyEvent (ev, true); @@ -267198,14 +267305,12 @@ bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev) { - const MessageManagerLock mml; updateKeysDown (ev, false); return handleKeyEvent (ev, false); } void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); handleModifierKeysChange(); } @@ -267213,7 +267318,6 @@ void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) #if MACOS_10_4_OR_EARLIER bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) { - const MessageManagerLock mml; if ([ev type] == NSKeyDown) return redirectKeyDown (ev); else if ([ev type] == NSKeyUp) @@ -267225,7 +267329,6 @@ bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); int x, y; @@ -267236,7 +267339,6 @@ void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) { - const MessageManagerLock mml; const int oldMods = currentModifiers; updateModifiers (ev); currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]); @@ -267248,7 +267350,6 @@ void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); int x, y; @@ -267259,7 +267360,6 @@ void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); int x, y; getMousePos (ev, view, x, y); @@ -267269,7 +267369,6 @@ void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); int x, y; getMousePos (ev, view, x, y); @@ -267279,7 +267378,6 @@ void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); int x, y; getMousePos (ev, view, x, y); @@ -267289,7 +267387,6 @@ void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) { - const MessageManagerLock mml; updateModifiers (ev); handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f), @@ -267299,8 +267396,6 @@ void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) BOOL NSViewComponentPeer::sendDragCallback (int type, id sender) { - const MessageManagerLock mml; - NSString* bestType = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]]; @@ -267351,7 +267446,6 @@ void NSViewComponentPeer::drawRect (NSRect r) if (r.size.width < 1.0f || r.size.height < 1.0f) return; - const MessageManagerLock mml; const float y = [view frame].size.height - (r.origin.y + r.size.height); JuceNSImage temp ((int) (r.size.width + 0.5f), @@ -267385,8 +267479,6 @@ void NSViewComponentPeer::drawRect (NSRect r) bool NSViewComponentPeer::canBecomeKeyWindow() { - const MessageManagerLock mml; - // If running as a plugin, let the component decide whether it's going to allow the window to get focused. return JUCEApplication::getInstance() != 0 || (isValidPeer (this) && getComponent()->getWantsKeyboardFocus()); @@ -267394,8 +267486,6 @@ bool NSViewComponentPeer::canBecomeKeyWindow() bool NSViewComponentPeer::windowShouldClose() { - const MessageManagerLock mml; - if (! isValidPeer (this)) return YES; @@ -267405,7 +267495,6 @@ bool NSViewComponentPeer::windowShouldClose() void NSViewComponentPeer::redirectMovedOrResized() { - const MessageManagerLock mml; handleMovedOrResized(); } @@ -268036,7 +268125,6 @@ void AppleRemoteDevice::handleCallbackInternal() { if (strcmp (cookies, buttonPatterns + i) == 0) { - const MessageManagerLock mml; buttonPressed ((ButtonType) buttonNum, totalValues > 0); break; } @@ -268515,16 +268603,11 @@ public: void updateMenus() { if (Time::getMillisecondCounter() > lastUpdateTime + 500) - { - const MessageManagerLock mml; menuBarItemsChanged (0); - } } void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const { - const MessageManagerLock mml; - if (currentModel != 0) { if (commandManager != 0) @@ -269336,8 +269419,6 @@ END_JUCE_NAMESPACE JUCE_NAMESPACE::Thread::sleep (300); float progress = [[[burn status] objectForKey: DRStatusPercentCompleteKey] floatValue]; -NSLog ([[burn status] description]); - if (listener != 0 && listener->audioCDBurnProgress (progress)) { [burn abort]; @@ -269618,7 +269699,7 @@ class FontHelper public: String name; - bool isBold, isItalic; + bool isBold, isItalic, needsItalicTransform; float fontSize, totalSize, ascent; int refCount; NSMutableDictionary* attributes; @@ -269631,6 +269712,7 @@ public: name (name_), isBold (bold_), isItalic (italic_), + needsItalicTransform (false), fontSize (size_), refCount (1) { @@ -269644,10 +269726,7 @@ public: NSFont* newFont = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSItalicFontMask]; if (newFont == font) - { - // couldn't find an italic version, so fake it with obliqueness.. - [attributes setObject: [NSNumber numberWithFloat: 0.16] forKey: NSObliquenessAttributeName]; - } + needsItalicTransform = true; // couldn't find a proper italic version, so fake it with a transform.. font = newFont; } @@ -269732,6 +269811,9 @@ public: break; } } + + if (needsItalicTransform) + path->applyTransform (AffineTransform::identity.sheared (-0.15, 0)); } return kerning != 0; @@ -269962,7 +270044,6 @@ public: { if (JUCEApplication::getInstance() != 0) { - const MessageManagerLock mml; JUCEApplication::getInstance()->systemRequestedQuit(); return NSTerminateCancel; } @@ -269974,7 +270055,6 @@ public: { if (JUCEApplication::getInstance() != 0) { - const MessageManagerLock mml; JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename)); return YES; } @@ -269990,14 +270070,12 @@ public: if (files.size() > 0 && JUCEApplication::getInstance() != 0) { - const MessageManagerLock mml; JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" "))); } } virtual void focusChanged() { - const MessageManagerLock mml; juce_HandleProcessFocusChange(); } @@ -270009,7 +270087,6 @@ public: virtual void performCallback (CallbackMessagePayload* pl) { - const MessageManagerLock mml; pl->result = (*pl->function) (pl->parameter); pl->hasBeenExecuted = true; } @@ -270257,6 +270334,11 @@ void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* call } else { + // If a thread has a MessageManagerLock and then tries to call this method, it'll + // deadlock because the message manager is blocked from running, so can never + // call your function.. + jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + const ScopedAutoReleasePool pool; CallbackMessagePayload cmp; @@ -270316,8 +270398,6 @@ END_JUCE_NAMESPACE { NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"]; - const MessageManagerLock mml; - if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString]))) [listener use]; else diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 3fa07effbb..6fc4c23098 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -15016,8 +15016,8 @@ private: #if ! JUCE_ONLY_BUILD_CORE_LIBRARY /********* Start of inlined file: juce_app_includes.h *********/ -#ifndef __JUCE_APP_INCLUDES_JUCEHEADER__ -#define __JUCE_APP_INCLUDES_JUCEHEADER__ +#ifndef __JUCE_JUCE_APP_INCLUDES_INCLUDEFILES__ +#define __JUCE_JUCE_APP_INCLUDES_INCLUDEFILES__ #ifndef __JUCE_APPLICATION_JUCEHEADER__ @@ -33145,6 +33145,13 @@ l */ */ int getTextIndexAt (const int x, const int y) throw(); + /** Counts the number of characters in the text. + + This is quicker than getting the text as a string if you just need to know + the length. + */ + int getTotalNumChars() throw(); + /** Returns the total width of the text, as it is currently laid-out. This may be larger than the size of the TextEditor, and can change when @@ -33266,13 +33273,6 @@ protected: /** Used internally to dispatch a text-change message. */ void textChanged() throw(); - /** Counts the number of characters in the text. - - This is quicker than getting the text as a string if you just need to know - the length. - */ - int getTotalNumChars() throw(); - /** Begins a new transaction in the UndoManager. */ void newTransaction() throw(); @@ -36131,11 +36131,13 @@ private: /********* End of inlined file: juce_PluginListComponent.h *********/ #endif -#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ +#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ -/********* Start of inlined file: juce_AiffAudioFormat.h *********/ -#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ -#define __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ +/********* Start of inlined file: juce_FlacAudioFormat.h *********/ +#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ +#define __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ + +#if JUCE_USE_FLAC || defined (DOXYGEN) /********* Start of inlined file: juce_AudioFormat.h *********/ #ifndef __JUCE_AUDIOFORMAT_JUCEHEADER__ @@ -36411,6 +36413,282 @@ private: #endif // __JUCE_AUDIOFORMAT_JUCEHEADER__ /********* End of inlined file: juce_AudioFormat.h *********/ +/** + Reads and writes the lossless-compression FLAC audio format. + + To compile this, you'll need to set the JUCE_USE_FLAC flag in juce_Config.h, + and make sure your include search path and library search path are set up to find + the FLAC header files and static libraries. + + @see AudioFormat +*/ +class JUCE_API FlacAudioFormat : public AudioFormat +{ +public: + + FlacAudioFormat(); + ~FlacAudioFormat(); + + const Array getPossibleSampleRates(); + const Array getPossibleBitDepths(); + bool canDoStereo(); + bool canDoMono(); + bool isCompressed(); + + AudioFormatReader* createReaderFor (InputStream* sourceStream, + const bool deleteStreamIfOpeningFails); + + AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, + double sampleRateToUse, + unsigned int numberOfChannels, + int bitsPerSample, + const StringPairArray& metadataValues, + int qualityOptionIndex); + + juce_UseDebuggingNewOperator +}; + +#endif +#endif // __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ +/********* End of inlined file: juce_FlacAudioFormat.h *********/ + +#endif +#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ + +/********* Start of inlined file: juce_WavAudioFormat.h *********/ +#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ +#define __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ + +/** + Reads and Writes WAV format audio files. + + @see AudioFormat +*/ +class JUCE_API WavAudioFormat : public AudioFormat +{ +public: + + /** Creates a format object. */ + WavAudioFormat(); + + /** Destructor. */ + ~WavAudioFormat(); + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavDescription; + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavOriginator; + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavOriginatorRef; + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + Date format is: yyyy-mm-dd + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavOriginationDate; + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + Time format is: hh-mm-ss + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavOriginationTime; + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + This is the number of samples from the start of an edit that the + file is supposed to begin at. Seems like an obvious mistake to + only allow a file to occur in an edit once, but that's the way + it is.. + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavTimeReference; + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + This is a + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavCodingHistory; + + /** Utility function to fill out the appropriate metadata for a BWAV file. + + This just makes it easier than using the property names directly, and it + fills out the time and date in the right format. + */ + static const StringPairArray createBWAVMetadata (const String& description, + const String& originator, + const String& originatorRef, + const Time& dateAndTime, + const int64 timeReferenceSamples, + const String& codingHistory); + + const Array getPossibleSampleRates(); + const Array getPossibleBitDepths(); + bool canDoStereo(); + bool canDoMono(); + + AudioFormatReader* createReaderFor (InputStream* sourceStream, + const bool deleteStreamIfOpeningFails); + + AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, + double sampleRateToUse, + unsigned int numberOfChannels, + int bitsPerSample, + const StringPairArray& metadataValues, + int qualityOptionIndex); + + /** Utility function to replace the metadata in a wav file with a new set of values. + + If possible, this cheats by overwriting just the metadata region of the file, rather + than by copying the whole file again. + */ + bool replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata); + + juce_UseDebuggingNewOperator +}; + +#endif // __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ +/********* End of inlined file: juce_WavAudioFormat.h *********/ + +#endif +#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ + +/********* Start of inlined file: juce_OggVorbisAudioFormat.h *********/ +#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ +#define __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ + +#if JUCE_USE_OGGVORBIS || defined (DOXYGEN) + +/** + Reads and writes the Ogg-Vorbis audio format. + + To compile this, you'll need to set the JUCE_USE_OGGVORBIS flag in juce_Config.h, + and make sure your include search path and library search path are set up to find + the Vorbis and Ogg header files and static libraries. + + @see AudioFormat, +*/ +class JUCE_API OggVorbisAudioFormat : public AudioFormat +{ +public: + + OggVorbisAudioFormat(); + ~OggVorbisAudioFormat(); + + const Array getPossibleSampleRates(); + const Array getPossibleBitDepths(); + bool canDoStereo(); + bool canDoMono(); + bool isCompressed(); + const StringArray getQualityOptions(); + + /** Tries to estimate the quality level of an ogg file based on its size. + + If it can't read the file for some reason, this will just return 1 (medium quality), + otherwise it will return the approximate quality setting that would have been used + to create the file. + + @see getQualityOptions + */ + int estimateOggFileQuality (const File& source); + + AudioFormatReader* createReaderFor (InputStream* sourceStream, + const bool deleteStreamIfOpeningFails); + + AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, + double sampleRateToUse, + unsigned int numberOfChannels, + int bitsPerSample, + const StringPairArray& metadataValues, + int qualityOptionIndex); + + juce_UseDebuggingNewOperator +}; + +#endif +#endif // __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ +/********* End of inlined file: juce_OggVorbisAudioFormat.h *********/ + +#endif +#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ + +/********* Start of inlined file: juce_QuickTimeAudioFormat.h *********/ +#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ +#define __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ + +#if JUCE_QUICKTIME + +/** + Uses QuickTime to read the audio track a movie or media file. + + As well as QuickTime movies, this should also manage to open other audio + files that quicktime can understand, like mp3, m4a, etc. + + @see AudioFormat +*/ +class JUCE_API QuickTimeAudioFormat : public AudioFormat +{ +public: + + /** Creates a format object. */ + QuickTimeAudioFormat(); + + /** Destructor. */ + ~QuickTimeAudioFormat(); + + const Array getPossibleSampleRates(); + const Array getPossibleBitDepths(); + bool canDoStereo(); + bool canDoMono(); + + AudioFormatReader* createReaderFor (InputStream* sourceStream, + const bool deleteStreamIfOpeningFails); + + AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, + double sampleRateToUse, + unsigned int numberOfChannels, + int bitsPerSample, + const StringPairArray& metadataValues, + int qualityOptionIndex); + + juce_UseDebuggingNewOperator +}; + +#endif +#endif // __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ +/********* End of inlined file: juce_QuickTimeAudioFormat.h *********/ + +#endif +#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ + +/********* Start of inlined file: juce_AiffAudioFormat.h *********/ +#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ +#define __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ + /** Reads and Writes AIFF format audio files. @@ -37100,423 +37378,11 @@ private: /********* End of inlined file: juce_AudioThumbnailCache.h *********/ #endif -#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ - -/********* Start of inlined file: juce_FlacAudioFormat.h *********/ -#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ -#define __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ - -#if JUCE_USE_FLAC || defined (DOXYGEN) - -/** - Reads and writes the lossless-compression FLAC audio format. - - To compile this, you'll need to set the JUCE_USE_FLAC flag in juce_Config.h, - and make sure your include search path and library search path are set up to find - the FLAC header files and static libraries. - - @see AudioFormat -*/ -class JUCE_API FlacAudioFormat : public AudioFormat -{ -public: - - FlacAudioFormat(); - ~FlacAudioFormat(); - - const Array getPossibleSampleRates(); - const Array getPossibleBitDepths(); - bool canDoStereo(); - bool canDoMono(); - bool isCompressed(); - - AudioFormatReader* createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails); - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex); - - juce_UseDebuggingNewOperator -}; - -#endif -#endif // __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ -/********* End of inlined file: juce_FlacAudioFormat.h *********/ - -#endif -#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ - -/********* Start of inlined file: juce_OggVorbisAudioFormat.h *********/ -#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ -#define __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ - -#if JUCE_USE_OGGVORBIS || defined (DOXYGEN) - -/** - Reads and writes the Ogg-Vorbis audio format. - - To compile this, you'll need to set the JUCE_USE_OGGVORBIS flag in juce_Config.h, - and make sure your include search path and library search path are set up to find - the Vorbis and Ogg header files and static libraries. - - @see AudioFormat, -*/ -class JUCE_API OggVorbisAudioFormat : public AudioFormat -{ -public: - - OggVorbisAudioFormat(); - ~OggVorbisAudioFormat(); - - const Array getPossibleSampleRates(); - const Array getPossibleBitDepths(); - bool canDoStereo(); - bool canDoMono(); - bool isCompressed(); - const StringArray getQualityOptions(); - - /** Tries to estimate the quality level of an ogg file based on its size. - - If it can't read the file for some reason, this will just return 1 (medium quality), - otherwise it will return the approximate quality setting that would have been used - to create the file. - - @see getQualityOptions - */ - int estimateOggFileQuality (const File& source); - - AudioFormatReader* createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails); - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex); - - juce_UseDebuggingNewOperator -}; - -#endif -#endif // __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ -/********* End of inlined file: juce_OggVorbisAudioFormat.h *********/ - -#endif -#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ - -/********* Start of inlined file: juce_QuickTimeAudioFormat.h *********/ -#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ -#define __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ - -#if JUCE_QUICKTIME - -/** - Uses QuickTime to read the audio track a movie or media file. - - As well as QuickTime movies, this should also manage to open other audio - files that quicktime can understand, like mp3, m4a, etc. - - @see AudioFormat -*/ -class JUCE_API QuickTimeAudioFormat : public AudioFormat -{ -public: - - /** Creates a format object. */ - QuickTimeAudioFormat(); - - /** Destructor. */ - ~QuickTimeAudioFormat(); - - const Array getPossibleSampleRates(); - const Array getPossibleBitDepths(); - bool canDoStereo(); - bool canDoMono(); - - AudioFormatReader* createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails); - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex); - - juce_UseDebuggingNewOperator -}; - -#endif -#endif // __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ -/********* End of inlined file: juce_QuickTimeAudioFormat.h *********/ - -#endif -#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ - -/********* Start of inlined file: juce_WavAudioFormat.h *********/ -#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ -#define __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ - -/** - Reads and Writes WAV format audio files. - - @see AudioFormat -*/ -class JUCE_API WavAudioFormat : public AudioFormat -{ -public: - - /** Creates a format object. */ - WavAudioFormat(); - - /** Destructor. */ - ~WavAudioFormat(); - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavDescription; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavOriginator; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavOriginatorRef; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - Date format is: yyyy-mm-dd - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavOriginationDate; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - Time format is: hh-mm-ss - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavOriginationTime; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - This is the number of samples from the start of an edit that the - file is supposed to begin at. Seems like an obvious mistake to - only allow a file to occur in an edit once, but that's the way - it is.. - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavTimeReference; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - This is a - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavCodingHistory; - - /** Utility function to fill out the appropriate metadata for a BWAV file. - - This just makes it easier than using the property names directly, and it - fills out the time and date in the right format. - */ - static const StringPairArray createBWAVMetadata (const String& description, - const String& originator, - const String& originatorRef, - const Time& dateAndTime, - const int64 timeReferenceSamples, - const String& codingHistory); - - const Array getPossibleSampleRates(); - const Array getPossibleBitDepths(); - bool canDoStereo(); - bool canDoMono(); - - AudioFormatReader* createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails); - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex); - - /** Utility function to replace the metadata in a wav file with a new set of values. - - If possible, this cheats by overwriting just the metadata region of the file, rather - than by copying the whole file again. - */ - bool replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata); - - juce_UseDebuggingNewOperator -}; - -#endif // __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ -/********* End of inlined file: juce_WavAudioFormat.h *********/ - -#endif -#ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__ - -/********* Start of inlined file: juce_ActionBroadcaster.h *********/ -#ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__ -#define __JUCE_ACTIONBROADCASTER_JUCEHEADER__ - -/********* Start of inlined file: juce_ActionListenerList.h *********/ -#ifndef __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ -#define __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ - -/** - A set of ActionListeners. - - Listeners can be added and removed from the list, and messages can be - broadcast to all the listeners. - - @see ActionListener, ActionBroadcaster -*/ -class JUCE_API ActionListenerList : public MessageListener -{ -public: - - /** Creates an empty list. */ - ActionListenerList() throw(); - - /** Destructor. */ - ~ActionListenerList() throw(); - - /** Adds a listener to the list. - - (Trying to add a listener that's already on the list will have no effect). - */ - void addActionListener (ActionListener* const listener) throw(); - - /** Removes a listener from the list. - - If the listener isn't on the list, this won't have any effect. - */ - void removeActionListener (ActionListener* const listener) throw(); - - /** Removes all listeners from the list. */ - void removeAllActionListeners() throw(); - - /** Broadcasts a message to all the registered listeners. - - This sends the message asynchronously. - - If a listener is on the list when this method is called but is removed from - the list before the message arrives, it won't receive the message. Similarly - listeners that are added to the list after the message is sent but before it - arrives won't get the message either. - */ - void sendActionMessage (const String& message) const; - - /** @internal */ - void handleMessage (const Message&); - - juce_UseDebuggingNewOperator - -private: - SortedSet actionListeners_; - CriticalSection actionListenerLock_; - - ActionListenerList (const ActionListenerList&); - const ActionListenerList& operator= (const ActionListenerList&); -}; - -#endif // __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ -/********* End of inlined file: juce_ActionListenerList.h *********/ - -/** Manages a list of ActionListeners, and can send them messages. - - To quickly add methods to your class that can add/remove action - listeners and broadcast to them, you can derive from this. - - @see ActionListenerList, ActionListener -*/ -class JUCE_API ActionBroadcaster -{ -public: - - /** Creates an ActionBroadcaster. */ - ActionBroadcaster() throw(); - - /** Destructor. */ - virtual ~ActionBroadcaster(); - - /** Adds a listener to the list. - - (Trying to add a listener that's already on the list will have no effect). - */ - void addActionListener (ActionListener* const listener); - - /** Removes a listener from the list. - - If the listener isn't on the list, this won't have any effect. - */ - void removeActionListener (ActionListener* const listener); - - /** Removes all listeners from the list. */ - void removeAllActionListeners(); - - /** Broadcasts a message to all the registered listeners. - - @see ActionListenerList::sendActionMessage - */ - void sendActionMessage (const String& message) const; - -private: - - ActionListenerList actionListenerList; - - ActionBroadcaster (const ActionBroadcaster&); - const ActionBroadcaster& operator= (const ActionBroadcaster&); -}; - -#endif // __JUCE_ACTIONBROADCASTER_JUCEHEADER__ -/********* End of inlined file: juce_ActionBroadcaster.h *********/ - -#endif -#ifndef __JUCE_ACTIONLISTENER_JUCEHEADER__ - -#endif -#ifndef __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ - -#endif -#ifndef __JUCE_ASYNCUPDATER_JUCEHEADER__ - -#endif -#ifndef __JUCE_CHANGEBROADCASTER_JUCEHEADER__ - -#endif -#ifndef __JUCE_CHANGELISTENER_JUCEHEADER__ - -#endif -#ifndef __JUCE_CHANGELISTENERLIST_JUCEHEADER__ +#ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__ -#endif -#ifndef __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__ +/********* Start of inlined file: juce_InterprocessConnectionServer.h *********/ +#ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__ +#define __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__ /********* Start of inlined file: juce_InterprocessConnection.h *********/ #ifndef __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__ @@ -37699,13 +37565,6 @@ private: #endif // __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__ /********* End of inlined file: juce_InterprocessConnection.h *********/ -#endif -#ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__ - -/********* Start of inlined file: juce_InterprocessConnectionServer.h *********/ -#ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__ -#define __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__ - /** An object that waits for client sockets to connect to a port on this host, and creates InterprocessConnection objects for each one. @@ -37779,6 +37638,108 @@ private: #endif #ifndef __JUCE_MESSAGELISTENER_JUCEHEADER__ +#endif +#ifndef __JUCE_MULTITIMER_JUCEHEADER__ + +/********* Start of inlined file: juce_MultiTimer.h *********/ +#ifndef __JUCE_MULTITIMER_JUCEHEADER__ +#define __JUCE_MULTITIMER_JUCEHEADER__ + +/** + A type of timer class that can run multiple timers with different frequencies, + all of which share a single callback. + + This class is very similar to the Timer class, but allows you run multiple + separate timers, where each one has a unique ID number. The methods in this + class are exactly equivalent to those in Timer, but with the addition of + this ID number. + + To use it, you need to create a subclass of MultiTimer, implementing the + timerCallback() method. Then you can start timers with startTimer(), and + each time the callback is triggered, it passes in the ID of the timer that + caused it. + + @see Timer +*/ +class JUCE_API MultiTimer +{ +protected: + + /** Creates a MultiTimer. + + When created, no timers are running, so use startTimer() to start things off. + */ + MultiTimer() throw(); + + /** Creates a copy of another timer. + + Note that this timer will not contain any running timers, even if the one you're + copying from was running. + */ + MultiTimer (const MultiTimer& other) throw(); + +public: + + /** Destructor. */ + virtual ~MultiTimer(); + + /** The user-defined callback routine that actually gets called by each of the + timers that are running. + + It's perfectly ok to call startTimer() or stopTimer() from within this + callback to change the subsequent intervals. + */ + virtual void timerCallback (const int timerId) = 0; + + /** Starts a timer and sets the length of interval required. + + If the timer is already started, this will reset it, so the + time between calling this method and the next timer callback + will not be less than the interval length passed in. + + @param timerId a unique Id number that identifies the timer to + start. This is the id that will be passed back + to the timerCallback() method when this timer is + triggered + @param intervalInMilliseconds the interval to use (any values less than 1 will be + rounded up to 1) + */ + void startTimer (const int timerId, const int intervalInMilliseconds) throw(); + + /** Stops a timer. + + If a timer has been started with the given ID number, it will be cancelled. + No more callbacks will be made for the specified timer after this method returns. + + If this is called from a different thread, any callbacks that may + be currently executing may be allowed to finish before the method + returns. + */ + void stopTimer (const int timerId) throw(); + + /** Checks whether a timer has been started for a specified ID. + + @returns true if a timer with the given ID is running. + */ + bool isTimerRunning (const int timerId) const throw(); + + /** Returns the interval for a specified timer ID. + + @returns the timer's interval in milliseconds if it's running, or 0 if it's no timer + is running for the ID number specified. + */ + int getTimerInterval (const int timerId) const throw(); + +private: + CriticalSection timerListLock; + VoidArray timers; + + const MultiTimer& operator= (const MultiTimer&); +}; + +#endif // __JUCE_MULTITIMER_JUCEHEADER__ +/********* End of inlined file: juce_MultiTimer.h *********/ + #endif #ifndef __JUCE_MESSAGEMANAGER_JUCEHEADER__ @@ -37786,6 +37747,123 @@ private: #ifndef __JUCE_MESSAGEMANAGER_JUCEHEADER__ #define __JUCE_MESSAGEMANAGER_JUCEHEADER__ +/********* Start of inlined file: juce_ActionListenerList.h *********/ +#ifndef __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ +#define __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ + +/** + A set of ActionListeners. + + Listeners can be added and removed from the list, and messages can be + broadcast to all the listeners. + + @see ActionListener, ActionBroadcaster +*/ +class JUCE_API ActionListenerList : public MessageListener +{ +public: + + /** Creates an empty list. */ + ActionListenerList() throw(); + + /** Destructor. */ + ~ActionListenerList() throw(); + + /** Adds a listener to the list. + + (Trying to add a listener that's already on the list will have no effect). + */ + void addActionListener (ActionListener* const listener) throw(); + + /** Removes a listener from the list. + + If the listener isn't on the list, this won't have any effect. + */ + void removeActionListener (ActionListener* const listener) throw(); + + /** Removes all listeners from the list. */ + void removeAllActionListeners() throw(); + + /** Broadcasts a message to all the registered listeners. + + This sends the message asynchronously. + + If a listener is on the list when this method is called but is removed from + the list before the message arrives, it won't receive the message. Similarly + listeners that are added to the list after the message is sent but before it + arrives won't get the message either. + */ + void sendActionMessage (const String& message) const; + + /** @internal */ + void handleMessage (const Message&); + + juce_UseDebuggingNewOperator + +private: + SortedSet actionListeners_; + CriticalSection actionListenerLock_; + + ActionListenerList (const ActionListenerList&); + const ActionListenerList& operator= (const ActionListenerList&); +}; + +#endif // __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ +/********* End of inlined file: juce_ActionListenerList.h *********/ + +/********* Start of inlined file: juce_CallbackMessage.h *********/ +#ifndef __JUCE_CMESSAGE_JUCEHEADER__ +#define __JUCE_CMESSAGE_JUCEHEADER__ + +/** + A message that calls a custom function when it gets delivered. + + You can use this class to fire off actions that you want to be performed later + on the message thread. + + Unlike other Message objects, these don't get sent to a MessageListener, you + just call the post() method to send them, and when they arrive, your + messageCallback() method will automatically be invoked. + + @see MessageListener, MessageManager, ActionListener, ChangeListener +*/ +class JUCE_API CallbackMessage : public Message +{ +protected: + CallbackMessage() throw(); + ~CallbackMessage() throw(); + +public: + + /** Called when the message is delivered. + + You should implement this method and make it do whatever action you want + to perform. + + Note that like all other messages, this object will be deleted immediately + after this method has been invoked. + */ + virtual void messageCallback() = 0; + + /** Instead of sending this message to a MessageListener, just call this method + to post it to the event queue. + + After you've called this, this object will belong to the MessageManager, + which will delete it later. So make sure you don't delete the object yourself, + call post() more than once, or call post() on a stack-based obect! + */ + void post(); + + juce_UseDebuggingNewOperator + +private: + CallbackMessage (const CallbackMessage&); + const CallbackMessage& operator= (const CallbackMessage&); +}; + +#endif // __JUCE_MESSAGE_JUCEHEADER__ +/********* End of inlined file: juce_CallbackMessage.h *********/ + class Component; class MessageManagerLock; @@ -37915,6 +37993,7 @@ private: friend class MessageListener; friend class ChangeBroadcaster; friend class ActionBroadcaster; + friend class CallbackMessage; static MessageManager* instance; SortedSet messageListeners; @@ -37928,13 +38007,14 @@ private: static void* exitModalLoopCallback (void*); void postMessageToQueue (Message* const message); + void postCallbackMessage (Message* const message); static void doPlatformSpecificInitialisation(); static void doPlatformSpecificShutdown(); friend class MessageManagerLock; - CriticalSection messageDispatchLock; - Thread::ThreadID currentLockingThreadId; + Thread::ThreadID volatile threadWithLock; + CriticalSection lockingLock; MessageManager (const MessageManager&); const MessageManager& operator= (const MessageManager&); @@ -37977,35 +38057,23 @@ public: /** Tries to acquire a lock on the message manager. - If this constructor - When this constructor returns, the message manager will have finished processing the - last message and will not send another message until this MessageManagerLock is - deleted. - - If the current thread already has the lock, nothing will be done, so it's perfectly - safe to create these locks recursively. - */ - MessageManagerLock() throw(); - - /** Releases the current thread's lock on the message manager. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! - */ - ~MessageManagerLock() throw(); - - /** Tries to acquire a lock on the message manager. + The constructor attempts to gain a lock on the message loop, and the lock will be + kept for the lifetime of this object. - This does the same thing as the normal constructor, but while it's waiting to get - the lock, it checks the specified thread to see if it has been given the + Optionally, you can pass a thread object here, and while waiting to obtain the lock, + this method will keep checking whether the thread has been given the Thread::signalThreadShouldExit() signal. If this happens, then it will return - without gaining the lock. + without gaining the lock. If you pass a thread, you must check whether the lock was + successful by calling lockWasGained(). If this is false, your thread is being told to + die, so you should take evasive action. - To find out whether the lock was successful, call lockWasGained(). If this is - false, your thread is being told to die, so you'd better get out of there. + If you pass zero for the thread object, it will wait indefinitely for the lock - be + careful when doing this, because it's very easy to deadlock if your message thread + attempts to call stopThread() on a thread just as that thread attempts to get the + message lock. - If the current thread already has the lock, nothing will be done, so it's perfectly - safe to create these locks recursively. + If the calling thread already has the lock, nothing will be done, so it's safe and + quick to use these locks recursively. E.g. @code @@ -38028,7 +38096,21 @@ public: @endcode */ - MessageManagerLock (Thread* const threadToCheckForExitSignal) throw(); + MessageManagerLock (Thread* const threadToCheckForExitSignal = 0) throw(); + + /** This has the same behaviour as the other constructor, but takes a ThreadPoolJob + instead of a thread. + + See the MessageManagerLock (Thread*) constructor for details on how this works. + */ + MessageManagerLock (ThreadPoolJob* const jobToCheckForExitSignal) throw(); + + /** Releases the current thread's lock on the message manager. + + Make sure this object is created and deleted by the same thread, + otherwise there are no guarantees what will happen! + */ + ~MessageManagerLock() throw(); /** Returns true if the lock was successfully acquired. @@ -38037,114 +38119,91 @@ public: bool lockWasGained() const throw() { return locked; } private: - Thread::ThreadID lastLockingThreadId; - bool locked; + bool locked, needsUnlocking; + void* sharedEvents; + + void init (Thread* const thread, ThreadPoolJob* const job) throw(); }; #endif // __JUCE_MESSAGEMANAGER_JUCEHEADER__ /********* End of inlined file: juce_MessageManager.h *********/ #endif -#ifndef __JUCE_MULTITIMER_JUCEHEADER__ - -/********* Start of inlined file: juce_MultiTimer.h *********/ -#ifndef __JUCE_MULTITIMER_JUCEHEADER__ -#define __JUCE_MULTITIMER_JUCEHEADER__ +#ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__ -/** - A type of timer class that can run multiple timers with different frequencies, - all of which share a single callback. +/********* Start of inlined file: juce_ActionBroadcaster.h *********/ +#ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__ +#define __JUCE_ACTIONBROADCASTER_JUCEHEADER__ - This class is very similar to the Timer class, but allows you run multiple - separate timers, where each one has a unique ID number. The methods in this - class are exactly equivalent to those in Timer, but with the addition of - this ID number. +/** Manages a list of ActionListeners, and can send them messages. - To use it, you need to create a subclass of MultiTimer, implementing the - timerCallback() method. Then you can start timers with startTimer(), and - each time the callback is triggered, it passes in the ID of the timer that - caused it. + To quickly add methods to your class that can add/remove action + listeners and broadcast to them, you can derive from this. - @see Timer + @see ActionListenerList, ActionListener */ -class JUCE_API MultiTimer +class JUCE_API ActionBroadcaster { -protected: +public: - /** Creates a MultiTimer. + /** Creates an ActionBroadcaster. */ + ActionBroadcaster() throw(); - When created, no timers are running, so use startTimer() to start things off. - */ - MultiTimer() throw(); + /** Destructor. */ + virtual ~ActionBroadcaster(); - /** Creates a copy of another timer. + /** Adds a listener to the list. - Note that this timer will not contain any running timers, even if the one you're - copying from was running. + (Trying to add a listener that's already on the list will have no effect). */ - MultiTimer (const MultiTimer& other) throw(); - -public: - - /** Destructor. */ - virtual ~MultiTimer(); + void addActionListener (ActionListener* const listener); - /** The user-defined callback routine that actually gets called by each of the - timers that are running. + /** Removes a listener from the list. - It's perfectly ok to call startTimer() or stopTimer() from within this - callback to change the subsequent intervals. + If the listener isn't on the list, this won't have any effect. */ - virtual void timerCallback (const int timerId) = 0; + void removeActionListener (ActionListener* const listener); - /** Starts a timer and sets the length of interval required. + /** Removes all listeners from the list. */ + void removeAllActionListeners(); - If the timer is already started, this will reset it, so the - time between calling this method and the next timer callback - will not be less than the interval length passed in. + /** Broadcasts a message to all the registered listeners. - @param timerId a unique Id number that identifies the timer to - start. This is the id that will be passed back - to the timerCallback() method when this timer is - triggered - @param intervalInMilliseconds the interval to use (any values less than 1 will be - rounded up to 1) + @see ActionListenerList::sendActionMessage */ - void startTimer (const int timerId, const int intervalInMilliseconds) throw(); + void sendActionMessage (const String& message) const; - /** Stops a timer. +private: - If a timer has been started with the given ID number, it will be cancelled. - No more callbacks will be made for the specified timer after this method returns. + ActionListenerList actionListenerList; - If this is called from a different thread, any callbacks that may - be currently executing may be allowed to finish before the method - returns. - */ - void stopTimer (const int timerId) throw(); + ActionBroadcaster (const ActionBroadcaster&); + const ActionBroadcaster& operator= (const ActionBroadcaster&); +}; - /** Checks whether a timer has been started for a specified ID. +#endif // __JUCE_ACTIONBROADCASTER_JUCEHEADER__ +/********* End of inlined file: juce_ActionBroadcaster.h *********/ - @returns true if a timer with the given ID is running. - */ - bool isTimerRunning (const int timerId) const throw(); +#endif +#ifndef __JUCE_ACTIONLISTENER_JUCEHEADER__ - /** Returns the interval for a specified timer ID. +#endif +#ifndef __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ - @returns the timer's interval in milliseconds if it's running, or 0 if it's no timer - is running for the ID number specified. - */ - int getTimerInterval (const int timerId) const throw(); +#endif +#ifndef __JUCE_ASYNCUPDATER_JUCEHEADER__ -private: - CriticalSection timerListLock; - VoidArray timers; +#endif +#ifndef __JUCE_CHANGEBROADCASTER_JUCEHEADER__ - const MultiTimer& operator= (const MultiTimer&); -}; +#endif +#ifndef __JUCE_CHANGELISTENER_JUCEHEADER__ -#endif // __JUCE_MULTITIMER_JUCEHEADER__ -/********* End of inlined file: juce_MultiTimer.h *********/ +#endif +#ifndef __JUCE_CHANGELISTENERLIST_JUCEHEADER__ + +#endif +#ifndef __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__ #endif #ifndef __JUCE_TIMER_JUCEHEADER__ @@ -40142,10 +40201,10 @@ private: /********* End of inlined file: juce_PositionedRectangle.h *********/ #endif -#ifndef __JUCE_RECTANGLE_JUCEHEADER__ +#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__ #endif -#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__ +#ifndef __JUCE_RECTANGLE_JUCEHEADER__ #endif #ifndef __JUCE_IMAGE_JUCEHEADER__ @@ -41083,9 +41142,6 @@ private: #endif // __JUCE_DRAWABLETEXT_JUCEHEADER__ /********* End of inlined file: juce_DrawableText.h *********/ -#endif -#ifndef __JUCE_COMPONENT_JUCEHEADER__ - #endif #ifndef __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__ @@ -41095,6 +41151,9 @@ private: #endif #ifndef __JUCE_DESKTOP_JUCEHEADER__ +#endif +#ifndef __JUCE_COMPONENT_JUCEHEADER__ + #endif #ifndef __JUCE_ARROWBUTTON_JUCEHEADER__ @@ -43122,6 +43181,12 @@ public: */ int getRowNumberInTree() const throw(); + /** Returns true if all the item's parent nodes are open. + + This is useful to check whether the item might actually be visible or not. + */ + bool areAllParentsOpen() const throw(); + /** Changes whether lines are drawn to connect any sub-items to this item. By default, line-drawing is turned on. @@ -44892,6 +44957,155 @@ private: #endif #ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__ +#endif +#ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__ + +/********* Start of inlined file: juce_ToolbarItemFactory.h *********/ +#ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__ +#define __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__ + +/** + A factory object which can create ToolbarItemComponent objects. + + A subclass of ToolbarItemFactory publishes a set of types of toolbar item + that it can create. + + Each type of item is identified by a unique ID, and multiple instances of an + item type can exist at once (even on the same toolbar, e.g. spacers or separator + bars). + + @see Toolbar, ToolbarItemComponent, ToolbarButton +*/ +class JUCE_API ToolbarItemFactory +{ +public: + + ToolbarItemFactory(); + + /** Destructor. */ + virtual ~ToolbarItemFactory(); + + /** A set of reserved item ID values, used for the built-in item types. + */ + enum SpecialItemIds + { + separatorBarId = -1, /**< The item ID for a vertical (or horizontal) separator bar that + can be placed between sets of items to break them into groups. */ + spacerId = -2, /**< The item ID for a fixed-width space that can be placed between + items.*/ + flexibleSpacerId = -3 /**< The item ID for a gap that pushes outwards against the things on + either side of it, filling any available space. */ + }; + + /** Must return a list of the IDs for all the item types that this factory can create. + + The ids should be added to the array that is passed-in. + + An item ID can be any integer you choose, except for 0, which is considered a null ID, + and the predefined IDs in the SpecialItemIds enum. + + You should also add the built-in types (separatorBarId, spacerId and flexibleSpacerId) + to this list if you want your toolbar to be able to contain those items. + + The list returned here is used by the ToolbarItemPalette class to obtain its list + of available items, and their order on the palette will reflect the order in which + they appear on this list. + + @see ToolbarItemPalette + */ + virtual void getAllToolbarItemIds (Array & ids) = 0; + + /** Must return the set of items that should be added to a toolbar as its default set. + + This method is used by Toolbar::addDefaultItems() to determine which items to + create. + + The items that your method adds to the array that is passed-in will be added to the + toolbar in the same order. Items can appear in the list more than once. + */ + virtual void getDefaultItemSet (Array & ids) = 0; + + /** Must create an instance of one of the items that the factory lists in its + getAllToolbarItemIds() method. + + The itemId parameter can be any of the values listed by your getAllToolbarItemIds() + method, except for the built-in item types from the SpecialItemIds enum, which + are created internally by the toolbar code. + + Try not to keep a pointer to the object that is returned, as it will be deleted + automatically by the toolbar, and remember that multiple instances of the same + item type are likely to exist at the same time. + */ + virtual ToolbarItemComponent* createItem (const int itemId) = 0; +}; + +#endif // __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__ +/********* End of inlined file: juce_ToolbarItemFactory.h *********/ + +#endif +#ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__ + +/********* Start of inlined file: juce_ToolbarItemPalette.h *********/ +#ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__ +#define __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__ + +/** + A component containing a list of toolbar items, which the user can drag onto + a toolbar to add them. + + You can use this class directly, but it's a lot easier to call Toolbar::showCustomisationDialog(), + which automatically shows one of these in a dialog box with lots of extra controls. + + @see Toolbar +*/ +class JUCE_API ToolbarItemPalette : public Component, + public DragAndDropContainer +{ +public: + + /** Creates a palette of items for a given factory, with the aim of adding them + to the specified toolbar. + + The ToolbarItemFactory::getAllToolbarItemIds() method is used to create the + set of items that are shown in this palette. + + The toolbar and factory must not be deleted while this object exists. + */ + ToolbarItemPalette (ToolbarItemFactory& factory, + Toolbar* const toolbar); + + /** Destructor. */ + ~ToolbarItemPalette(); + + /** @internal */ + void resized(); + + juce_UseDebuggingNewOperator + +private: + ToolbarItemFactory& factory; + Toolbar* toolbar; + Viewport* viewport; + + friend class Toolbar; + void replaceComponent (ToolbarItemComponent* const comp); + + ToolbarItemPalette (const ToolbarItemPalette&); + const ToolbarItemPalette& operator= (const ToolbarItemPalette&); +}; + +#endif // __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__ +/********* End of inlined file: juce_ToolbarItemPalette.h *********/ + +#endif +#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__ + +#endif +#ifndef __JUCE_TREEVIEW_JUCEHEADER__ + +#endif +#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__ + #endif #ifndef __JUCE_COMBOBOX_JUCEHEADER__ @@ -45746,7 +45960,11 @@ private: #ifndef __JUCE_SLIDERLISTENER_JUCEHEADER__ #endif -#ifndef __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__ +#ifndef __JUCE_TABLELISTBOX_JUCEHEADER__ + +/********* Start of inlined file: juce_TableListBox.h *********/ +#ifndef __JUCE_TABLELISTBOX_JUCEHEADER__ +#define __JUCE_TABLELISTBOX_JUCEHEADER__ /********* Start of inlined file: juce_TableHeaderComponent.h *********/ #ifndef __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__ @@ -46143,13 +46361,6 @@ private: #endif // __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__ /********* End of inlined file: juce_TableHeaderComponent.h *********/ -#endif -#ifndef __JUCE_TABLELISTBOX_JUCEHEADER__ - -/********* Start of inlined file: juce_TableListBox.h *********/ -#ifndef __JUCE_TABLELISTBOX_JUCEHEADER__ -#define __JUCE_TABLELISTBOX_JUCEHEADER__ - /** One of these is used by a TableListBox as the data model for the table's contents. @@ -46427,157 +46638,11 @@ private: /********* End of inlined file: juce_TableListBox.h *********/ #endif -#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__ +#ifndef __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__ #endif #ifndef __JUCE_TOOLBAR_JUCEHEADER__ -#endif -#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__ - -#endif -#ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__ - -/********* Start of inlined file: juce_ToolbarItemFactory.h *********/ -#ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__ -#define __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__ - -/** - A factory object which can create ToolbarItemComponent objects. - - A subclass of ToolbarItemFactory publishes a set of types of toolbar item - that it can create. - - Each type of item is identified by a unique ID, and multiple instances of an - item type can exist at once (even on the same toolbar, e.g. spacers or separator - bars). - - @see Toolbar, ToolbarItemComponent, ToolbarButton -*/ -class JUCE_API ToolbarItemFactory -{ -public: - - ToolbarItemFactory(); - - /** Destructor. */ - virtual ~ToolbarItemFactory(); - - /** A set of reserved item ID values, used for the built-in item types. - */ - enum SpecialItemIds - { - separatorBarId = -1, /**< The item ID for a vertical (or horizontal) separator bar that - can be placed between sets of items to break them into groups. */ - spacerId = -2, /**< The item ID for a fixed-width space that can be placed between - items.*/ - flexibleSpacerId = -3 /**< The item ID for a gap that pushes outwards against the things on - either side of it, filling any available space. */ - }; - - /** Must return a list of the IDs for all the item types that this factory can create. - - The ids should be added to the array that is passed-in. - - An item ID can be any integer you choose, except for 0, which is considered a null ID, - and the predefined IDs in the SpecialItemIds enum. - - You should also add the built-in types (separatorBarId, spacerId and flexibleSpacerId) - to this list if you want your toolbar to be able to contain those items. - - The list returned here is used by the ToolbarItemPalette class to obtain its list - of available items, and their order on the palette will reflect the order in which - they appear on this list. - - @see ToolbarItemPalette - */ - virtual void getAllToolbarItemIds (Array & ids) = 0; - - /** Must return the set of items that should be added to a toolbar as its default set. - - This method is used by Toolbar::addDefaultItems() to determine which items to - create. - - The items that your method adds to the array that is passed-in will be added to the - toolbar in the same order. Items can appear in the list more than once. - */ - virtual void getDefaultItemSet (Array & ids) = 0; - - /** Must create an instance of one of the items that the factory lists in its - getAllToolbarItemIds() method. - - The itemId parameter can be any of the values listed by your getAllToolbarItemIds() - method, except for the built-in item types from the SpecialItemIds enum, which - are created internally by the toolbar code. - - Try not to keep a pointer to the object that is returned, as it will be deleted - automatically by the toolbar, and remember that multiple instances of the same - item type are likely to exist at the same time. - */ - virtual ToolbarItemComponent* createItem (const int itemId) = 0; -}; - -#endif // __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__ -/********* End of inlined file: juce_ToolbarItemFactory.h *********/ - -#endif -#ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__ - -/********* Start of inlined file: juce_ToolbarItemPalette.h *********/ -#ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__ -#define __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__ - -/** - A component containing a list of toolbar items, which the user can drag onto - a toolbar to add them. - - You can use this class directly, but it's a lot easier to call Toolbar::showCustomisationDialog(), - which automatically shows one of these in a dialog box with lots of extra controls. - - @see Toolbar -*/ -class JUCE_API ToolbarItemPalette : public Component, - public DragAndDropContainer -{ -public: - - /** Creates a palette of items for a given factory, with the aim of adding them - to the specified toolbar. - - The ToolbarItemFactory::getAllToolbarItemIds() method is used to create the - set of items that are shown in this palette. - - The toolbar and factory must not be deleted while this object exists. - */ - ToolbarItemPalette (ToolbarItemFactory& factory, - Toolbar* const toolbar); - - /** Destructor. */ - ~ToolbarItemPalette(); - - /** @internal */ - void resized(); - - juce_UseDebuggingNewOperator - -private: - ToolbarItemFactory& factory; - Toolbar* toolbar; - Viewport* viewport; - - friend class Toolbar; - void replaceComponent (ToolbarItemComponent* const comp); - - ToolbarItemPalette (const ToolbarItemPalette&); - const ToolbarItemPalette& operator= (const ToolbarItemPalette&); -}; - -#endif // __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__ -/********* End of inlined file: juce_ToolbarItemPalette.h *********/ - -#endif -#ifndef __JUCE_TREEVIEW_JUCEHEADER__ - #endif #ifndef __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ @@ -46894,158 +46959,6 @@ private: #endif // __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ /********* End of inlined file: juce_TextPropertyComponent.h *********/ -#endif -#ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__ - -#endif -#ifndef __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__ - -#endif -#ifndef __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__ - -/********* Start of inlined file: juce_ComponentMovementWatcher.h *********/ -#ifndef __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__ -#define __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__ - -/** An object that watches for any movement of a component or any of its parent components. - - This makes it easy to check when a component is moved relative to its top-level - peer window. The normal Component::moved() method is only called when a component - moves relative to its immediate parent, and sometimes you want to know if any of - components higher up the tree have moved (which of course will affect the overall - position of all their sub-components). - - It also includes a callback that lets you know when the top-level peer is changed. - - This class is used by specialised components like OpenGLComponent or QuickTimeComponent - because they need to keep their custom windows in the right place and respond to - changes in the peer. -*/ -class JUCE_API ComponentMovementWatcher : public ComponentListener -{ -public: - - /** Creates a ComponentMovementWatcher to watch a given target component. */ - ComponentMovementWatcher (Component* const component); - - /** Destructor. */ - ~ComponentMovementWatcher(); - - /** This callback happens when the component that is being watched is moved - relative to its top-level peer window, or when it is resized. - */ - virtual void componentMovedOrResized (bool wasMoved, bool wasResized) = 0; - - /** This callback happens when the component's top-level peer is changed. - */ - virtual void componentPeerChanged() = 0; - - juce_UseDebuggingNewOperator - - /** @internal */ - void componentParentHierarchyChanged (Component& component); - /** @internal */ - void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized); - -private: - - Component* const component; - ComponentPeer* lastPeer; - VoidArray registeredParentComps; - bool reentrant; - int lastX, lastY, lastWidth, lastHeight; -#ifdef JUCE_DEBUG - ComponentDeletionWatcher* deletionWatcher; -#endif - - void unregister() throw(); - void registerWithParentComps() throw(); - - ComponentMovementWatcher (const ComponentMovementWatcher&); - const ComponentMovementWatcher& operator= (const ComponentMovementWatcher&); -}; - -#endif // __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__ -/********* End of inlined file: juce_ComponentMovementWatcher.h *********/ - -#endif -#ifndef __JUCE_GROUPCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_GroupComponent.h *********/ -#ifndef __JUCE_GROUPCOMPONENT_JUCEHEADER__ -#define __JUCE_GROUPCOMPONENT_JUCEHEADER__ - -/** - A component that draws an outline around itself and has an optional title at - the top, for drawing an outline around a group of controls. - -*/ -class JUCE_API GroupComponent : public Component -{ -public: - - /** Creates a GroupComponent. - - @param componentName the name to give the component - @param labelText the text to show at the top of the outline - */ - GroupComponent (const String& componentName, - const String& labelText); - - /** Destructor. */ - ~GroupComponent(); - - /** Changes the text that's shown at the top of the component. */ - void setText (const String& newText) throw(); - - /** Returns the currently displayed text label. */ - const String getText() const throw(); - - /** Sets the positioning of the text label. - - (The default is Justification::left) - - @see getTextLabelPosition - */ - void setTextLabelPosition (const Justification& justification); - - /** Returns the current text label position. - - @see setTextLabelPosition - */ - const Justification getTextLabelPosition() const throw() { return justification; } - - /** A set of colour IDs to use to change the colour of various aspects of the component. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - outlineColourId = 0x1005400, /**< The colour to use for drawing the line around the edge. */ - textColourId = 0x1005410 /**< The colour to use to draw the text label. */ - }; - - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void enablementChanged(); - /** @internal */ - void colourChanged(); - -private: - String text; - Justification justification; - - GroupComponent (const GroupComponent&); - const GroupComponent& operator= (const GroupComponent&); -}; - -#endif // __JUCE_GROUPCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_GroupComponent.h *********/ - #endif #ifndef __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__ @@ -48727,14 +48640,85 @@ private: /********* End of inlined file: juce_MultiDocumentPanel.h *********/ #endif -#ifndef __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__ +#ifndef __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__ + +/********* Start of inlined file: juce_ComponentMovementWatcher.h *********/ +#ifndef __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__ +#define __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__ + +/** An object that watches for any movement of a component or any of its parent components. + + This makes it easy to check when a component is moved relative to its top-level + peer window. The normal Component::moved() method is only called when a component + moves relative to its immediate parent, and sometimes you want to know if any of + components higher up the tree have moved (which of course will affect the overall + position of all their sub-components). + + It also includes a callback that lets you know when the top-level peer is changed. + + This class is used by specialised components like OpenGLComponent or QuickTimeComponent + because they need to keep their custom windows in the right place and respond to + changes in the peer. +*/ +class JUCE_API ComponentMovementWatcher : public ComponentListener +{ +public: + + /** Creates a ComponentMovementWatcher to watch a given target component. */ + ComponentMovementWatcher (Component* const component); + + /** Destructor. */ + ~ComponentMovementWatcher(); + + /** This callback happens when the component that is being watched is moved + relative to its top-level peer window, or when it is resized. + */ + virtual void componentMovedOrResized (bool wasMoved, bool wasResized) = 0; + + /** This callback happens when the component's top-level peer is changed. + */ + virtual void componentPeerChanged() = 0; + juce_UseDebuggingNewOperator + + /** @internal */ + void componentParentHierarchyChanged (Component& component); + /** @internal */ + void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized); + +private: + + Component* const component; + ComponentPeer* lastPeer; + VoidArray registeredParentComps; + bool reentrant; + int lastX, lastY, lastWidth, lastHeight; +#ifdef JUCE_DEBUG + ComponentDeletionWatcher* deletionWatcher; #endif -#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__ + + void unregister() throw(); + void registerWithParentComps() throw(); + + ComponentMovementWatcher (const ComponentMovementWatcher&); + const ComponentMovementWatcher& operator= (const ComponentMovementWatcher&); +}; + +#endif // __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__ +/********* End of inlined file: juce_ComponentMovementWatcher.h *********/ + +#endif +#ifndef __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__ #endif #ifndef __JUCE_SCROLLBAR_JUCEHEADER__ +#endif +#ifndef __JUCE_TABBEDBUTTONBAR_JUCEHEADER__ + +#endif +#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__ + #endif #ifndef __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__ @@ -48897,250 +48881,672 @@ public: the position returned is the item's left-hand position, again relative to the x position of the rectangle used. - @see getItemCurrentSize, setItemPosition + @see getItemCurrentSize, setItemPosition + */ + int getItemCurrentPosition (const int itemIndex) const; + + /** Returns the current size of one of the items. + + This is only meaningful after layOutComponents() has been called, as it + returns the last size that this item was given. If the layout was done + vertically, it'll return the item's height in pixels; if it was horizontal, + it'll return its width. + + @see getItemCurrentRelativeSize + */ + int getItemCurrentAbsoluteSize (const int itemIndex) const; + + /** Returns the current size of one of the items. + + This is only meaningful after layOutComponents() has been called, as it + returns the last size that this item was given. If the layout was done + vertically, it'll return a negative value representing the item's height relative + to the last size used for laying the components out; if the layout was done + horizontally it'll be the proportion of its width. + + @see getItemCurrentAbsoluteSize + */ + double getItemCurrentRelativeSize (const int itemIndex) const; + + /** Moves one of the items, shifting along any other items as necessary in + order to get it to the desired position. + + Calling this method will also update the preferred sizes of the items it + shuffles along, so that they reflect their new positions. + + (This is the method that a StretchableLayoutResizerBar uses to shift the items + about when it's dragged). + + @param itemIndex the item to move + @param newPosition the absolute position that you'd like this item to move + to. The item might not be able to always reach exactly this position, + because other items may have minimum sizes that constrain how + far it can go + */ + void setItemPosition (const int itemIndex, + int newPosition); + + juce_UseDebuggingNewOperator + +private: + struct ItemLayoutProperties + { + int itemIndex; + int currentSize; + double minSize, maxSize, preferredSize; + }; + + OwnedArray items; + int totalSize; + + static int sizeToRealSize (double size, int totalSpace); + + ItemLayoutProperties* getInfoFor (const int itemIndex) const; + + void setTotalSize (const int newTotalSize); + + int fitComponentsIntoSpace (const int startIndex, + const int endIndex, + const int availableSpace, + int startPos); + + int getMinimumSizeOfItems (const int startIndex, const int endIndex) const; + int getMaximumSizeOfItems (const int startIndex, const int endIndex) const; + + void updatePrefSizesToMatchCurrentPositions(); + + StretchableLayoutManager (const StretchableLayoutManager&); + const StretchableLayoutManager& operator= (const StretchableLayoutManager&); +}; + +#endif // __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__ +/********* End of inlined file: juce_StretchableLayoutManager.h *********/ + +#endif +#ifndef __JUCE_TABBEDCOMPONENT_JUCEHEADER__ + +#endif +#ifndef __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__ + +/********* Start of inlined file: juce_StretchableLayoutResizerBar.h *********/ +#ifndef __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__ +#define __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__ + +/** + A component that acts as one of the vertical or horizontal bars you see being + used to resize panels in a window. + + One of these acts with a StretchableLayoutManager to resize the other components. + + @see StretchableLayoutManager +*/ +class JUCE_API StretchableLayoutResizerBar : public Component +{ +public: + + /** Creates a resizer bar for use on a specified layout. + + @param layoutToUse the layout that will be affected when this bar + is dragged + @param itemIndexInLayout the item index in the layout that corresponds to + this bar component. You'll need to set up the item + properties in a suitable way for a divider bar, e.g. + for an 8-pixel wide bar which, you could call + myLayout->setItemLayout (barIndex, 8, 8, 8) + @param isBarVertical true if it's an upright bar that you drag left and + right; false for a horizontal one that you drag up and + down + */ + StretchableLayoutResizerBar (StretchableLayoutManager* const layoutToUse, + const int itemIndexInLayout, + const bool isBarVertical); + + /** Destructor. */ + ~StretchableLayoutResizerBar(); + + /** This is called when the bar is dragged. + + This method must update the positions of any components whose position is + determined by the StretchableLayoutManager, because they might have just + moved. + + The default implementation calls the resized() method of this component's + parent component, because that's often where you're likely to apply the + layout, but it can be overridden for more specific needs. + */ + virtual void hasBeenMoved(); + + /** @internal */ + void paint (Graphics& g); + /** @internal */ + void mouseDown (const MouseEvent& e); + /** @internal */ + void mouseDrag (const MouseEvent& e); + + juce_UseDebuggingNewOperator + +private: + StretchableLayoutManager* layout; + int itemIndex, mouseDownPos; + bool isVertical; + + StretchableLayoutResizerBar (const StretchableLayoutResizerBar&); + const StretchableLayoutResizerBar& operator= (const StretchableLayoutResizerBar&); +}; + +#endif // __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__ +/********* End of inlined file: juce_StretchableLayoutResizerBar.h *********/ + +#endif +#ifndef __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__ + +/********* Start of inlined file: juce_StretchableObjectResizer.h *********/ +#ifndef __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__ +#define __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__ + +/** + A utility class for fitting a set of objects whose sizes can vary between + a minimum and maximum size, into a space. + + This is a trickier algorithm than it would first seem, so I've put it in this + class to allow it to be shared by various bits of code. + + To use it, create one of these objects, call addItem() to add the list of items + you need, then call resizeToFit(), which will change all their sizes. You can + then retrieve the new sizes with getItemSize() and getNumItems(). + + It's currently used by the TableHeaderComponent for stretching out the table + headings to fill the table's width. +*/ +class StretchableObjectResizer +{ +public: + + /** Creates an empty object resizer. */ + StretchableObjectResizer(); + + /** Destructor. */ + ~StretchableObjectResizer(); + + /** Adds an item to the list. + + The order parameter lets you specify groups of items that are resized first when some + space needs to be found. Those items with an order of 0 will be the first ones to be + resized, and if that doesn't provide enough space to meet the requirements, the algorithm + will then try resizing the items with an order of 1, then 2, and so on. + */ + void addItem (const double currentSize, + const double minSize, + const double maxSize, + const int order = 0); + + /** Resizes all the items to fit this amount of space. + + This will attempt to fit them in without exceeding each item's miniumum and + maximum sizes. In cases where none of the items can be expanded or enlarged any + further, the final size may be greater or less than the size passed in. + + After calling this method, you can retrieve the new sizes with the getItemSize() + method. + */ + void resizeToFit (const double targetSize); + + /** Returns the number of items that have been added. */ + int getNumItems() const throw() { return items.size(); } + + /** Returns the size of one of the items. */ + double getItemSize (const int index) const throw(); + + juce_UseDebuggingNewOperator + +private: + struct Item + { + double size; + double minSize; + double maxSize; + int order; + }; + + OwnedArray items; + + StretchableObjectResizer (const StretchableObjectResizer&); + const StretchableObjectResizer& operator= (const StretchableObjectResizer&); +}; + +#endif // __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__ +/********* End of inlined file: juce_StretchableObjectResizer.h *********/ + +#endif +#ifndef __JUCE_VIEWPORT_JUCEHEADER__ + +#endif +#ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__ + +#endif +#ifndef __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__ + +#endif +#ifndef __JUCE_GROUPCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_GroupComponent.h *********/ +#ifndef __JUCE_GROUPCOMPONENT_JUCEHEADER__ +#define __JUCE_GROUPCOMPONENT_JUCEHEADER__ + +/** + A component that draws an outline around itself and has an optional title at + the top, for drawing an outline around a group of controls. + +*/ +class JUCE_API GroupComponent : public Component +{ +public: + + /** Creates a GroupComponent. + + @param componentName the name to give the component + @param labelText the text to show at the top of the outline + */ + GroupComponent (const String& componentName, + const String& labelText); + + /** Destructor. */ + ~GroupComponent(); + + /** Changes the text that's shown at the top of the component. */ + void setText (const String& newText) throw(); + + /** Returns the currently displayed text label. */ + const String getText() const throw(); + + /** Sets the positioning of the text label. + + (The default is Justification::left) + + @see getTextLabelPosition + */ + void setTextLabelPosition (const Justification& justification); + + /** Returns the current text label position. + + @see setTextLabelPosition + */ + const Justification getTextLabelPosition() const throw() { return justification; } + + /** A set of colour IDs to use to change the colour of various aspects of the component. + + These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() + methods. + + @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + */ + enum ColourIds + { + outlineColourId = 0x1005400, /**< The colour to use for drawing the line around the edge. */ + textColourId = 0x1005410 /**< The colour to use to draw the text label. */ + }; + + /** @internal */ + void paint (Graphics& g); + /** @internal */ + void enablementChanged(); + /** @internal */ + void colourChanged(); + +private: + String text; + Justification justification; + + GroupComponent (const GroupComponent&); + const GroupComponent& operator= (const GroupComponent&); +}; + +#endif // __JUCE_GROUPCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_GroupComponent.h *********/ + +#endif +#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_FilenameComponent.h *********/ +#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__ +#define __JUCE_FILENAMECOMPONENT_JUCEHEADER__ + +class FilenameComponent; + +/** + Listens for events happening to a FilenameComponent. + + Use FilenameComponent::addListener() and FilenameComponent::removeListener() to + register one of these objects for event callbacks when the filename is changed. + + @See FilenameComponent +*/ +class JUCE_API FilenameComponentListener +{ +public: + /** Destructor. */ + virtual ~FilenameComponentListener() {} + + /** This method is called after the FilenameComponent's file has been changed. */ + virtual void filenameComponentChanged (FilenameComponent* fileComponentThatHasChanged) = 0; +}; + +/** + Shows a filename as an editable text box, with a 'browse' button and a + drop-down list for recently selected files. + + A handy component for dialogue boxes where you want the user to be able to + select a file or directory. + + Attach an FilenameComponentListener using the addListener() method, and it will + get called each time the user changes the filename, either by browsing for a file + and clicking 'ok', or by typing a new filename into the box and pressing return. + + @see FileChooser, ComboBox +*/ +class JUCE_API FilenameComponent : public Component, + public SettableTooltipClient, + public FileDragAndDropTarget, + private AsyncUpdater, + private ButtonListener, + private ComboBoxListener +{ +public: + + /** Creates a FilenameComponent. + + @param name the name for this component. + @param currentFile the file to initially show in the box + @param canEditFilename if true, the user can manually edit the filename; if false, + they can only change it by browsing for a new file + @param isDirectory if true, the file will be treated as a directory, and + an appropriate directory browser used + @param isForSaving if true, the file browser will allow non-existent files to + be picked, as the file is assumed to be used for saving rather + than loading + @param fileBrowserWildcard a wildcard pattern to use in the file browser - e.g. "*.txt;*.foo". + If an empty string is passed in, then the pattern is assumed to be "*" + @param enforcedSuffix if this is non-empty, it is treated as a suffix that will be added + to any filenames that are entered or chosen + @param textWhenNothingSelected the message to display in the box before any filename is entered. (This + will only appear if the initial file isn't valid) + */ + FilenameComponent (const String& name, + const File& currentFile, + const bool canEditFilename, + const bool isDirectory, + const bool isForSaving, + const String& fileBrowserWildcard, + const String& enforcedSuffix, + const String& textWhenNothingSelected); + + /** Destructor. */ + ~FilenameComponent(); + + /** Returns the currently displayed filename. */ + const File getCurrentFile() const; + + /** Changes the current filename. + + If addToRecentlyUsedList is true, the filename will also be added to the + drop-down list of recent files. + + If sendChangeNotification is false, then the listeners won't be told of the + change. + */ + void setCurrentFile (File newFile, + const bool addToRecentlyUsedList, + const bool sendChangeNotification = true); + + /** Changes whether the use can type into the filename box. + */ + void setFilenameIsEditable (const bool shouldBeEditable); + + /** Sets a file or directory to be the default starting point for the browser to show. + + This is only used if the current file hasn't been set. */ - int getItemCurrentPosition (const int itemIndex) const; + void setDefaultBrowseTarget (const File& newDefaultDirectory) throw(); - /** Returns the current size of one of the items. + /** Returns all the entries on the recent files list. - This is only meaningful after layOutComponents() has been called, as it - returns the last size that this item was given. If the layout was done - vertically, it'll return the item's height in pixels; if it was horizontal, - it'll return its width. + This can be used in conjunction with setRecentlyUsedFilenames() for saving the + state of this list. - @see getItemCurrentRelativeSize + @see setRecentlyUsedFilenames */ - int getItemCurrentAbsoluteSize (const int itemIndex) const; + const StringArray getRecentlyUsedFilenames() const; - /** Returns the current size of one of the items. + /** Sets all the entries on the recent files list. - This is only meaningful after layOutComponents() has been called, as it - returns the last size that this item was given. If the layout was done - vertically, it'll return a negative value representing the item's height relative - to the last size used for laying the components out; if the layout was done - horizontally it'll be the proportion of its width. + This can be used in conjunction with getRecentlyUsedFilenames() for saving the + state of this list. - @see getItemCurrentAbsoluteSize + @see getRecentlyUsedFilenames, addRecentlyUsedFile */ - double getItemCurrentRelativeSize (const int itemIndex) const; + void setRecentlyUsedFilenames (const StringArray& filenames); - /** Moves one of the items, shifting along any other items as necessary in - order to get it to the desired position. + /** Adds an entry to the recently-used files dropdown list. - Calling this method will also update the preferred sizes of the items it - shuffles along, so that they reflect their new positions. + If the file is already in the list, it will be moved to the top. A limit + is also placed on the number of items that are kept in the list. - (This is the method that a StretchableLayoutResizerBar uses to shift the items - about when it's dragged). + @see getRecentlyUsedFilenames, setRecentlyUsedFilenames, setMaxNumberOfRecentFiles + */ + void addRecentlyUsedFile (const File& file); - @param itemIndex the item to move - @param newPosition the absolute position that you'd like this item to move - to. The item might not be able to always reach exactly this position, - because other items may have minimum sizes that constrain how - far it can go + /** Changes the limit for the number of files that will be stored in the recent-file list. */ - void setItemPosition (const int itemIndex, - int newPosition); + void setMaxNumberOfRecentFiles (const int newMaximum); - juce_UseDebuggingNewOperator + /** Changes the text shown on the 'browse' button. -private: - struct ItemLayoutProperties - { - int itemIndex; - int currentSize; - double minSize, maxSize, preferredSize; - }; + By default this button just says "..." but you can change it. The button itself + can be changed using the look-and-feel classes, so it might not actually have any + text on it. + */ + void setBrowseButtonText (const String& browseButtonText); - OwnedArray items; - int totalSize; + /** Adds a listener that will be called when the selected file is changed. */ + void addListener (FilenameComponentListener* const listener) throw(); - static int sizeToRealSize (double size, int totalSpace); + /** Removes a previously-registered listener. */ + void removeListener (FilenameComponentListener* const listener) throw(); - ItemLayoutProperties* getInfoFor (const int itemIndex) const; + /** Gives the component a tooltip. */ + void setTooltip (const String& newTooltip); - void setTotalSize (const int newTotalSize); + /** @internal */ + void paintOverChildren (Graphics& g); + /** @internal */ + void resized(); + /** @internal */ + void lookAndFeelChanged(); + /** @internal */ + bool isInterestedInFileDrag (const StringArray& files); + /** @internal */ + void filesDropped (const StringArray& files, int, int); + /** @internal */ + void fileDragEnter (const StringArray& files, int, int); + /** @internal */ + void fileDragExit (const StringArray& files); - int fitComponentsIntoSpace (const int startIndex, - const int endIndex, - const int availableSpace, - int startPos); + juce_UseDebuggingNewOperator - int getMinimumSizeOfItems (const int startIndex, const int endIndex) const; - int getMaximumSizeOfItems (const int startIndex, const int endIndex) const; +private: - void updatePrefSizesToMatchCurrentPositions(); + ComboBox* filenameBox; + String lastFilename; + Button* browseButton; + int maxRecentFiles; + bool isDir, isSaving, isFileDragOver; + String wildcard, enforcedSuffix, browseButtonText; + SortedSet listeners; + File defaultBrowseFile; - StretchableLayoutManager (const StretchableLayoutManager&); - const StretchableLayoutManager& operator= (const StretchableLayoutManager&); + void comboBoxChanged (ComboBox*); + void buttonClicked (Button* button); + void handleAsyncUpdate(); + + FilenameComponent (const FilenameComponent&); + const FilenameComponent& operator= (const FilenameComponent&); }; -#endif // __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__ -/********* End of inlined file: juce_StretchableLayoutManager.h *********/ +#endif // __JUCE_FILENAMECOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_FilenameComponent.h *********/ #endif -#ifndef __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__ +#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ -/********* Start of inlined file: juce_StretchableLayoutResizerBar.h *********/ -#ifndef __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__ -#define __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__ +/********* Start of inlined file: juce_FilePreviewComponent.h *********/ +#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ +#define __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ /** - A component that acts as one of the vertical or horizontal bars you see being - used to resize panels in a window. + Base class for components that live inside a file chooser dialog box and + show previews of the files that get selected. - One of these acts with a StretchableLayoutManager to resize the other components. + One of these allows special extra information to be displayed for files + in a dialog box as the user selects them. Each time the current file or + directory is changed, the selectedFileChanged() method will be called + to allow it to update itself appropriately. - @see StretchableLayoutManager + @see FileChooser, ImagePreviewComponent */ -class JUCE_API StretchableLayoutResizerBar : public Component +class JUCE_API FilePreviewComponent : public Component { public: - /** Creates a resizer bar for use on a specified layout. - - @param layoutToUse the layout that will be affected when this bar - is dragged - @param itemIndexInLayout the item index in the layout that corresponds to - this bar component. You'll need to set up the item - properties in a suitable way for a divider bar, e.g. - for an 8-pixel wide bar which, you could call - myLayout->setItemLayout (barIndex, 8, 8, 8) - @param isBarVertical true if it's an upright bar that you drag left and - right; false for a horizontal one that you drag up and - down - */ - StretchableLayoutResizerBar (StretchableLayoutManager* const layoutToUse, - const int itemIndexInLayout, - const bool isBarVertical); + /** Creates a FilePreviewComponent. */ + FilePreviewComponent(); /** Destructor. */ - ~StretchableLayoutResizerBar(); - - /** This is called when the bar is dragged. + ~FilePreviewComponent(); - This method must update the positions of any components whose position is - determined by the StretchableLayoutManager, because they might have just - moved. + /** Called to indicate that the user's currently selected file has changed. - The default implementation calls the resized() method of this component's - parent component, because that's often where you're likely to apply the - layout, but it can be overridden for more specific needs. + @param newSelectedFile the newly selected file or directory, which may be + File::nonexistent if none is selected. */ - virtual void hasBeenMoved(); - - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void mouseDown (const MouseEvent& e); - /** @internal */ - void mouseDrag (const MouseEvent& e); + virtual void selectedFileChanged (const File& newSelectedFile) = 0; juce_UseDebuggingNewOperator private: - StretchableLayoutManager* layout; - int itemIndex, mouseDownPos; - bool isVertical; - - StretchableLayoutResizerBar (const StretchableLayoutResizerBar&); - const StretchableLayoutResizerBar& operator= (const StretchableLayoutResizerBar&); + FilePreviewComponent (const FilePreviewComponent&); + const FilePreviewComponent& operator= (const FilePreviewComponent&); }; -#endif // __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__ -/********* End of inlined file: juce_StretchableLayoutResizerBar.h *********/ +#endif // __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_FilePreviewComponent.h *********/ #endif -#ifndef __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__ +#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ -/********* Start of inlined file: juce_StretchableObjectResizer.h *********/ -#ifndef __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__ -#define __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__ +/********* Start of inlined file: juce_FileSearchPathListComponent.h *********/ +#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ +#define __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ /** - A utility class for fitting a set of objects whose sizes can vary between - a minimum and maximum size, into a space. - - This is a trickier algorithm than it would first seem, so I've put it in this - class to allow it to be shared by various bits of code. - - To use it, create one of these objects, call addItem() to add the list of items - you need, then call resizeToFit(), which will change all their sizes. You can - then retrieve the new sizes with getItemSize() and getNumItems(). + Shows a set of file paths in a list, allowing them to be added, removed or + re-ordered. - It's currently used by the TableHeaderComponent for stretching out the table - headings to fill the table's width. + @see FileSearchPath */ -class StretchableObjectResizer +class JUCE_API FileSearchPathListComponent : public Component, + public SettableTooltipClient, + public FileDragAndDropTarget, + private ButtonListener, + private ListBoxModel { public: - /** Creates an empty object resizer. */ - StretchableObjectResizer(); + /** Creates an empty FileSearchPathListComponent. + + */ + FileSearchPathListComponent(); /** Destructor. */ - ~StretchableObjectResizer(); + ~FileSearchPathListComponent(); - /** Adds an item to the list. + /** Returns the path as it is currently shown. */ + const FileSearchPath& getPath() const throw() { return path; } - The order parameter lets you specify groups of items that are resized first when some - space needs to be found. Those items with an order of 0 will be the first ones to be - resized, and if that doesn't provide enough space to meet the requirements, the algorithm - will then try resizing the items with an order of 1, then 2, and so on. + /** Changes the current path. */ + void setPath (const FileSearchPath& newPath); + + /** Sets a file or directory to be the default starting point for the browser to show. + + This is only used if the current file hasn't been set. */ - void addItem (const double currentSize, - const double minSize, - const double maxSize, - const int order = 0); + void setDefaultBrowseTarget (const File& newDefaultDirectory) throw(); - /** Resizes all the items to fit this amount of space. + /** A set of colour IDs to use to change the colour of various aspects of the label. - This will attempt to fit them in without exceeding each item's miniumum and - maximum sizes. In cases where none of the items can be expanded or enlarged any - further, the final size may be greater or less than the size passed in. + These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() + methods. - After calling this method, you can retrieve the new sizes with the getItemSize() - method. + @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour */ - void resizeToFit (const double targetSize); - - /** Returns the number of items that have been added. */ - int getNumItems() const throw() { return items.size(); } + enum ColourIds + { + backgroundColourId = 0x1004100, /**< The background colour to fill the component with. + Make this transparent if you don't want the background to be filled. */ + }; - /** Returns the size of one of the items. */ - double getItemSize (const int index) const throw(); + /** @internal */ + int getNumRows(); + /** @internal */ + void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected); + /** @internal */ + void deleteKeyPressed (int lastRowSelected); + /** @internal */ + void returnKeyPressed (int lastRowSelected); + /** @internal */ + void listBoxItemDoubleClicked (int row, const MouseEvent&); + /** @internal */ + void selectedRowsChanged (int lastRowSelected); + /** @internal */ + void resized(); + /** @internal */ + void paint (Graphics& g); + /** @internal */ + bool isInterestedInFileDrag (const StringArray& files); + /** @internal */ + void filesDropped (const StringArray& files, int, int); + /** @internal */ + void buttonClicked (Button* button); juce_UseDebuggingNewOperator private: - struct Item - { - double size; - double minSize; - double maxSize; - int order; - }; - OwnedArray items; + FileSearchPath path; + File defaultBrowseTarget; - StretchableObjectResizer (const StretchableObjectResizer&); - const StretchableObjectResizer& operator= (const StretchableObjectResizer&); -}; + ListBox* listBox; + Button* addButton; + Button* removeButton; + Button* changeButton; + Button* upButton; + Button* downButton; -#endif // __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__ -/********* End of inlined file: juce_StretchableObjectResizer.h *********/ + void changed() throw(); + void updateButtons() throw(); -#endif -#ifndef __JUCE_TABBEDBUTTONBAR_JUCEHEADER__ + FileSearchPathListComponent (const FileSearchPathListComponent&); + const FileSearchPathListComponent& operator= (const FileSearchPathListComponent&); +}; -#endif -#ifndef __JUCE_TABBEDCOMPONENT_JUCEHEADER__ +#endif // __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_FileSearchPathListComponent.h *********/ #endif -#ifndef __JUCE_VIEWPORT_JUCEHEADER__ +#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ -#endif -#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ +/********* Start of inlined file: juce_FileTreeComponent.h *********/ +#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ +#define __JUCE_FILETREECOMPONENT_JUCEHEADER__ /********* Start of inlined file: juce_DirectoryContentsDisplayComponent.h *********/ #ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ @@ -49474,57 +49880,179 @@ protected: #endif // __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ /********* End of inlined file: juce_DirectoryContentsDisplayComponent.h *********/ -#endif -#ifndef __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__ +/** + A component that displays the files in a directory as a treeview. -#endif -#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ + This implements the DirectoryContentsDisplayComponent base class so that + it can be used in a FileBrowserComponent. -/********* Start of inlined file: juce_FileBrowserComponent.h *********/ -#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ -#define __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ + To attach a listener to it, use its DirectoryContentsDisplayComponent base + class and the FileBrowserListener class. -/********* Start of inlined file: juce_FilePreviewComponent.h *********/ -#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ -#define __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ + @see DirectoryContentsList, FileListComponent +*/ +class JUCE_API FileTreeComponent : public TreeView, + public DirectoryContentsDisplayComponent +{ +public: + + /** Creates a listbox to show the contents of a specified directory. + */ + FileTreeComponent (DirectoryContentsList& listToShow); + + /** Destructor. */ + ~FileTreeComponent(); + + /** Returns the number of selected files in the tree. + */ + int getNumSelectedFiles() const throw() { return TreeView::getNumSelectedItems(); } + + /** Returns one of the files that the user has currently selected. + + Returns File::nonexistent if none is selected. + */ + const File getSelectedFile (int index) const throw(); + + /** Returns the first of the files that the user has currently selected. + + Returns File::nonexistent if none is selected. + */ + const File getSelectedFile() const; + + /** Scrolls the list to the top. */ + void scrollToTop(); + + /** Setting a name for this allows tree items to be dragged. + + The string that you pass in here will be returned by the getDragSourceDescription() + of the items in the tree. For more info, see TreeViewItem::getDragSourceDescription(). + */ + void setDragAndDropDescription (const String& description) throw(); + + /** Returns the last value that was set by setDragAndDropDescription(). + */ + const String& getDragAndDropDescription() const throw() { return dragAndDropDescription; } + + juce_UseDebuggingNewOperator + +private: + String dragAndDropDescription; + + FileTreeComponent (const FileTreeComponent&); + const FileTreeComponent& operator= (const FileTreeComponent&); +}; + +#endif // __JUCE_FILETREECOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_FileTreeComponent.h *********/ + +#endif +#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ + +/********* Start of inlined file: juce_WildcardFileFilter.h *********/ +#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ +#define __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ /** - Base class for components that live inside a file chooser dialog box and - show previews of the files that get selected. + A type of FileFilter that works by wildcard pattern matching. - One of these allows special extra information to be displayed for files - in a dialog box as the user selects them. Each time the current file or - directory is changed, the selectedFileChanged() method will be called - to allow it to update itself appropriately. + This filter only allows files that match one of the specified patterns, but + allows all directories through. - @see FileChooser, ImagePreviewComponent + @see FileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent */ -class JUCE_API FilePreviewComponent : public Component +class JUCE_API WildcardFileFilter : public FileFilter { public: - /** Creates a FilePreviewComponent. */ - FilePreviewComponent(); + /** + Creates a wildcard filter for one or more patterns. + + The wildcardPatterns parameter is a comma or semicolon-delimited set of + patterns, e.g. "*.wav;*.aiff" would look for files ending in either .wav + or .aiff. + + The description is a name to show the user in a list of possible patterns, so + for the wav/aiff example, your description might be "audio files". + */ + WildcardFileFilter (const String& wildcardPatterns, + const String& description); /** Destructor. */ - ~FilePreviewComponent(); + ~WildcardFileFilter(); - /** Called to indicate that the user's currently selected file has changed. + /** Returns true if the filename matches one of the patterns specified. */ + bool isFileSuitable (const File& file) const; - @param newSelectedFile the newly selected file or directory, which may be - File::nonexistent if none is selected. - */ - virtual void selectedFileChanged (const File& newSelectedFile) = 0; + /** This always returns true. */ + bool isDirectorySuitable (const File& file) const; juce_UseDebuggingNewOperator private: - FilePreviewComponent (const FilePreviewComponent&); - const FilePreviewComponent& operator= (const FilePreviewComponent&); + StringArray wildcards; }; -#endif // __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_FilePreviewComponent.h *********/ +#endif // __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ +/********* End of inlined file: juce_WildcardFileFilter.h *********/ + +#endif +#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_ImagePreviewComponent.h *********/ +#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ +#define __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ + +/** + A simple preview component that shows thumbnails of image files. + + @see FileChooserDialogBox, FilePreviewComponent +*/ +class JUCE_API ImagePreviewComponent : public FilePreviewComponent, + private Timer +{ +public: + + /** Creates an ImagePreviewComponent. */ + ImagePreviewComponent(); + + /** Destructor. */ + ~ImagePreviewComponent(); + + /** @internal */ + void selectedFileChanged (const File& newSelectedFile); + /** @internal */ + void paint (Graphics& g); + /** @internal */ + void timerCallback(); + + juce_UseDebuggingNewOperator + +private: + File fileToLoad; + Image* currentThumbnail; + String currentDetails; + + void getThumbSize (int& w, int& h) const; + + ImagePreviewComponent (const ImagePreviewComponent&); + const ImagePreviewComponent& operator= (const ImagePreviewComponent&); +}; + +#endif // __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_ImagePreviewComponent.h *********/ + +#endif +#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ + +#endif +#ifndef __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__ + +#endif +#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_FileBrowserComponent.h *********/ +#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ +#define __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ /** A component for browsing and selecting a file or directory to open or save. @@ -50050,469 +50578,6 @@ private: #endif // __JUCE_FILELISTCOMPONENT_JUCEHEADER__ /********* End of inlined file: juce_FileListComponent.h *********/ -#endif -#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_FilenameComponent.h *********/ -#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__ -#define __JUCE_FILENAMECOMPONENT_JUCEHEADER__ - -class FilenameComponent; - -/** - Listens for events happening to a FilenameComponent. - - Use FilenameComponent::addListener() and FilenameComponent::removeListener() to - register one of these objects for event callbacks when the filename is changed. - - @See FilenameComponent -*/ -class JUCE_API FilenameComponentListener -{ -public: - /** Destructor. */ - virtual ~FilenameComponentListener() {} - - /** This method is called after the FilenameComponent's file has been changed. */ - virtual void filenameComponentChanged (FilenameComponent* fileComponentThatHasChanged) = 0; -}; - -/** - Shows a filename as an editable text box, with a 'browse' button and a - drop-down list for recently selected files. - - A handy component for dialogue boxes where you want the user to be able to - select a file or directory. - - Attach an FilenameComponentListener using the addListener() method, and it will - get called each time the user changes the filename, either by browsing for a file - and clicking 'ok', or by typing a new filename into the box and pressing return. - - @see FileChooser, ComboBox -*/ -class JUCE_API FilenameComponent : public Component, - public SettableTooltipClient, - public FileDragAndDropTarget, - private AsyncUpdater, - private ButtonListener, - private ComboBoxListener -{ -public: - - /** Creates a FilenameComponent. - - @param name the name for this component. - @param currentFile the file to initially show in the box - @param canEditFilename if true, the user can manually edit the filename; if false, - they can only change it by browsing for a new file - @param isDirectory if true, the file will be treated as a directory, and - an appropriate directory browser used - @param isForSaving if true, the file browser will allow non-existent files to - be picked, as the file is assumed to be used for saving rather - than loading - @param fileBrowserWildcard a wildcard pattern to use in the file browser - e.g. "*.txt;*.foo". - If an empty string is passed in, then the pattern is assumed to be "*" - @param enforcedSuffix if this is non-empty, it is treated as a suffix that will be added - to any filenames that are entered or chosen - @param textWhenNothingSelected the message to display in the box before any filename is entered. (This - will only appear if the initial file isn't valid) - */ - FilenameComponent (const String& name, - const File& currentFile, - const bool canEditFilename, - const bool isDirectory, - const bool isForSaving, - const String& fileBrowserWildcard, - const String& enforcedSuffix, - const String& textWhenNothingSelected); - - /** Destructor. */ - ~FilenameComponent(); - - /** Returns the currently displayed filename. */ - const File getCurrentFile() const; - - /** Changes the current filename. - - If addToRecentlyUsedList is true, the filename will also be added to the - drop-down list of recent files. - - If sendChangeNotification is false, then the listeners won't be told of the - change. - */ - void setCurrentFile (File newFile, - const bool addToRecentlyUsedList, - const bool sendChangeNotification = true); - - /** Changes whether the use can type into the filename box. - */ - void setFilenameIsEditable (const bool shouldBeEditable); - - /** Sets a file or directory to be the default starting point for the browser to show. - - This is only used if the current file hasn't been set. - */ - void setDefaultBrowseTarget (const File& newDefaultDirectory) throw(); - - /** Returns all the entries on the recent files list. - - This can be used in conjunction with setRecentlyUsedFilenames() for saving the - state of this list. - - @see setRecentlyUsedFilenames - */ - const StringArray getRecentlyUsedFilenames() const; - - /** Sets all the entries on the recent files list. - - This can be used in conjunction with getRecentlyUsedFilenames() for saving the - state of this list. - - @see getRecentlyUsedFilenames, addRecentlyUsedFile - */ - void setRecentlyUsedFilenames (const StringArray& filenames); - - /** Adds an entry to the recently-used files dropdown list. - - If the file is already in the list, it will be moved to the top. A limit - is also placed on the number of items that are kept in the list. - - @see getRecentlyUsedFilenames, setRecentlyUsedFilenames, setMaxNumberOfRecentFiles - */ - void addRecentlyUsedFile (const File& file); - - /** Changes the limit for the number of files that will be stored in the recent-file list. - */ - void setMaxNumberOfRecentFiles (const int newMaximum); - - /** Changes the text shown on the 'browse' button. - - By default this button just says "..." but you can change it. The button itself - can be changed using the look-and-feel classes, so it might not actually have any - text on it. - */ - void setBrowseButtonText (const String& browseButtonText); - - /** Adds a listener that will be called when the selected file is changed. */ - void addListener (FilenameComponentListener* const listener) throw(); - - /** Removes a previously-registered listener. */ - void removeListener (FilenameComponentListener* const listener) throw(); - - /** Gives the component a tooltip. */ - void setTooltip (const String& newTooltip); - - /** @internal */ - void paintOverChildren (Graphics& g); - /** @internal */ - void resized(); - /** @internal */ - void lookAndFeelChanged(); - /** @internal */ - bool isInterestedInFileDrag (const StringArray& files); - /** @internal */ - void filesDropped (const StringArray& files, int, int); - /** @internal */ - void fileDragEnter (const StringArray& files, int, int); - /** @internal */ - void fileDragExit (const StringArray& files); - - juce_UseDebuggingNewOperator - -private: - - ComboBox* filenameBox; - String lastFilename; - Button* browseButton; - int maxRecentFiles; - bool isDir, isSaving, isFileDragOver; - String wildcard, enforcedSuffix, browseButtonText; - SortedSet listeners; - File defaultBrowseFile; - - void comboBoxChanged (ComboBox*); - void buttonClicked (Button* button); - void handleAsyncUpdate(); - - FilenameComponent (const FilenameComponent&); - const FilenameComponent& operator= (const FilenameComponent&); -}; - -#endif // __JUCE_FILENAMECOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_FilenameComponent.h *********/ - -#endif -#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ - -#endif -#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_FileSearchPathListComponent.h *********/ -#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ -#define __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ - -/** - Shows a set of file paths in a list, allowing them to be added, removed or - re-ordered. - - @see FileSearchPath -*/ -class JUCE_API FileSearchPathListComponent : public Component, - public SettableTooltipClient, - public FileDragAndDropTarget, - private ButtonListener, - private ListBoxModel -{ -public: - - /** Creates an empty FileSearchPathListComponent. - - */ - FileSearchPathListComponent(); - - /** Destructor. */ - ~FileSearchPathListComponent(); - - /** Returns the path as it is currently shown. */ - const FileSearchPath& getPath() const throw() { return path; } - - /** Changes the current path. */ - void setPath (const FileSearchPath& newPath); - - /** Sets a file or directory to be the default starting point for the browser to show. - - This is only used if the current file hasn't been set. - */ - void setDefaultBrowseTarget (const File& newDefaultDirectory) throw(); - - /** A set of colour IDs to use to change the colour of various aspects of the label. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - backgroundColourId = 0x1004100, /**< The background colour to fill the component with. - Make this transparent if you don't want the background to be filled. */ - }; - - /** @internal */ - int getNumRows(); - /** @internal */ - void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected); - /** @internal */ - void deleteKeyPressed (int lastRowSelected); - /** @internal */ - void returnKeyPressed (int lastRowSelected); - /** @internal */ - void listBoxItemDoubleClicked (int row, const MouseEvent&); - /** @internal */ - void selectedRowsChanged (int lastRowSelected); - /** @internal */ - void resized(); - /** @internal */ - void paint (Graphics& g); - /** @internal */ - bool isInterestedInFileDrag (const StringArray& files); - /** @internal */ - void filesDropped (const StringArray& files, int, int); - /** @internal */ - void buttonClicked (Button* button); - - juce_UseDebuggingNewOperator - -private: - - FileSearchPath path; - File defaultBrowseTarget; - - ListBox* listBox; - Button* addButton; - Button* removeButton; - Button* changeButton; - Button* upButton; - Button* downButton; - - void changed() throw(); - void updateButtons() throw(); - - FileSearchPathListComponent (const FileSearchPathListComponent&); - const FileSearchPathListComponent& operator= (const FileSearchPathListComponent&); -}; - -#endif // __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_FileSearchPathListComponent.h *********/ - -#endif -#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_FileTreeComponent.h *********/ -#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ -#define __JUCE_FILETREECOMPONENT_JUCEHEADER__ - -/** - A component that displays the files in a directory as a treeview. - - This implements the DirectoryContentsDisplayComponent base class so that - it can be used in a FileBrowserComponent. - - To attach a listener to it, use its DirectoryContentsDisplayComponent base - class and the FileBrowserListener class. - - @see DirectoryContentsList, FileListComponent -*/ -class JUCE_API FileTreeComponent : public TreeView, - public DirectoryContentsDisplayComponent -{ -public: - - /** Creates a listbox to show the contents of a specified directory. - */ - FileTreeComponent (DirectoryContentsList& listToShow); - - /** Destructor. */ - ~FileTreeComponent(); - - /** Returns the number of selected files in the tree. - */ - int getNumSelectedFiles() const throw() { return TreeView::getNumSelectedItems(); } - - /** Returns one of the files that the user has currently selected. - - Returns File::nonexistent if none is selected. - */ - const File getSelectedFile (int index) const throw(); - - /** Returns the first of the files that the user has currently selected. - - Returns File::nonexistent if none is selected. - */ - const File getSelectedFile() const; - - /** Scrolls the list to the top. */ - void scrollToTop(); - - /** Setting a name for this allows tree items to be dragged. - - The string that you pass in here will be returned by the getDragSourceDescription() - of the items in the tree. For more info, see TreeViewItem::getDragSourceDescription(). - */ - void setDragAndDropDescription (const String& description) throw(); - - /** Returns the last value that was set by setDragAndDropDescription(). - */ - const String& getDragAndDropDescription() const throw() { return dragAndDropDescription; } - - juce_UseDebuggingNewOperator - -private: - String dragAndDropDescription; - - FileTreeComponent (const FileTreeComponent&); - const FileTreeComponent& operator= (const FileTreeComponent&); -}; - -#endif // __JUCE_FILETREECOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_FileTreeComponent.h *********/ - -#endif -#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_ImagePreviewComponent.h *********/ -#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ -#define __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ - -/** - A simple preview component that shows thumbnails of image files. - - @see FileChooserDialogBox, FilePreviewComponent -*/ -class JUCE_API ImagePreviewComponent : public FilePreviewComponent, - private Timer -{ -public: - - /** Creates an ImagePreviewComponent. */ - ImagePreviewComponent(); - - /** Destructor. */ - ~ImagePreviewComponent(); - - /** @internal */ - void selectedFileChanged (const File& newSelectedFile); - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void timerCallback(); - - juce_UseDebuggingNewOperator - -private: - File fileToLoad; - Image* currentThumbnail; - String currentDetails; - - void getThumbSize (int& w, int& h) const; - - ImagePreviewComponent (const ImagePreviewComponent&); - const ImagePreviewComponent& operator= (const ImagePreviewComponent&); -}; - -#endif // __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_ImagePreviewComponent.h *********/ - -#endif -#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ - -/********* Start of inlined file: juce_WildcardFileFilter.h *********/ -#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ -#define __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ - -/** - A type of FileFilter that works by wildcard pattern matching. - - This filter only allows files that match one of the specified patterns, but - allows all directories through. - - @see FileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent -*/ -class JUCE_API WildcardFileFilter : public FileFilter -{ -public: - - /** - Creates a wildcard filter for one or more patterns. - - The wildcardPatterns parameter is a comma or semicolon-delimited set of - patterns, e.g. "*.wav;*.aiff" would look for files ending in either .wav - or .aiff. - - The description is a name to show the user in a list of possible patterns, so - for the wav/aiff example, your description might be "audio files". - */ - WildcardFileFilter (const String& wildcardPatterns, - const String& description); - - /** Destructor. */ - ~WildcardFileFilter(); - - /** Returns true if the filename matches one of the patterns specified. */ - bool isFileSuitable (const File& file) const; - - /** This always returns true. */ - bool isDirectorySuitable (const File& file) const; - - juce_UseDebuggingNewOperator - -private: - StringArray wildcards; -}; - -#endif // __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ -/********* End of inlined file: juce_WildcardFileFilter.h *********/ - #endif #ifndef __JUCE_ALERTWINDOW_JUCEHEADER__ @@ -51092,6 +51157,9 @@ private: #endif // __JUCE_SPLASHSCREEN_JUCEHEADER__ /********* End of inlined file: juce_SplashScreen.h *********/ +#endif +#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__ + #endif #ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__ @@ -51225,10 +51293,164 @@ private: /********* End of inlined file: juce_ThreadWithProgressWindow.h *********/ #endif -#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__ +#ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__ #endif -#ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__ +#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_SystemTrayIconComponent.h *********/ +#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ +#define __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ + +#if JUCE_WIN32 || JUCE_LINUX + +/** + On Windows only, this component sits in the taskbar tray as a small icon. + + To use it, just create one of these components, but don't attempt to make it + visible, add it to a parent, or put it on the desktop. + + You can then call setIconImage() to create an icon for it in the taskbar. + + To change the icon's tooltip, you can use setIconTooltip(). + + To respond to mouse-events, you can override the normal mouseDown(), + mouseUp(), mouseDoubleClick() and mouseMove() methods, and although the x, y + position will not be valid, you can use this to respond to clicks. Traditionally + you'd use a left-click to show your application's window, and a right-click + to show a pop-up menu. +*/ +class JUCE_API SystemTrayIconComponent : public Component +{ +public: + + SystemTrayIconComponent(); + + /** Destructor. */ + ~SystemTrayIconComponent(); + + /** Changes the image shown in the taskbar. + */ + void setIconImage (const Image& newImage); + + /** Changes the tooltip that Windows shows above the icon. */ + void setIconTooltip (const String& tooltip); + +#if JUCE_LINUX + /** @internal */ + void paint (Graphics& g); +#endif + + juce_UseDebuggingNewOperator + +private: + + SystemTrayIconComponent (const SystemTrayIconComponent&); + const SystemTrayIconComponent& operator= (const SystemTrayIconComponent&); +}; + +#endif +#endif // __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_SystemTrayIconComponent.h *********/ + +#endif +#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_WebBrowserComponent.h *********/ +#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ +#define __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ + +#if JUCE_WEB_BROWSER + +class WebBrowserComponentInternal; + +/** + A component that displays an embedded web browser. + + The browser itself will be platform-dependent. On the Mac, probably Safari, on + Windows, probably IE. + +*/ +class WebBrowserComponent : public Component +{ +public: + + /** Creates a WebBrowserComponent. + + Once it's created and visible, send the browser to a URL using goToURL(). + */ + WebBrowserComponent(); + + /** Destructor. */ + ~WebBrowserComponent(); + + /** Sends the browser to a particular URL. + + @param url the URL to go to. + @param headers an optional set of parameters to put in the HTTP header. If + you supply this, it should be a set of string in the form + "HeaderKey: HeaderValue" + @param postData an optional block of data that will be attached to the HTTP + POST request + */ + void goToURL (const String& url, + const StringArray* headers = 0, + const MemoryBlock* postData = 0); + + /** Stops the current page loading. + */ + void stop(); + + /** Sends the browser back one page. + */ + void goBack(); + + /** Sends the browser forward one page. + */ + void goForward(); + + /** Refreshes the browser. + */ + void refresh(); + + /** This callback is called when the browser is about to navigate + to a new location. + + You can override this method to perform some action when the user + tries to go to a particular URL. To allow the operation to carry on, + return true, or return false to stop the navigation happening. + */ + virtual bool pageAboutToLoad (const String& newURL); + + /** @internal */ + void paint (Graphics& g); + /** @internal */ + void resized(); + /** @internal */ + void parentHierarchyChanged(); + /** @internal */ + void visibilityChanged(); + + juce_UseDebuggingNewOperator + +private: + WebBrowserComponentInternal* browser; + bool blankPageShown; + + String lastURL; + StringArray lastHeaders; + MemoryBlock lastPostData; + + void reloadLastURL(); + void checkWindowAssociation(); + + WebBrowserComponent (const WebBrowserComponent&); + const WebBrowserComponent& operator= (const WebBrowserComponent&); +}; + +#endif +#endif // __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_WebBrowserComponent.h *********/ #endif #ifndef __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__ @@ -52954,163 +53176,6 @@ private: #endif // __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__ /********* End of inlined file: juce_QuickTimeMovieComponent.h *********/ -#endif -#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_SystemTrayIconComponent.h *********/ -#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ -#define __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ - -#if JUCE_WIN32 || JUCE_LINUX - -/** - On Windows only, this component sits in the taskbar tray as a small icon. - - To use it, just create one of these components, but don't attempt to make it - visible, add it to a parent, or put it on the desktop. - - You can then call setIconImage() to create an icon for it in the taskbar. - - To change the icon's tooltip, you can use setIconTooltip(). - - To respond to mouse-events, you can override the normal mouseDown(), - mouseUp(), mouseDoubleClick() and mouseMove() methods, and although the x, y - position will not be valid, you can use this to respond to clicks. Traditionally - you'd use a left-click to show your application's window, and a right-click - to show a pop-up menu. -*/ -class JUCE_API SystemTrayIconComponent : public Component -{ -public: - - SystemTrayIconComponent(); - - /** Destructor. */ - ~SystemTrayIconComponent(); - - /** Changes the image shown in the taskbar. - */ - void setIconImage (const Image& newImage); - - /** Changes the tooltip that Windows shows above the icon. */ - void setIconTooltip (const String& tooltip); - -#if JUCE_LINUX - /** @internal */ - void paint (Graphics& g); -#endif - - juce_UseDebuggingNewOperator - -private: - - SystemTrayIconComponent (const SystemTrayIconComponent&); - const SystemTrayIconComponent& operator= (const SystemTrayIconComponent&); -}; - -#endif -#endif // __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_SystemTrayIconComponent.h *********/ - -#endif -#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_WebBrowserComponent.h *********/ -#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ -#define __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ - -#if JUCE_WEB_BROWSER - -class WebBrowserComponentInternal; - -/** - A component that displays an embedded web browser. - - The browser itself will be platform-dependent. On the Mac, probably Safari, on - Windows, probably IE. - -*/ -class WebBrowserComponent : public Component -{ -public: - - /** Creates a WebBrowserComponent. - - Once it's created and visible, send the browser to a URL using goToURL(). - */ - WebBrowserComponent(); - - /** Destructor. */ - ~WebBrowserComponent(); - - /** Sends the browser to a particular URL. - - @param url the URL to go to. - @param headers an optional set of parameters to put in the HTTP header. If - you supply this, it should be a set of string in the form - "HeaderKey: HeaderValue" - @param postData an optional block of data that will be attached to the HTTP - POST request - */ - void goToURL (const String& url, - const StringArray* headers = 0, - const MemoryBlock* postData = 0); - - /** Stops the current page loading. - */ - void stop(); - - /** Sends the browser back one page. - */ - void goBack(); - - /** Sends the browser forward one page. - */ - void goForward(); - - /** Refreshes the browser. - */ - void refresh(); - - /** This callback is called when the browser is about to navigate - to a new location. - - You can override this method to perform some action when the user - tries to go to a particular URL. To allow the operation to carry on, - return true, or return false to stop the navigation happening. - */ - virtual bool pageAboutToLoad (const String& newURL); - - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void resized(); - /** @internal */ - void parentHierarchyChanged(); - /** @internal */ - void visibilityChanged(); - - juce_UseDebuggingNewOperator - -private: - WebBrowserComponentInternal* browser; - bool blankPageShown; - - String lastURL; - StringArray lastHeaders; - MemoryBlock lastPostData; - - void reloadLastURL(); - void checkWindowAssociation(); - - WebBrowserComponent (const WebBrowserComponent&); - const WebBrowserComponent& operator= (const WebBrowserComponent&); -}; - -#endif -#endif // __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_WebBrowserComponent.h *********/ - #endif #ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__ @@ -54233,7 +54298,7 @@ private: #endif -#endif // __JUCE_APP_INCLUDES_JUCEHEADER__ +#endif /********* End of inlined file: juce_app_includes.h *********/ #endif diff --git a/src/juce_app_includes.h b/src/juce_app_includes.h index dbd358998b..e117f6522d 100644 --- a/src/juce_app_includes.h +++ b/src/juce_app_includes.h @@ -29,8 +29,8 @@ ============================================================================== */ -#ifndef __JUCE_APP_INCLUDES_JUCEHEADER__ -#define __JUCE_APP_INCLUDES_JUCEHEADER__ +#ifndef __JUCE_JUCE_APP_INCLUDES_INCLUDEFILES__ +#define __JUCE_JUCE_APP_INCLUDES_INCLUDEFILES__ #ifndef __JUCE_APPLICATION_JUCEHEADER__ #include "juce_appframework/application/juce_Application.h" @@ -197,6 +197,18 @@ #ifndef __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__ #include "juce_appframework/audio/plugins/juce_PluginListComponent.h" #endif +#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ + #include "juce_appframework/audio/audio_file_formats/juce_FlacAudioFormat.h" +#endif +#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ + #include "juce_appframework/audio/audio_file_formats/juce_WavAudioFormat.h" +#endif +#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ + #include "juce_appframework/audio/audio_file_formats/juce_OggVorbisAudioFormat.h" +#endif +#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ + #include "juce_appframework/audio/audio_file_formats/juce_QuickTimeAudioFormat.h" +#endif #ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ #include "juce_appframework/audio/audio_file_formats/juce_AiffAudioFormat.h" #endif @@ -227,17 +239,27 @@ #ifndef __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__ #include "juce_appframework/audio/audio_file_formats/juce_AudioThumbnailCache.h" #endif -#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ - #include "juce_appframework/audio/audio_file_formats/juce_FlacAudioFormat.h" +#ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__ + #include "juce_appframework/events/juce_InterprocessConnectionServer.h" #endif -#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ - #include "juce_appframework/audio/audio_file_formats/juce_OggVorbisAudioFormat.h" +#ifndef __JUCE_MESSAGE_JUCEHEADER__ + #include "juce_appframework/events/juce_Message.h" #endif -#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ - #include "juce_appframework/audio/audio_file_formats/juce_QuickTimeAudioFormat.h" +#ifndef __JUCE_TIMER_JUCEHEADER__ + #include "juce_appframework/events/juce_Timer.h" #endif -#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ - #include "juce_appframework/audio/audio_file_formats/juce_WavAudioFormat.h" +#ifndef __JUCE_MESSAGELISTENER_JUCEHEADER__ + #include "juce_appframework/events/juce_MessageListener.h" +#endif +#ifndef __JUCE_MULTITIMER_JUCEHEADER__ + #include "juce_appframework/events/juce_MultiTimer.h" +#endif +#ifndef __JUCE_MESSAGEMANAGER_JUCEHEADER__ + #include "juce_appframework/events/juce_MessageManager.h" +#endif +#include "juce_appframework/events/._juce_CallbackMessage.h" +#ifndef __JUCE_CALLBACKMESSAGE_JUCEHEADER__ + #include "juce_appframework/events/juce_CallbackMessage.h" #endif #ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__ #include "juce_appframework/events/juce_ActionBroadcaster.h" @@ -263,24 +285,6 @@ #ifndef __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__ #include "juce_appframework/events/juce_InterprocessConnection.h" #endif -#ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__ - #include "juce_appframework/events/juce_InterprocessConnectionServer.h" -#endif -#ifndef __JUCE_MESSAGE_JUCEHEADER__ - #include "juce_appframework/events/juce_Message.h" -#endif -#ifndef __JUCE_MESSAGELISTENER_JUCEHEADER__ - #include "juce_appframework/events/juce_MessageListener.h" -#endif -#ifndef __JUCE_MESSAGEMANAGER_JUCEHEADER__ - #include "juce_appframework/events/juce_MessageManager.h" -#endif -#ifndef __JUCE_MULTITIMER_JUCEHEADER__ - #include "juce_appframework/events/juce_MultiTimer.h" -#endif -#ifndef __JUCE_TIMER_JUCEHEADER__ - #include "juce_appframework/events/juce_Timer.h" -#endif #ifndef __JUCE_BRUSH_JUCEHEADER__ #include "juce_appframework/gui/graphics/brushes/juce_Brush.h" #endif @@ -338,9 +342,6 @@ #ifndef __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__ #include "juce_appframework/gui/graphics/contexts/juce_RectanglePlacement.h" #endif -#ifndef __JUCE_AFFINETRANSFORM_JUCEHEADER__ - #include "juce_appframework/gui/graphics/geometry/juce_AffineTransform.h" -#endif #ifndef __JUCE_BORDERSIZE_JUCEHEADER__ #include "juce_appframework/gui/graphics/geometry/juce_BorderSize.h" #endif @@ -362,11 +363,14 @@ #ifndef __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__ #include "juce_appframework/gui/graphics/geometry/juce_PositionedRectangle.h" #endif +#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__ + #include "juce_appframework/gui/graphics/geometry/juce_RectangleList.h" +#endif #ifndef __JUCE_RECTANGLE_JUCEHEADER__ #include "juce_appframework/gui/graphics/geometry/juce_Rectangle.h" #endif -#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__ - #include "juce_appframework/gui/graphics/geometry/juce_RectangleList.h" +#ifndef __JUCE_AFFINETRANSFORM_JUCEHEADER__ + #include "juce_appframework/gui/graphics/geometry/juce_AffineTransform.h" #endif #ifndef __JUCE_IMAGE_JUCEHEADER__ #include "juce_appframework/gui/graphics/imaging/juce_Image.h" @@ -395,9 +399,6 @@ #ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__ #include "juce_appframework/gui/graphics/drawables/juce_DrawableText.h" #endif -#ifndef __JUCE_COMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/juce_Component.h" -#endif #ifndef __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__ #include "juce_appframework/gui/components/juce_ComponentDeletionWatcher.h" #endif @@ -407,14 +408,8 @@ #ifndef __JUCE_DESKTOP_JUCEHEADER__ #include "juce_appframework/gui/components/juce_Desktop.h" #endif -#ifndef __JUCE_ARROWBUTTON_JUCEHEADER__ - #include "juce_appframework/gui/components/buttons/juce_ArrowButton.h" -#endif -#ifndef __JUCE_BUTTON_JUCEHEADER__ - #include "juce_appframework/gui/components/buttons/juce_Button.h" -#endif -#ifndef __JUCE_DRAWABLEBUTTON_JUCEHEADER__ - #include "juce_appframework/gui/components/buttons/juce_DrawableButton.h" +#ifndef __JUCE_COMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/juce_Component.h" #endif #ifndef __JUCE_HYPERLINKBUTTON_JUCEHEADER__ #include "juce_appframework/gui/components/buttons/juce_HyperlinkButton.h" @@ -434,6 +429,15 @@ #ifndef __JUCE_TOOLBARBUTTON_JUCEHEADER__ #include "juce_appframework/gui/components/buttons/juce_ToolbarButton.h" #endif +#ifndef __JUCE_ARROWBUTTON_JUCEHEADER__ + #include "juce_appframework/gui/components/buttons/juce_ArrowButton.h" +#endif +#ifndef __JUCE_BUTTON_JUCEHEADER__ + #include "juce_appframework/gui/components/buttons/juce_Button.h" +#endif +#ifndef __JUCE_DRAWABLEBUTTON_JUCEHEADER__ + #include "juce_appframework/gui/components/buttons/juce_DrawableButton.h" +#endif #ifndef __JUCE_DROPSHADOWEFFECT_JUCEHEADER__ #include "juce_appframework/gui/graphics/effects/juce_DropShadowEffect.h" #endif @@ -476,12 +480,6 @@ #ifndef __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__ #include "juce_appframework/gui/components/menus/juce_PopupMenuCustomComponent.h" #endif -#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__ - #include "juce_appframework/gui/components/mouse/juce_ComponentDragger.h" -#endif -#ifndef __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__ - #include "juce_appframework/gui/components/mouse/juce_DragAndDropContainer.h" -#endif #ifndef __JUCE_DRAGANDDROPTARGET_JUCEHEADER__ #include "juce_appframework/gui/components/mouse/juce_DragAndDropTarget.h" #endif @@ -506,47 +504,59 @@ #ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__ #include "juce_appframework/gui/components/mouse/juce_TooltipClient.h" #endif +#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__ + #include "juce_appframework/gui/components/mouse/juce_ComponentDragger.h" +#endif +#ifndef __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__ + #include "juce_appframework/gui/components/mouse/juce_DragAndDropContainer.h" +#endif +#ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__ + #include "juce_appframework/gui/components/controls/juce_ToolbarItemFactory.h" +#endif +#ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__ + #include "juce_appframework/gui/components/controls/juce_ToolbarItemPalette.h" +#endif +#ifndef __JUCE_SLIDER_JUCEHEADER__ + #include "juce_appframework/gui/components/controls/juce_Slider.h" +#endif +#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/controls/juce_ToolbarItemComponent.h" +#endif +#ifndef __JUCE_TREEVIEW_JUCEHEADER__ + #include "juce_appframework/gui/components/controls/juce_TreeView.h" +#endif +#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__ + #include "juce_appframework/gui/components/controls/juce_TextEditor.h" +#endif #ifndef __JUCE_COMBOBOX_JUCEHEADER__ #include "juce_appframework/gui/components/controls/juce_ComboBox.h" #endif -#ifndef __JUCE_LABEL_JUCEHEADER__ - #include "juce_appframework/gui/components/controls/juce_Label.h" -#endif #ifndef __JUCE_LISTBOX_JUCEHEADER__ #include "juce_appframework/gui/components/controls/juce_ListBox.h" #endif #ifndef __JUCE_PROGRESSBAR_JUCEHEADER__ #include "juce_appframework/gui/components/controls/juce_ProgressBar.h" #endif -#ifndef __JUCE_SLIDER_JUCEHEADER__ - #include "juce_appframework/gui/components/controls/juce_Slider.h" -#endif #ifndef __JUCE_SLIDERLISTENER_JUCEHEADER__ #include "juce_appframework/gui/components/controls/juce_SliderListener.h" #endif -#ifndef __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/controls/juce_TableHeaderComponent.h" -#endif #ifndef __JUCE_TABLELISTBOX_JUCEHEADER__ #include "juce_appframework/gui/components/controls/juce_TableListBox.h" #endif -#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__ - #include "juce_appframework/gui/components/controls/juce_TextEditor.h" +#ifndef __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/controls/juce_TableHeaderComponent.h" #endif #ifndef __JUCE_TOOLBAR_JUCEHEADER__ #include "juce_appframework/gui/components/controls/juce_Toolbar.h" #endif -#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/controls/juce_ToolbarItemComponent.h" -#endif -#ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__ - #include "juce_appframework/gui/components/controls/juce_ToolbarItemFactory.h" +#ifndef __JUCE_LABEL_JUCEHEADER__ + #include "juce_appframework/gui/components/controls/juce_Label.h" #endif -#ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__ - #include "juce_appframework/gui/components/controls/juce_ToolbarItemPalette.h" +#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/properties/juce_SliderPropertyComponent.h" #endif -#ifndef __JUCE_TREEVIEW_JUCEHEADER__ - #include "juce_appframework/gui/components/controls/juce_TreeView.h" +#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/properties/juce_TextPropertyComponent.h" #endif #ifndef __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ #include "juce_appframework/gui/components/properties/juce_BooleanPropertyComponent.h" @@ -563,54 +573,66 @@ #ifndef __JUCE_PROPERTYPANEL_JUCEHEADER__ #include "juce_appframework/gui/components/properties/juce_PropertyPanel.h" #endif -#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/properties/juce_SliderPropertyComponent.h" -#endif -#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/properties/juce_TextPropertyComponent.h" -#endif -#ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__ - #include "juce_appframework/gui/components/layout/juce_ComponentAnimator.h" -#endif -#ifndef __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__ - #include "juce_appframework/gui/components/layout/juce_ComponentBoundsConstrainer.h" +#ifndef __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__ + #include "juce_appframework/gui/components/layout/juce_MultiDocumentPanel.h" #endif #ifndef __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__ #include "juce_appframework/gui/components/layout/juce_ComponentMovementWatcher.h" #endif -#ifndef __JUCE_GROUPCOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/layout/juce_GroupComponent.h" -#endif -#ifndef __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__ - #include "juce_appframework/gui/components/layout/juce_MultiDocumentPanel.h" -#endif #ifndef __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__ #include "juce_appframework/gui/components/layout/juce_ResizableBorderComponent.h" #endif -#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/layout/juce_ResizableCornerComponent.h" -#endif #ifndef __JUCE_SCROLLBAR_JUCEHEADER__ #include "juce_appframework/gui/components/layout/juce_ScrollBar.h" #endif +#ifndef __JUCE_TABBEDBUTTONBAR_JUCEHEADER__ + #include "juce_appframework/gui/components/layout/juce_TabbedButtonBar.h" +#endif +#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/layout/juce_ResizableCornerComponent.h" +#endif #ifndef __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__ #include "juce_appframework/gui/components/layout/juce_StretchableLayoutManager.h" #endif +#ifndef __JUCE_TABBEDCOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/layout/juce_TabbedComponent.h" +#endif #ifndef __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__ #include "juce_appframework/gui/components/layout/juce_StretchableLayoutResizerBar.h" #endif #ifndef __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__ #include "juce_appframework/gui/components/layout/juce_StretchableObjectResizer.h" #endif -#ifndef __JUCE_TABBEDBUTTONBAR_JUCEHEADER__ - #include "juce_appframework/gui/components/layout/juce_TabbedButtonBar.h" -#endif -#ifndef __JUCE_TABBEDCOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/layout/juce_TabbedComponent.h" -#endif #ifndef __JUCE_VIEWPORT_JUCEHEADER__ #include "juce_appframework/gui/components/layout/juce_Viewport.h" #endif +#ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__ + #include "juce_appframework/gui/components/layout/juce_ComponentAnimator.h" +#endif +#ifndef __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__ + #include "juce_appframework/gui/components/layout/juce_ComponentBoundsConstrainer.h" +#endif +#ifndef __JUCE_GROUPCOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/layout/juce_GroupComponent.h" +#endif +#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/filebrowser/juce_FilenameComponent.h" +#endif +#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/filebrowser/juce_FilePreviewComponent.h" +#endif +#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/filebrowser/juce_FileSearchPathListComponent.h" +#endif +#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.h" +#endif +#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ + #include "juce_appframework/gui/components/filebrowser/juce_WildcardFileFilter.h" +#endif +#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/filebrowser/juce_ImagePreviewComponent.h" +#endif #ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ #include "juce_appframework/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.h" #endif @@ -635,24 +657,6 @@ #ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__ #include "juce_appframework/gui/components/filebrowser/juce_FileListComponent.h" #endif -#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/filebrowser/juce_FilenameComponent.h" -#endif -#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/filebrowser/juce_FilePreviewComponent.h" -#endif -#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/filebrowser/juce_FileSearchPathListComponent.h" -#endif -#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.h" -#endif -#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/filebrowser/juce_ImagePreviewComponent.h" -#endif -#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ - #include "juce_appframework/gui/components/filebrowser/juce_WildcardFileFilter.h" -#endif #ifndef __JUCE_ALERTWINDOW_JUCEHEADER__ #include "juce_appframework/gui/components/windows/juce_AlertWindow.h" #endif @@ -671,15 +675,21 @@ #ifndef __JUCE_SPLASHSCREEN_JUCEHEADER__ #include "juce_appframework/gui/components/windows/juce_SplashScreen.h" #endif -#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__ - #include "juce_appframework/gui/components/windows/juce_ThreadWithProgressWindow.h" -#endif #ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__ #include "juce_appframework/gui/components/windows/juce_TooltipWindow.h" #endif +#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__ + #include "juce_appframework/gui/components/windows/juce_ThreadWithProgressWindow.h" +#endif #ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__ #include "juce_appframework/gui/components/windows/juce_TopLevelWindow.h" #endif +#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/special/juce_SystemTrayIconComponent.h" +#endif +#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ + #include "juce_appframework/gui/components/special/juce_WebBrowserComponent.h" +#endif #ifndef __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__ #include "juce_appframework/gui/components/special/juce_ActiveXControlComponent.h" #endif @@ -716,12 +726,6 @@ #ifndef __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__ #include "juce_appframework/gui/components/special/juce_QuickTimeMovieComponent.h" #endif -#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/special/juce_SystemTrayIconComponent.h" -#endif -#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ - #include "juce_appframework/gui/components/special/juce_WebBrowserComponent.h" -#endif #ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__ #include "juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.h" #endif @@ -744,4 +748,4 @@ #include "juce_appframework/documents/juce_UndoManager.h" #endif -#endif // __JUCE_APP_INCLUDES_JUCEHEADER__ +#endif diff --git a/src/juce_appframework/application/juce_Application.cpp b/src/juce_appframework/application/juce_Application.cpp index 2f7522e438..3171523f35 100644 --- a/src/juce_appframework/application/juce_Application.cpp +++ b/src/juce_appframework/application/juce_Application.cpp @@ -194,12 +194,8 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app) { juce_setCurrentThreadName ("Juce Message Thread"); - { - const MessageManagerLock mml; - - // let the app do its setting-up.. - app->initialise (app->commandLineParameters); - } + // let the app do its setting-up.. + app->initialise (app->commandLineParameters); // register for broadcast new app messages MessageManager::getInstance()->registerBroadcastListener (app); @@ -246,7 +242,6 @@ int JUCEApplication::shutdownAppAndClearUp() JUCE_TRY { // give the app a chance to clean up.. - const MessageManagerLock mml; app->shutdown(); } #if JUCE_CATCH_UNHANDLED_EXCEPTIONS @@ -346,7 +341,6 @@ void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI() const ScopedAutoReleasePool pool; #endif { - const MessageManagerLock mml; DeletedAtShutdown::deleteAll(); LookAndFeel::clearDefaultLookAndFeel(); diff --git a/src/juce_appframework/audio/audio_file_formats/flac/libFLAC/stream_decoder.c b/src/juce_appframework/audio/audio_file_formats/flac/libFLAC/stream_decoder.c index 8975c47128..db3264624d 100644 --- a/src/juce_appframework/audio/audio_file_formats/flac/libFLAC/stream_decoder.c +++ b/src/juce_appframework/audio/audio_file_formats/flac/libFLAC/stream_decoder.c @@ -2945,23 +2945,22 @@ FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); } } - else { - return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; - } - } - else { - /* - * If we never got STREAMINFO, turn off MD5 checking to save - * cycles since we don't have a sum to compare to anyway - */ - if(!decoder->private_->has_stream_info) - decoder->private_->do_md5_checking = false; - if(decoder->private_->do_md5_checking) { - if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8)) - return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; - } - return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); + + return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } + + /* + * If we never got STREAMINFO, turn off MD5 checking to save + * cycles since we don't have a sum to compare to anyway + */ + if(!decoder->private_->has_stream_info) + decoder->private_->do_md5_checking = false; + if(decoder->private_->do_md5_checking) { + if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8)) + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + } + + return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); } void send_error_to_client_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status) diff --git a/src/juce_appframework/audio/audio_sources/juce_ResamplingAudioSource.cpp b/src/juce_appframework/audio/audio_sources/juce_ResamplingAudioSource.cpp index c95b4cedb1..47441bcb79 100644 --- a/src/juce_appframework/audio/audio_sources/juce_ResamplingAudioSource.cpp +++ b/src/juce_appframework/audio/audio_sources/juce_ResamplingAudioSource.cpp @@ -179,6 +179,27 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf for (int i = jmin (2, info.buffer->getNumChannels()); --i >= 0;) applyFilter (info.buffer->getSampleData (i, info.startSample), info.numSamples, filterStates[i]); } + else if (ratio <= 1.0001) + { + // if the filter's not currently being applied, keep it stoked with the last couple of samples to avoid discontinuities + for (int i = jmin (2, info.buffer->getNumChannels()); --i >= 0;) + { + const float* const endOfBuffer = info.buffer->getSampleData (i, info.startSample + info.numSamples - 1); + FilterState& fs = filterStates[i]; + + if (info.numSamples > 1) + { + fs.y2 = fs.x2 = *(endOfBuffer - 1); + } + else + { + fs.y2 = fs.y1; + fs.x2 = fs.x1; + } + + fs.y1 = fs.x1 = *endOfBuffer; + } + } jassert (sampsInBuffer >= 0); } diff --git a/src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp b/src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp index 93ee49d7f9..12b08b4708 100644 --- a/src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp +++ b/src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp @@ -2339,8 +2339,6 @@ VstIntPtr VSTPluginInstance::handleCallback (VstInt32 opcode, VstInt32 index, Vs if (getActiveEditor() != 0) dispatch (effEditIdle, 0, 0, 0, 0); #endif - const MessageManagerLock mml; - juce_callAnyTimersSynchronously(); handleUpdateNowIfNeeded(); diff --git a/src/juce_appframework/events/juce_CallbackMessage.h b/src/juce_appframework/events/juce_CallbackMessage.h new file mode 100644 index 0000000000..377563aa9a --- /dev/null +++ b/src/juce_appframework/events/juce_CallbackMessage.h @@ -0,0 +1,88 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef __JUCE_CALLBACKMESSAGE_JUCEHEADER__ +#define __JUCE_CALLBACKMESSAGE_JUCEHEADER__ + +#include "juce_Message.h" + +//============================================================================== +/** + A message that calls a custom function when it gets delivered. + + You can use this class to fire off actions that you want to be performed later + on the message thread. + + Unlike other Message objects, these don't get sent to a MessageListener, you + just call the post() method to send them, and when they arrive, your + messageCallback() method will automatically be invoked. + + @see MessageListener, MessageManager, ActionListener, ChangeListener +*/ +class JUCE_API CallbackMessage : public Message +{ +public: + //============================================================================== + CallbackMessage() throw(); + + /** Destructor. */ + ~CallbackMessage() throw(); + + //============================================================================== + /** Called when the message is delivered. + + You should implement this method and make it do whatever action you want + to perform. + + Note that like all other messages, this object will be deleted immediately + after this method has been invoked. + */ + virtual void messageCallback() = 0; + + /** Instead of sending this message to a MessageListener, just call this method + to post it to the event queue. + + After you've called this, this object will belong to the MessageManager, + which will delete it later. So make sure you don't delete the object yourself, + call post() more than once, or call post() on a stack-based obect! + */ + void post(); + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + CallbackMessage (const CallbackMessage&); + const CallbackMessage& operator= (const CallbackMessage&); +}; + + +#endif // __JUCE_CALLBACKMESSAGE_JUCEHEADER__ diff --git a/src/juce_appframework/events/juce_MessageManager.cpp b/src/juce_appframework/events/juce_MessageManager.cpp index 3e88b28e49..0b69c6574b 100644 --- a/src/juce_appframework/events/juce_MessageManager.cpp +++ b/src/juce_appframework/events/juce_MessageManager.cpp @@ -38,6 +38,7 @@ BEGIN_JUCE_NAMESPACE #include "../application/juce_Application.h" #include "../gui/components/juce_Component.h" #include "../../juce_core/threads/juce_Thread.h" +#include "../../juce_core/threads/juce_ScopedLock.h" #include "../../juce_core/basics/juce_Time.h" @@ -46,7 +47,6 @@ BEGIN_JUCE_NAMESPACE bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages); bool juce_postMessageToSystemQueue (void* message); - //============================================================================== MessageManager* MessageManager::instance = 0; @@ -55,9 +55,9 @@ static const int quitMessageId = 0xfffff321; MessageManager::MessageManager() throw() : broadcastListeners (0), quitMessagePosted (false), - quitMessageReceived (false) + quitMessageReceived (false), + threadWithLock (0) { - currentLockingThreadId = 0; messageThreadId = Thread::getCurrentThreadId(); } @@ -88,27 +88,48 @@ void MessageManager::postMessageToQueue (Message* const message) delete message; } +//============================================================================== +CallbackMessage::CallbackMessage() throw() {} +CallbackMessage::~CallbackMessage() throw() {} + +void CallbackMessage::post() +{ + if (MessageManager::instance != 0) + MessageManager::instance->postCallbackMessage (this); +} + +void MessageManager::postCallbackMessage (Message* const message) +{ + message->messageRecipient = 0; + postMessageToQueue (message); +} + //============================================================================== // not for public use.. void MessageManager::deliverMessage (void* message) { - const MessageManagerLock lock; - Message* const m = (Message*) message; MessageListener* const recipient = m->messageRecipient; - if (messageListeners.contains (recipient)) + JUCE_TRY { - JUCE_TRY + if (messageListeners.contains (recipient)) { recipient->handleMessage (*m); } - JUCE_CATCH_EXCEPTION - } - else if (recipient == 0 && m->intParameter1 == quitMessageId) - { - quitMessageReceived = true; + else if (recipient == 0) + { + if (m->intParameter1 == quitMessageId) + { + quitMessageReceived = true; + } + else if (dynamic_cast (m) != 0) + { + (dynamic_cast (m))->messageCallback(); + } + } } + JUCE_CATCH_EXCEPTION delete m; } @@ -186,54 +207,135 @@ void MessageManager::setCurrentMessageThread (const Thread::ThreadID threadId) t bool MessageManager::currentThreadHasLockedMessageManager() const throw() { - return Thread::getCurrentThreadId() == currentLockingThreadId; + const Thread::ThreadID thisThread = Thread::getCurrentThreadId(); + return thisThread == messageThreadId || thisThread == threadWithLock; } //============================================================================== -MessageManagerLock::MessageManagerLock() throw() - : lastLockingThreadId (0), - locked (false) +//============================================================================== +/* The only safe way to lock the message thread while another thread does + some work is by posting a special message, whose purpose is to tie up the event + loop until the other thread has finished its business. + + Any other approach can get horribly deadlocked if the OS uses its own hidden locks which + get locked before making an event callback, because if the same OS lock gets indirectly + accessed from another thread inside a MM lock, you're screwed. (this is exactly what happens + in Cocoa). +*/ +class SharedLockingEvents : public ReferenceCountedObject { - if (MessageManager::instance != 0) +public: + SharedLockingEvents() throw() {} + ~SharedLockingEvents() {} + + /* This class just holds a couple of events to communicate between the MMLockMessage + and the MessageManagerLock. Because both of these objects may be deleted at any time, + this shared data must be kept in a separate, ref-counted container. */ + WaitableEvent lockedEvent, releaseEvent; +}; + +class MMLockMessage : public CallbackMessage +{ +public: + MMLockMessage (SharedLockingEvents* const events_) throw() + : events (events_) + {} + + ~MMLockMessage() throw() {} + + ReferenceCountedObjectPtr events; + + void messageCallback() { - MessageManager::instance->messageDispatchLock.enter(); - lastLockingThreadId = MessageManager::instance->currentLockingThreadId; - MessageManager::instance->currentLockingThreadId = Thread::getCurrentThreadId(); - locked = true; + events->lockedEvent.signal(); + events->releaseEvent.wait(); } + + juce_UseDebuggingNewOperator + + MMLockMessage (const MMLockMessage&); + const MMLockMessage& operator= (const MMLockMessage&); +}; + +//============================================================================== +MessageManagerLock::MessageManagerLock (Thread* const threadToCheck) throw() + : locked (false), + needsUnlocking (false) +{ + init (threadToCheck, 0); } -MessageManagerLock::MessageManagerLock (Thread* const thread) throw() - : locked (false) +MessageManagerLock::MessageManagerLock (ThreadPoolJob* const jobToCheckForExitSignal) throw() + : locked (false), + needsUnlocking (false) { - jassert (thread != 0); // This will only work if you give it a valid thread! + init (0, jobToCheckForExitSignal); +} +void MessageManagerLock::init (Thread* const threadToCheck, ThreadPoolJob* const job) throw() +{ if (MessageManager::instance != 0) { - for (;;) + if (MessageManager::instance->currentThreadHasLockedMessageManager()) + { + locked = true; // either we're on the message thread, or this it's a re-entrant call. + } + else { - if (MessageManager::instance->messageDispatchLock.tryEnter()) + if (threadToCheck == 0 && job == 0) + { + MessageManager::instance->lockingLock.enter(); + } + else + { + while (! MessageManager::instance->lockingLock.tryEnter()) + { + if ((threadToCheck != 0 && threadToCheck->threadShouldExit()) + || (job != 0 && job->shouldExit())) + return; + + Thread::sleep (1); + } + } + + SharedLockingEvents* const events = new SharedLockingEvents(); + sharedEvents = events; + events->incReferenceCount(); + + (new MMLockMessage (events))->post(); + + while (! events->lockedEvent.wait (50)) { - locked = true; - lastLockingThreadId = MessageManager::instance->currentLockingThreadId; - MessageManager::instance->currentLockingThreadId = Thread::getCurrentThreadId(); - break; + if ((threadToCheck != 0 && threadToCheck->threadShouldExit()) + || (job != 0 && job->shouldExit())) + { + events->releaseEvent.signal(); + events->decReferenceCount(); + MessageManager::instance->lockingLock.exit(); + return; + } } - if (thread != 0 && thread->threadShouldExit()) - break; + jassert (MessageManager::instance->threadWithLock == 0); - Thread::sleep (1); + MessageManager::instance->threadWithLock = Thread::getCurrentThreadId(); + locked = true; + needsUnlocking = true; } } } + MessageManagerLock::~MessageManagerLock() throw() { - if (locked && MessageManager::instance != 0) + if (needsUnlocking && MessageManager::instance != 0) { - MessageManager::instance->currentLockingThreadId = lastLockingThreadId; - MessageManager::instance->messageDispatchLock.exit(); + jassert (MessageManager::instance->currentThreadHasLockedMessageManager()); + + ((SharedLockingEvents*) sharedEvents)->releaseEvent.signal(); + ((SharedLockingEvents*) sharedEvents)->decReferenceCount(); + MessageManager::instance->threadWithLock = 0; + MessageManager::instance->lockingLock.exit(); } } diff --git a/src/juce_appframework/events/juce_MessageManager.h b/src/juce_appframework/events/juce_MessageManager.h index adcbd90f1b..2d53c32739 100644 --- a/src/juce_appframework/events/juce_MessageManager.h +++ b/src/juce_appframework/events/juce_MessageManager.h @@ -36,7 +36,9 @@ #include "../../juce_core/containers/juce_SortedSet.h" #include "../../juce_core/containers/juce_VoidArray.h" #include "../../juce_core/threads/juce_Thread.h" +#include "../../juce_core/threads/juce_ThreadPool.h" #include "juce_ActionListenerList.h" +#include "juce_CallbackMessage.h" class Component; class MessageManagerLock; @@ -175,6 +177,7 @@ private: friend class MessageListener; friend class ChangeBroadcaster; friend class ActionBroadcaster; + friend class CallbackMessage; static MessageManager* instance; SortedSet messageListeners; @@ -188,13 +191,14 @@ private: static void* exitModalLoopCallback (void*); void postMessageToQueue (Message* const message); + void postCallbackMessage (Message* const message); static void doPlatformSpecificInitialisation(); static void doPlatformSpecificShutdown(); friend class MessageManagerLock; - CriticalSection messageDispatchLock; - Thread::ThreadID currentLockingThreadId; + Thread::ThreadID volatile threadWithLock; + CriticalSection lockingLock; MessageManager (const MessageManager&); const MessageManager& operator= (const MessageManager&); @@ -239,36 +243,23 @@ public: //============================================================================== /** Tries to acquire a lock on the message manager. - If this constructor - When this constructor returns, the message manager will have finished processing the - last message and will not send another message until this MessageManagerLock is - deleted. + The constructor attempts to gain a lock on the message loop, and the lock will be + kept for the lifetime of this object. - If the current thread already has the lock, nothing will be done, so it's perfectly - safe to create these locks recursively. - */ - MessageManagerLock() throw(); - - /** Releases the current thread's lock on the message manager. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! - */ - ~MessageManagerLock() throw(); - - //============================================================================== - /** Tries to acquire a lock on the message manager. - - This does the same thing as the normal constructor, but while it's waiting to get - the lock, it checks the specified thread to see if it has been given the + Optionally, you can pass a thread object here, and while waiting to obtain the lock, + this method will keep checking whether the thread has been given the Thread::signalThreadShouldExit() signal. If this happens, then it will return - without gaining the lock. + without gaining the lock. If you pass a thread, you must check whether the lock was + successful by calling lockWasGained(). If this is false, your thread is being told to + die, so you should take evasive action. - To find out whether the lock was successful, call lockWasGained(). If this is - false, your thread is being told to die, so you'd better get out of there. + If you pass zero for the thread object, it will wait indefinitely for the lock - be + careful when doing this, because it's very easy to deadlock if your message thread + attempts to call stopThread() on a thread just as that thread attempts to get the + message lock. - If the current thread already has the lock, nothing will be done, so it's perfectly - safe to create these locks recursively. + If the calling thread already has the lock, nothing will be done, so it's safe and + quick to use these locks recursively. E.g. @code @@ -291,9 +282,26 @@ public: @endcode */ - MessageManagerLock (Thread* const threadToCheckForExitSignal) throw(); + MessageManagerLock (Thread* const threadToCheckForExitSignal = 0) throw(); + //============================================================================== + /** This has the same behaviour as the other constructor, but takes a ThreadPoolJob + instead of a thread. + See the MessageManagerLock (Thread*) constructor for details on how this works. + */ + MessageManagerLock (ThreadPoolJob* const jobToCheckForExitSignal) throw(); + + + //============================================================================== + /** Releases the current thread's lock on the message manager. + + Make sure this object is created and deleted by the same thread, + otherwise there are no guarantees what will happen! + */ + ~MessageManagerLock() throw(); + + //============================================================================== /** Returns true if the lock was successfully acquired. (See the constructor that takes a Thread for more info). @@ -302,8 +310,10 @@ public: private: - Thread::ThreadID lastLockingThreadId; - bool locked; + bool locked, needsUnlocking; + void* sharedEvents; + + void init (Thread* const thread, ThreadPoolJob* const job) throw(); }; diff --git a/src/juce_appframework/gui/components/controls/juce_TextEditor.h b/src/juce_appframework/gui/components/controls/juce_TextEditor.h index fdadd47133..3b6e5d4129 100644 --- a/src/juce_appframework/gui/components/controls/juce_TextEditor.h +++ b/src/juce_appframework/gui/components/controls/juce_TextEditor.h @@ -467,6 +467,13 @@ l */ */ int getTextIndexAt (const int x, const int y) throw(); + /** Counts the number of characters in the text. + + This is quicker than getting the text as a string if you just need to know + the length. + */ + int getTotalNumChars() throw(); + /** Returns the total width of the text, as it is currently laid-out. This may be larger than the size of the TextEditor, and can change when @@ -590,13 +597,6 @@ protected: /** Used internally to dispatch a text-change message. */ void textChanged() throw(); - /** Counts the number of characters in the text. - - This is quicker than getting the text as a string if you just need to know - the length. - */ - int getTotalNumChars() throw(); - /** Begins a new transaction in the UndoManager. */ void newTransaction() throw(); diff --git a/src/juce_appframework/gui/components/controls/juce_TreeView.cpp b/src/juce_appframework/gui/components/controls/juce_TreeView.cpp index 9ea9c58ca9..53b5bac502 100644 --- a/src/juce_appframework/gui/components/controls/juce_TreeView.cpp +++ b/src/juce_appframework/gui/components/controls/juce_TreeView.cpp @@ -1006,13 +1006,19 @@ void TreeViewItem::treeHasChanged() const throw() void TreeViewItem::repaintItem() const { - if (ownerView != 0) + if (ownerView != 0 && areAllParentsOpen()) { - const Rectangle r (getItemPosition (false)); + const Rectangle r (getItemPosition (true)); ownerView->viewport->repaint (0, r.getY(), r.getRight(), r.getHeight()); } } +bool TreeViewItem::areAllParentsOpen() const throw() +{ + return parentItem == 0 + || (parentItem->isOpen() && parentItem->areAllParentsOpen()); +} + void TreeViewItem::updatePositions (int newY) { y = newY; diff --git a/src/juce_appframework/gui/components/controls/juce_TreeView.h b/src/juce_appframework/gui/components/controls/juce_TreeView.h index ee6aee2e9c..d007f607bf 100644 --- a/src/juce_appframework/gui/components/controls/juce_TreeView.h +++ b/src/juce_appframework/gui/components/controls/juce_TreeView.h @@ -166,6 +166,12 @@ public: */ int getRowNumberInTree() const throw(); + /** Returns true if all the item's parent nodes are open. + + This is useful to check whether the item might actually be visible or not. + */ + bool areAllParentsOpen() const throw(); + /** Changes whether lines are drawn to connect any sub-items to this item. By default, line-drawing is turned on. diff --git a/src/juce_appframework/gui/components/juce_Component.h b/src/juce_appframework/gui/components/juce_Component.h index 8a18c3fa6a..417611e27b 100644 --- a/src/juce_appframework/gui/components/juce_Component.h +++ b/src/juce_appframework/gui/components/juce_Component.h @@ -1774,7 +1774,7 @@ public: of the components in this list is the reverse of the order in which they became modal - so the component at index 0 is always the active component, and the others are progressively earlier ones that are themselves now blocked by later ones. - + @returns the modal component, or null if no components are modal (or if the index is out of range) @see getNumCurrentlyModalComponents, runModalLoop, isCurrentlyModal diff --git a/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp b/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp index 8794c34ad0..dbcddc98fc 100644 --- a/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp +++ b/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp @@ -476,7 +476,7 @@ AlertWindow* LookAndFeel::createAlertWindow (const String& title, Component* associatedComponent) { AlertWindow* aw = new AlertWindow (title, message, iconType); - + if (numButtons == 1) { aw->addButton (button1, 0, @@ -489,7 +489,7 @@ AlertWindow* LookAndFeel::createAlertWindow (const String& title, KeyPress button2ShortCut (CharacterFunctions::toLowerCase (button2[0]), 0, 0); if (button1ShortCut == button2ShortCut) button2ShortCut = KeyPress(); - + if (numButtons == 2) { aw->addButton (button1, 1, KeyPress (KeyPress::returnKey, 0, 0), button1ShortCut); @@ -498,7 +498,7 @@ AlertWindow* LookAndFeel::createAlertWindow (const String& title, else { jassert (numButtons == 3); - + aw->addButton (button1, 1, button1ShortCut); aw->addButton (button2, 2, button2ShortCut); aw->addButton (button3, 0, KeyPress (KeyPress::escapeKey, 0, 0)); @@ -538,8 +538,8 @@ void LookAndFeel::drawAlertBox (Graphics& g, colour = 0x55ff5555; character = '!'; - icon.addTriangle (iconRect.getX() + iconRect.getWidth() * 0.5f, (float) iconRect.getY(), - (float) iconRect.getRight(), (float) iconRect.getBottom(), + icon.addTriangle (iconRect.getX() + iconRect.getWidth() * 0.5f, (float) iconRect.getY(), + (float) iconRect.getRight(), (float) iconRect.getBottom(), (float) iconRect.getX(), (float) iconRect.getBottom()); icon = icon.createPathWithRoundedCorners (5.0f); diff --git a/src/juce_appframework/gui/components/mouse/juce_ComponentDragger.cpp b/src/juce_appframework/gui/components/mouse/juce_ComponentDragger.cpp index 12ec76009d..7f5475b156 100644 --- a/src/juce_appframework/gui/components/mouse/juce_ComponentDragger.cpp +++ b/src/juce_appframework/gui/components/mouse/juce_ComponentDragger.cpp @@ -71,8 +71,8 @@ void ComponentDragger::dragComponent (Component* const componentToDrag, const Mo if (componentToDrag->isValidComponent()) { - int x = originalX + e.getDistanceFromDragStartX(); - int y = originalY + e.getDistanceFromDragStartY(); + int x = originalX; + int y = originalY; int w = componentToDrag->getWidth(); int h = componentToDrag->getHeight(); @@ -80,6 +80,9 @@ void ComponentDragger::dragComponent (Component* const componentToDrag, const Mo if (parentComp != 0) parentComp->globalPositionToRelative (x, y); + x += e.getDistanceFromDragStartX(); + y += e.getDistanceFromDragStartY(); + if (constrainer != 0) constrainer->setBoundsForComponent (componentToDrag, x, y, w, h, false, false, false, false); diff --git a/src/juce_appframework/gui/components/windows/juce_AlertWindow.h b/src/juce_appframework/gui/components/windows/juce_AlertWindow.h index 98c4182ee0..d193434376 100644 --- a/src/juce_appframework/gui/components/windows/juce_AlertWindow.h +++ b/src/juce_appframework/gui/components/windows/juce_AlertWindow.h @@ -294,7 +294,7 @@ public: @param associatedComponent if this is non-zero, it specifies the component that the alert window should be associated with. Depending on the look and feel, this might be used for positioning of the alert window. - + @returns one of the following values: - 0 if the third button was pressed (normally used for 'cancel') - 1 if the first button was pressed (normally used for 'yes') diff --git a/src/juce_appframework/gui/components/windows/juce_ThreadWithProgressWindow.cpp b/src/juce_appframework/gui/components/windows/juce_ThreadWithProgressWindow.cpp index 68f540a144..0ca1ec1664 100644 --- a/src/juce_appframework/gui/components/windows/juce_ThreadWithProgressWindow.cpp +++ b/src/juce_appframework/gui/components/windows/juce_ThreadWithProgressWindow.cpp @@ -50,7 +50,7 @@ ThreadWithProgressWindow::ThreadWithProgressWindow (const String& title, timeOutMsWhenCancelling (timeOutMsWhenCancelling_) { alertWindow = LookAndFeel::getDefaultLookAndFeel() - .createAlertWindow (title, String::empty, cancelButtonText, String::empty, String::empty, + .createAlertWindow (title, String::empty, cancelButtonText, String::empty, String::empty, AlertWindow::NoIcon, 1, 0); if (hasProgressBar) diff --git a/src/juce_appframework/gui/graphics/geometry/juce_Rectangle.h b/src/juce_appframework/gui/graphics/geometry/juce_Rectangle.h index d776e955fa..c172fd92d9 100644 --- a/src/juce_appframework/gui/graphics/geometry/juce_Rectangle.h +++ b/src/juce_appframework/gui/graphics/geometry/juce_Rectangle.h @@ -123,7 +123,7 @@ public: @see getBottom */ void setBottom (const int newBottom) throw(); - + /** Moves the rectangle's position by adding amount to its x and y co-ordinates. */ void translate (const int deltaX, const int deltaY) throw(); diff --git a/src/juce_core_includes.h b/src/juce_core_includes.h index 14291fc3d2..00e0a96d7c 100644 --- a/src/juce_core_includes.h +++ b/src/juce_core_includes.h @@ -32,21 +32,9 @@ #ifndef __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__ #define __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__ -#ifndef __JUCE_ATOMIC_JUCEHEADER__ - #include "juce_core/basics/juce_Atomic.h" -#endif -#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__ - #include "juce_core/basics/juce_DataConversions.h" -#endif -#ifndef __JUCE_FILELOGGER_JUCEHEADER__ - #include "juce_core/basics/juce_FileLogger.h" -#endif #ifndef __JUCE_INITIALISATION_JUCEHEADER__ #include "juce_core/basics/juce_Initialisation.h" #endif -#ifndef __JUCE_LOGGER_JUCEHEADER__ - #include "juce_core/basics/juce_Logger.h" -#endif #ifndef __JUCE_MATHSFUNCTIONS_JUCEHEADER__ #include "juce_core/basics/juce_MathsFunctions.h" #endif @@ -74,6 +62,30 @@ #ifndef __JUCE_TIME_JUCEHEADER__ #include "juce_core/basics/juce_Time.h" #endif +#ifndef __JUCE_ATOMIC_JUCEHEADER__ + #include "juce_core/basics/juce_Atomic.h" +#endif +#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__ + #include "juce_core/basics/juce_DataConversions.h" +#endif +#ifndef __JUCE_FILELOGGER_JUCEHEADER__ + #include "juce_core/basics/juce_FileLogger.h" +#endif +#ifndef __JUCE_LOGGER_JUCEHEADER__ + #include "juce_core/basics/juce_Logger.h" +#endif +#ifndef __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__ + #include "juce_core/containers/juce_ReferenceCountedArray.h" +#endif +#ifndef __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__ + #include "juce_core/containers/juce_ReferenceCountedObject.h" +#endif +#ifndef __JUCE_SPARSESET_JUCEHEADER__ + #include "juce_core/containers/juce_SparseSet.h" +#endif +#ifndef __JUCE_VOIDARRAY_JUCEHEADER__ + #include "juce_core/containers/juce_VoidArray.h" +#endif #ifndef __JUCE_ARRAY_JUCEHEADER__ #include "juce_core/containers/juce_Array.h" #endif @@ -95,21 +107,9 @@ #ifndef __JUCE_PROPERTYSET_JUCEHEADER__ #include "juce_core/containers/juce_PropertySet.h" #endif -#ifndef __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__ - #include "juce_core/containers/juce_ReferenceCountedArray.h" -#endif -#ifndef __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__ - #include "juce_core/containers/juce_ReferenceCountedObject.h" -#endif #ifndef __JUCE_SORTEDSET_JUCEHEADER__ #include "juce_core/containers/juce_SortedSet.h" #endif -#ifndef __JUCE_SPARSESET_JUCEHEADER__ - #include "juce_core/containers/juce_SparseSet.h" -#endif -#ifndef __JUCE_VOIDARRAY_JUCEHEADER__ - #include "juce_core/containers/juce_VoidArray.h" -#endif #ifndef __JUCE_INPUTSTREAM_JUCEHEADER__ #include "juce_core/io/juce_InputStream.h" #endif @@ -152,6 +152,12 @@ #ifndef __JUCE_URL_JUCEHEADER__ #include "juce_core/io/network/juce_URL.h" #endif +#ifndef __JUCE_MEMORYOUTPUTSTREAM_JUCEHEADER__ + #include "juce_core/io/streams/juce_MemoryOutputStream.h" +#endif +#ifndef __JUCE_SUBREGIONSTREAM_JUCEHEADER__ + #include "juce_core/io/streams/juce_SubregionStream.h" +#endif #ifndef __JUCE_BUFFEREDINPUTSTREAM_JUCEHEADER__ #include "juce_core/io/streams/juce_BufferedInputStream.h" #endif @@ -170,12 +176,6 @@ #ifndef __JUCE_MEMORYINPUTSTREAM_JUCEHEADER__ #include "juce_core/io/streams/juce_MemoryInputStream.h" #endif -#ifndef __JUCE_MEMORYOUTPUTSTREAM_JUCEHEADER__ - #include "juce_core/io/streams/juce_MemoryOutputStream.h" -#endif -#ifndef __JUCE_SUBREGIONSTREAM_JUCEHEADER__ - #include "juce_core/io/streams/juce_SubregionStream.h" -#endif #ifndef __JUCE_PERFORMANCECOUNTER_JUCEHEADER__ #include "juce_core/misc/juce_PerformanceCounter.h" #endif @@ -209,6 +209,18 @@ #ifndef __JUCE_XMLELEMENT_JUCEHEADER__ #include "juce_core/text/juce_XmlElement.h" #endif +#ifndef __JUCE_THREAD_JUCEHEADER__ + #include "juce_core/threads/juce_Thread.h" +#endif +#ifndef __JUCE_THREADPOOL_JUCEHEADER__ + #include "juce_core/threads/juce_ThreadPool.h" +#endif +#ifndef __JUCE_TIMESLICETHREAD_JUCEHEADER__ + #include "juce_core/threads/juce_TimeSliceThread.h" +#endif +#ifndef __JUCE_WAITABLEEVENT_JUCEHEADER__ + #include "juce_core/threads/juce_WaitableEvent.h" +#endif #ifndef __JUCE_CRITICALSECTION_JUCEHEADER__ #include "juce_core/threads/juce_CriticalSection.h" #endif @@ -233,17 +245,5 @@ #ifndef __JUCE_SCOPEDWRITELOCK_JUCEHEADER__ #include "juce_core/threads/juce_ScopedWriteLock.h" #endif -#ifndef __JUCE_THREAD_JUCEHEADER__ - #include "juce_core/threads/juce_Thread.h" -#endif -#ifndef __JUCE_THREADPOOL_JUCEHEADER__ - #include "juce_core/threads/juce_ThreadPool.h" -#endif -#ifndef __JUCE_TIMESLICETHREAD_JUCEHEADER__ - #include "juce_core/threads/juce_TimeSliceThread.h" -#endif -#ifndef __JUCE_WAITABLEEVENT_JUCEHEADER__ - #include "juce_core/threads/juce_WaitableEvent.h" -#endif #endif