From 540474d0ce72b2d696e3ab15dd306d0fb20626bb Mon Sep 17 00:00:00 2001 From: jules Date: Sat, 7 Mar 2009 12:02:32 +0000 Subject: [PATCH] Rewrote MessageManagerLock (again), hopefully now making it bulletproof. Also gave it an extra constructor and changed the threads section of the juce demo to use messagemanagerlocks to animate its components. Stopped using NSLog on the mac because it's unsafe for non-literal strings. Added a bodge to fake italic fonts on the mac if a real italic is unavailable. Added a new class: CallbackMessage, for triggering a custom callback on the event thread. Updated the RTAS plugin build to use the 8.0 version of the SDK. Fixed a problem with ComponentDraggers when working inside a magnifier component. --- .../juce_linux_Windowing.cpp | 2 - build/macosx/Juce.xcodeproj/project.pbxproj | 4 + .../juce_mac_AppleRemote.mm | 1 - .../juce_mac_AudioCDBurner.mm | 2 - .../juce_mac_Debugging.mm | 6 +- .../platform_specific_code/juce_mac_Fonts.mm | 11 +- .../juce_mac_MainMenu.mm | 5 - .../juce_mac_MessageManager.mm | 12 +- .../juce_mac_NSViewComponentPeer.mm | 25 - .../juce_mac_Network.mm | 2 +- .../juce_mac_WebBrowserComponent.mm | 2 - .../juce_win32_Messaging.cpp | 2 - .../juce_win32_Windowing.cpp | 2 - build/win32/vc8/JUCE.vcproj | 10 +- .../How to use this framework.txt | 50 +- .../wrapper/AU/juce_AU_Wrapper.mm | 1 - .../wrapper/RTAS/juce_RTAS_Wrapper.cpp | 54 +- .../wrapper/VST/juce_VST_Wrapper.cpp | 23 - extras/juce demo/src/BinaryData.cpp | 1 - extras/juce demo/src/demos/ThreadingDemo.cpp | 57 +- extras/the jucer/src/BinaryData.cpp | 1 - juce_amalgamated.cpp | 320 +- juce_amalgamated.h | 3121 +++++++++-------- src/juce_app_includes.h | 274 +- .../application/juce_Application.cpp | 10 +- .../flac/libFLAC/stream_decoder.c | 31 +- .../juce_ResamplingAudioSource.cpp | 21 + .../plugins/formats/juce_VSTPluginFormat.cpp | 2 - .../events/juce_CallbackMessage.h | 88 + .../events/juce_MessageManager.cpp | 174 +- .../events/juce_MessageManager.h | 72 +- .../gui/components/controls/juce_TextEditor.h | 14 +- .../gui/components/controls/juce_TreeView.cpp | 10 +- .../gui/components/controls/juce_TreeView.h | 6 + .../gui/components/juce_Component.h | 2 +- .../lookandfeel/juce_LookAndFeel.cpp | 10 +- .../mouse/juce_ComponentDragger.cpp | 7 +- .../gui/components/windows/juce_AlertWindow.h | 2 +- .../windows/juce_ThreadWithProgressWindow.cpp | 2 +- .../gui/graphics/geometry/juce_Rectangle.h | 2 +- src/juce_core_includes.h | 84 +- 41 files changed, 2430 insertions(+), 2095 deletions(-) create mode 100644 src/juce_appframework/events/juce_CallbackMessage.h 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; + + Thread::sleep (1); + } } - if (thread != 0 && thread->threadShouldExit()) - break; + SharedLockingEvents* const events = new SharedLockingEvents(); + sharedEvents = events; + events->incReferenceCount(); - Thread::sleep (1); + (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__ +#ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_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__ - -#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. + 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 @@ -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__ +#ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__ -/********* Start of inlined file: juce_MultiTimer.h *********/ -#ifndef __JUCE_MULTITIMER_JUCEHEADER__ -#define __JUCE_MULTITIMER_JUCEHEADER__ +/********* Start of inlined file: juce_ActionBroadcaster.h *********/ +#ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__ +#define __JUCE_ACTIONBROADCASTER_JUCEHEADER__ -/** - A type of timer class that can run multiple timers with different frequencies, - all of which share a single callback. +/** Manages a list of ActionListeners, and can send them messages. - 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 quickly add methods to your class that can add/remove action + listeners and broadcast to them, you can derive from this. - 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 + @see ActionListenerList, ActionListener */ -class JUCE_API MultiTimer +class JUCE_API ActionBroadcaster { -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: + /** Creates an ActionBroadcaster. */ + ActionBroadcaster() throw(); + /** Destructor. */ - virtual ~MultiTimer(); + virtual ~ActionBroadcaster(); - /** The user-defined callback routine that actually gets called by each of the - timers that are running. + /** Adds a listener to the list. - It's perfectly ok to call startTimer() or stopTimer() from within this - callback to change the subsequent intervals. + (Trying to add a listener that's already on the list will have no effect). */ - virtual void timerCallback (const int timerId) = 0; + void addActionListener (ActionListener* const listener); - /** Starts a timer and sets the length of interval required. + /** Removes a listener from the list. - 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) + If the listener isn't on the list, this won't have any effect. */ - void startTimer (const int timerId, const int intervalInMilliseconds) throw(); + void removeActionListener (ActionListener* const listener); - /** Stops a timer. + /** Removes all listeners from the list. */ + void removeAllActionListeners(); - 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. + /** Broadcasts a message to all the registered listeners. - If this is called from a different thread, any callbacks that may - be currently executing may be allowed to finish before the method - returns. + @see ActionListenerList::sendActionMessage */ - 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(); + void sendActionMessage (const String& message) const; private: - CriticalSection timerListLock; - VoidArray timers; - const MultiTimer& operator= (const MultiTimer&); + ActionListenerList actionListenerList; + + ActionBroadcaster (const ActionBroadcaster&); + const ActionBroadcaster& operator= (const ActionBroadcaster&); }; -#endif // __JUCE_MULTITIMER_JUCEHEADER__ -/********* End of inlined file: juce_MultiTimer.h *********/ +#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__ + +#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__ @@ -48726,14 +48639,85 @@ private: #endif // __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__ /********* End of inlined file: juce_MultiDocumentPanel.h *********/ +#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_RESIZABLEBORDERCOMPONENT_JUCEHEADER__ #endif -#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__ +#ifndef __JUCE_SCROLLBAR_JUCEHEADER__ #endif -#ifndef __JUCE_SCROLLBAR_JUCEHEADER__ +#ifndef __JUCE_TABBEDBUTTONBAR_JUCEHEADER__ + +#endif +#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__ #endif #ifndef __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__ @@ -48978,6 +48962,9 @@ private: #endif // __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__ /********* End of inlined file: juce_StretchableLayoutManager.h *********/ +#endif +#ifndef __JUCE_TABBEDCOMPONENT_JUCEHEADER__ + #endif #ifndef __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__ @@ -49130,17 +49117,436 @@ private: #endif // __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__ /********* End of inlined file: juce_StretchableObjectResizer.h *********/ -#endif -#ifndef __JUCE_TABBEDBUTTONBAR_JUCEHEADER__ - -#endif -#ifndef __JUCE_TABBEDCOMPONENT_JUCEHEADER__ - #endif #ifndef __JUCE_VIEWPORT_JUCEHEADER__ #endif -#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ +#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. + */ + 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__ + +/********* Start of inlined file: juce_FilePreviewComponent.h *********/ +#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ +#define __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ + +/** + Base class for components that live inside a file chooser dialog box and + show previews of the files that get selected. + + 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 FileChooser, ImagePreviewComponent +*/ +class JUCE_API FilePreviewComponent : public Component +{ +public: + + /** Creates a FilePreviewComponent. */ + FilePreviewComponent(); + + /** Destructor. */ + ~FilePreviewComponent(); + + /** Called to indicate that the user's currently selected file has changed. + + @param newSelectedFile the newly selected file or directory, which may be + File::nonexistent if none is selected. + */ + virtual void selectedFileChanged (const File& newSelectedFile) = 0; + + juce_UseDebuggingNewOperator + +private: + FilePreviewComponent (const FilePreviewComponent&); + const FilePreviewComponent& operator= (const FilePreviewComponent&); +}; + +#endif // __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_FilePreviewComponent.h *********/ + +#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__ /********* Start of inlined file: juce_DirectoryContentsDisplayComponent.h *********/ #ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ @@ -49474,6 +49880,170 @@ protected: #endif // __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ /********* End of inlined file: juce_DirectoryContentsDisplayComponent.h *********/ +/** + 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_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_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__ @@ -49484,48 +50054,6 @@ protected: #ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ #define __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ -/********* Start of inlined file: juce_FilePreviewComponent.h *********/ -#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ -#define __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ - -/** - Base class for components that live inside a file chooser dialog box and - show previews of the files that get selected. - - 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 FileChooser, ImagePreviewComponent -*/ -class JUCE_API FilePreviewComponent : public Component -{ -public: - - /** Creates a FilePreviewComponent. */ - FilePreviewComponent(); - - /** Destructor. */ - ~FilePreviewComponent(); - - /** Called to indicate that the user's currently selected file has changed. - - @param newSelectedFile the newly selected file or directory, which may be - File::nonexistent if none is selected. - */ - virtual void selectedFileChanged (const File& newSelectedFile) = 0; - - juce_UseDebuggingNewOperator - -private: - FilePreviewComponent (const FilePreviewComponent&); - const FilePreviewComponent& operator= (const FilePreviewComponent&); -}; - -#endif // __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_FilePreviewComponent.h *********/ - /** 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,38 +504,11 @@ #ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__ #include "juce_appframework/gui/components/mouse/juce_TooltipClient.h" #endif -#ifndef __JUCE_COMBOBOX_JUCEHEADER__ - #include "juce_appframework/gui/components/controls/juce_ComboBox.h" +#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__ + #include "juce_appframework/gui/components/mouse/juce_ComponentDragger.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" -#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" +#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" @@ -545,9 +516,48 @@ #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_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_SLIDERLISTENER_JUCEHEADER__ + #include "juce_appframework/gui/components/controls/juce_SliderListener.h" +#endif +#ifndef __JUCE_TABLELISTBOX_JUCEHEADER__ + #include "juce_appframework/gui/components/controls/juce_TableListBox.h" +#endif +#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_LABEL_JUCEHEADER__ + #include "juce_appframework/gui/components/controls/juce_Label.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_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ #include "juce_appframework/gui/components/properties/juce_BooleanPropertyComponent.h" #endif @@ -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()) { - 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; + + Thread::sleep (1); + } } - if (thread != 0 && thread->threadShouldExit()) - break; + SharedLockingEvents* const events = new SharedLockingEvents(); + sharedEvents = events; + events->incReferenceCount(); - Thread::sleep (1); + (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(); } } 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