| @@ -716,7 +716,7 @@ | |||||
| 84A06BAA09CAD6A3006A43BD /* juce_AudioIODevice.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_AudioIODevice.cpp; sourceTree = "<group>"; }; | 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>"; }; | 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>"; }; | 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; }; | 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; }; | 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; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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 */, | 84A4899708A22E4A00752A2B /* juce_core */, | ||||
| 84A4881C08A22E2400752A2B /* mac specific code */, | 84A4881C08A22E2400752A2B /* mac specific code */, | ||||
| ); | ); | ||||
| lineEnding = 2; | |||||
| name = Source; | name = Source; | ||||
| sourceTree = "<group>"; | sourceTree = "<group>"; | ||||
| }; | }; | ||||
| @@ -265,6 +265,7 @@ void AppleRemoteDevice::handleCallbackInternal() | |||||
| { | { | ||||
| if (strcmp (cookies, buttonPatterns + i) == 0) | if (strcmp (cookies, buttonPatterns + i) == 0) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| buttonPressed ((ButtonType) buttonNum, totalValues > 0); | buttonPressed ((ButtonType) buttonNum, totalValues > 0); | ||||
| break; | break; | ||||
| } | } | ||||
| @@ -44,6 +44,7 @@ public: | |||||
| bool isBold, isItalic; | bool isBold, isItalic; | ||||
| float fontSize, totalSize, ascent; | float fontSize, totalSize, ascent; | ||||
| int refCount; | int refCount; | ||||
| NSMutableDictionary* attributes; | |||||
| FontHelper (const String& name_, | FontHelper (const String& name_, | ||||
| const bool bold_, | const bool bold_, | ||||
| @@ -56,10 +57,23 @@ public: | |||||
| fontSize (size_), | fontSize (size_), | ||||
| refCount (1) | refCount (1) | ||||
| { | { | ||||
| attributes = [[NSMutableDictionary dictionaryWithObject: [NSNumber numberWithInt: 0] | |||||
| forKey: NSLigatureAttributeName] retain]; | |||||
| font = [NSFont fontWithName: juceStringToNS (name_) size: size_]; | font = [NSFont fontWithName: juceStringToNS (name_) size: size_]; | ||||
| if (italic_) | 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_) | if (bold_) | ||||
| font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSBoldFontMask]; | font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSBoldFontMask]; | ||||
| @@ -73,6 +87,7 @@ public: | |||||
| ~FontHelper() | ~FontHelper() | ||||
| { | { | ||||
| [font release]; | [font release]; | ||||
| [attributes release]; | |||||
| } | } | ||||
| bool getPathAndKerning (const juce_wchar char1, | bool getPathAndKerning (const juce_wchar char1, | ||||
| @@ -90,10 +105,9 @@ public: | |||||
| String chars; | String chars; | ||||
| chars << ' ' << char1 << char2; | 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]; | NSLayoutManager* layoutManager = [[[NSLayoutManager alloc] init] autorelease]; | ||||
| NSTextContainer* textContainer = [[[NSTextContainer alloc] init] autorelease]; | NSTextContainer* textContainer = [[[NSTextContainer alloc] init] autorelease]; | ||||
| [layoutManager addTextContainer: textContainer]; | [layoutManager addTextContainer: textContainer]; | ||||
| @@ -212,11 +212,16 @@ public: | |||||
| void updateMenus() | void updateMenus() | ||||
| { | { | ||||
| if (Time::getMillisecondCounter() > lastUpdateTime + 500) | if (Time::getMillisecondCounter() > lastUpdateTime + 500) | ||||
| { | |||||
| const MessageManagerLock mml; | |||||
| menuBarItemsChanged (0); | menuBarItemsChanged (0); | ||||
| } | |||||
| } | } | ||||
| void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const | void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| if (currentModel != 0) | if (currentModel != 0) | ||||
| { | { | ||||
| if (commandManager != 0) | if (commandManager != 0) | ||||
| @@ -61,6 +61,7 @@ public: | |||||
| { | { | ||||
| if (JUCEApplication::getInstance() != 0) | if (JUCEApplication::getInstance() != 0) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| JUCEApplication::getInstance()->systemRequestedQuit(); | JUCEApplication::getInstance()->systemRequestedQuit(); | ||||
| return NSTerminateCancel; | return NSTerminateCancel; | ||||
| } | } | ||||
| @@ -72,6 +73,7 @@ public: | |||||
| { | { | ||||
| if (JUCEApplication::getInstance() != 0) | if (JUCEApplication::getInstance() != 0) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename)); | JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename)); | ||||
| return YES; | return YES; | ||||
| } | } | ||||
| @@ -86,19 +88,31 @@ public: | |||||
| files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i])); | files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i])); | ||||
| if (files.size() > 0 && JUCEApplication::getInstance() != 0) | if (files.size() > 0 && JUCEApplication::getInstance() != 0) | ||||
| { | |||||
| const MessageManagerLock mml; | |||||
| JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" "))); | JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" "))); | ||||
| } | |||||
| } | } | ||||
| virtual void focusChanged() | virtual void focusChanged() | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| juce_HandleProcessFocusChange(); | juce_HandleProcessFocusChange(); | ||||
| } | } | ||||
| virtual void deliverMessage (void* message) | virtual void deliverMessage (void* message) | ||||
| { | { | ||||
| // no need for an mm lock here - deliverMessage locks it | |||||
| MessageManager::getInstance()->deliverMessage (message); | MessageManager::getInstance()->deliverMessage (message); | ||||
| } | } | ||||
| virtual void performCallback (CallbackMessagePayload* pl) | |||||
| { | |||||
| const MessageManagerLock mml; | |||||
| pl->result = (*pl->function) (pl->parameter); | |||||
| pl->hasBeenExecuted = true; | |||||
| } | |||||
| virtual void deleteSelf() | virtual void deleteSelf() | ||||
| { | { | ||||
| delete this; | delete this; | ||||
| @@ -227,10 +241,7 @@ static bool flushingMessages = false; | |||||
| CallbackMessagePayload* pl = (CallbackMessagePayload*) [((NSData*) info) bytes]; | CallbackMessagePayload* pl = (CallbackMessagePayload*) [((NSData*) info) bytes]; | ||||
| if (pl != 0) | if (pl != 0) | ||||
| { | |||||
| pl->result = (*pl->function) (pl->parameter); | |||||
| pl->hasBeenExecuted = true; | |||||
| } | |||||
| redirector->performCallback (pl); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -249,7 +260,6 @@ static JuceAppDelegate* juceAppDelegate = 0; | |||||
| void MessageManager::runDispatchLoop() | void MessageManager::runDispatchLoop() | ||||
| { | { | ||||
| const ScopedAutoReleasePool pool; | const ScopedAutoReleasePool pool; | ||||
| MessageManagerLock mml; | |||||
| // must only be called by the message thread! | // must only be called by the message thread! | ||||
| jassert (isThisTheMessageThread()); | jassert (isThisTheMessageThread()); | ||||
| @@ -100,6 +100,7 @@ END_JUCE_NAMESPACE | |||||
| - (void) setOwner: (NSViewComponentPeer*) owner; | - (void) setOwner: (NSViewComponentPeer*) owner; | ||||
| - (BOOL) canBecomeKeyWindow; | - (BOOL) canBecomeKeyWindow; | ||||
| - (void) becomeKeyWindow; | |||||
| - (BOOL) windowShouldClose: (id) window; | - (BOOL) windowShouldClose: (id) window; | ||||
| - (NSRect) constrainFrameRect: (NSRect) frameRect toScreen: (NSScreen*) screen; | - (NSRect) constrainFrameRect: (NSRect) frameRect toScreen: (NSScreen*) screen; | ||||
| - (NSSize) windowWillResize: (NSWindow*) window toSize: (NSSize) proposedFrameSize; | - (NSSize) windowWillResize: (NSWindow*) window toSize: (NSSize) proposedFrameSize; | ||||
| @@ -428,6 +429,14 @@ END_JUCE_NAMESPACE | |||||
| return owner != 0 && owner->canBecomeKeyWindow(); | return owner != 0 && owner->canBecomeKeyWindow(); | ||||
| } | } | ||||
| - (void) becomeKeyWindow | |||||
| { | |||||
| [super becomeKeyWindow]; | |||||
| if (owner != 0) | |||||
| owner->grabFocus(); | |||||
| } | |||||
| - (BOOL) windowShouldClose: (id) window | - (BOOL) windowShouldClose: (id) window | ||||
| { | { | ||||
| return owner == 0 || owner->windowShouldClose(); | return owner == 0 || owner->windowShouldClose(); | ||||
| @@ -909,6 +918,8 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r) | |||||
| { | { | ||||
| if (constrainer != 0) | if (constrainer != 0) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| NSRect current = [window frame]; | NSRect current = [window frame]; | ||||
| current.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - current.origin.y - current.size.height; | 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 makeKeyWindow]; | ||||
| [window makeFirstResponder: view]; | [window makeFirstResponder: view]; | ||||
| viewFocusGain(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -1133,6 +1146,8 @@ void NSViewComponentPeer::textInputRequired (int /*x*/, int /*y*/) | |||||
| bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) | bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| String unicode (nsStringToJuce ([ev characters])); | String unicode (nsStringToJuce ([ev characters])); | ||||
| String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers])); | String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers])); | ||||
| int keyCode = getKeyCodeFromEvent (ev); | int keyCode = getKeyCodeFromEvent (ev); | ||||
| @@ -1172,6 +1187,7 @@ bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) | |||||
| bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) | bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateKeysDown (ev, true); | updateKeysDown (ev, true); | ||||
| bool used = handleKeyEvent (ev, true); | bool used = handleKeyEvent (ev, true); | ||||
| @@ -1187,12 +1203,14 @@ bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) | |||||
| bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev) | bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateKeysDown (ev, false); | updateKeysDown (ev, false); | ||||
| return handleKeyEvent (ev, false); | return handleKeyEvent (ev, false); | ||||
| } | } | ||||
| void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) | void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| handleModifierKeysChange(); | handleModifierKeysChange(); | ||||
| } | } | ||||
| @@ -1200,6 +1218,7 @@ void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) | |||||
| #if MACOS_10_4_OR_EARLIER | #if MACOS_10_4_OR_EARLIER | ||||
| bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) | bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| if ([ev type] == NSKeyDown) | if ([ev type] == NSKeyDown) | ||||
| return redirectKeyDown (ev); | return redirectKeyDown (ev); | ||||
| else if ([ev type] == NSKeyUp) | else if ([ev type] == NSKeyUp) | ||||
| @@ -1212,6 +1231,7 @@ bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) | |||||
| //============================================================================== | //============================================================================== | ||||
| void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) | void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | ||||
| int x, y; | int x, y; | ||||
| @@ -1222,6 +1242,7 @@ void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) | |||||
| void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) | void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| const int oldMods = currentModifiers; | const int oldMods = currentModifiers; | ||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]); | currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]); | ||||
| @@ -1233,6 +1254,7 @@ void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) | |||||
| void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) | void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | ||||
| int x, y; | int x, y; | ||||
| @@ -1243,6 +1265,7 @@ void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) | |||||
| void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) | void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| int x, y; | int x, y; | ||||
| getMousePos (ev, view, x, y); | getMousePos (ev, view, x, y); | ||||
| @@ -1252,6 +1275,7 @@ void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) | |||||
| void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) | void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| int x, y; | int x, y; | ||||
| getMousePos (ev, view, x, y); | getMousePos (ev, view, x, y); | ||||
| @@ -1261,6 +1285,7 @@ void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) | |||||
| void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) | void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| int x, y; | int x, y; | ||||
| getMousePos (ev, view, x, y); | getMousePos (ev, view, x, y); | ||||
| @@ -1270,6 +1295,7 @@ void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) | |||||
| void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f), | handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f), | ||||
| @@ -1280,6 +1306,8 @@ void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | |||||
| //============================================================================== | //============================================================================== | ||||
| BOOL NSViewComponentPeer::sendDragCallback (int type, id <NSDraggingInfo> sender) | BOOL NSViewComponentPeer::sendDragCallback (int type, id <NSDraggingInfo> sender) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| NSString* bestType | NSString* bestType | ||||
| = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]]; | = [[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) | if (r.size.width < 1.0f || r.size.height < 1.0f) | ||||
| return; | return; | ||||
| const MessageManagerLock mml; | |||||
| const float y = [view frame].size.height - (r.origin.y + r.size.height); | const float y = [view frame].size.height - (r.origin.y + r.size.height); | ||||
| JuceNSImage temp ((int) (r.size.width + 0.5f), | JuceNSImage temp ((int) (r.size.width + 0.5f), | ||||
| @@ -1363,6 +1392,8 @@ void NSViewComponentPeer::drawRect (NSRect r) | |||||
| bool NSViewComponentPeer::canBecomeKeyWindow() | 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. | // If running as a plugin, let the component decide whether it's going to allow the window to get focused. | ||||
| return JUCEApplication::getInstance() != 0 | return JUCEApplication::getInstance() != 0 | ||||
| || (isValidPeer (this) && getComponent()->getWantsKeyboardFocus()); | || (isValidPeer (this) && getComponent()->getWantsKeyboardFocus()); | ||||
| @@ -1370,6 +1401,8 @@ bool NSViewComponentPeer::canBecomeKeyWindow() | |||||
| bool NSViewComponentPeer::windowShouldClose() | bool NSViewComponentPeer::windowShouldClose() | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| if (! isValidPeer (this)) | if (! isValidPeer (this)) | ||||
| return YES; | return YES; | ||||
| @@ -1379,6 +1412,7 @@ bool NSViewComponentPeer::windowShouldClose() | |||||
| void NSViewComponentPeer::redirectMovedOrResized() | void NSViewComponentPeer::redirectMovedOrResized() | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| handleMovedOrResized(); | handleMovedOrResized(); | ||||
| } | } | ||||
| @@ -69,6 +69,8 @@ END_JUCE_NAMESPACE | |||||
| { | { | ||||
| NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"]; | NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"]; | ||||
| const MessageManagerLock mml; | |||||
| if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString]))) | if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString]))) | ||||
| [listener use]; | [listener use]; | ||||
| else | else | ||||
| @@ -101,6 +101,8 @@ bool juce_dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages | |||||
| if (GetMessage (&m, (HWND) 0, 0, 0) > 0) | if (GetMessage (&m, (HWND) 0, 0, 0) > 0) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| if (m.message == specialId | if (m.message == specialId | ||||
| && m.hwnd == juce_messageWindowHandle) | && m.hwnd == juce_messageWindowHandle) | ||||
| { | { | ||||
| @@ -15680,8 +15680,12 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app) | |||||
| { | { | ||||
| juce_setCurrentThreadName ("Juce Message Thread"); | 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 | // register for broadcast new app messages | ||||
| MessageManager::getInstance()->registerBroadcastListener (app); | MessageManager::getInstance()->registerBroadcastListener (app); | ||||
| @@ -15728,6 +15732,7 @@ int JUCEApplication::shutdownAppAndClearUp() | |||||
| JUCE_TRY | JUCE_TRY | ||||
| { | { | ||||
| // give the app a chance to clean up.. | // give the app a chance to clean up.. | ||||
| const MessageManagerLock mml; | |||||
| app->shutdown(); | app->shutdown(); | ||||
| } | } | ||||
| #if JUCE_CATCH_UNHANDLED_EXCEPTIONS | #if JUCE_CATCH_UNHANDLED_EXCEPTIONS | ||||
| @@ -15824,9 +15829,15 @@ void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI() | |||||
| #if JUCE_MAC | #if JUCE_MAC | ||||
| const ScopedAutoReleasePool pool; | const ScopedAutoReleasePool pool; | ||||
| #endif | #endif | ||||
| DeletedAtShutdown::deleteAll(); | |||||
| { | |||||
| const MessageManagerLock mml; | |||||
| DeletedAtShutdown::deleteAll(); | |||||
| LookAndFeel::clearDefaultLookAndFeel(); | |||||
| } | |||||
| delete MessageManager::getInstance(); | |||||
| LookAndFeel::clearDefaultLookAndFeel(); | |||||
| shutdownJuce_NonGUI(); | shutdownJuce_NonGUI(); | ||||
| juceInitialisedGUI = false; | juceInitialisedGUI = false; | ||||
| @@ -21872,7 +21883,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||||
| input->getNextAudioBlock (readInfo); | input->getNextAudioBlock (readInfo); | ||||
| if (ratio > 1.0) | |||||
| if (ratio > 1.0001) | |||||
| { | { | ||||
| // for down-sampling, pre-apply the filter.. | // 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.. | // for up-sampling, apply the filter after transposing.. | ||||
| @@ -28855,13 +28866,19 @@ OSStatus AudioUnitPluginInstance::getBeatAndTempo (Float64* outCurrentBeat, Floa | |||||
| if (ph != 0 && ph->getCurrentPosition (result)) | 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 | else | ||||
| { | { | ||||
| *outCurrentBeat = 0; | |||||
| *outCurrentTempo = 120.0; | |||||
| if (outCurrentBeat != 0) | |||||
| *outCurrentBeat = 0; | |||||
| if (outCurrentTempo != 0) | |||||
| *outCurrentTempo = 120.0; | |||||
| } | } | ||||
| return noErr; | return noErr; | ||||
| @@ -28877,18 +28894,31 @@ OSStatus AudioUnitPluginInstance::getMusicalTimeLocation (UInt32* outDeltaSample | |||||
| if (ph != 0 && ph->getCurrentPosition (result)) | 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 | 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; | return noErr; | ||||
| @@ -36771,7 +36801,8 @@ MessageManager::MessageManager() throw() | |||||
| quitMessagePosted (false), | quitMessagePosted (false), | ||||
| quitMessageReceived (false) | quitMessageReceived (false) | ||||
| { | { | ||||
| currentLockingThreadId = messageThreadId = Thread::getCurrentThreadId(); | |||||
| currentLockingThreadId = 0; | |||||
| messageThreadId = Thread::getCurrentThreadId(); | |||||
| } | } | ||||
| MessageManager::~MessageManager() throw() | MessageManager::~MessageManager() throw() | ||||
| @@ -38879,9 +38910,14 @@ bool Component::isCurrentlyBlockedByAnotherModalComponent() const throw() | |||||
| && ! mc->canModalEventBeSentToComponent (this); | && ! 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; | return c->isValidComponent() ? c : 0; | ||||
| } | } | ||||
| @@ -51957,7 +51993,9 @@ void TreeView::paint (Graphics& g) | |||||
| void TreeView::resized() | void TreeView::resized() | ||||
| { | { | ||||
| viewport->setBounds (0, 0, getWidth(), getHeight()); | viewport->setBounds (0, 0, getWidth(), getHeight()); | ||||
| itemsChanged(); | itemsChanged(); | ||||
| handleAsyncUpdate(); | |||||
| } | } | ||||
| void TreeView::moveSelectedRow (int delta) | void TreeView::moveSelectedRow (int delta) | ||||
| @@ -56283,6 +56321,7 @@ bool KeyPressMappingSet::keyStateChanged (Component* originatingComponent) | |||||
| { | { | ||||
| keyPressEntryIndex = k; | keyPressEntryIndex = k; | ||||
| wasDown = true; | wasDown = true; | ||||
| used = true; | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| @@ -60278,78 +60317,104 @@ void LookAndFeel::changeToggleButtonWidthToFitText (ToggleButton& button) | |||||
| button.getHeight()); | 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, | void LookAndFeel::drawAlertBox (Graphics& g, | ||||
| AlertWindow& alert, | AlertWindow& alert, | ||||
| const Rectangle& textArea, | const Rectangle& textArea, | ||||
| TextLayout& textLayout) | 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; | int iconSpaceUsed = 0; | ||||
| Justification alignment (Justification::horizontallyCentred); | Justification alignment (Justification::horizontallyCentred); | ||||
| const int iconWidth = 80; | |||||
| int iconSize = jmin (iconWidth + 50, alert.getHeight() + 20); | int iconSize = jmin (iconWidth + 50, alert.getHeight() + 20); | ||||
| if (alert.containsAnyExtraComponents() || alert.getNumButtons() > 2) | if (alert.containsAnyExtraComponents() || alert.getNumButtons() > 2) | ||||
| iconSize = jmin (iconSize, textArea.getHeight() + 50); | 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 | 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; | iconSpaceUsed = iconWidth; | ||||
| alignment = Justification::left; | alignment = Justification::left; | ||||
| @@ -60358,10 +60423,8 @@ void LookAndFeel::drawAlertBox (Graphics& g, | |||||
| g.setColour (alert.findColour (AlertWindow::textColourId)); | g.setColour (alert.findColour (AlertWindow::textColourId)); | ||||
| textLayout.drawWithin (g, | 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); | alignment.getFlags() | Justification::top); | ||||
| g.setColour (alert.findColour (AlertWindow::outlineColourId)); | g.setColour (alert.findColour (AlertWindow::outlineColourId)); | ||||
| @@ -71264,18 +71327,17 @@ private: | |||||
| AlertWindow::AlertWindow (const String& title, | AlertWindow::AlertWindow (const String& title, | ||||
| const String& message, | const String& message, | ||||
| AlertIconType iconType) | |||||
| AlertIconType iconType, | |||||
| Component* associatedComponent_) | |||||
| : TopLevelWindow (title, true), | : TopLevelWindow (title, true), | ||||
| alertIconType (iconType) | |||||
| alertIconType (iconType), | |||||
| associatedComponent (associatedComponent_) | |||||
| { | { | ||||
| if (message.isEmpty()) | if (message.isEmpty()) | ||||
| text = T(" "); // to force an update if the message is empty | text = T(" "); // to force an update if the message is empty | ||||
| setMessage (message); | setMessage (message); | ||||
| #if JUCE_MAC | |||||
| setAlwaysOnTop (true); | |||||
| #else | |||||
| for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) | for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) | ||||
| { | { | ||||
| Component* const c = Desktop::getInstance().getComponent (i); | Component* const c = Desktop::getInstance().getComponent (i); | ||||
| @@ -71286,7 +71348,6 @@ AlertWindow::AlertWindow (const String& title, | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| #endif | |||||
| lookAndFeelChanged(); | lookAndFeelChanged(); | ||||
| @@ -71634,7 +71695,7 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) | |||||
| if (! isVisible()) | if (! isVisible()) | ||||
| { | { | ||||
| centreAroundComponent (0, w, h); | |||||
| centreAroundComponent (associatedComponent, w, h); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -71751,7 +71812,7 @@ void AlertWindow::lookAndFeelChanged() | |||||
| const int flags = getLookAndFeel().getAlertBoxWindowFlags(); | const int flags = getLookAndFeel().getAlertBoxWindowFlags(); | ||||
| setUsingNativeTitleBar ((flags & ComponentPeer::windowHasTitleBar) != 0); | setUsingNativeTitleBar ((flags & ComponentPeer::windowHasTitleBar) != 0); | ||||
| setDropShadowEnabled ((flags & ComponentPeer::windowHasDropShadow) != 0); | |||||
| setDropShadowEnabled (isOpaque() && (flags & ComponentPeer::windowHasDropShadow) != 0); | |||||
| } | } | ||||
| int AlertWindow::getDesktopWindowStyleFlags() const | int AlertWindow::getDesktopWindowStyleFlags() const | ||||
| @@ -71764,6 +71825,7 @@ struct AlertWindowInfo | |||||
| String title, message, button1, button2, button3; | String title, message, button1, button2, button3; | ||||
| AlertWindow::AlertIconType iconType; | AlertWindow::AlertIconType iconType; | ||||
| int numButtons; | int numButtons; | ||||
| Component* associatedComponent; | |||||
| int run() const | int run() const | ||||
| { | { | ||||
| @@ -71774,37 +71836,19 @@ struct AlertWindowInfo | |||||
| private: | private: | ||||
| int show() const | 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) | static void* showCallback (void* userData) | ||||
| @@ -71816,7 +71860,8 @@ private: | |||||
| void AlertWindow::showMessageBox (AlertIconType iconType, | void AlertWindow::showMessageBox (AlertIconType iconType, | ||||
| const String& title, | const String& title, | ||||
| const String& message, | const String& message, | ||||
| const String& buttonText) | |||||
| const String& buttonText, | |||||
| Component* associatedComponent) | |||||
| { | { | ||||
| AlertWindowInfo info; | AlertWindowInfo info; | ||||
| info.title = title; | info.title = title; | ||||
| @@ -71824,6 +71869,7 @@ void AlertWindow::showMessageBox (AlertIconType iconType, | |||||
| info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText; | info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText; | ||||
| info.iconType = iconType; | info.iconType = iconType; | ||||
| info.numButtons = 1; | info.numButtons = 1; | ||||
| info.associatedComponent = associatedComponent; | |||||
| info.run(); | info.run(); | ||||
| } | } | ||||
| @@ -71832,7 +71878,8 @@ bool AlertWindow::showOkCancelBox (AlertIconType iconType, | |||||
| const String& title, | const String& title, | ||||
| const String& message, | const String& message, | ||||
| const String& button1Text, | const String& button1Text, | ||||
| const String& button2Text) | |||||
| const String& button2Text, | |||||
| Component* associatedComponent) | |||||
| { | { | ||||
| AlertWindowInfo info; | AlertWindowInfo info; | ||||
| info.title = title; | info.title = title; | ||||
| @@ -71841,6 +71888,7 @@ bool AlertWindow::showOkCancelBox (AlertIconType iconType, | |||||
| info.button2 = button2Text.isEmpty() ? TRANS("cancel") : button2Text; | info.button2 = button2Text.isEmpty() ? TRANS("cancel") : button2Text; | ||||
| info.iconType = iconType; | info.iconType = iconType; | ||||
| info.numButtons = 2; | info.numButtons = 2; | ||||
| info.associatedComponent = associatedComponent; | |||||
| return info.run() != 0; | return info.run() != 0; | ||||
| } | } | ||||
| @@ -71850,7 +71898,8 @@ int AlertWindow::showYesNoCancelBox (AlertIconType iconType, | |||||
| const String& message, | const String& message, | ||||
| const String& button1Text, | const String& button1Text, | ||||
| const String& button2Text, | const String& button2Text, | ||||
| const String& button3Text) | |||||
| const String& button3Text, | |||||
| Component* associatedComponent) | |||||
| { | { | ||||
| AlertWindowInfo info; | AlertWindowInfo info; | ||||
| info.title = title; | info.title = title; | ||||
| @@ -71860,6 +71909,7 @@ int AlertWindow::showYesNoCancelBox (AlertIconType iconType, | |||||
| info.button3 = button3Text.isEmpty() ? TRANS("cancel") : button3Text; | info.button3 = button3Text.isEmpty() ? TRANS("cancel") : button3Text; | ||||
| info.iconType = iconType; | info.iconType = iconType; | ||||
| info.numButtons = 3; | info.numButtons = 3; | ||||
| info.associatedComponent = associatedComponent; | |||||
| return info.run(); | return info.run(); | ||||
| } | } | ||||
| @@ -73672,19 +73722,23 @@ ThreadWithProgressWindow::ThreadWithProgressWindow (const String& title, | |||||
| const String& cancelButtonText) | const String& cancelButtonText) | ||||
| : Thread ("Juce Progress Window"), | : Thread ("Juce Progress Window"), | ||||
| progress (0.0), | progress (0.0), | ||||
| alertWindow (title, String::empty, AlertWindow::NoIcon), | |||||
| timeOutMsWhenCancelling (timeOutMsWhenCancelling_) | timeOutMsWhenCancelling (timeOutMsWhenCancelling_) | ||||
| { | { | ||||
| alertWindow = LookAndFeel::getDefaultLookAndFeel() | |||||
| .createAlertWindow (title, String::empty, cancelButtonText, String::empty, String::empty, | |||||
| AlertWindow::NoIcon, 1, 0); | |||||
| if (hasProgressBar) | if (hasProgressBar) | ||||
| alertWindow.addProgressBarComponent (progress); | |||||
| alertWindow->addProgressBarComponent (progress); | |||||
| if (hasCancelButton) | if (hasCancelButton) | ||||
| alertWindow.addButton (cancelButtonText, 1); | |||||
| alertWindow->addButton (cancelButtonText, 1); | |||||
| } | } | ||||
| ThreadWithProgressWindow::~ThreadWithProgressWindow() | ThreadWithProgressWindow::~ThreadWithProgressWindow() | ||||
| { | { | ||||
| stopThread (timeOutMsWhenCancelling); | stopThread (timeOutMsWhenCancelling); | ||||
| delete alertWindow; | |||||
| } | } | ||||
| bool ThreadWithProgressWindow::runThread (const int priority) | bool ThreadWithProgressWindow::runThread (const int priority) | ||||
| @@ -73694,14 +73748,14 @@ bool ThreadWithProgressWindow::runThread (const int priority) | |||||
| { | { | ||||
| const ScopedLock sl (messageLock); | const ScopedLock sl (messageLock); | ||||
| alertWindow.setMessage (message); | |||||
| alertWindow->setMessage (message); | |||||
| } | } | ||||
| const bool wasCancelled = alertWindow.runModalLoop() != 0; | |||||
| const bool wasCancelled = alertWindow->runModalLoop() != 0; | |||||
| stopThread (timeOutMsWhenCancelling); | stopThread (timeOutMsWhenCancelling); | ||||
| alertWindow.setVisible (false); | |||||
| alertWindow->setVisible (false); | |||||
| return ! wasCancelled; | return ! wasCancelled; | ||||
| } | } | ||||
| @@ -73722,13 +73776,13 @@ void ThreadWithProgressWindow::timerCallback() | |||||
| if (! isThreadRunning()) | if (! isThreadRunning()) | ||||
| { | { | ||||
| // thread has finished normally.. | // thread has finished normally.. | ||||
| alertWindow.exitModalState (0); | |||||
| alertWindow.setVisible (false); | |||||
| alertWindow->exitModalState (0); | |||||
| alertWindow->setVisible (false); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const ScopedLock sl (messageLock); | const ScopedLock sl (messageLock); | ||||
| alertWindow.setMessage (message); | |||||
| alertWindow->setMessage (message); | |||||
| } | } | ||||
| } | } | ||||
| @@ -87373,6 +87427,30 @@ void Rectangle::setSize (const int w_, | |||||
| h = h_; | 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, | void Rectangle::translate (const int dx, | ||||
| const int dy) throw() | const int dy) throw() | ||||
| { | { | ||||
| @@ -242157,6 +242235,8 @@ bool juce_dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages | |||||
| if (GetMessage (&m, (HWND) 0, 0, 0) > 0) | if (GetMessage (&m, (HWND) 0, 0, 0) > 0) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| if (m.message == specialId | if (m.message == specialId | ||||
| && m.hwnd == juce_messageWindowHandle) | && m.hwnd == juce_messageWindowHandle) | ||||
| { | { | ||||
| @@ -265915,7 +265995,6 @@ void juce_updateMultiMonitorInfo (Array <Rectangle>& monitorCoords, const bool c | |||||
| #endif | #endif | ||||
| #endif | #endif | ||||
| /********* End of inlined file: juce_mac_MiscUtilities.mm *********/ | /********* End of inlined file: juce_mac_MiscUtilities.mm *********/ | ||||
| /********* Start of inlined file: juce_mac_Debugging.mm *********/ | /********* Start of inlined file: juce_mac_Debugging.mm *********/ | ||||
| @@ -266034,6 +266113,7 @@ END_JUCE_NAMESPACE | |||||
| - (void) setOwner: (NSViewComponentPeer*) owner; | - (void) setOwner: (NSViewComponentPeer*) owner; | ||||
| - (BOOL) canBecomeKeyWindow; | - (BOOL) canBecomeKeyWindow; | ||||
| - (void) becomeKeyWindow; | |||||
| - (BOOL) windowShouldClose: (id) window; | - (BOOL) windowShouldClose: (id) window; | ||||
| - (NSRect) constrainFrameRect: (NSRect) frameRect toScreen: (NSScreen*) screen; | - (NSRect) constrainFrameRect: (NSRect) frameRect toScreen: (NSScreen*) screen; | ||||
| - (NSSize) windowWillResize: (NSWindow*) window toSize: (NSSize) proposedFrameSize; | - (NSSize) windowWillResize: (NSWindow*) window toSize: (NSSize) proposedFrameSize; | ||||
| @@ -266351,6 +266431,14 @@ END_JUCE_NAMESPACE | |||||
| return owner != 0 && owner->canBecomeKeyWindow(); | return owner != 0 && owner->canBecomeKeyWindow(); | ||||
| } | } | ||||
| - (void) becomeKeyWindow | |||||
| { | |||||
| [super becomeKeyWindow]; | |||||
| if (owner != 0) | |||||
| owner->grabFocus(); | |||||
| } | |||||
| - (BOOL) windowShouldClose: (id) window | - (BOOL) windowShouldClose: (id) window | ||||
| { | { | ||||
| return owner == 0 || owner->windowShouldClose(); | return owner == 0 || owner->windowShouldClose(); | ||||
| @@ -266826,6 +266914,8 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r) | |||||
| { | { | ||||
| if (constrainer != 0) | if (constrainer != 0) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| NSRect current = [window frame]; | NSRect current = [window frame]; | ||||
| current.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - current.origin.y - current.size.height; | 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 makeKeyWindow]; | ||||
| [window makeFirstResponder: view]; | [window makeFirstResponder: view]; | ||||
| viewFocusGain(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -267049,6 +267141,8 @@ void NSViewComponentPeer::textInputRequired (int /*x*/, int /*y*/) | |||||
| bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) | bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| String unicode (nsStringToJuce ([ev characters])); | String unicode (nsStringToJuce ([ev characters])); | ||||
| String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers])); | String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers])); | ||||
| int keyCode = getKeyCodeFromEvent (ev); | int keyCode = getKeyCodeFromEvent (ev); | ||||
| @@ -267088,6 +267182,7 @@ bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) | |||||
| bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) | bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateKeysDown (ev, true); | updateKeysDown (ev, true); | ||||
| bool used = handleKeyEvent (ev, true); | bool used = handleKeyEvent (ev, true); | ||||
| @@ -267103,12 +267198,14 @@ bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) | |||||
| bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev) | bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateKeysDown (ev, false); | updateKeysDown (ev, false); | ||||
| return handleKeyEvent (ev, false); | return handleKeyEvent (ev, false); | ||||
| } | } | ||||
| void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) | void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| handleModifierKeysChange(); | handleModifierKeysChange(); | ||||
| } | } | ||||
| @@ -267116,6 +267213,7 @@ void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) | |||||
| #if MACOS_10_4_OR_EARLIER | #if MACOS_10_4_OR_EARLIER | ||||
| bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) | bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| if ([ev type] == NSKeyDown) | if ([ev type] == NSKeyDown) | ||||
| return redirectKeyDown (ev); | return redirectKeyDown (ev); | ||||
| else if ([ev type] == NSKeyUp) | else if ([ev type] == NSKeyUp) | ||||
| @@ -267127,6 +267225,7 @@ bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) | |||||
| void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) | void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | ||||
| int x, y; | int x, y; | ||||
| @@ -267137,6 +267236,7 @@ void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) | |||||
| void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) | void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| const int oldMods = currentModifiers; | const int oldMods = currentModifiers; | ||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]); | currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]); | ||||
| @@ -267148,6 +267248,7 @@ void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) | |||||
| void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) | void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | ||||
| int x, y; | int x, y; | ||||
| @@ -267158,6 +267259,7 @@ void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) | |||||
| void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) | void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| int x, y; | int x, y; | ||||
| getMousePos (ev, view, x, y); | getMousePos (ev, view, x, y); | ||||
| @@ -267167,6 +267269,7 @@ void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) | |||||
| void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) | void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| int x, y; | int x, y; | ||||
| getMousePos (ev, view, x, y); | getMousePos (ev, view, x, y); | ||||
| @@ -267176,6 +267279,7 @@ void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) | |||||
| void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) | void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| int x, y; | int x, y; | ||||
| getMousePos (ev, view, x, y); | getMousePos (ev, view, x, y); | ||||
| @@ -267185,6 +267289,7 @@ void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) | |||||
| void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f), | handleMouseWheel (roundFloatToInt ([ev deltaX] * 10.0f), | ||||
| @@ -267194,6 +267299,8 @@ void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | |||||
| BOOL NSViewComponentPeer::sendDragCallback (int type, id <NSDraggingInfo> sender) | BOOL NSViewComponentPeer::sendDragCallback (int type, id <NSDraggingInfo> sender) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| NSString* bestType | NSString* bestType | ||||
| = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]]; | = [[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) | if (r.size.width < 1.0f || r.size.height < 1.0f) | ||||
| return; | return; | ||||
| const MessageManagerLock mml; | |||||
| const float y = [view frame].size.height - (r.origin.y + r.size.height); | const float y = [view frame].size.height - (r.origin.y + r.size.height); | ||||
| JuceNSImage temp ((int) (r.size.width + 0.5f), | JuceNSImage temp ((int) (r.size.width + 0.5f), | ||||
| @@ -267277,6 +267385,8 @@ void NSViewComponentPeer::drawRect (NSRect r) | |||||
| bool NSViewComponentPeer::canBecomeKeyWindow() | 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. | // If running as a plugin, let the component decide whether it's going to allow the window to get focused. | ||||
| return JUCEApplication::getInstance() != 0 | return JUCEApplication::getInstance() != 0 | ||||
| || (isValidPeer (this) && getComponent()->getWantsKeyboardFocus()); | || (isValidPeer (this) && getComponent()->getWantsKeyboardFocus()); | ||||
| @@ -267284,6 +267394,8 @@ bool NSViewComponentPeer::canBecomeKeyWindow() | |||||
| bool NSViewComponentPeer::windowShouldClose() | bool NSViewComponentPeer::windowShouldClose() | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| if (! isValidPeer (this)) | if (! isValidPeer (this)) | ||||
| return YES; | return YES; | ||||
| @@ -267293,6 +267405,7 @@ bool NSViewComponentPeer::windowShouldClose() | |||||
| void NSViewComponentPeer::redirectMovedOrResized() | void NSViewComponentPeer::redirectMovedOrResized() | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| handleMovedOrResized(); | handleMovedOrResized(); | ||||
| } | } | ||||
| @@ -267923,6 +268036,7 @@ void AppleRemoteDevice::handleCallbackInternal() | |||||
| { | { | ||||
| if (strcmp (cookies, buttonPatterns + i) == 0) | if (strcmp (cookies, buttonPatterns + i) == 0) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| buttonPressed ((ButtonType) buttonNum, totalValues > 0); | buttonPressed ((ButtonType) buttonNum, totalValues > 0); | ||||
| break; | break; | ||||
| } | } | ||||
| @@ -268149,7 +268263,7 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| NSOpenGLContext* renderContext; | NSOpenGLContext* renderContext; | ||||
| ThreadSafeNSOpenGLView* view; | |||||
| ThreadSafeNSOpenGLView* view; | |||||
| private: | private: | ||||
| OpenGLPixelFormat pixelFormat; | OpenGLPixelFormat pixelFormat; | ||||
| @@ -268401,11 +268515,16 @@ public: | |||||
| void updateMenus() | void updateMenus() | ||||
| { | { | ||||
| if (Time::getMillisecondCounter() > lastUpdateTime + 500) | if (Time::getMillisecondCounter() > lastUpdateTime + 500) | ||||
| { | |||||
| const MessageManagerLock mml; | |||||
| menuBarItemsChanged (0); | menuBarItemsChanged (0); | ||||
| } | |||||
| } | } | ||||
| void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const | void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| if (currentModel != 0) | if (currentModel != 0) | ||||
| { | { | ||||
| if (commandManager != 0) | if (commandManager != 0) | ||||
| @@ -269502,6 +269621,7 @@ public: | |||||
| bool isBold, isItalic; | bool isBold, isItalic; | ||||
| float fontSize, totalSize, ascent; | float fontSize, totalSize, ascent; | ||||
| int refCount; | int refCount; | ||||
| NSMutableDictionary* attributes; | |||||
| FontHelper (const String& name_, | FontHelper (const String& name_, | ||||
| const bool bold_, | const bool bold_, | ||||
| @@ -269514,10 +269634,23 @@ public: | |||||
| fontSize (size_), | fontSize (size_), | ||||
| refCount (1) | refCount (1) | ||||
| { | { | ||||
| attributes = [[NSMutableDictionary dictionaryWithObject: [NSNumber numberWithInt: 0] | |||||
| forKey: NSLigatureAttributeName] retain]; | |||||
| font = [NSFont fontWithName: juceStringToNS (name_) size: size_]; | font = [NSFont fontWithName: juceStringToNS (name_) size: size_]; | ||||
| if (italic_) | 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_) | if (bold_) | ||||
| font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSBoldFontMask]; | font = [[NSFontManager sharedFontManager] convertFont: font toHaveTrait: NSBoldFontMask]; | ||||
| @@ -269531,6 +269664,7 @@ public: | |||||
| ~FontHelper() | ~FontHelper() | ||||
| { | { | ||||
| [font release]; | [font release]; | ||||
| [attributes release]; | |||||
| } | } | ||||
| bool getPathAndKerning (const juce_wchar char1, | bool getPathAndKerning (const juce_wchar char1, | ||||
| @@ -269548,10 +269682,9 @@ public: | |||||
| String chars; | String chars; | ||||
| chars << ' ' << char1 << char2; | 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]; | NSLayoutManager* layoutManager = [[[NSLayoutManager alloc] init] autorelease]; | ||||
| NSTextContainer* textContainer = [[[NSTextContainer alloc] init] autorelease]; | NSTextContainer* textContainer = [[[NSTextContainer alloc] init] autorelease]; | ||||
| [layoutManager addTextContainer: textContainer]; | [layoutManager addTextContainer: textContainer]; | ||||
| @@ -269829,6 +269962,7 @@ public: | |||||
| { | { | ||||
| if (JUCEApplication::getInstance() != 0) | if (JUCEApplication::getInstance() != 0) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| JUCEApplication::getInstance()->systemRequestedQuit(); | JUCEApplication::getInstance()->systemRequestedQuit(); | ||||
| return NSTerminateCancel; | return NSTerminateCancel; | ||||
| } | } | ||||
| @@ -269840,6 +269974,7 @@ public: | |||||
| { | { | ||||
| if (JUCEApplication::getInstance() != 0) | if (JUCEApplication::getInstance() != 0) | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename)); | JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename)); | ||||
| return YES; | return YES; | ||||
| } | } | ||||
| @@ -269854,19 +269989,31 @@ public: | |||||
| files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i])); | files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i])); | ||||
| if (files.size() > 0 && JUCEApplication::getInstance() != 0) | if (files.size() > 0 && JUCEApplication::getInstance() != 0) | ||||
| { | |||||
| const MessageManagerLock mml; | |||||
| JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" "))); | JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" "))); | ||||
| } | |||||
| } | } | ||||
| virtual void focusChanged() | virtual void focusChanged() | ||||
| { | { | ||||
| const MessageManagerLock mml; | |||||
| juce_HandleProcessFocusChange(); | juce_HandleProcessFocusChange(); | ||||
| } | } | ||||
| virtual void deliverMessage (void* message) | virtual void deliverMessage (void* message) | ||||
| { | { | ||||
| // no need for an mm lock here - deliverMessage locks it | |||||
| MessageManager::getInstance()->deliverMessage (message); | MessageManager::getInstance()->deliverMessage (message); | ||||
| } | } | ||||
| virtual void performCallback (CallbackMessagePayload* pl) | |||||
| { | |||||
| const MessageManagerLock mml; | |||||
| pl->result = (*pl->function) (pl->parameter); | |||||
| pl->hasBeenExecuted = true; | |||||
| } | |||||
| virtual void deleteSelf() | virtual void deleteSelf() | ||||
| { | { | ||||
| delete this; | delete this; | ||||
| @@ -269995,10 +270142,7 @@ static bool flushingMessages = false; | |||||
| CallbackMessagePayload* pl = (CallbackMessagePayload*) [((NSData*) info) bytes]; | CallbackMessagePayload* pl = (CallbackMessagePayload*) [((NSData*) info) bytes]; | ||||
| if (pl != 0) | if (pl != 0) | ||||
| { | |||||
| pl->result = (*pl->function) (pl->parameter); | |||||
| pl->hasBeenExecuted = true; | |||||
| } | |||||
| redirector->performCallback (pl); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -270017,7 +270161,6 @@ static JuceAppDelegate* juceAppDelegate = 0; | |||||
| void MessageManager::runDispatchLoop() | void MessageManager::runDispatchLoop() | ||||
| { | { | ||||
| const ScopedAutoReleasePool pool; | const ScopedAutoReleasePool pool; | ||||
| MessageManagerLock mml; | |||||
| // must only be called by the message thread! | // must only be called by the message thread! | ||||
| jassert (isThisTheMessageThread()); | jassert (isThisTheMessageThread()); | ||||
| @@ -270173,6 +270316,8 @@ END_JUCE_NAMESPACE | |||||
| { | { | ||||
| NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"]; | NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"]; | ||||
| const MessageManagerLock mml; | |||||
| if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString]))) | if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString]))) | ||||
| [listener use]; | [listener use]; | ||||
| else | else | ||||
| @@ -15016,8 +15016,8 @@ private: | |||||
| #if ! JUCE_ONLY_BUILD_CORE_LIBRARY | #if ! JUCE_ONLY_BUILD_CORE_LIBRARY | ||||
| /********* Start of inlined file: juce_app_includes.h *********/ | /********* 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__ | #ifndef __JUCE_APPLICATION_JUCEHEADER__ | ||||
| @@ -17747,6 +17747,28 @@ public: | |||||
| void setBounds (const int newX, const int newY, | void setBounds (const int newX, const int newY, | ||||
| const int newWidth, const int newHeight) throw(); | 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. */ | /** Moves the rectangle's position by adding amount to its x and y co-ordinates. */ | ||||
| void translate (const int deltaX, | void translate (const int deltaX, | ||||
| const int deltaY) throw(); | const int deltaY) throw(); | ||||
| @@ -22451,12 +22473,23 @@ public: | |||||
| */ | */ | ||||
| bool isCurrentlyModal() const throw(); | 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 | /** Checks whether there's a modal component somewhere that's stopping this one | ||||
| from receiving messages. | from receiving messages. | ||||
| @@ -37764,7 +37797,7 @@ typedef void* (MessageCallbackFunction) (void* userData); | |||||
| @see Message, MessageListener, MessageManagerLock, JUCEApplication | @see Message, MessageListener, MessageManagerLock, JUCEApplication | ||||
| */ | */ | ||||
| class JUCE_API MessageManager : private DeletedAtShutdown | |||||
| class JUCE_API MessageManager | |||||
| { | { | ||||
| public: | public: | ||||
| @@ -37871,12 +37904,13 @@ public: | |||||
| void deliverMessage (void*); | void deliverMessage (void*); | ||||
| /** @internal */ | /** @internal */ | ||||
| void deliverBroadcastMessage (const String&); | void deliverBroadcastMessage (const String&); | ||||
| /** @internal */ | |||||
| ~MessageManager() throw(); | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| MessageManager() throw(); | MessageManager() throw(); | ||||
| ~MessageManager() throw(); | |||||
| friend class MessageListener; | friend class MessageListener; | ||||
| friend class ChangeBroadcaster; | friend class ChangeBroadcaster; | ||||
| @@ -50522,10 +50556,14 @@ public: | |||||
| @param message a longer, more descriptive message to show underneath the | @param message a longer, more descriptive message to show underneath the | ||||
| headline | headline | ||||
| @param iconType the type of icon to display | @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, | AlertWindow (const String& title, | ||||
| const String& message, | const String& message, | ||||
| AlertIconType iconType); | |||||
| AlertIconType iconType, | |||||
| Component* associatedComponent = 0); | |||||
| /** Destroys the AlertWindow */ | /** Destroys the AlertWindow */ | ||||
| ~AlertWindow(); | ~AlertWindow(); | ||||
| @@ -50670,11 +50708,15 @@ public: | |||||
| headline | headline | ||||
| @param buttonText the text to show in the button - if this string is empty, the | @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. | 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, | static void JUCE_CALLTYPE showMessageBox (AlertIconType iconType, | ||||
| const String& title, | const String& title, | ||||
| const String& message, | const String& message, | ||||
| const String& buttonText = String::empty); | |||||
| const String& buttonText = String::empty, | |||||
| Component* associatedComponent = 0); | |||||
| /** Shows a dialog box with two buttons. | /** 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 | @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) | empty, the default string "cancel" (or a localised version of it) | ||||
| will be used. | 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, | static bool JUCE_CALLTYPE showOkCancelBox (AlertIconType iconType, | ||||
| const String& title, | const String& title, | ||||
| const String& message, | const String& message, | ||||
| const String& button1Text = String::empty, | 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. | /** Shows a dialog box with three buttons. | ||||
| @@ -50715,6 +50761,9 @@ public: | |||||
| "no" will be used (or a localised version of it) | "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 | @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) | "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: | @returns one of the following values: | ||||
| - 0 if the third button was pressed (normally used for 'cancel') | - 0 if the third button was pressed (normally used for 'cancel') | ||||
| @@ -50726,7 +50775,8 @@ public: | |||||
| const String& message, | const String& message, | ||||
| const String& button1Text = String::empty, | const String& button1Text = String::empty, | ||||
| const String& button2Text = 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. | /** Shows an operating-system native dialog box. | ||||
| @@ -50785,6 +50835,7 @@ private: | |||||
| VoidArray progressBars, customComps, textBlocks, allComps; | VoidArray progressBars, customComps, textBlocks, allComps; | ||||
| StringArray textboxNames, comboBoxNames; | StringArray textboxNames, comboBoxNames; | ||||
| Font font; | Font font; | ||||
| Component* associatedComponent; | |||||
| void updateLayout (const bool onlyIncreaseSize); | void updateLayout (const bool onlyIncreaseSize); | ||||
| @@ -51161,7 +51212,7 @@ private: | |||||
| void timerCallback(); | void timerCallback(); | ||||
| double progress; | double progress; | ||||
| AlertWindow alertWindow; | |||||
| AlertWindow* alertWindow; | |||||
| String message; | String message; | ||||
| CriticalSection messageLock; | CriticalSection messageLock; | ||||
| const int timeOutMsWhenCancelling; | const int timeOutMsWhenCancelling; | ||||
| @@ -53196,8 +53247,17 @@ public: | |||||
| const bool isMouseOverButton, | const bool isMouseOverButton, | ||||
| const bool isButtonDown); | 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, | virtual void drawAlertBox (Graphics& g, | ||||
| AlertWindow& alert, | AlertWindow& alert, | ||||
| const Rectangle& textArea, | const Rectangle& textArea, | ||||
| @@ -54173,7 +54233,7 @@ private: | |||||
| #endif | #endif | ||||
| #endif | |||||
| #endif // __JUCE_APP_INCLUDES_JUCEHEADER__ | |||||
| /********* End of inlined file: juce_app_includes.h *********/ | /********* End of inlined file: juce_app_includes.h *********/ | ||||
| #endif | #endif | ||||
| @@ -194,8 +194,12 @@ int JUCEApplication::main (String& commandLine, JUCEApplication* const app) | |||||
| { | { | ||||
| juce_setCurrentThreadName ("Juce Message Thread"); | 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 | // register for broadcast new app messages | ||||
| MessageManager::getInstance()->registerBroadcastListener (app); | MessageManager::getInstance()->registerBroadcastListener (app); | ||||
| @@ -242,6 +246,7 @@ int JUCEApplication::shutdownAppAndClearUp() | |||||
| JUCE_TRY | JUCE_TRY | ||||
| { | { | ||||
| // give the app a chance to clean up.. | // give the app a chance to clean up.. | ||||
| const MessageManagerLock mml; | |||||
| app->shutdown(); | app->shutdown(); | ||||
| } | } | ||||
| #if JUCE_CATCH_UNHANDLED_EXCEPTIONS | #if JUCE_CATCH_UNHANDLED_EXCEPTIONS | ||||
| @@ -340,9 +345,15 @@ void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI() | |||||
| #if JUCE_MAC | #if JUCE_MAC | ||||
| const ScopedAutoReleasePool pool; | const ScopedAutoReleasePool pool; | ||||
| #endif | #endif | ||||
| DeletedAtShutdown::deleteAll(); | |||||
| { | |||||
| const MessageManagerLock mml; | |||||
| DeletedAtShutdown::deleteAll(); | |||||
| LookAndFeel::clearDefaultLookAndFeel(); | |||||
| } | |||||
| delete MessageManager::getInstance(); | |||||
| LookAndFeel::clearDefaultLookAndFeel(); | |||||
| shutdownJuce_NonGUI(); | shutdownJuce_NonGUI(); | ||||
| juceInitialisedGUI = false; | juceInitialisedGUI = false; | ||||
| @@ -126,7 +126,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||||
| input->getNextAudioBlock (readInfo); | input->getNextAudioBlock (readInfo); | ||||
| if (ratio > 1.0) | |||||
| if (ratio > 1.0001) | |||||
| { | { | ||||
| // for down-sampling, pre-apply the filter.. | // 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.. | // for up-sampling, apply the filter after transposing.. | ||||
| @@ -730,13 +730,19 @@ OSStatus AudioUnitPluginInstance::getBeatAndTempo (Float64* outCurrentBeat, Floa | |||||
| if (ph != 0 && ph->getCurrentPosition (result)) | 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 | else | ||||
| { | { | ||||
| *outCurrentBeat = 0; | |||||
| *outCurrentTempo = 120.0; | |||||
| if (outCurrentBeat != 0) | |||||
| *outCurrentBeat = 0; | |||||
| if (outCurrentTempo != 0) | |||||
| *outCurrentTempo = 120.0; | |||||
| } | } | ||||
| return noErr; | return noErr; | ||||
| @@ -752,18 +758,31 @@ OSStatus AudioUnitPluginInstance::getMusicalTimeLocation (UInt32* outDeltaSample | |||||
| if (ph != 0 && ph->getCurrentPosition (result)) | 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 | 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; | return noErr; | ||||
| @@ -57,7 +57,8 @@ MessageManager::MessageManager() throw() | |||||
| quitMessagePosted (false), | quitMessagePosted (false), | ||||
| quitMessageReceived (false) | quitMessageReceived (false) | ||||
| { | { | ||||
| currentLockingThreadId = messageThreadId = Thread::getCurrentThreadId(); | |||||
| currentLockingThreadId = 0; | |||||
| messageThreadId = Thread::getCurrentThreadId(); | |||||
| } | } | ||||
| MessageManager::~MessageManager() throw() | MessageManager::~MessageManager() throw() | ||||
| @@ -52,7 +52,7 @@ typedef void* (MessageCallbackFunction) (void* userData); | |||||
| @see Message, MessageListener, MessageManagerLock, JUCEApplication | @see Message, MessageListener, MessageManagerLock, JUCEApplication | ||||
| */ | */ | ||||
| class JUCE_API MessageManager : private DeletedAtShutdown | |||||
| class JUCE_API MessageManager | |||||
| { | { | ||||
| public: | public: | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -163,13 +163,14 @@ public: | |||||
| void deliverMessage (void*); | void deliverMessage (void*); | ||||
| /** @internal */ | /** @internal */ | ||||
| void deliverBroadcastMessage (const String&); | void deliverBroadcastMessage (const String&); | ||||
| /** @internal */ | |||||
| ~MessageManager() throw(); | |||||
| //============================================================================== | //============================================================================== | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| MessageManager() throw(); | MessageManager() throw(); | ||||
| ~MessageManager() throw(); | |||||
| friend class MessageListener; | friend class MessageListener; | ||||
| friend class ChangeBroadcaster; | friend class ChangeBroadcaster; | ||||
| @@ -567,7 +567,9 @@ void TreeView::paint (Graphics& g) | |||||
| void TreeView::resized() | void TreeView::resized() | ||||
| { | { | ||||
| viewport->setBounds (0, 0, getWidth(), getHeight()); | viewport->setBounds (0, 0, getWidth(), getHeight()); | ||||
| itemsChanged(); | itemsChanged(); | ||||
| handleAsyncUpdate(); | |||||
| } | } | ||||
| void TreeView::moveSelectedRow (int delta) | void TreeView::moveSelectedRow (int delta) | ||||
| @@ -1539,9 +1539,14 @@ bool Component::isCurrentlyBlockedByAnotherModalComponent() const throw() | |||||
| && ! mc->canModalEventBeSentToComponent (this); | && ! 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; | return c->isValidComponent() ? c : 0; | ||||
| } | } | ||||
| @@ -1763,12 +1763,23 @@ public: | |||||
| */ | */ | ||||
| bool isCurrentlyModal() const throw(); | 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 | /** Checks whether there's a modal component somewhere that's stopping this one | ||||
| from receiving messages. | from receiving messages. | ||||
| @@ -393,6 +393,7 @@ bool KeyPressMappingSet::keyStateChanged (Component* originatingComponent) | |||||
| { | { | ||||
| keyPressEntryIndex = k; | keyPressEntryIndex = k; | ||||
| wasDown = true; | wasDown = true; | ||||
| used = true; | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| @@ -465,78 +465,105 @@ void LookAndFeel::changeToggleButtonWidthToFitText (ToggleButton& button) | |||||
| button.getHeight()); | 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, | void LookAndFeel::drawAlertBox (Graphics& g, | ||||
| AlertWindow& alert, | AlertWindow& alert, | ||||
| const Rectangle& textArea, | const Rectangle& textArea, | ||||
| TextLayout& textLayout) | 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; | int iconSpaceUsed = 0; | ||||
| Justification alignment (Justification::horizontallyCentred); | Justification alignment (Justification::horizontallyCentred); | ||||
| const int iconWidth = 80; | |||||
| int iconSize = jmin (iconWidth + 50, alert.getHeight() + 20); | int iconSize = jmin (iconWidth + 50, alert.getHeight() + 20); | ||||
| if (alert.containsAnyExtraComponents() || alert.getNumButtons() > 2) | if (alert.containsAnyExtraComponents() || alert.getNumButtons() > 2) | ||||
| iconSize = jmin (iconSize, textArea.getHeight() + 50); | 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 | 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; | iconSpaceUsed = iconWidth; | ||||
| alignment = Justification::left; | alignment = Justification::left; | ||||
| @@ -545,10 +572,8 @@ void LookAndFeel::drawAlertBox (Graphics& g, | |||||
| g.setColour (alert.findColour (AlertWindow::textColourId)); | g.setColour (alert.findColour (AlertWindow::textColourId)); | ||||
| textLayout.drawWithin (g, | 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); | alignment.getFlags() | Justification::top); | ||||
| g.setColour (alert.findColour (AlertWindow::outlineColourId)); | g.setColour (alert.findColour (AlertWindow::outlineColourId)); | ||||
| @@ -571,6 +596,7 @@ const Font LookAndFeel::getAlertWindowFont() | |||||
| return Font (12.0f); | return Font (12.0f); | ||||
| } | } | ||||
| //============================================================================== | |||||
| void LookAndFeel::drawProgressBar (Graphics& g, ProgressBar& progressBar, | void LookAndFeel::drawProgressBar (Graphics& g, ProgressBar& progressBar, | ||||
| int width, int height, | int width, int height, | ||||
| double progress, const String& textToShow) | double progress, const String& textToShow) | ||||
| @@ -36,6 +36,7 @@ | |||||
| #include "../../graphics/effects/juce_DropShadowEffect.h" | #include "../../graphics/effects/juce_DropShadowEffect.h" | ||||
| #include "../controls/juce_Slider.h" | #include "../controls/juce_Slider.h" | ||||
| #include "../layout/juce_TabbedComponent.h" | #include "../layout/juce_TabbedComponent.h" | ||||
| #include "../windows/juce_AlertWindow.h" | |||||
| class ToggleButton; | class ToggleButton; | ||||
| class TextButton; | class TextButton; | ||||
| @@ -175,8 +176,17 @@ public: | |||||
| const bool isButtonDown); | 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, | virtual void drawAlertBox (Graphics& g, | ||||
| AlertWindow& alert, | AlertWindow& alert, | ||||
| const Rectangle& textArea, | const Rectangle& textArea, | ||||
| @@ -90,18 +90,17 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| AlertWindow::AlertWindow (const String& title, | AlertWindow::AlertWindow (const String& title, | ||||
| const String& message, | const String& message, | ||||
| AlertIconType iconType) | |||||
| AlertIconType iconType, | |||||
| Component* associatedComponent_) | |||||
| : TopLevelWindow (title, true), | : TopLevelWindow (title, true), | ||||
| alertIconType (iconType) | |||||
| alertIconType (iconType), | |||||
| associatedComponent (associatedComponent_) | |||||
| { | { | ||||
| if (message.isEmpty()) | if (message.isEmpty()) | ||||
| text = T(" "); // to force an update if the message is empty | text = T(" "); // to force an update if the message is empty | ||||
| setMessage (message); | setMessage (message); | ||||
| #if JUCE_MAC | |||||
| setAlwaysOnTop (true); | |||||
| #else | |||||
| for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) | for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) | ||||
| { | { | ||||
| Component* const c = Desktop::getInstance().getComponent (i); | Component* const c = Desktop::getInstance().getComponent (i); | ||||
| @@ -112,7 +111,6 @@ AlertWindow::AlertWindow (const String& title, | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| #endif | |||||
| lookAndFeelChanged(); | lookAndFeelChanged(); | ||||
| @@ -470,7 +468,7 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize) | |||||
| if (! isVisible()) | if (! isVisible()) | ||||
| { | { | ||||
| centreAroundComponent (0, w, h); | |||||
| centreAroundComponent (associatedComponent, w, h); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -588,7 +586,7 @@ void AlertWindow::lookAndFeelChanged() | |||||
| const int flags = getLookAndFeel().getAlertBoxWindowFlags(); | const int flags = getLookAndFeel().getAlertBoxWindowFlags(); | ||||
| setUsingNativeTitleBar ((flags & ComponentPeer::windowHasTitleBar) != 0); | setUsingNativeTitleBar ((flags & ComponentPeer::windowHasTitleBar) != 0); | ||||
| setDropShadowEnabled ((flags & ComponentPeer::windowHasDropShadow) != 0); | |||||
| setDropShadowEnabled (isOpaque() && (flags & ComponentPeer::windowHasDropShadow) != 0); | |||||
| } | } | ||||
| int AlertWindow::getDesktopWindowStyleFlags() const | int AlertWindow::getDesktopWindowStyleFlags() const | ||||
| @@ -602,6 +600,7 @@ struct AlertWindowInfo | |||||
| String title, message, button1, button2, button3; | String title, message, button1, button2, button3; | ||||
| AlertWindow::AlertIconType iconType; | AlertWindow::AlertIconType iconType; | ||||
| int numButtons; | int numButtons; | ||||
| Component* associatedComponent; | |||||
| int run() const | int run() const | ||||
| { | { | ||||
| @@ -612,37 +611,19 @@ struct AlertWindowInfo | |||||
| private: | private: | ||||
| int show() const | 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) | static void* showCallback (void* userData) | ||||
| @@ -654,7 +635,8 @@ private: | |||||
| void AlertWindow::showMessageBox (AlertIconType iconType, | void AlertWindow::showMessageBox (AlertIconType iconType, | ||||
| const String& title, | const String& title, | ||||
| const String& message, | const String& message, | ||||
| const String& buttonText) | |||||
| const String& buttonText, | |||||
| Component* associatedComponent) | |||||
| { | { | ||||
| AlertWindowInfo info; | AlertWindowInfo info; | ||||
| info.title = title; | info.title = title; | ||||
| @@ -662,6 +644,7 @@ void AlertWindow::showMessageBox (AlertIconType iconType, | |||||
| info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText; | info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText; | ||||
| info.iconType = iconType; | info.iconType = iconType; | ||||
| info.numButtons = 1; | info.numButtons = 1; | ||||
| info.associatedComponent = associatedComponent; | |||||
| info.run(); | info.run(); | ||||
| } | } | ||||
| @@ -670,7 +653,8 @@ bool AlertWindow::showOkCancelBox (AlertIconType iconType, | |||||
| const String& title, | const String& title, | ||||
| const String& message, | const String& message, | ||||
| const String& button1Text, | const String& button1Text, | ||||
| const String& button2Text) | |||||
| const String& button2Text, | |||||
| Component* associatedComponent) | |||||
| { | { | ||||
| AlertWindowInfo info; | AlertWindowInfo info; | ||||
| info.title = title; | info.title = title; | ||||
| @@ -679,6 +663,7 @@ bool AlertWindow::showOkCancelBox (AlertIconType iconType, | |||||
| info.button2 = button2Text.isEmpty() ? TRANS("cancel") : button2Text; | info.button2 = button2Text.isEmpty() ? TRANS("cancel") : button2Text; | ||||
| info.iconType = iconType; | info.iconType = iconType; | ||||
| info.numButtons = 2; | info.numButtons = 2; | ||||
| info.associatedComponent = associatedComponent; | |||||
| return info.run() != 0; | return info.run() != 0; | ||||
| } | } | ||||
| @@ -688,7 +673,8 @@ int AlertWindow::showYesNoCancelBox (AlertIconType iconType, | |||||
| const String& message, | const String& message, | ||||
| const String& button1Text, | const String& button1Text, | ||||
| const String& button2Text, | const String& button2Text, | ||||
| const String& button3Text) | |||||
| const String& button3Text, | |||||
| Component* associatedComponent) | |||||
| { | { | ||||
| AlertWindowInfo info; | AlertWindowInfo info; | ||||
| info.title = title; | info.title = title; | ||||
| @@ -698,6 +684,7 @@ int AlertWindow::showYesNoCancelBox (AlertIconType iconType, | |||||
| info.button3 = button3Text.isEmpty() ? TRANS("cancel") : button3Text; | info.button3 = button3Text.isEmpty() ? TRANS("cancel") : button3Text; | ||||
| info.iconType = iconType; | info.iconType = iconType; | ||||
| info.numButtons = 3; | info.numButtons = 3; | ||||
| info.associatedComponent = associatedComponent; | |||||
| return info.run(); | return info.run(); | ||||
| } | } | ||||
| @@ -76,10 +76,14 @@ public: | |||||
| @param message a longer, more descriptive message to show underneath the | @param message a longer, more descriptive message to show underneath the | ||||
| headline | headline | ||||
| @param iconType the type of icon to display | @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, | AlertWindow (const String& title, | ||||
| const String& message, | const String& message, | ||||
| AlertIconType iconType); | |||||
| AlertIconType iconType, | |||||
| Component* associatedComponent = 0); | |||||
| /** Destroys the AlertWindow */ | /** Destroys the AlertWindow */ | ||||
| ~AlertWindow(); | ~AlertWindow(); | ||||
| @@ -234,11 +238,15 @@ public: | |||||
| headline | headline | ||||
| @param buttonText the text to show in the button - if this string is empty, the | @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. | 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, | static void JUCE_CALLTYPE showMessageBox (AlertIconType iconType, | ||||
| const String& title, | const String& title, | ||||
| const String& message, | const String& message, | ||||
| const String& buttonText = String::empty); | |||||
| const String& buttonText = String::empty, | |||||
| Component* associatedComponent = 0); | |||||
| /** Shows a dialog box with two buttons. | /** 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 | @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) | empty, the default string "cancel" (or a localised version of it) | ||||
| will be used. | 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, | static bool JUCE_CALLTYPE showOkCancelBox (AlertIconType iconType, | ||||
| const String& title, | const String& title, | ||||
| const String& message, | const String& message, | ||||
| const String& button1Text = String::empty, | 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. | /** Shows a dialog box with three buttons. | ||||
| @@ -279,7 +291,10 @@ public: | |||||
| "no" will be used (or a localised version of it) | "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 | @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) | "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: | @returns one of the following values: | ||||
| - 0 if the third button was pressed (normally used for 'cancel') | - 0 if the third button was pressed (normally used for 'cancel') | ||||
| - 1 if the first button was pressed (normally used for 'yes') | - 1 if the first button was pressed (normally used for 'yes') | ||||
| @@ -290,7 +305,8 @@ public: | |||||
| const String& message, | const String& message, | ||||
| const String& button1Text = String::empty, | const String& button1Text = String::empty, | ||||
| const String& button2Text = 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. | /** Shows an operating-system native dialog box. | ||||
| @@ -353,6 +369,7 @@ private: | |||||
| VoidArray progressBars, customComps, textBlocks, allComps; | VoidArray progressBars, customComps, textBlocks, allComps; | ||||
| StringArray textboxNames, comboBoxNames; | StringArray textboxNames, comboBoxNames; | ||||
| Font font; | Font font; | ||||
| Component* associatedComponent; | |||||
| void updateLayout (const bool onlyIncreaseSize); | void updateLayout (const bool onlyIncreaseSize); | ||||
| @@ -35,6 +35,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_ThreadWithProgressWindow.h" | #include "juce_ThreadWithProgressWindow.h" | ||||
| #include "../lookandfeel/juce_LookAndFeel.h" | |||||
| #include "../../../../juce_core/text/juce_LocalisedStrings.h" | #include "../../../../juce_core/text/juce_LocalisedStrings.h" | ||||
| @@ -46,19 +47,23 @@ ThreadWithProgressWindow::ThreadWithProgressWindow (const String& title, | |||||
| const String& cancelButtonText) | const String& cancelButtonText) | ||||
| : Thread ("Juce Progress Window"), | : Thread ("Juce Progress Window"), | ||||
| progress (0.0), | progress (0.0), | ||||
| alertWindow (title, String::empty, AlertWindow::NoIcon), | |||||
| timeOutMsWhenCancelling (timeOutMsWhenCancelling_) | timeOutMsWhenCancelling (timeOutMsWhenCancelling_) | ||||
| { | { | ||||
| alertWindow = LookAndFeel::getDefaultLookAndFeel() | |||||
| .createAlertWindow (title, String::empty, cancelButtonText, String::empty, String::empty, | |||||
| AlertWindow::NoIcon, 1, 0); | |||||
| if (hasProgressBar) | if (hasProgressBar) | ||||
| alertWindow.addProgressBarComponent (progress); | |||||
| alertWindow->addProgressBarComponent (progress); | |||||
| if (hasCancelButton) | if (hasCancelButton) | ||||
| alertWindow.addButton (cancelButtonText, 1); | |||||
| alertWindow->addButton (cancelButtonText, 1); | |||||
| } | } | ||||
| ThreadWithProgressWindow::~ThreadWithProgressWindow() | ThreadWithProgressWindow::~ThreadWithProgressWindow() | ||||
| { | { | ||||
| stopThread (timeOutMsWhenCancelling); | stopThread (timeOutMsWhenCancelling); | ||||
| delete alertWindow; | |||||
| } | } | ||||
| bool ThreadWithProgressWindow::runThread (const int priority) | bool ThreadWithProgressWindow::runThread (const int priority) | ||||
| @@ -68,14 +73,14 @@ bool ThreadWithProgressWindow::runThread (const int priority) | |||||
| { | { | ||||
| const ScopedLock sl (messageLock); | const ScopedLock sl (messageLock); | ||||
| alertWindow.setMessage (message); | |||||
| alertWindow->setMessage (message); | |||||
| } | } | ||||
| const bool wasCancelled = alertWindow.runModalLoop() != 0; | |||||
| const bool wasCancelled = alertWindow->runModalLoop() != 0; | |||||
| stopThread (timeOutMsWhenCancelling); | stopThread (timeOutMsWhenCancelling); | ||||
| alertWindow.setVisible (false); | |||||
| alertWindow->setVisible (false); | |||||
| return ! wasCancelled; | return ! wasCancelled; | ||||
| } | } | ||||
| @@ -96,13 +101,13 @@ void ThreadWithProgressWindow::timerCallback() | |||||
| if (! isThreadRunning()) | if (! isThreadRunning()) | ||||
| { | { | ||||
| // thread has finished normally.. | // thread has finished normally.. | ||||
| alertWindow.exitModalState (0); | |||||
| alertWindow.setVisible (false); | |||||
| alertWindow->exitModalState (0); | |||||
| alertWindow->setVisible (false); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const ScopedLock sl (messageLock); | const ScopedLock sl (messageLock); | ||||
| alertWindow.setMessage (message); | |||||
| alertWindow->setMessage (message); | |||||
| } | } | ||||
| } | } | ||||
| @@ -155,7 +155,7 @@ private: | |||||
| void timerCallback(); | void timerCallback(); | ||||
| double progress; | double progress; | ||||
| AlertWindow alertWindow; | |||||
| AlertWindow* alertWindow; | |||||
| String message; | String message; | ||||
| CriticalSection messageLock; | CriticalSection messageLock; | ||||
| const int timeOutMsWhenCancelling; | const int timeOutMsWhenCancelling; | ||||
| @@ -106,6 +106,30 @@ void Rectangle::setSize (const int w_, | |||||
| h = h_; | 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, | void Rectangle::translate (const int dx, | ||||
| const int dy) throw() | const int dy) throw() | ||||
| { | { | ||||
| @@ -102,6 +102,28 @@ public: | |||||
| void setBounds (const int newX, const int newY, | void setBounds (const int newX, const int newY, | ||||
| const int newWidth, const int newHeight) throw(); | 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. */ | /** Moves the rectangle's position by adding amount to its x and y co-ordinates. */ | ||||
| void translate (const int deltaX, | void translate (const int deltaX, | ||||
| const int deltaY) throw(); | const int deltaY) throw(); | ||||