| @@ -716,7 +716,7 @@ | |||
| 84A06BAA09CAD6A3006A43BD /* juce_AudioIODevice.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_AudioIODevice.cpp; sourceTree = "<group>"; }; | |||
| 84A06BAB09CAD6A3006A43BD /* juce_AudioIODeviceType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_AudioIODeviceType.cpp; sourceTree = "<group>"; }; | |||
| 84A06BAC09CAD6A3006A43BD /* juce_AudioIODeviceType.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_AudioIODeviceType.h; sourceTree = "<group>"; }; | |||
| 84A4883508A22E4900752A2B /* juce_Application.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Application.cpp; path = ../../src/juce_appframework/application/juce_Application.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 84A4883508A22E4900752A2B /* juce_Application.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; name = juce_Application.cpp; path = ../../src/juce_appframework/application/juce_Application.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 84A4883608A22E4900752A2B /* juce_Application.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_Application.h; path = ../../src/juce_appframework/application/juce_Application.h; sourceTree = SOURCE_ROOT; }; | |||
| 84A4883708A22E4900752A2B /* juce_DeletedAtShutdown.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DeletedAtShutdown.cpp; path = ../../src/juce_appframework/application/juce_DeletedAtShutdown.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 84A4883808A22E4900752A2B /* juce_DeletedAtShutdown.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_DeletedAtShutdown.h; path = ../../src/juce_appframework/application/juce_DeletedAtShutdown.h; sourceTree = SOURCE_ROOT; }; | |||
| @@ -1080,13 +1080,13 @@ | |||
| 84E024DE0E94028C003E41AF /* juce_mac_CoreMidi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_mac_CoreMidi.cpp; sourceTree = "<group>"; }; | |||
| 84E024DF0E94028C003E41AF /* juce_mac_FileChooser.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_FileChooser.mm; sourceTree = "<group>"; }; | |||
| 84E024E00E94028C003E41AF /* juce_mac_Files.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_Files.mm; sourceTree = "<group>"; }; | |||
| 84E024E10E94028C003E41AF /* juce_mac_Fonts.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_Fonts.mm; sourceTree = "<group>"; }; | |||
| 84E024E10E94028C003E41AF /* juce_mac_Fonts.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 2; path = juce_mac_Fonts.mm; sourceTree = "<group>"; }; | |||
| 84E024E20E94028C003E41AF /* juce_mac_MainMenu.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_MainMenu.mm; sourceTree = "<group>"; }; | |||
| 84E024E30E94028C003E41AF /* juce_mac_MessageManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_MessageManager.mm; sourceTree = "<group>"; }; | |||
| 84E024E30E94028C003E41AF /* juce_mac_MessageManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 2; path = juce_mac_MessageManager.mm; sourceTree = "<group>"; }; | |||
| 84E024E40E94028C003E41AF /* juce_mac_MouseCursor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_MouseCursor.mm; sourceTree = "<group>"; }; | |||
| 84E024E50E94028C003E41AF /* juce_mac_NamedPipe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_mac_NamedPipe.cpp; sourceTree = "<group>"; }; | |||
| 84E024E60E94028C003E41AF /* juce_mac_NativeCode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_NativeCode.mm; sourceTree = "<group>"; }; | |||
| 84E024E80E94028C003E41AF /* juce_mac_Network.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_Network.mm; sourceTree = "<group>"; }; | |||
| 84E024E80E94028C003E41AF /* juce_mac_Network.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 2; path = juce_mac_Network.mm; sourceTree = "<group>"; }; | |||
| 84E024E90E94028C003E41AF /* juce_mac_NSViewComponent.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_NSViewComponent.mm; sourceTree = "<group>"; }; | |||
| 84E024EA0E94028C003E41AF /* juce_mac_NSViewComponentPeer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 2; path = juce_mac_NSViewComponentPeer.mm; sourceTree = "<group>"; }; | |||
| 84E024EB0E94028C003E41AF /* juce_mac_OpenGLComponent.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 2; path = juce_mac_OpenGLComponent.mm; sourceTree = "<group>"; }; | |||
| @@ -1210,6 +1210,7 @@ | |||
| 84A4899708A22E4A00752A2B /* juce_core */, | |||
| 84A4881C08A22E2400752A2B /* mac specific code */, | |||
| ); | |||
| lineEnding = 2; | |||
| name = Source; | |||
| sourceTree = "<group>"; | |||
| }; | |||
| @@ -265,6 +265,7 @@ void AppleRemoteDevice::handleCallbackInternal() | |||
| { | |||
| if (strcmp (cookies, buttonPatterns + i) == 0) | |||
| { | |||
| const MessageManagerLock mml; | |||
| buttonPressed ((ButtonType) buttonNum, totalValues > 0); | |||
| break; | |||
| } | |||
| @@ -44,6 +44,7 @@ public: | |||
| bool isBold, isItalic; | |||
| float fontSize, totalSize, ascent; | |||
| int refCount; | |||
| NSMutableDictionary* attributes; | |||
| FontHelper (const String& name_, | |||
| const bool bold_, | |||
| @@ -56,10 +57,23 @@ public: | |||
| fontSize (size_), | |||
| refCount (1) | |||
| { | |||
| attributes = [[NSMutableDictionary dictionaryWithObject: [NSNumber numberWithInt: 0] | |||
| forKey: NSLigatureAttributeName] retain]; | |||
| font = [NSFont fontWithName: juceStringToNS (name_) size: size_]; | |||
| if (italic_) | |||
| font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSItalicFontMask]; | |||
| { | |||
| 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]; | |||
| } | |||
| font = newFont; | |||
| } | |||
| if (bold_) | |||
| font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSBoldFontMask]; | |||
| @@ -73,6 +87,7 @@ public: | |||
| ~FontHelper() | |||
| { | |||
| [font release]; | |||
| [attributes release]; | |||
| } | |||
| bool getPathAndKerning (const juce_wchar char1, | |||
| @@ -90,10 +105,9 @@ public: | |||
| String chars; | |||
| chars << ' ' << char1 << char2; | |||
| NSTextStorage* textStorage = [[[NSTextStorage alloc] | |||
| initWithString: juceStringToNS (chars) | |||
| attributes: [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: 0] | |||
| forKey: NSLigatureAttributeName]] autorelease]; | |||
| NSTextStorage* textStorage = [[[NSTextStorage alloc] initWithString: juceStringToNS (chars) | |||
| attributes: attributes] autorelease]; | |||
| NSLayoutManager* layoutManager = [[[NSLayoutManager alloc] init] autorelease]; | |||
| NSTextContainer* textContainer = [[[NSTextContainer alloc] init] autorelease]; | |||
| [layoutManager addTextContainer: textContainer]; | |||
| @@ -212,11 +212,16 @@ 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) | |||
| @@ -61,6 +61,7 @@ public: | |||
| { | |||
| if (JUCEApplication::getInstance() != 0) | |||
| { | |||
| const MessageManagerLock mml; | |||
| JUCEApplication::getInstance()->systemRequestedQuit(); | |||
| return NSTerminateCancel; | |||
| } | |||
| @@ -72,6 +73,7 @@ public: | |||
| { | |||
| if (JUCEApplication::getInstance() != 0) | |||
| { | |||
| const MessageManagerLock mml; | |||
| JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename)); | |||
| return YES; | |||
| } | |||
| @@ -86,19 +88,31 @@ public: | |||
| files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i])); | |||
| if (files.size() > 0 && JUCEApplication::getInstance() != 0) | |||
| { | |||
| const MessageManagerLock mml; | |||
| JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" "))); | |||
| } | |||
| } | |||
| virtual void focusChanged() | |||
| { | |||
| const MessageManagerLock mml; | |||
| juce_HandleProcessFocusChange(); | |||
| } | |||
| virtual void deliverMessage (void* message) | |||
| { | |||
| // no need for an mm lock here - deliverMessage locks it | |||
| MessageManager::getInstance()->deliverMessage (message); | |||
| } | |||
| virtual void performCallback (CallbackMessagePayload* pl) | |||
| { | |||
| const MessageManagerLock mml; | |||
| pl->result = (*pl->function) (pl->parameter); | |||
| pl->hasBeenExecuted = true; | |||
| } | |||
| virtual void deleteSelf() | |||
| { | |||
| delete this; | |||
| @@ -227,10 +241,7 @@ static bool flushingMessages = false; | |||
| CallbackMessagePayload* pl = (CallbackMessagePayload*) [((NSData*) info) bytes]; | |||
| if (pl != 0) | |||
| { | |||
| pl->result = (*pl->function) (pl->parameter); | |||
| pl->hasBeenExecuted = true; | |||
| } | |||
| redirector->performCallback (pl); | |||
| } | |||
| else | |||
| { | |||
| @@ -249,7 +260,6 @@ static JuceAppDelegate* juceAppDelegate = 0; | |||
| void MessageManager::runDispatchLoop() | |||
| { | |||
| const ScopedAutoReleasePool pool; | |||
| MessageManagerLock mml; | |||
| // must only be called by the message thread! | |||
| jassert (isThisTheMessageThread()); | |||
| @@ -100,6 +100,7 @@ END_JUCE_NAMESPACE | |||
| - (void) setOwner: (NSViewComponentPeer*) owner; | |||
| - (BOOL) canBecomeKeyWindow; | |||
| - (void) becomeKeyWindow; | |||
| - (BOOL) windowShouldClose: (id) window; | |||
| - (NSRect) constrainFrameRect: (NSRect) frameRect toScreen: (NSScreen*) screen; | |||
| - (NSSize) windowWillResize: (NSWindow*) window toSize: (NSSize) proposedFrameSize; | |||
| @@ -428,6 +429,14 @@ END_JUCE_NAMESPACE | |||
| return owner != 0 && owner->canBecomeKeyWindow(); | |||
| } | |||
| - (void) becomeKeyWindow | |||
| { | |||
| [super becomeKeyWindow]; | |||
| if (owner != 0) | |||
| owner->grabFocus(); | |||
| } | |||
| - (BOOL) windowShouldClose: (id) window | |||
| { | |||
| return owner == 0 || owner->windowShouldClose(); | |||
| @@ -909,6 +918,8 @@ 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; | |||
| @@ -1124,6 +1135,8 @@ void NSViewComponentPeer::grabFocus() | |||
| { | |||
| [window makeKeyWindow]; | |||
| [window makeFirstResponder: view]; | |||
| viewFocusGain(); | |||
| } | |||
| } | |||
| @@ -1133,6 +1146,8 @@ 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); | |||
| @@ -1172,6 +1187,7 @@ bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) | |||
| bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateKeysDown (ev, true); | |||
| bool used = handleKeyEvent (ev, true); | |||
| @@ -1187,12 +1203,14 @@ 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(); | |||
| } | |||
| @@ -1200,6 +1218,7 @@ 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) | |||
| @@ -1212,6 +1231,7 @@ bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) | |||
| //============================================================================== | |||
| void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateModifiers (ev); | |||
| currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | |||
| int x, y; | |||
| @@ -1222,6 +1242,7 @@ void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) | |||
| void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| const int oldMods = currentModifiers; | |||
| updateModifiers (ev); | |||
| currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]); | |||
| @@ -1233,6 +1254,7 @@ void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) | |||
| void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateModifiers (ev); | |||
| currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | |||
| int x, y; | |||
| @@ -1243,6 +1265,7 @@ void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) | |||
| void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateModifiers (ev); | |||
| int x, y; | |||
| getMousePos (ev, view, x, y); | |||
| @@ -1252,6 +1275,7 @@ void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) | |||
| void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateModifiers (ev); | |||
| int x, y; | |||
| getMousePos (ev, view, x, y); | |||
| @@ -1261,6 +1285,7 @@ void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) | |||
| void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateModifiers (ev); | |||
| int x, y; | |||
| getMousePos (ev, view, x, y); | |||
| @@ -1270,6 +1295,7 @@ void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) | |||
| void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateModifiers (ev); | |||
| handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f), | |||
| @@ -1280,6 +1306,8 @@ void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | |||
| //============================================================================== | |||
| BOOL NSViewComponentPeer::sendDragCallback (int type, id <NSDraggingInfo> sender) | |||
| { | |||
| const MessageManagerLock mml; | |||
| NSString* bestType | |||
| = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]]; | |||
| @@ -1330,6 +1358,7 @@ 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), | |||
| @@ -1363,6 +1392,8 @@ 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()); | |||
| @@ -1370,6 +1401,8 @@ bool NSViewComponentPeer::canBecomeKeyWindow() | |||
| bool NSViewComponentPeer::windowShouldClose() | |||
| { | |||
| const MessageManagerLock mml; | |||
| if (! isValidPeer (this)) | |||
| return YES; | |||
| @@ -1379,6 +1412,7 @@ bool NSViewComponentPeer::windowShouldClose() | |||
| void NSViewComponentPeer::redirectMovedOrResized() | |||
| { | |||
| const MessageManagerLock mml; | |||
| handleMovedOrResized(); | |||
| } | |||
| @@ -69,6 +69,8 @@ END_JUCE_NAMESPACE | |||
| { | |||
| NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"]; | |||
| const MessageManagerLock mml; | |||
| if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString]))) | |||
| [listener use]; | |||
| else | |||
| @@ -101,6 +101,8 @@ 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) | |||
| { | |||
| @@ -15680,8 +15680,12 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app) | |||
| { | |||
| juce_setCurrentThreadName ("Juce Message Thread"); | |||
| // let the app do its setting-up.. | |||
| app->initialise (app->commandLineParameters); | |||
| { | |||
| const MessageManagerLock mml; | |||
| // let the app do its setting-up.. | |||
| app->initialise (app->commandLineParameters); | |||
| } | |||
| // register for broadcast new app messages | |||
| MessageManager::getInstance()->registerBroadcastListener (app); | |||
| @@ -15728,6 +15732,7 @@ int JUCEApplication::shutdownAppAndClearUp() | |||
| JUCE_TRY | |||
| { | |||
| // give the app a chance to clean up.. | |||
| const MessageManagerLock mml; | |||
| app->shutdown(); | |||
| } | |||
| #if JUCE_CATCH_UNHANDLED_EXCEPTIONS | |||
| @@ -15824,9 +15829,15 @@ void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI() | |||
| #if JUCE_MAC | |||
| const ScopedAutoReleasePool pool; | |||
| #endif | |||
| DeletedAtShutdown::deleteAll(); | |||
| { | |||
| const MessageManagerLock mml; | |||
| DeletedAtShutdown::deleteAll(); | |||
| LookAndFeel::clearDefaultLookAndFeel(); | |||
| } | |||
| delete MessageManager::getInstance(); | |||
| LookAndFeel::clearDefaultLookAndFeel(); | |||
| shutdownJuce_NonGUI(); | |||
| juceInitialisedGUI = false; | |||
| @@ -21872,7 +21883,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||
| input->getNextAudioBlock (readInfo); | |||
| if (ratio > 1.0) | |||
| if (ratio > 1.0001) | |||
| { | |||
| // for down-sampling, pre-apply the filter.. | |||
| @@ -21918,7 +21929,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||
| } | |||
| } | |||
| if (ratio < 1.0) | |||
| if (ratio < 0.9999) | |||
| { | |||
| // for up-sampling, apply the filter after transposing.. | |||
| @@ -28855,13 +28866,19 @@ OSStatus AudioUnitPluginInstance::getBeatAndTempo (Float64* outCurrentBeat, Floa | |||
| if (ph != 0 && ph->getCurrentPosition (result)) | |||
| { | |||
| *outCurrentBeat = result.ppqPosition; | |||
| *outCurrentTempo = result.bpm; | |||
| if (outCurrentBeat != 0) | |||
| *outCurrentBeat = result.ppqPosition; | |||
| if (outCurrentTempo != 0) | |||
| *outCurrentTempo = result.bpm; | |||
| } | |||
| else | |||
| { | |||
| *outCurrentBeat = 0; | |||
| *outCurrentTempo = 120.0; | |||
| if (outCurrentBeat != 0) | |||
| *outCurrentBeat = 0; | |||
| if (outCurrentTempo != 0) | |||
| *outCurrentTempo = 120.0; | |||
| } | |||
| return noErr; | |||
| @@ -28877,18 +28894,31 @@ OSStatus AudioUnitPluginInstance::getMusicalTimeLocation (UInt32* outDeltaSample | |||
| if (ph != 0 && ph->getCurrentPosition (result)) | |||
| { | |||
| *outTimeSig_Numerator = result.timeSigNumerator; | |||
| *outTimeSig_Denominator = result.timeSigDenominator; | |||
| if (outTimeSig_Numerator != 0) | |||
| *outTimeSig_Numerator = result.timeSigNumerator; | |||
| *outDeltaSampleOffsetToNextBeat = 0; //xxx | |||
| *outCurrentMeasureDownBeat = result.ppqPositionOfLastBarStart; //xxx wrong | |||
| if (outTimeSig_Denominator != 0) | |||
| *outTimeSig_Denominator = result.timeSigDenominator; | |||
| if (outDeltaSampleOffsetToNextBeat != 0) | |||
| *outDeltaSampleOffsetToNextBeat = 0; //xxx | |||
| if (outCurrentMeasureDownBeat != 0) | |||
| *outCurrentMeasureDownBeat = result.ppqPositionOfLastBarStart; //xxx wrong | |||
| } | |||
| else | |||
| { | |||
| *outDeltaSampleOffsetToNextBeat = 0; | |||
| *outTimeSig_Numerator = 4; | |||
| *outTimeSig_Denominator = 4; | |||
| *outCurrentMeasureDownBeat = 0; | |||
| if (outDeltaSampleOffsetToNextBeat != 0) | |||
| *outDeltaSampleOffsetToNextBeat = 0; | |||
| if (outTimeSig_Numerator != 0) | |||
| *outTimeSig_Numerator = 4; | |||
| if (outTimeSig_Denominator != 0) | |||
| *outTimeSig_Denominator = 4; | |||
| if (outCurrentMeasureDownBeat != 0) | |||
| *outCurrentMeasureDownBeat = 0; | |||
| } | |||
| return noErr; | |||
| @@ -36771,7 +36801,8 @@ MessageManager::MessageManager() throw() | |||
| quitMessagePosted (false), | |||
| quitMessageReceived (false) | |||
| { | |||
| currentLockingThreadId = messageThreadId = Thread::getCurrentThreadId(); | |||
| currentLockingThreadId = 0; | |||
| messageThreadId = Thread::getCurrentThreadId(); | |||
| } | |||
| MessageManager::~MessageManager() throw() | |||
| @@ -38879,9 +38910,14 @@ bool Component::isCurrentlyBlockedByAnotherModalComponent() const throw() | |||
| && ! mc->canModalEventBeSentToComponent (this); | |||
| } | |||
| Component* JUCE_CALLTYPE Component::getCurrentlyModalComponent() throw() | |||
| int JUCE_CALLTYPE Component::getNumCurrentlyModalComponents() throw() | |||
| { | |||
| return modalComponentStack.size(); | |||
| } | |||
| Component* JUCE_CALLTYPE Component::getCurrentlyModalComponent (int index) throw() | |||
| { | |||
| Component* const c = (Component*) modalComponentStack.getLast(); | |||
| Component* const c = (Component*) (modalComponentStack [modalComponentStack.size() - index - 1]); | |||
| return c->isValidComponent() ? c : 0; | |||
| } | |||
| @@ -51957,7 +51993,9 @@ void TreeView::paint (Graphics& g) | |||
| void TreeView::resized() | |||
| { | |||
| viewport->setBounds (0, 0, getWidth(), getHeight()); | |||
| itemsChanged(); | |||
| handleAsyncUpdate(); | |||
| } | |||
| void TreeView::moveSelectedRow (int delta) | |||
| @@ -56283,6 +56321,7 @@ bool KeyPressMappingSet::keyStateChanged (Component* originatingComponent) | |||
| { | |||
| keyPressEntryIndex = k; | |||
| wasDown = true; | |||
| used = true; | |||
| break; | |||
| } | |||
| } | |||
| @@ -60278,78 +60317,104 @@ void LookAndFeel::changeToggleButtonWidthToFitText (ToggleButton& button) | |||
| button.getHeight()); | |||
| } | |||
| AlertWindow* LookAndFeel::createAlertWindow (const String& title, | |||
| const String& message, | |||
| const String& button1, | |||
| const String& button2, | |||
| const String& button3, | |||
| AlertWindow::AlertIconType iconType, | |||
| int numButtons, | |||
| Component* associatedComponent) | |||
| { | |||
| AlertWindow* aw = new AlertWindow (title, message, iconType); | |||
| if (numButtons == 1) | |||
| { | |||
| aw->addButton (button1, 0, | |||
| KeyPress (KeyPress::escapeKey, 0, 0), | |||
| KeyPress (KeyPress::returnKey, 0, 0)); | |||
| } | |||
| else | |||
| { | |||
| const KeyPress button1ShortCut (CharacterFunctions::toLowerCase (button1[0]), 0, 0); | |||
| 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); | |||
| aw->addButton (button2, 0, KeyPress (KeyPress::escapeKey, 0, 0), button2ShortCut); | |||
| } | |||
| else | |||
| { | |||
| jassert (numButtons == 3); | |||
| aw->addButton (button1, 1, button1ShortCut); | |||
| aw->addButton (button2, 2, button2ShortCut); | |||
| aw->addButton (button3, 0, KeyPress (KeyPress::escapeKey, 0, 0)); | |||
| } | |||
| } | |||
| return aw; | |||
| } | |||
| void LookAndFeel::drawAlertBox (Graphics& g, | |||
| AlertWindow& alert, | |||
| const Rectangle& textArea, | |||
| TextLayout& textLayout) | |||
| { | |||
| const int iconWidth = 80; | |||
| const Colour background (alert.findColour (AlertWindow::backgroundColourId)); | |||
| g.fillAll (background); | |||
| g.fillAll (alert.findColour (AlertWindow::backgroundColourId)); | |||
| int iconSpaceUsed = 0; | |||
| Justification alignment (Justification::horizontallyCentred); | |||
| const int iconWidth = 80; | |||
| int iconSize = jmin (iconWidth + 50, alert.getHeight() + 20); | |||
| if (alert.containsAnyExtraComponents() || alert.getNumButtons() > 2) | |||
| iconSize = jmin (iconSize, textArea.getHeight() + 50); | |||
| const Rectangle iconRect (iconSize / -10, | |||
| iconSize / -10, | |||
| iconSize, | |||
| iconSize); | |||
| const Rectangle iconRect (iconSize / -10, iconSize / -10, | |||
| iconSize, iconSize); | |||
| if (alert.getAlertType() == AlertWindow::QuestionIcon | |||
| || alert.getAlertType() == AlertWindow::InfoIcon) | |||
| if (alert.getAlertType() != AlertWindow::NoIcon) | |||
| { | |||
| if (alert.getAlertType() == AlertWindow::InfoIcon) | |||
| g.setColour (background.overlaidWith (Colour (0x280000ff))); | |||
| Path icon; | |||
| uint32 colour; | |||
| char character; | |||
| if (alert.getAlertType() == AlertWindow::WarningIcon) | |||
| { | |||
| colour = 0x55ff5555; | |||
| character = '!'; | |||
| 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); | |||
| } | |||
| else | |||
| g.setColour (background.overlaidWith (Colours::gold.darker().withAlpha (0.25f))); | |||
| g.fillEllipse ((float) iconRect.getX(), | |||
| (float) iconRect.getY(), | |||
| (float) iconRect.getWidth(), | |||
| (float) iconRect.getHeight()); | |||
| g.setColour (background); | |||
| g.setFont (iconRect.getHeight() * 0.9f, Font::bold); | |||
| g.drawText ((alert.getAlertType() == AlertWindow::InfoIcon) ? "i" | |||
| : "?", | |||
| iconRect.getX(), | |||
| iconRect.getY(), | |||
| iconRect.getWidth(), | |||
| iconRect.getHeight(), | |||
| Justification::centred, false); | |||
| { | |||
| colour = alert.getAlertType() == AlertWindow::InfoIcon ? 0x605555ff : 0x40b69900; | |||
| character = alert.getAlertType() == AlertWindow::InfoIcon ? 'i' : '?'; | |||
| iconSpaceUsed = iconWidth; | |||
| alignment = Justification::left; | |||
| } | |||
| else if (alert.getAlertType() == AlertWindow::WarningIcon) | |||
| { | |||
| Path p; | |||
| p.addTriangle (iconRect.getX() + iconRect.getWidth() * 0.5f, | |||
| (float) iconRect.getY(), | |||
| (float) iconRect.getRight(), | |||
| (float) iconRect.getBottom(), | |||
| (float) iconRect.getX(), | |||
| (float) iconRect.getBottom()); | |||
| g.setColour (background.overlaidWith (Colour (0x33ff0000))); | |||
| g.fillPath (p.createPathWithRoundedCorners (5.0f)); | |||
| g.setColour (background); | |||
| g.setFont (iconRect.getHeight() * 0.9f, Font::bold); | |||
| g.drawText (T("!"), | |||
| iconRect.getX(), | |||
| iconRect.getY(), | |||
| iconRect.getWidth(), | |||
| iconRect.getHeight() + iconRect.getHeight() / 8, | |||
| Justification::centred, false); | |||
| icon.addEllipse ((float) iconRect.getX(), (float) iconRect.getY(), | |||
| (float) iconRect.getWidth(), (float) iconRect.getHeight()); | |||
| } | |||
| GlyphArrangement ga; | |||
| ga.addFittedText (Font (iconRect.getHeight() * 0.9f, Font::bold), | |||
| String::charToString (character), | |||
| (float) iconRect.getX(), (float) iconRect.getY(), | |||
| (float) iconRect.getWidth(), (float) iconRect.getHeight(), | |||
| Justification::centred, false); | |||
| ga.createPath (icon); | |||
| icon.setUsingNonZeroWinding (false); | |||
| g.setColour (Colour (colour)); | |||
| g.fillPath (icon); | |||
| iconSpaceUsed = iconWidth; | |||
| alignment = Justification::left; | |||
| @@ -60358,10 +60423,8 @@ void LookAndFeel::drawAlertBox (Graphics& g, | |||
| g.setColour (alert.findColour (AlertWindow::textColourId)); | |||
| textLayout.drawWithin (g, | |||
| textArea.getX() + iconSpaceUsed, | |||
| textArea.getY(), | |||
| textArea.getWidth() - iconSpaceUsed, | |||
| textArea.getHeight(), | |||
| textArea.getX() + iconSpaceUsed, textArea.getY(), | |||
| textArea.getWidth() - iconSpaceUsed, textArea.getHeight(), | |||
| alignment.getFlags() | Justification::top); | |||
| g.setColour (alert.findColour (AlertWindow::outlineColourId)); | |||
| @@ -71264,18 +71327,17 @@ private: | |||
| AlertWindow::AlertWindow (const String& title, | |||
| const String& message, | |||
| AlertIconType iconType) | |||
| AlertIconType iconType, | |||
| Component* associatedComponent_) | |||
| : TopLevelWindow (title, true), | |||
| alertIconType (iconType) | |||
| alertIconType (iconType), | |||
| associatedComponent (associatedComponent_) | |||
| { | |||
| if (message.isEmpty()) | |||
| text = T(" "); // to force an update if the message is empty | |||
| setMessage (message); | |||
| #if JUCE_MAC | |||
| setAlwaysOnTop (true); | |||
| #else | |||
| for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) | |||
| { | |||
| Component* const c = Desktop::getInstance().getComponent (i); | |||
| @@ -71286,7 +71348,6 @@ AlertWindow::AlertWindow (const String& title, | |||
| break; | |||
| } | |||
| } | |||
| #endif | |||
| lookAndFeelChanged(); | |||
| @@ -71634,7 +71695,7 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) | |||
| if (! isVisible()) | |||
| { | |||
| centreAroundComponent (0, w, h); | |||
| centreAroundComponent (associatedComponent, w, h); | |||
| } | |||
| else | |||
| { | |||
| @@ -71751,7 +71812,7 @@ void AlertWindow::lookAndFeelChanged() | |||
| const int flags = getLookAndFeel().getAlertBoxWindowFlags(); | |||
| setUsingNativeTitleBar ((flags & ComponentPeer::windowHasTitleBar) != 0); | |||
| setDropShadowEnabled ((flags & ComponentPeer::windowHasDropShadow) != 0); | |||
| setDropShadowEnabled (isOpaque() && (flags & ComponentPeer::windowHasDropShadow) != 0); | |||
| } | |||
| int AlertWindow::getDesktopWindowStyleFlags() const | |||
| @@ -71764,6 +71825,7 @@ struct AlertWindowInfo | |||
| String title, message, button1, button2, button3; | |||
| AlertWindow::AlertIconType iconType; | |||
| int numButtons; | |||
| Component* associatedComponent; | |||
| int run() const | |||
| { | |||
| @@ -71774,37 +71836,19 @@ struct AlertWindowInfo | |||
| private: | |||
| int show() const | |||
| { | |||
| AlertWindow aw (title, message, iconType); | |||
| jassert (associatedComponent == 0 || associatedComponent->isValidComponent()); // has your comp been deleted? | |||
| if (numButtons == 1) | |||
| { | |||
| aw.addButton (button1, 0, | |||
| KeyPress (KeyPress::escapeKey, 0, 0), | |||
| KeyPress (KeyPress::returnKey, 0, 0)); | |||
| } | |||
| else | |||
| { | |||
| const KeyPress button1ShortCut (CharacterFunctions::toLowerCase (button1[0]), 0, 0); | |||
| KeyPress button2ShortCut (CharacterFunctions::toLowerCase (button2[0]), 0, 0); | |||
| if (button1ShortCut == button2ShortCut) | |||
| button2ShortCut = KeyPress(); | |||
| LookAndFeel& lf = associatedComponent->isValidComponent() ? associatedComponent->getLookAndFeel() | |||
| : LookAndFeel::getDefaultLookAndFeel(); | |||
| if (numButtons == 2) | |||
| { | |||
| aw.addButton (button1, 1, KeyPress (KeyPress::returnKey, 0, 0), button1ShortCut); | |||
| aw.addButton (button2, 0, KeyPress (KeyPress::escapeKey, 0, 0), button2ShortCut); | |||
| } | |||
| else | |||
| { | |||
| jassert (numButtons == 3); | |||
| Component* const alertBox = lf.createAlertWindow (title, message, button1, button2, button3, | |||
| iconType, numButtons, associatedComponent); | |||
| aw.addButton (button1, 1, button1ShortCut); | |||
| aw.addButton (button2, 2, button2ShortCut); | |||
| aw.addButton (button3, 0, KeyPress (KeyPress::escapeKey, 0, 0)); | |||
| } | |||
| } | |||
| jassert (alertBox != 0); // you have to return one of these! | |||
| return aw.runModalLoop(); | |||
| const int result = alertBox->runModalLoop(); | |||
| delete alertBox; | |||
| return result; | |||
| } | |||
| static void* showCallback (void* userData) | |||
| @@ -71816,7 +71860,8 @@ private: | |||
| void AlertWindow::showMessageBox (AlertIconType iconType, | |||
| const String& title, | |||
| const String& message, | |||
| const String& buttonText) | |||
| const String& buttonText, | |||
| Component* associatedComponent) | |||
| { | |||
| AlertWindowInfo info; | |||
| info.title = title; | |||
| @@ -71824,6 +71869,7 @@ void AlertWindow::showMessageBox (AlertIconType iconType, | |||
| info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText; | |||
| info.iconType = iconType; | |||
| info.numButtons = 1; | |||
| info.associatedComponent = associatedComponent; | |||
| info.run(); | |||
| } | |||
| @@ -71832,7 +71878,8 @@ bool AlertWindow::showOkCancelBox (AlertIconType iconType, | |||
| const String& title, | |||
| const String& message, | |||
| const String& button1Text, | |||
| const String& button2Text) | |||
| const String& button2Text, | |||
| Component* associatedComponent) | |||
| { | |||
| AlertWindowInfo info; | |||
| info.title = title; | |||
| @@ -71841,6 +71888,7 @@ bool AlertWindow::showOkCancelBox (AlertIconType iconType, | |||
| info.button2 = button2Text.isEmpty() ? TRANS("cancel") : button2Text; | |||
| info.iconType = iconType; | |||
| info.numButtons = 2; | |||
| info.associatedComponent = associatedComponent; | |||
| return info.run() != 0; | |||
| } | |||
| @@ -71850,7 +71898,8 @@ int AlertWindow::showYesNoCancelBox (AlertIconType iconType, | |||
| const String& message, | |||
| const String& button1Text, | |||
| const String& button2Text, | |||
| const String& button3Text) | |||
| const String& button3Text, | |||
| Component* associatedComponent) | |||
| { | |||
| AlertWindowInfo info; | |||
| info.title = title; | |||
| @@ -71860,6 +71909,7 @@ int AlertWindow::showYesNoCancelBox (AlertIconType iconType, | |||
| info.button3 = button3Text.isEmpty() ? TRANS("cancel") : button3Text; | |||
| info.iconType = iconType; | |||
| info.numButtons = 3; | |||
| info.associatedComponent = associatedComponent; | |||
| return info.run(); | |||
| } | |||
| @@ -73672,19 +73722,23 @@ ThreadWithProgressWindow::ThreadWithProgressWindow (const String& title, | |||
| const String& cancelButtonText) | |||
| : Thread ("Juce Progress Window"), | |||
| progress (0.0), | |||
| alertWindow (title, String::empty, AlertWindow::NoIcon), | |||
| timeOutMsWhenCancelling (timeOutMsWhenCancelling_) | |||
| { | |||
| alertWindow = LookAndFeel::getDefaultLookAndFeel() | |||
| .createAlertWindow (title, String::empty, cancelButtonText, String::empty, String::empty, | |||
| AlertWindow::NoIcon, 1, 0); | |||
| if (hasProgressBar) | |||
| alertWindow.addProgressBarComponent (progress); | |||
| alertWindow->addProgressBarComponent (progress); | |||
| if (hasCancelButton) | |||
| alertWindow.addButton (cancelButtonText, 1); | |||
| alertWindow->addButton (cancelButtonText, 1); | |||
| } | |||
| ThreadWithProgressWindow::~ThreadWithProgressWindow() | |||
| { | |||
| stopThread (timeOutMsWhenCancelling); | |||
| delete alertWindow; | |||
| } | |||
| bool ThreadWithProgressWindow::runThread (const int priority) | |||
| @@ -73694,14 +73748,14 @@ bool ThreadWithProgressWindow::runThread (const int priority) | |||
| { | |||
| const ScopedLock sl (messageLock); | |||
| alertWindow.setMessage (message); | |||
| alertWindow->setMessage (message); | |||
| } | |||
| const bool wasCancelled = alertWindow.runModalLoop() != 0; | |||
| const bool wasCancelled = alertWindow->runModalLoop() != 0; | |||
| stopThread (timeOutMsWhenCancelling); | |||
| alertWindow.setVisible (false); | |||
| alertWindow->setVisible (false); | |||
| return ! wasCancelled; | |||
| } | |||
| @@ -73722,13 +73776,13 @@ void ThreadWithProgressWindow::timerCallback() | |||
| if (! isThreadRunning()) | |||
| { | |||
| // thread has finished normally.. | |||
| alertWindow.exitModalState (0); | |||
| alertWindow.setVisible (false); | |||
| alertWindow->exitModalState (0); | |||
| alertWindow->setVisible (false); | |||
| } | |||
| else | |||
| { | |||
| const ScopedLock sl (messageLock); | |||
| alertWindow.setMessage (message); | |||
| alertWindow->setMessage (message); | |||
| } | |||
| } | |||
| @@ -87373,6 +87427,30 @@ void Rectangle::setSize (const int w_, | |||
| h = h_; | |||
| } | |||
| void Rectangle::setLeft (const int newLeft) throw() | |||
| { | |||
| w = jmax (0, x + w - newLeft); | |||
| x = newLeft; | |||
| } | |||
| void Rectangle::setTop (const int newTop) throw() | |||
| { | |||
| h = jmax (0, y + h - newTop); | |||
| y = newTop; | |||
| } | |||
| void Rectangle::setRight (const int newRight) throw() | |||
| { | |||
| x = jmin (x, newRight); | |||
| w = newRight - x; | |||
| } | |||
| void Rectangle::setBottom (const int newBottom) throw() | |||
| { | |||
| y = jmin (y, newBottom); | |||
| h = newBottom - y; | |||
| } | |||
| void Rectangle::translate (const int dx, | |||
| const int dy) throw() | |||
| { | |||
| @@ -242157,6 +242235,8 @@ 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) | |||
| { | |||
| @@ -265915,7 +265995,6 @@ void juce_updateMultiMonitorInfo (Array <Rectangle>& monitorCoords, const bool c | |||
| #endif | |||
| #endif | |||
| /********* End of inlined file: juce_mac_MiscUtilities.mm *********/ | |||
| /********* Start of inlined file: juce_mac_Debugging.mm *********/ | |||
| @@ -266034,6 +266113,7 @@ END_JUCE_NAMESPACE | |||
| - (void) setOwner: (NSViewComponentPeer*) owner; | |||
| - (BOOL) canBecomeKeyWindow; | |||
| - (void) becomeKeyWindow; | |||
| - (BOOL) windowShouldClose: (id) window; | |||
| - (NSRect) constrainFrameRect: (NSRect) frameRect toScreen: (NSScreen*) screen; | |||
| - (NSSize) windowWillResize: (NSWindow*) window toSize: (NSSize) proposedFrameSize; | |||
| @@ -266351,6 +266431,14 @@ END_JUCE_NAMESPACE | |||
| return owner != 0 && owner->canBecomeKeyWindow(); | |||
| } | |||
| - (void) becomeKeyWindow | |||
| { | |||
| [super becomeKeyWindow]; | |||
| if (owner != 0) | |||
| owner->grabFocus(); | |||
| } | |||
| - (BOOL) windowShouldClose: (id) window | |||
| { | |||
| return owner == 0 || owner->windowShouldClose(); | |||
| @@ -266826,6 +266914,8 @@ 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; | |||
| @@ -267040,6 +267130,8 @@ void NSViewComponentPeer::grabFocus() | |||
| { | |||
| [window makeKeyWindow]; | |||
| [window makeFirstResponder: view]; | |||
| viewFocusGain(); | |||
| } | |||
| } | |||
| @@ -267049,6 +267141,8 @@ 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); | |||
| @@ -267088,6 +267182,7 @@ bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) | |||
| bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateKeysDown (ev, true); | |||
| bool used = handleKeyEvent (ev, true); | |||
| @@ -267103,12 +267198,14 @@ 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(); | |||
| } | |||
| @@ -267116,6 +267213,7 @@ 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) | |||
| @@ -267127,6 +267225,7 @@ bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) | |||
| void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateModifiers (ev); | |||
| currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | |||
| int x, y; | |||
| @@ -267137,6 +267236,7 @@ void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) | |||
| void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| const int oldMods = currentModifiers; | |||
| updateModifiers (ev); | |||
| currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]); | |||
| @@ -267148,6 +267248,7 @@ void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) | |||
| void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateModifiers (ev); | |||
| currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | |||
| int x, y; | |||
| @@ -267158,6 +267259,7 @@ void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) | |||
| void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateModifiers (ev); | |||
| int x, y; | |||
| getMousePos (ev, view, x, y); | |||
| @@ -267167,6 +267269,7 @@ void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) | |||
| void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateModifiers (ev); | |||
| int x, y; | |||
| getMousePos (ev, view, x, y); | |||
| @@ -267176,6 +267279,7 @@ void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) | |||
| void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateModifiers (ev); | |||
| int x, y; | |||
| getMousePos (ev, view, x, y); | |||
| @@ -267185,6 +267289,7 @@ void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) | |||
| void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | |||
| { | |||
| const MessageManagerLock mml; | |||
| updateModifiers (ev); | |||
| handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f), | |||
| @@ -267194,6 +267299,8 @@ void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | |||
| BOOL NSViewComponentPeer::sendDragCallback (int type, id <NSDraggingInfo> sender) | |||
| { | |||
| const MessageManagerLock mml; | |||
| NSString* bestType | |||
| = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]]; | |||
| @@ -267244,6 +267351,7 @@ 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), | |||
| @@ -267277,6 +267385,8 @@ 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()); | |||
| @@ -267284,6 +267394,8 @@ bool NSViewComponentPeer::canBecomeKeyWindow() | |||
| bool NSViewComponentPeer::windowShouldClose() | |||
| { | |||
| const MessageManagerLock mml; | |||
| if (! isValidPeer (this)) | |||
| return YES; | |||
| @@ -267293,6 +267405,7 @@ bool NSViewComponentPeer::windowShouldClose() | |||
| void NSViewComponentPeer::redirectMovedOrResized() | |||
| { | |||
| const MessageManagerLock mml; | |||
| handleMovedOrResized(); | |||
| } | |||
| @@ -267923,6 +268036,7 @@ void AppleRemoteDevice::handleCallbackInternal() | |||
| { | |||
| if (strcmp (cookies, buttonPatterns + i) == 0) | |||
| { | |||
| const MessageManagerLock mml; | |||
| buttonPressed ((ButtonType) buttonNum, totalValues > 0); | |||
| break; | |||
| } | |||
| @@ -268149,7 +268263,7 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| NSOpenGLContext* renderContext; | |||
| ThreadSafeNSOpenGLView* view; | |||
| ThreadSafeNSOpenGLView* view; | |||
| private: | |||
| OpenGLPixelFormat pixelFormat; | |||
| @@ -268401,11 +268515,16 @@ 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) | |||
| @@ -269502,6 +269621,7 @@ public: | |||
| bool isBold, isItalic; | |||
| float fontSize, totalSize, ascent; | |||
| int refCount; | |||
| NSMutableDictionary* attributes; | |||
| FontHelper (const String& name_, | |||
| const bool bold_, | |||
| @@ -269514,10 +269634,23 @@ public: | |||
| fontSize (size_), | |||
| refCount (1) | |||
| { | |||
| attributes = [[NSMutableDictionary dictionaryWithObject: [NSNumber numberWithInt: 0] | |||
| forKey: NSLigatureAttributeName] retain]; | |||
| font = [NSFont fontWithName: juceStringToNS (name_) size: size_]; | |||
| if (italic_) | |||
| font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSItalicFontMask]; | |||
| { | |||
| 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]; | |||
| } | |||
| font = newFont; | |||
| } | |||
| if (bold_) | |||
| font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSBoldFontMask]; | |||
| @@ -269531,6 +269664,7 @@ public: | |||
| ~FontHelper() | |||
| { | |||
| [font release]; | |||
| [attributes release]; | |||
| } | |||
| bool getPathAndKerning (const juce_wchar char1, | |||
| @@ -269548,10 +269682,9 @@ public: | |||
| String chars; | |||
| chars << ' ' << char1 << char2; | |||
| NSTextStorage* textStorage = [[[NSTextStorage alloc] | |||
| initWithString: juceStringToNS (chars) | |||
| attributes: [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: 0] | |||
| forKey: NSLigatureAttributeName]] autorelease]; | |||
| NSTextStorage* textStorage = [[[NSTextStorage alloc] initWithString: juceStringToNS (chars) | |||
| attributes: attributes] autorelease]; | |||
| NSLayoutManager* layoutManager = [[[NSLayoutManager alloc] init] autorelease]; | |||
| NSTextContainer* textContainer = [[[NSTextContainer alloc] init] autorelease]; | |||
| [layoutManager addTextContainer: textContainer]; | |||
| @@ -269829,6 +269962,7 @@ public: | |||
| { | |||
| if (JUCEApplication::getInstance() != 0) | |||
| { | |||
| const MessageManagerLock mml; | |||
| JUCEApplication::getInstance()->systemRequestedQuit(); | |||
| return NSTerminateCancel; | |||
| } | |||
| @@ -269840,6 +269974,7 @@ public: | |||
| { | |||
| if (JUCEApplication::getInstance() != 0) | |||
| { | |||
| const MessageManagerLock mml; | |||
| JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename)); | |||
| return YES; | |||
| } | |||
| @@ -269854,19 +269989,31 @@ public: | |||
| files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i])); | |||
| if (files.size() > 0 && JUCEApplication::getInstance() != 0) | |||
| { | |||
| const MessageManagerLock mml; | |||
| JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" "))); | |||
| } | |||
| } | |||
| virtual void focusChanged() | |||
| { | |||
| const MessageManagerLock mml; | |||
| juce_HandleProcessFocusChange(); | |||
| } | |||
| virtual void deliverMessage (void* message) | |||
| { | |||
| // no need for an mm lock here - deliverMessage locks it | |||
| MessageManager::getInstance()->deliverMessage (message); | |||
| } | |||
| virtual void performCallback (CallbackMessagePayload* pl) | |||
| { | |||
| const MessageManagerLock mml; | |||
| pl->result = (*pl->function) (pl->parameter); | |||
| pl->hasBeenExecuted = true; | |||
| } | |||
| virtual void deleteSelf() | |||
| { | |||
| delete this; | |||
| @@ -269995,10 +270142,7 @@ static bool flushingMessages = false; | |||
| CallbackMessagePayload* pl = (CallbackMessagePayload*) [((NSData*) info) bytes]; | |||
| if (pl != 0) | |||
| { | |||
| pl->result = (*pl->function) (pl->parameter); | |||
| pl->hasBeenExecuted = true; | |||
| } | |||
| redirector->performCallback (pl); | |||
| } | |||
| else | |||
| { | |||
| @@ -270017,7 +270161,6 @@ static JuceAppDelegate* juceAppDelegate = 0; | |||
| void MessageManager::runDispatchLoop() | |||
| { | |||
| const ScopedAutoReleasePool pool; | |||
| MessageManagerLock mml; | |||
| // must only be called by the message thread! | |||
| jassert (isThisTheMessageThread()); | |||
| @@ -270173,6 +270316,8 @@ END_JUCE_NAMESPACE | |||
| { | |||
| NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"]; | |||
| const MessageManagerLock mml; | |||
| if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString]))) | |||
| [listener use]; | |||
| else | |||
| @@ -15016,8 +15016,8 @@ private: | |||
| #if ! JUCE_ONLY_BUILD_CORE_LIBRARY | |||
| /********* Start of inlined file: juce_app_includes.h *********/ | |||
| #ifndef __JUCE_JUCE_APP_INCLUDES_INCLUDEFILES__ | |||
| #define __JUCE_JUCE_APP_INCLUDES_INCLUDEFILES__ | |||
| #ifndef __JUCE_APP_INCLUDES_JUCEHEADER__ | |||
| #define __JUCE_APP_INCLUDES_JUCEHEADER__ | |||
| #ifndef __JUCE_APPLICATION_JUCEHEADER__ | |||
| @@ -17747,6 +17747,28 @@ public: | |||
| void setBounds (const int newX, const int newY, | |||
| const int newWidth, const int newHeight) throw(); | |||
| /** Moves the x position, adjusting the width so that the right-hand edge remains in the same place. | |||
| If the x is moved to be on the right of the current right-hand edge, the width will be set to zero. | |||
| */ | |||
| void setLeft (const int newLeft) throw(); | |||
| /** Moves the y position, adjusting the height so that the bottom edge remains in the same place. | |||
| If the y is moved to be below the current bottom edge, the height will be set to zero. | |||
| */ | |||
| void setTop (const int newTop) throw(); | |||
| /** Adjusts the width so that the right-hand edge of the rectangle has this new value. | |||
| If the new right is below the current X value, the X will be pushed down to match it. | |||
| @see getRight | |||
| */ | |||
| void setRight (const int newRight) throw(); | |||
| /** Adjusts the height so that the bottom edge of the rectangle has this new value. | |||
| If the new bottom is lower than the current Y value, the Y will be pushed down to match it. | |||
| @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(); | |||
| @@ -22451,12 +22473,23 @@ public: | |||
| */ | |||
| bool isCurrentlyModal() const throw(); | |||
| /** Returns the component that is currently modal. | |||
| /** Returns the number of components that are currently in a modal state. | |||
| @see getCurrentlyModalComponent | |||
| */ | |||
| static int JUCE_CALLTYPE getNumCurrentlyModalComponents() throw(); | |||
| /** Returns one of the components that are currently modal. | |||
| @returns the modal component, or null if no components are modal | |||
| @see runModalLoop, isCurrentlyModal | |||
| The index specifies which of the possible modal components to return. The order | |||
| 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 | |||
| */ | |||
| static Component* JUCE_CALLTYPE getCurrentlyModalComponent() throw(); | |||
| static Component* JUCE_CALLTYPE getCurrentlyModalComponent (int index = 0) throw(); | |||
| /** Checks whether there's a modal component somewhere that's stopping this one | |||
| from receiving messages. | |||
| @@ -37764,7 +37797,7 @@ typedef void* (MessageCallbackFunction) (void* userData); | |||
| @see Message, MessageListener, MessageManagerLock, JUCEApplication | |||
| */ | |||
| class JUCE_API MessageManager : private DeletedAtShutdown | |||
| class JUCE_API MessageManager | |||
| { | |||
| public: | |||
| @@ -37871,12 +37904,13 @@ public: | |||
| void deliverMessage (void*); | |||
| /** @internal */ | |||
| void deliverBroadcastMessage (const String&); | |||
| /** @internal */ | |||
| ~MessageManager() throw(); | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| MessageManager() throw(); | |||
| ~MessageManager() throw(); | |||
| friend class MessageListener; | |||
| friend class ChangeBroadcaster; | |||
| @@ -50522,10 +50556,14 @@ public: | |||
| @param message a longer, more descriptive message to show underneath the | |||
| headline | |||
| @param iconType the type of icon to display | |||
| @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. | |||
| */ | |||
| AlertWindow (const String& title, | |||
| const String& message, | |||
| AlertIconType iconType); | |||
| AlertIconType iconType, | |||
| Component* associatedComponent = 0); | |||
| /** Destroys the AlertWindow */ | |||
| ~AlertWindow(); | |||
| @@ -50670,11 +50708,15 @@ public: | |||
| headline | |||
| @param buttonText the text to show in the button - if this string is empty, the | |||
| default string "ok" (or a localised version) will be used. | |||
| @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. | |||
| */ | |||
| static void JUCE_CALLTYPE showMessageBox (AlertIconType iconType, | |||
| const String& title, | |||
| const String& message, | |||
| const String& buttonText = String::empty); | |||
| const String& buttonText = String::empty, | |||
| Component* associatedComponent = 0); | |||
| /** Shows a dialog box with two buttons. | |||
| @@ -50691,13 +50733,17 @@ public: | |||
| @param button2Text the text to show in the second button - if this string is | |||
| empty, the default string "cancel" (or a localised version of it) | |||
| will be used. | |||
| @returns true if button 1 was clicked, false if it was button 2 | |||
| @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 true if button 1 was clicked, false if it was button 2 | |||
| */ | |||
| static bool JUCE_CALLTYPE showOkCancelBox (AlertIconType iconType, | |||
| const String& title, | |||
| const String& message, | |||
| const String& button1Text = String::empty, | |||
| const String& button2Text = String::empty); | |||
| const String& button2Text = String::empty, | |||
| Component* associatedComponent = 0); | |||
| /** Shows a dialog box with three buttons. | |||
| @@ -50715,6 +50761,9 @@ public: | |||
| "no" will be used (or a localised version of it) | |||
| @param button3Text the text to show in the first button - if an empty string, then | |||
| "cancel" will be used (or a localised version of it) | |||
| @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') | |||
| @@ -50726,7 +50775,8 @@ public: | |||
| const String& message, | |||
| const String& button1Text = String::empty, | |||
| const String& button2Text = String::empty, | |||
| const String& button3Text = String::empty); | |||
| const String& button3Text = String::empty, | |||
| Component* associatedComponent = 0); | |||
| /** Shows an operating-system native dialog box. | |||
| @@ -50785,6 +50835,7 @@ private: | |||
| VoidArray progressBars, customComps, textBlocks, allComps; | |||
| StringArray textboxNames, comboBoxNames; | |||
| Font font; | |||
| Component* associatedComponent; | |||
| void updateLayout (const bool onlyIncreaseSize); | |||
| @@ -51161,7 +51212,7 @@ private: | |||
| void timerCallback(); | |||
| double progress; | |||
| AlertWindow alertWindow; | |||
| AlertWindow* alertWindow; | |||
| String message; | |||
| CriticalSection messageLock; | |||
| const int timeOutMsWhenCancelling; | |||
| @@ -53196,8 +53247,17 @@ public: | |||
| const bool isMouseOverButton, | |||
| const bool isButtonDown); | |||
| /** Draws the contents of a message box. | |||
| /** AlertWindow handling.. | |||
| */ | |||
| virtual AlertWindow* createAlertWindow (const String& title, | |||
| const String& message, | |||
| const String& button1, | |||
| const String& button2, | |||
| const String& button3, | |||
| AlertWindow::AlertIconType iconType, | |||
| int numButtons, | |||
| Component* associatedComponent); | |||
| virtual void drawAlertBox (Graphics& g, | |||
| AlertWindow& alert, | |||
| const Rectangle& textArea, | |||
| @@ -54173,7 +54233,7 @@ private: | |||
| #endif | |||
| #endif | |||
| #endif // __JUCE_APP_INCLUDES_JUCEHEADER__ | |||
| /********* End of inlined file: juce_app_includes.h *********/ | |||
| #endif | |||
| @@ -194,8 +194,12 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app) | |||
| { | |||
| juce_setCurrentThreadName ("Juce Message Thread"); | |||
| // let the app do its setting-up.. | |||
| app->initialise (app->commandLineParameters); | |||
| { | |||
| const MessageManagerLock mml; | |||
| // let the app do its setting-up.. | |||
| app->initialise (app->commandLineParameters); | |||
| } | |||
| // register for broadcast new app messages | |||
| MessageManager::getInstance()->registerBroadcastListener (app); | |||
| @@ -242,6 +246,7 @@ int JUCEApplication::shutdownAppAndClearUp() | |||
| JUCE_TRY | |||
| { | |||
| // give the app a chance to clean up.. | |||
| const MessageManagerLock mml; | |||
| app->shutdown(); | |||
| } | |||
| #if JUCE_CATCH_UNHANDLED_EXCEPTIONS | |||
| @@ -340,9 +345,15 @@ void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI() | |||
| #if JUCE_MAC | |||
| const ScopedAutoReleasePool pool; | |||
| #endif | |||
| DeletedAtShutdown::deleteAll(); | |||
| { | |||
| const MessageManagerLock mml; | |||
| DeletedAtShutdown::deleteAll(); | |||
| LookAndFeel::clearDefaultLookAndFeel(); | |||
| } | |||
| delete MessageManager::getInstance(); | |||
| LookAndFeel::clearDefaultLookAndFeel(); | |||
| shutdownJuce_NonGUI(); | |||
| juceInitialisedGUI = false; | |||
| @@ -126,7 +126,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||
| input->getNextAudioBlock (readInfo); | |||
| if (ratio > 1.0) | |||
| if (ratio > 1.0001) | |||
| { | |||
| // for down-sampling, pre-apply the filter.. | |||
| @@ -172,7 +172,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||
| } | |||
| } | |||
| if (ratio < 1.0) | |||
| if (ratio < 0.9999) | |||
| { | |||
| // for up-sampling, apply the filter after transposing.. | |||
| @@ -730,13 +730,19 @@ OSStatus AudioUnitPluginInstance::getBeatAndTempo (Float64* outCurrentBeat, Floa | |||
| if (ph != 0 && ph->getCurrentPosition (result)) | |||
| { | |||
| *outCurrentBeat = result.ppqPosition; | |||
| *outCurrentTempo = result.bpm; | |||
| if (outCurrentBeat != 0) | |||
| *outCurrentBeat = result.ppqPosition; | |||
| if (outCurrentTempo != 0) | |||
| *outCurrentTempo = result.bpm; | |||
| } | |||
| else | |||
| { | |||
| *outCurrentBeat = 0; | |||
| *outCurrentTempo = 120.0; | |||
| if (outCurrentBeat != 0) | |||
| *outCurrentBeat = 0; | |||
| if (outCurrentTempo != 0) | |||
| *outCurrentTempo = 120.0; | |||
| } | |||
| return noErr; | |||
| @@ -752,18 +758,31 @@ OSStatus AudioUnitPluginInstance::getMusicalTimeLocation (UInt32* outDeltaSample | |||
| if (ph != 0 && ph->getCurrentPosition (result)) | |||
| { | |||
| *outTimeSig_Numerator = result.timeSigNumerator; | |||
| *outTimeSig_Denominator = result.timeSigDenominator; | |||
| if (outTimeSig_Numerator != 0) | |||
| *outTimeSig_Numerator = result.timeSigNumerator; | |||
| if (outTimeSig_Denominator != 0) | |||
| *outTimeSig_Denominator = result.timeSigDenominator; | |||
| if (outDeltaSampleOffsetToNextBeat != 0) | |||
| *outDeltaSampleOffsetToNextBeat = 0; //xxx | |||
| *outDeltaSampleOffsetToNextBeat = 0; //xxx | |||
| *outCurrentMeasureDownBeat = result.ppqPositionOfLastBarStart; //xxx wrong | |||
| if (outCurrentMeasureDownBeat != 0) | |||
| *outCurrentMeasureDownBeat = result.ppqPositionOfLastBarStart; //xxx wrong | |||
| } | |||
| else | |||
| { | |||
| *outDeltaSampleOffsetToNextBeat = 0; | |||
| *outTimeSig_Numerator = 4; | |||
| *outTimeSig_Denominator = 4; | |||
| *outCurrentMeasureDownBeat = 0; | |||
| if (outDeltaSampleOffsetToNextBeat != 0) | |||
| *outDeltaSampleOffsetToNextBeat = 0; | |||
| if (outTimeSig_Numerator != 0) | |||
| *outTimeSig_Numerator = 4; | |||
| if (outTimeSig_Denominator != 0) | |||
| *outTimeSig_Denominator = 4; | |||
| if (outCurrentMeasureDownBeat != 0) | |||
| *outCurrentMeasureDownBeat = 0; | |||
| } | |||
| return noErr; | |||
| @@ -57,7 +57,8 @@ MessageManager::MessageManager() throw() | |||
| quitMessagePosted (false), | |||
| quitMessageReceived (false) | |||
| { | |||
| currentLockingThreadId = messageThreadId = Thread::getCurrentThreadId(); | |||
| currentLockingThreadId = 0; | |||
| messageThreadId = Thread::getCurrentThreadId(); | |||
| } | |||
| MessageManager::~MessageManager() throw() | |||
| @@ -52,7 +52,7 @@ typedef void* (MessageCallbackFunction) (void* userData); | |||
| @see Message, MessageListener, MessageManagerLock, JUCEApplication | |||
| */ | |||
| class JUCE_API MessageManager : private DeletedAtShutdown | |||
| class JUCE_API MessageManager | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| @@ -163,13 +163,14 @@ public: | |||
| void deliverMessage (void*); | |||
| /** @internal */ | |||
| void deliverBroadcastMessage (const String&); | |||
| /** @internal */ | |||
| ~MessageManager() throw(); | |||
| //============================================================================== | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| MessageManager() throw(); | |||
| ~MessageManager() throw(); | |||
| friend class MessageListener; | |||
| friend class ChangeBroadcaster; | |||
| @@ -567,7 +567,9 @@ void TreeView::paint (Graphics& g) | |||
| void TreeView::resized() | |||
| { | |||
| viewport->setBounds (0, 0, getWidth(), getHeight()); | |||
| itemsChanged(); | |||
| handleAsyncUpdate(); | |||
| } | |||
| void TreeView::moveSelectedRow (int delta) | |||
| @@ -1539,9 +1539,14 @@ bool Component::isCurrentlyBlockedByAnotherModalComponent() const throw() | |||
| && ! mc->canModalEventBeSentToComponent (this); | |||
| } | |||
| Component* JUCE_CALLTYPE Component::getCurrentlyModalComponent() throw() | |||
| int JUCE_CALLTYPE Component::getNumCurrentlyModalComponents() throw() | |||
| { | |||
| Component* const c = (Component*) modalComponentStack.getLast(); | |||
| return modalComponentStack.size(); | |||
| } | |||
| Component* JUCE_CALLTYPE Component::getCurrentlyModalComponent (int index) throw() | |||
| { | |||
| Component* const c = (Component*) (modalComponentStack [modalComponentStack.size() - index - 1]); | |||
| return c->isValidComponent() ? c : 0; | |||
| } | |||
| @@ -1763,12 +1763,23 @@ public: | |||
| */ | |||
| bool isCurrentlyModal() const throw(); | |||
| /** Returns the component that is currently modal. | |||
| /** Returns the number of components that are currently in a modal state. | |||
| @see getCurrentlyModalComponent | |||
| */ | |||
| static int JUCE_CALLTYPE getNumCurrentlyModalComponents() throw(); | |||
| /** Returns one of the components that are currently modal. | |||
| @returns the modal component, or null if no components are modal | |||
| @see runModalLoop, isCurrentlyModal | |||
| The index specifies which of the possible modal components to return. The order | |||
| 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 | |||
| */ | |||
| static Component* JUCE_CALLTYPE getCurrentlyModalComponent() throw(); | |||
| static Component* JUCE_CALLTYPE getCurrentlyModalComponent (int index = 0) throw(); | |||
| /** Checks whether there's a modal component somewhere that's stopping this one | |||
| from receiving messages. | |||
| @@ -393,6 +393,7 @@ bool KeyPressMappingSet::keyStateChanged (Component* originatingComponent) | |||
| { | |||
| keyPressEntryIndex = k; | |||
| wasDown = true; | |||
| used = true; | |||
| break; | |||
| } | |||
| } | |||
| @@ -465,78 +465,105 @@ void LookAndFeel::changeToggleButtonWidthToFitText (ToggleButton& button) | |||
| button.getHeight()); | |||
| } | |||
| //============================================================================== | |||
| AlertWindow* LookAndFeel::createAlertWindow (const String& title, | |||
| const String& message, | |||
| const String& button1, | |||
| const String& button2, | |||
| const String& button3, | |||
| AlertWindow::AlertIconType iconType, | |||
| int numButtons, | |||
| Component* associatedComponent) | |||
| { | |||
| AlertWindow* aw = new AlertWindow (title, message, iconType); | |||
| if (numButtons == 1) | |||
| { | |||
| aw->addButton (button1, 0, | |||
| KeyPress (KeyPress::escapeKey, 0, 0), | |||
| KeyPress (KeyPress::returnKey, 0, 0)); | |||
| } | |||
| else | |||
| { | |||
| const KeyPress button1ShortCut (CharacterFunctions::toLowerCase (button1[0]), 0, 0); | |||
| 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); | |||
| aw->addButton (button2, 0, KeyPress (KeyPress::escapeKey, 0, 0), button2ShortCut); | |||
| } | |||
| else | |||
| { | |||
| jassert (numButtons == 3); | |||
| aw->addButton (button1, 1, button1ShortCut); | |||
| aw->addButton (button2, 2, button2ShortCut); | |||
| aw->addButton (button3, 0, KeyPress (KeyPress::escapeKey, 0, 0)); | |||
| } | |||
| } | |||
| return aw; | |||
| } | |||
| void LookAndFeel::drawAlertBox (Graphics& g, | |||
| AlertWindow& alert, | |||
| const Rectangle& textArea, | |||
| TextLayout& textLayout) | |||
| { | |||
| const int iconWidth = 80; | |||
| const Colour background (alert.findColour (AlertWindow::backgroundColourId)); | |||
| g.fillAll (background); | |||
| g.fillAll (alert.findColour (AlertWindow::backgroundColourId)); | |||
| int iconSpaceUsed = 0; | |||
| Justification alignment (Justification::horizontallyCentred); | |||
| const int iconWidth = 80; | |||
| int iconSize = jmin (iconWidth + 50, alert.getHeight() + 20); | |||
| if (alert.containsAnyExtraComponents() || alert.getNumButtons() > 2) | |||
| iconSize = jmin (iconSize, textArea.getHeight() + 50); | |||
| const Rectangle iconRect (iconSize / -10, | |||
| iconSize / -10, | |||
| iconSize, | |||
| iconSize); | |||
| const Rectangle iconRect (iconSize / -10, iconSize / -10, | |||
| iconSize, iconSize); | |||
| if (alert.getAlertType() == AlertWindow::QuestionIcon | |||
| || alert.getAlertType() == AlertWindow::InfoIcon) | |||
| if (alert.getAlertType() != AlertWindow::NoIcon) | |||
| { | |||
| if (alert.getAlertType() == AlertWindow::InfoIcon) | |||
| g.setColour (background.overlaidWith (Colour (0x280000ff))); | |||
| Path icon; | |||
| uint32 colour; | |||
| char character; | |||
| if (alert.getAlertType() == AlertWindow::WarningIcon) | |||
| { | |||
| colour = 0x55ff5555; | |||
| character = '!'; | |||
| 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); | |||
| } | |||
| else | |||
| g.setColour (background.overlaidWith (Colours::gold.darker().withAlpha (0.25f))); | |||
| g.fillEllipse ((float) iconRect.getX(), | |||
| (float) iconRect.getY(), | |||
| (float) iconRect.getWidth(), | |||
| (float) iconRect.getHeight()); | |||
| g.setColour (background); | |||
| g.setFont (iconRect.getHeight() * 0.9f, Font::bold); | |||
| g.drawText ((alert.getAlertType() == AlertWindow::InfoIcon) ? "i" | |||
| : "?", | |||
| iconRect.getX(), | |||
| iconRect.getY(), | |||
| iconRect.getWidth(), | |||
| iconRect.getHeight(), | |||
| Justification::centred, false); | |||
| { | |||
| colour = alert.getAlertType() == AlertWindow::InfoIcon ? 0x605555ff : 0x40b69900; | |||
| character = alert.getAlertType() == AlertWindow::InfoIcon ? 'i' : '?'; | |||
| iconSpaceUsed = iconWidth; | |||
| alignment = Justification::left; | |||
| } | |||
| else if (alert.getAlertType() == AlertWindow::WarningIcon) | |||
| { | |||
| Path p; | |||
| p.addTriangle (iconRect.getX() + iconRect.getWidth() * 0.5f, | |||
| (float) iconRect.getY(), | |||
| (float) iconRect.getRight(), | |||
| (float) iconRect.getBottom(), | |||
| (float) iconRect.getX(), | |||
| (float) iconRect.getBottom()); | |||
| g.setColour (background.overlaidWith (Colour (0x33ff0000))); | |||
| g.fillPath (p.createPathWithRoundedCorners (5.0f)); | |||
| g.setColour (background); | |||
| g.setFont (iconRect.getHeight() * 0.9f, Font::bold); | |||
| g.drawText (T("!"), | |||
| iconRect.getX(), | |||
| iconRect.getY(), | |||
| iconRect.getWidth(), | |||
| iconRect.getHeight() + iconRect.getHeight() / 8, | |||
| Justification::centred, false); | |||
| icon.addEllipse ((float) iconRect.getX(), (float) iconRect.getY(), | |||
| (float) iconRect.getWidth(), (float) iconRect.getHeight()); | |||
| } | |||
| GlyphArrangement ga; | |||
| ga.addFittedText (Font (iconRect.getHeight() * 0.9f, Font::bold), | |||
| String::charToString (character), | |||
| (float) iconRect.getX(), (float) iconRect.getY(), | |||
| (float) iconRect.getWidth(), (float) iconRect.getHeight(), | |||
| Justification::centred, false); | |||
| ga.createPath (icon); | |||
| icon.setUsingNonZeroWinding (false); | |||
| g.setColour (Colour (colour)); | |||
| g.fillPath (icon); | |||
| iconSpaceUsed = iconWidth; | |||
| alignment = Justification::left; | |||
| @@ -545,10 +572,8 @@ void LookAndFeel::drawAlertBox (Graphics& g, | |||
| g.setColour (alert.findColour (AlertWindow::textColourId)); | |||
| textLayout.drawWithin (g, | |||
| textArea.getX() + iconSpaceUsed, | |||
| textArea.getY(), | |||
| textArea.getWidth() - iconSpaceUsed, | |||
| textArea.getHeight(), | |||
| textArea.getX() + iconSpaceUsed, textArea.getY(), | |||
| textArea.getWidth() - iconSpaceUsed, textArea.getHeight(), | |||
| alignment.getFlags() | Justification::top); | |||
| g.setColour (alert.findColour (AlertWindow::outlineColourId)); | |||
| @@ -571,6 +596,7 @@ const Font LookAndFeel::getAlertWindowFont() | |||
| return Font (12.0f); | |||
| } | |||
| //============================================================================== | |||
| void LookAndFeel::drawProgressBar (Graphics& g, ProgressBar& progressBar, | |||
| int width, int height, | |||
| double progress, const String& textToShow) | |||
| @@ -36,6 +36,7 @@ | |||
| #include "../../graphics/effects/juce_DropShadowEffect.h" | |||
| #include "../controls/juce_Slider.h" | |||
| #include "../layout/juce_TabbedComponent.h" | |||
| #include "../windows/juce_AlertWindow.h" | |||
| class ToggleButton; | |||
| class TextButton; | |||
| @@ -175,8 +176,17 @@ public: | |||
| const bool isButtonDown); | |||
| //============================================================================== | |||
| /** Draws the contents of a message box. | |||
| /** AlertWindow handling.. | |||
| */ | |||
| virtual AlertWindow* createAlertWindow (const String& title, | |||
| const String& message, | |||
| const String& button1, | |||
| const String& button2, | |||
| const String& button3, | |||
| AlertWindow::AlertIconType iconType, | |||
| int numButtons, | |||
| Component* associatedComponent); | |||
| virtual void drawAlertBox (Graphics& g, | |||
| AlertWindow& alert, | |||
| const Rectangle& textArea, | |||
| @@ -90,18 +90,17 @@ private: | |||
| //============================================================================== | |||
| AlertWindow::AlertWindow (const String& title, | |||
| const String& message, | |||
| AlertIconType iconType) | |||
| AlertIconType iconType, | |||
| Component* associatedComponent_) | |||
| : TopLevelWindow (title, true), | |||
| alertIconType (iconType) | |||
| alertIconType (iconType), | |||
| associatedComponent (associatedComponent_) | |||
| { | |||
| if (message.isEmpty()) | |||
| text = T(" "); // to force an update if the message is empty | |||
| setMessage (message); | |||
| #if JUCE_MAC | |||
| setAlwaysOnTop (true); | |||
| #else | |||
| for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) | |||
| { | |||
| Component* const c = Desktop::getInstance().getComponent (i); | |||
| @@ -112,7 +111,6 @@ AlertWindow::AlertWindow (const String& title, | |||
| break; | |||
| } | |||
| } | |||
| #endif | |||
| lookAndFeelChanged(); | |||
| @@ -470,7 +468,7 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) | |||
| if (! isVisible()) | |||
| { | |||
| centreAroundComponent (0, w, h); | |||
| centreAroundComponent (associatedComponent, w, h); | |||
| } | |||
| else | |||
| { | |||
| @@ -588,7 +586,7 @@ void AlertWindow::lookAndFeelChanged() | |||
| const int flags = getLookAndFeel().getAlertBoxWindowFlags(); | |||
| setUsingNativeTitleBar ((flags & ComponentPeer::windowHasTitleBar) != 0); | |||
| setDropShadowEnabled ((flags & ComponentPeer::windowHasDropShadow) != 0); | |||
| setDropShadowEnabled (isOpaque() && (flags & ComponentPeer::windowHasDropShadow) != 0); | |||
| } | |||
| int AlertWindow::getDesktopWindowStyleFlags() const | |||
| @@ -602,6 +600,7 @@ struct AlertWindowInfo | |||
| String title, message, button1, button2, button3; | |||
| AlertWindow::AlertIconType iconType; | |||
| int numButtons; | |||
| Component* associatedComponent; | |||
| int run() const | |||
| { | |||
| @@ -612,37 +611,19 @@ struct AlertWindowInfo | |||
| private: | |||
| int show() const | |||
| { | |||
| AlertWindow aw (title, message, iconType); | |||
| jassert (associatedComponent == 0 || associatedComponent->isValidComponent()); // has your comp been deleted? | |||
| if (numButtons == 1) | |||
| { | |||
| aw.addButton (button1, 0, | |||
| KeyPress (KeyPress::escapeKey, 0, 0), | |||
| KeyPress (KeyPress::returnKey, 0, 0)); | |||
| } | |||
| else | |||
| { | |||
| const KeyPress button1ShortCut (CharacterFunctions::toLowerCase (button1[0]), 0, 0); | |||
| 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); | |||
| aw.addButton (button2, 0, KeyPress (KeyPress::escapeKey, 0, 0), button2ShortCut); | |||
| } | |||
| else | |||
| { | |||
| jassert (numButtons == 3); | |||
| aw.addButton (button1, 1, button1ShortCut); | |||
| aw.addButton (button2, 2, button2ShortCut); | |||
| aw.addButton (button3, 0, KeyPress (KeyPress::escapeKey, 0, 0)); | |||
| } | |||
| } | |||
| LookAndFeel& lf = associatedComponent->isValidComponent() ? associatedComponent->getLookAndFeel() | |||
| : LookAndFeel::getDefaultLookAndFeel(); | |||
| Component* const alertBox = lf.createAlertWindow (title, message, button1, button2, button3, | |||
| iconType, numButtons, associatedComponent); | |||
| jassert (alertBox != 0); // you have to return one of these! | |||
| return aw.runModalLoop(); | |||
| const int result = alertBox->runModalLoop(); | |||
| delete alertBox; | |||
| return result; | |||
| } | |||
| static void* showCallback (void* userData) | |||
| @@ -654,7 +635,8 @@ private: | |||
| void AlertWindow::showMessageBox (AlertIconType iconType, | |||
| const String& title, | |||
| const String& message, | |||
| const String& buttonText) | |||
| const String& buttonText, | |||
| Component* associatedComponent) | |||
| { | |||
| AlertWindowInfo info; | |||
| info.title = title; | |||
| @@ -662,6 +644,7 @@ void AlertWindow::showMessageBox (AlertIconType iconType, | |||
| info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText; | |||
| info.iconType = iconType; | |||
| info.numButtons = 1; | |||
| info.associatedComponent = associatedComponent; | |||
| info.run(); | |||
| } | |||
| @@ -670,7 +653,8 @@ bool AlertWindow::showOkCancelBox (AlertIconType iconType, | |||
| const String& title, | |||
| const String& message, | |||
| const String& button1Text, | |||
| const String& button2Text) | |||
| const String& button2Text, | |||
| Component* associatedComponent) | |||
| { | |||
| AlertWindowInfo info; | |||
| info.title = title; | |||
| @@ -679,6 +663,7 @@ bool AlertWindow::showOkCancelBox (AlertIconType iconType, | |||
| info.button2 = button2Text.isEmpty() ? TRANS("cancel") : button2Text; | |||
| info.iconType = iconType; | |||
| info.numButtons = 2; | |||
| info.associatedComponent = associatedComponent; | |||
| return info.run() != 0; | |||
| } | |||
| @@ -688,7 +673,8 @@ int AlertWindow::showYesNoCancelBox (AlertIconType iconType, | |||
| const String& message, | |||
| const String& button1Text, | |||
| const String& button2Text, | |||
| const String& button3Text) | |||
| const String& button3Text, | |||
| Component* associatedComponent) | |||
| { | |||
| AlertWindowInfo info; | |||
| info.title = title; | |||
| @@ -698,6 +684,7 @@ int AlertWindow::showYesNoCancelBox (AlertIconType iconType, | |||
| info.button3 = button3Text.isEmpty() ? TRANS("cancel") : button3Text; | |||
| info.iconType = iconType; | |||
| info.numButtons = 3; | |||
| info.associatedComponent = associatedComponent; | |||
| return info.run(); | |||
| } | |||
| @@ -76,10 +76,14 @@ public: | |||
| @param message a longer, more descriptive message to show underneath the | |||
| headline | |||
| @param iconType the type of icon to display | |||
| @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. | |||
| */ | |||
| AlertWindow (const String& title, | |||
| const String& message, | |||
| AlertIconType iconType); | |||
| AlertIconType iconType, | |||
| Component* associatedComponent = 0); | |||
| /** Destroys the AlertWindow */ | |||
| ~AlertWindow(); | |||
| @@ -234,11 +238,15 @@ public: | |||
| headline | |||
| @param buttonText the text to show in the button - if this string is empty, the | |||
| default string "ok" (or a localised version) will be used. | |||
| @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. | |||
| */ | |||
| static void JUCE_CALLTYPE showMessageBox (AlertIconType iconType, | |||
| const String& title, | |||
| const String& message, | |||
| const String& buttonText = String::empty); | |||
| const String& buttonText = String::empty, | |||
| Component* associatedComponent = 0); | |||
| /** Shows a dialog box with two buttons. | |||
| @@ -255,13 +263,17 @@ public: | |||
| @param button2Text the text to show in the second button - if this string is | |||
| empty, the default string "cancel" (or a localised version of it) | |||
| will be used. | |||
| @returns true if button 1 was clicked, false if it was button 2 | |||
| @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 true if button 1 was clicked, false if it was button 2 | |||
| */ | |||
| static bool JUCE_CALLTYPE showOkCancelBox (AlertIconType iconType, | |||
| const String& title, | |||
| const String& message, | |||
| const String& button1Text = String::empty, | |||
| const String& button2Text = String::empty); | |||
| const String& button2Text = String::empty, | |||
| Component* associatedComponent = 0); | |||
| /** Shows a dialog box with three buttons. | |||
| @@ -279,7 +291,10 @@ public: | |||
| "no" will be used (or a localised version of it) | |||
| @param button3Text the text to show in the first button - if an empty string, then | |||
| "cancel" will be used (or a localised version of it) | |||
| @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') | |||
| @@ -290,7 +305,8 @@ public: | |||
| const String& message, | |||
| const String& button1Text = String::empty, | |||
| const String& button2Text = String::empty, | |||
| const String& button3Text = String::empty); | |||
| const String& button3Text = String::empty, | |||
| Component* associatedComponent = 0); | |||
| //============================================================================== | |||
| /** Shows an operating-system native dialog box. | |||
| @@ -353,6 +369,7 @@ private: | |||
| VoidArray progressBars, customComps, textBlocks, allComps; | |||
| StringArray textboxNames, comboBoxNames; | |||
| Font font; | |||
| Component* associatedComponent; | |||
| void updateLayout (const bool onlyIncreaseSize); | |||
| @@ -35,6 +35,7 @@ BEGIN_JUCE_NAMESPACE | |||
| #include "juce_ThreadWithProgressWindow.h" | |||
| #include "../lookandfeel/juce_LookAndFeel.h" | |||
| #include "../../../../juce_core/text/juce_LocalisedStrings.h" | |||
| @@ -46,19 +47,23 @@ ThreadWithProgressWindow::ThreadWithProgressWindow (const String& title, | |||
| const String& cancelButtonText) | |||
| : Thread ("Juce Progress Window"), | |||
| progress (0.0), | |||
| alertWindow (title, String::empty, AlertWindow::NoIcon), | |||
| timeOutMsWhenCancelling (timeOutMsWhenCancelling_) | |||
| { | |||
| alertWindow = LookAndFeel::getDefaultLookAndFeel() | |||
| .createAlertWindow (title, String::empty, cancelButtonText, String::empty, String::empty, | |||
| AlertWindow::NoIcon, 1, 0); | |||
| if (hasProgressBar) | |||
| alertWindow.addProgressBarComponent (progress); | |||
| alertWindow->addProgressBarComponent (progress); | |||
| if (hasCancelButton) | |||
| alertWindow.addButton (cancelButtonText, 1); | |||
| alertWindow->addButton (cancelButtonText, 1); | |||
| } | |||
| ThreadWithProgressWindow::~ThreadWithProgressWindow() | |||
| { | |||
| stopThread (timeOutMsWhenCancelling); | |||
| delete alertWindow; | |||
| } | |||
| bool ThreadWithProgressWindow::runThread (const int priority) | |||
| @@ -68,14 +73,14 @@ bool ThreadWithProgressWindow::runThread (const int priority) | |||
| { | |||
| const ScopedLock sl (messageLock); | |||
| alertWindow.setMessage (message); | |||
| alertWindow->setMessage (message); | |||
| } | |||
| const bool wasCancelled = alertWindow.runModalLoop() != 0; | |||
| const bool wasCancelled = alertWindow->runModalLoop() != 0; | |||
| stopThread (timeOutMsWhenCancelling); | |||
| alertWindow.setVisible (false); | |||
| alertWindow->setVisible (false); | |||
| return ! wasCancelled; | |||
| } | |||
| @@ -96,13 +101,13 @@ void ThreadWithProgressWindow::timerCallback() | |||
| if (! isThreadRunning()) | |||
| { | |||
| // thread has finished normally.. | |||
| alertWindow.exitModalState (0); | |||
| alertWindow.setVisible (false); | |||
| alertWindow->exitModalState (0); | |||
| alertWindow->setVisible (false); | |||
| } | |||
| else | |||
| { | |||
| const ScopedLock sl (messageLock); | |||
| alertWindow.setMessage (message); | |||
| alertWindow->setMessage (message); | |||
| } | |||
| } | |||
| @@ -155,7 +155,7 @@ private: | |||
| void timerCallback(); | |||
| double progress; | |||
| AlertWindow alertWindow; | |||
| AlertWindow* alertWindow; | |||
| String message; | |||
| CriticalSection messageLock; | |||
| const int timeOutMsWhenCancelling; | |||
| @@ -106,6 +106,30 @@ void Rectangle::setSize (const int w_, | |||
| h = h_; | |||
| } | |||
| void Rectangle::setLeft (const int newLeft) throw() | |||
| { | |||
| w = jmax (0, x + w - newLeft); | |||
| x = newLeft; | |||
| } | |||
| void Rectangle::setTop (const int newTop) throw() | |||
| { | |||
| h = jmax (0, y + h - newTop); | |||
| y = newTop; | |||
| } | |||
| void Rectangle::setRight (const int newRight) throw() | |||
| { | |||
| x = jmin (x, newRight); | |||
| w = newRight - x; | |||
| } | |||
| void Rectangle::setBottom (const int newBottom) throw() | |||
| { | |||
| y = jmin (y, newBottom); | |||
| h = newBottom - y; | |||
| } | |||
| void Rectangle::translate (const int dx, | |||
| const int dy) throw() | |||
| { | |||
| @@ -102,6 +102,28 @@ public: | |||
| void setBounds (const int newX, const int newY, | |||
| const int newWidth, const int newHeight) throw(); | |||
| /** Moves the x position, adjusting the width so that the right-hand edge remains in the same place. | |||
| If the x is moved to be on the right of the current right-hand edge, the width will be set to zero. | |||
| */ | |||
| void setLeft (const int newLeft) throw(); | |||
| /** Moves the y position, adjusting the height so that the bottom edge remains in the same place. | |||
| If the y is moved to be below the current bottom edge, the height will be set to zero. | |||
| */ | |||
| void setTop (const int newTop) throw(); | |||
| /** Adjusts the width so that the right-hand edge of the rectangle has this new value. | |||
| If the new right is below the current X value, the X will be pushed down to match it. | |||
| @see getRight | |||
| */ | |||
| void setRight (const int newRight) throw(); | |||
| /** Adjusts the height so that the bottom edge of the rectangle has this new value. | |||
| If the new bottom is lower than the current Y value, the Y will be pushed down to match it. | |||
| @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(); | |||