diff --git a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj index 298a7f0ee0..f55ee1b46b 100644 --- a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj +++ b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj @@ -281,8 +281,8 @@ C9FB7884928BF0D6140AF881 = { isa = PBXBuildFile; fileRef = 9DC2C10B16A645EEB82220D8; }; 5C9628DB3E0C0BA8809AE45D = { isa = PBXBuildFile; fileRef = EE5F18DF1DED7617C4A41FF3; }; 724DA2BCA5ABC5772604C3B4 = { isa = PBXBuildFile; fileRef = B2BCE9DDC8F0F54CA3D913E7; }; - 140FD4605CC549620CC7F44D = { isa = PBXBuildFile; fileRef = 562A8671221397C9CAD1BB2A; }; 035B1F7B1505ABF24455690E = { isa = PBXBuildFile; fileRef = 5249EFBE3B22E6FC1A7B6D42; }; + 3C71EA297D7418FEBB52F9DD = { isa = PBXBuildFile; fileRef = A257B76FCE9D594EAD41414C; }; 7A86E411B55E15DA7AF1FE67 = { isa = PBXBuildFile; fileRef = 8280AA34B23B4D366711A9E7; }; BD86381924AE45021246ABA3 = { isa = PBXBuildFile; fileRef = C9561A66310DAD5EEB4A9462; }; 306AB64E97A05B800349E7E2 = { isa = PBXBuildFile; fileRef = B62991F8AEE7327BA8A5070F; }; @@ -296,7 +296,6 @@ D04EEEC7EAE7C806E95ED41C = { isa = PBXBuildFile; fileRef = 7DB37383434F45D8A7B674C3; }; 7EA440527972D6B7322EC307 = { isa = PBXBuildFile; fileRef = CB16B2438EDCC10C499645E6; }; CB9FE1DA1AFE5FBA9FF06061 = { isa = PBXBuildFile; fileRef = BEB35C6173793C1CB7AB6311; }; - DEDFFA49B5CBF862CD6EDFD4 = { isa = PBXBuildFile; fileRef = 1B00957D2190CF28CF03E304; }; 26454A5DB5BAFD7901F17DA7 = { isa = PBXBuildFile; fileRef = BA58B49B820A47F6F55CDACB; }; F41B46F970BA78762DCE67D1 = { isa = PBXBuildFile; fileRef = 930E58E13FC92BF70AC20EEF; }; B7A8CF6F889840BED05C8C27 = { isa = PBXBuildFile; fileRef = 9113CDD122D2790E147A8CF5; }; @@ -308,6 +307,7 @@ 5E330E219B2D2944BCE95174 = { isa = PBXBuildFile; fileRef = FE6E3F911679B0D7547577A3; }; 275FBC09BE58E708A73B88C1 = { isa = PBXBuildFile; fileRef = 8BCE60CBC91DBAAB089958A1; }; 6DA99BA218FB45568258841C = { isa = PBXBuildFile; fileRef = 3F11593DC3A168A52FCC2DD9; }; + 32F1C95EDEE7722797B8CEE8 = { isa = PBXBuildFile; fileRef = FC2C82760E717788B5A6E691; }; 029A0E8B44DC17211722677D = { isa = PBXBuildFile; fileRef = 42059626955C547DA6AD3196; }; 4B4E17467BC41E2166549998 = { isa = PBXBuildFile; fileRef = 8F383A785B4876198C5B0194; }; 9686F29C29D1C26E353DE68A = { isa = PBXBuildFile; fileRef = F3B50EE3939E9F16D13C3C7C; }; @@ -982,8 +982,8 @@ 9DC2C10B16A645EEB82220D8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Windowing.cpp"; path = "../../src/native/linux/juce_linux_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; EE5F18DF1DED7617C4A41FF3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ios_Audio.cpp"; path = "../../src/native/mac/juce_ios_Audio.cpp"; sourceTree = "SOURCE_ROOT"; }; B2BCE9DDC8F0F54CA3D913E7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_MessageManager.mm"; path = "../../src/native/mac/juce_ios_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; - 562A8671221397C9CAD1BB2A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_MiscUtilities.mm"; path = "../../src/native/mac/juce_ios_MiscUtilities.mm"; sourceTree = "SOURCE_ROOT"; }; 5249EFBE3B22E6FC1A7B6D42 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_UIViewComponentPeer.mm"; path = "../../src/native/mac/juce_ios_UIViewComponentPeer.mm"; sourceTree = "SOURCE_ROOT"; }; + A257B76FCE9D594EAD41414C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_Windowing.mm"; path = "../../src/native/mac/juce_ios_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; 8280AA34B23B4D366711A9E7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../src/native/mac/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; }; C9561A66310DAD5EEB4A9462 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDBurner.mm"; path = "../../src/native/mac/juce_mac_AudioCDBurner.mm"; sourceTree = "SOURCE_ROOT"; }; B62991F8AEE7327BA8A5070F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDReader.mm"; path = "../../src/native/mac/juce_mac_AudioCDReader.mm"; sourceTree = "SOURCE_ROOT"; }; @@ -998,7 +998,6 @@ 7DB37383434F45D8A7B674C3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Fonts.mm"; path = "../../src/native/mac/juce_mac_Fonts.mm"; sourceTree = "SOURCE_ROOT"; }; CB16B2438EDCC10C499645E6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MainMenu.mm"; path = "../../src/native/mac/juce_mac_MainMenu.mm"; sourceTree = "SOURCE_ROOT"; }; BEB35C6173793C1CB7AB6311 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MessageManager.mm"; path = "../../src/native/mac/juce_mac_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; - 1B00957D2190CF28CF03E304 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MiscUtilities.mm"; path = "../../src/native/mac/juce_mac_MiscUtilities.mm"; sourceTree = "SOURCE_ROOT"; }; BA58B49B820A47F6F55CDACB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MouseCursor.mm"; path = "../../src/native/mac/juce_mac_MouseCursor.mm"; sourceTree = "SOURCE_ROOT"; }; 930E58E13FC92BF70AC20EEF = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_NativeCode.mm"; path = "../../src/native/mac/juce_mac_NativeCode.mm"; sourceTree = "SOURCE_ROOT"; }; 2F1812B26076D9CC1495D452 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_NativeIncludes.h"; path = "../../src/native/mac/juce_mac_NativeIncludes.h"; sourceTree = "SOURCE_ROOT"; }; @@ -1012,6 +1011,7 @@ FE6E3F911679B0D7547577A3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_SystemStats.mm"; path = "../../src/native/mac/juce_mac_SystemStats.mm"; sourceTree = "SOURCE_ROOT"; }; 8BCE60CBC91DBAAB089958A1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Threads.mm"; path = "../../src/native/mac/juce_mac_Threads.mm"; sourceTree = "SOURCE_ROOT"; }; 3F11593DC3A168A52FCC2DD9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_WebBrowserComponent.mm"; path = "../../src/native/mac/juce_mac_WebBrowserComponent.mm"; sourceTree = "SOURCE_ROOT"; }; + FC2C82760E717788B5A6E691 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Windowing.mm"; path = "../../src/native/mac/juce_mac_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; AB0F3F5A622CBB251F64945A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_MessageQueue.h"; path = "../../src/native/mac/juce_osx_MessageQueue.h"; sourceTree = "SOURCE_ROOT"; }; AD495FA1991295C722B46843 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_ObjCHelpers.h"; path = "../../src/native/mac/juce_osx_ObjCHelpers.h"; sourceTree = "SOURCE_ROOT"; }; 42059626955C547DA6AD3196 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_ActiveXComponent.cpp"; path = "../../src/native/windows/juce_win32_ActiveXComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1824,8 +1824,8 @@ 13513EE40AD6BAB30E26C88B = { isa = PBXGroup; children = ( EE5F18DF1DED7617C4A41FF3, B2BCE9DDC8F0F54CA3D913E7, - 562A8671221397C9CAD1BB2A, 5249EFBE3B22E6FC1A7B6D42, + A257B76FCE9D594EAD41414C, 8280AA34B23B4D366711A9E7, C9561A66310DAD5EEB4A9462, B62991F8AEE7327BA8A5070F, @@ -1840,7 +1840,6 @@ 7DB37383434F45D8A7B674C3, CB16B2438EDCC10C499645E6, BEB35C6173793C1CB7AB6311, - 1B00957D2190CF28CF03E304, BA58B49B820A47F6F55CDACB, 930E58E13FC92BF70AC20EEF, 2F1812B26076D9CC1495D452, @@ -1854,6 +1853,7 @@ FE6E3F911679B0D7547577A3, 8BCE60CBC91DBAAB089958A1, 3F11593DC3A168A52FCC2DD9, + FC2C82760E717788B5A6E691, AB0F3F5A622CBB251F64945A, AD495FA1991295C722B46843 ); name = mac; sourceTree = ""; }; 64DE2D4534D79E74C40A0DEE = { isa = PBXGroup; children = ( @@ -2344,8 +2344,8 @@ C9FB7884928BF0D6140AF881, 5C9628DB3E0C0BA8809AE45D, 724DA2BCA5ABC5772604C3B4, - 140FD4605CC549620CC7F44D, 035B1F7B1505ABF24455690E, + 3C71EA297D7418FEBB52F9DD, 7A86E411B55E15DA7AF1FE67, BD86381924AE45021246ABA3, 306AB64E97A05B800349E7E2, @@ -2359,7 +2359,6 @@ D04EEEC7EAE7C806E95ED41C, 7EA440527972D6B7322EC307, CB9FE1DA1AFE5FBA9FF06061, - DEDFFA49B5CBF862CD6EDFD4, 26454A5DB5BAFD7901F17DA7, F41B46F970BA78762DCE67D1, B7A8CF6F889840BED05C8C27, @@ -2371,6 +2370,7 @@ 5E330E219B2D2944BCE95174, 275FBC09BE58E708A73B88C1, 6DA99BA218FB45568258841C, + 32F1C95EDEE7722797B8CEE8, 029A0E8B44DC17211722677D, 4B4E17467BC41E2166549998, 9686F29C29D1C26E353DE68A, diff --git a/Builds/VisualStudio2005/Juce.vcproj b/Builds/VisualStudio2005/Juce.vcproj index fcd41e82c8..d80a877a9f 100644 --- a/Builds/VisualStudio2005/Juce.vcproj +++ b/Builds/VisualStudio2005/Juce.vcproj @@ -883,8 +883,8 @@ - + @@ -899,7 +899,6 @@ - @@ -913,6 +912,7 @@ + diff --git a/Builds/VisualStudio2008/Juce.vcproj b/Builds/VisualStudio2008/Juce.vcproj index 7ab0421ba0..62c41280ba 100644 --- a/Builds/VisualStudio2008/Juce.vcproj +++ b/Builds/VisualStudio2008/Juce.vcproj @@ -883,8 +883,8 @@ - + @@ -899,7 +899,6 @@ - @@ -913,6 +912,7 @@ + diff --git a/Builds/VisualStudio2008_DLL/Juce.vcproj b/Builds/VisualStudio2008_DLL/Juce.vcproj index f3347f92a7..2beb19c93e 100644 --- a/Builds/VisualStudio2008_DLL/Juce.vcproj +++ b/Builds/VisualStudio2008_DLL/Juce.vcproj @@ -885,8 +885,8 @@ - + @@ -901,7 +901,6 @@ - @@ -915,6 +914,7 @@ + diff --git a/Builds/VisualStudio2010/Juce.vcxproj.filters b/Builds/VisualStudio2010/Juce.vcxproj.filters index 5e4de1d9f6..33b7b7adb5 100644 --- a/Builds/VisualStudio2010/Juce.vcxproj.filters +++ b/Builds/VisualStudio2010/Juce.vcxproj.filters @@ -1042,10 +1042,10 @@ Juce\Source\native\mac - + Juce\Source\native\mac - + Juce\Source\native\mac @@ -1087,9 +1087,6 @@ Juce\Source\native\mac - - Juce\Source\native\mac - Juce\Source\native\mac @@ -1123,6 +1120,9 @@ Juce\Source\native\mac + + Juce\Source\native\mac + Juce\Source\native\windows diff --git a/Builds/iOS/Juce.xcodeproj/project.pbxproj b/Builds/iOS/Juce.xcodeproj/project.pbxproj index 363f5f6d0e..195bb2d6f7 100644 --- a/Builds/iOS/Juce.xcodeproj/project.pbxproj +++ b/Builds/iOS/Juce.xcodeproj/project.pbxproj @@ -281,8 +281,8 @@ C9FB7884928BF0D6140AF881 = { isa = PBXBuildFile; fileRef = 9DC2C10B16A645EEB82220D8; }; 5C9628DB3E0C0BA8809AE45D = { isa = PBXBuildFile; fileRef = EE5F18DF1DED7617C4A41FF3; }; 724DA2BCA5ABC5772604C3B4 = { isa = PBXBuildFile; fileRef = B2BCE9DDC8F0F54CA3D913E7; }; - 140FD4605CC549620CC7F44D = { isa = PBXBuildFile; fileRef = 562A8671221397C9CAD1BB2A; }; 035B1F7B1505ABF24455690E = { isa = PBXBuildFile; fileRef = 5249EFBE3B22E6FC1A7B6D42; }; + 3C71EA297D7418FEBB52F9DD = { isa = PBXBuildFile; fileRef = A257B76FCE9D594EAD41414C; }; 7A86E411B55E15DA7AF1FE67 = { isa = PBXBuildFile; fileRef = 8280AA34B23B4D366711A9E7; }; BD86381924AE45021246ABA3 = { isa = PBXBuildFile; fileRef = C9561A66310DAD5EEB4A9462; }; 306AB64E97A05B800349E7E2 = { isa = PBXBuildFile; fileRef = B62991F8AEE7327BA8A5070F; }; @@ -296,7 +296,6 @@ D04EEEC7EAE7C806E95ED41C = { isa = PBXBuildFile; fileRef = 7DB37383434F45D8A7B674C3; }; 7EA440527972D6B7322EC307 = { isa = PBXBuildFile; fileRef = CB16B2438EDCC10C499645E6; }; CB9FE1DA1AFE5FBA9FF06061 = { isa = PBXBuildFile; fileRef = BEB35C6173793C1CB7AB6311; }; - DEDFFA49B5CBF862CD6EDFD4 = { isa = PBXBuildFile; fileRef = 1B00957D2190CF28CF03E304; }; 26454A5DB5BAFD7901F17DA7 = { isa = PBXBuildFile; fileRef = BA58B49B820A47F6F55CDACB; }; F41B46F970BA78762DCE67D1 = { isa = PBXBuildFile; fileRef = 930E58E13FC92BF70AC20EEF; }; B7A8CF6F889840BED05C8C27 = { isa = PBXBuildFile; fileRef = 9113CDD122D2790E147A8CF5; }; @@ -308,6 +307,7 @@ 5E330E219B2D2944BCE95174 = { isa = PBXBuildFile; fileRef = FE6E3F911679B0D7547577A3; }; 275FBC09BE58E708A73B88C1 = { isa = PBXBuildFile; fileRef = 8BCE60CBC91DBAAB089958A1; }; 6DA99BA218FB45568258841C = { isa = PBXBuildFile; fileRef = 3F11593DC3A168A52FCC2DD9; }; + 32F1C95EDEE7722797B8CEE8 = { isa = PBXBuildFile; fileRef = FC2C82760E717788B5A6E691; }; 029A0E8B44DC17211722677D = { isa = PBXBuildFile; fileRef = 42059626955C547DA6AD3196; }; 4B4E17467BC41E2166549998 = { isa = PBXBuildFile; fileRef = 8F383A785B4876198C5B0194; }; 9686F29C29D1C26E353DE68A = { isa = PBXBuildFile; fileRef = F3B50EE3939E9F16D13C3C7C; }; @@ -982,8 +982,8 @@ 9DC2C10B16A645EEB82220D8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Windowing.cpp"; path = "../../src/native/linux/juce_linux_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; EE5F18DF1DED7617C4A41FF3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ios_Audio.cpp"; path = "../../src/native/mac/juce_ios_Audio.cpp"; sourceTree = "SOURCE_ROOT"; }; B2BCE9DDC8F0F54CA3D913E7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_MessageManager.mm"; path = "../../src/native/mac/juce_ios_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; - 562A8671221397C9CAD1BB2A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_MiscUtilities.mm"; path = "../../src/native/mac/juce_ios_MiscUtilities.mm"; sourceTree = "SOURCE_ROOT"; }; 5249EFBE3B22E6FC1A7B6D42 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_UIViewComponentPeer.mm"; path = "../../src/native/mac/juce_ios_UIViewComponentPeer.mm"; sourceTree = "SOURCE_ROOT"; }; + A257B76FCE9D594EAD41414C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_Windowing.mm"; path = "../../src/native/mac/juce_ios_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; 8280AA34B23B4D366711A9E7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../src/native/mac/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; }; C9561A66310DAD5EEB4A9462 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDBurner.mm"; path = "../../src/native/mac/juce_mac_AudioCDBurner.mm"; sourceTree = "SOURCE_ROOT"; }; B62991F8AEE7327BA8A5070F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDReader.mm"; path = "../../src/native/mac/juce_mac_AudioCDReader.mm"; sourceTree = "SOURCE_ROOT"; }; @@ -998,7 +998,6 @@ 7DB37383434F45D8A7B674C3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Fonts.mm"; path = "../../src/native/mac/juce_mac_Fonts.mm"; sourceTree = "SOURCE_ROOT"; }; CB16B2438EDCC10C499645E6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MainMenu.mm"; path = "../../src/native/mac/juce_mac_MainMenu.mm"; sourceTree = "SOURCE_ROOT"; }; BEB35C6173793C1CB7AB6311 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MessageManager.mm"; path = "../../src/native/mac/juce_mac_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; - 1B00957D2190CF28CF03E304 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MiscUtilities.mm"; path = "../../src/native/mac/juce_mac_MiscUtilities.mm"; sourceTree = "SOURCE_ROOT"; }; BA58B49B820A47F6F55CDACB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MouseCursor.mm"; path = "../../src/native/mac/juce_mac_MouseCursor.mm"; sourceTree = "SOURCE_ROOT"; }; 930E58E13FC92BF70AC20EEF = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_NativeCode.mm"; path = "../../src/native/mac/juce_mac_NativeCode.mm"; sourceTree = "SOURCE_ROOT"; }; 2F1812B26076D9CC1495D452 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_NativeIncludes.h"; path = "../../src/native/mac/juce_mac_NativeIncludes.h"; sourceTree = "SOURCE_ROOT"; }; @@ -1012,6 +1011,7 @@ FE6E3F911679B0D7547577A3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_SystemStats.mm"; path = "../../src/native/mac/juce_mac_SystemStats.mm"; sourceTree = "SOURCE_ROOT"; }; 8BCE60CBC91DBAAB089958A1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Threads.mm"; path = "../../src/native/mac/juce_mac_Threads.mm"; sourceTree = "SOURCE_ROOT"; }; 3F11593DC3A168A52FCC2DD9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_WebBrowserComponent.mm"; path = "../../src/native/mac/juce_mac_WebBrowserComponent.mm"; sourceTree = "SOURCE_ROOT"; }; + FC2C82760E717788B5A6E691 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Windowing.mm"; path = "../../src/native/mac/juce_mac_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; AB0F3F5A622CBB251F64945A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_MessageQueue.h"; path = "../../src/native/mac/juce_osx_MessageQueue.h"; sourceTree = "SOURCE_ROOT"; }; AD495FA1991295C722B46843 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_ObjCHelpers.h"; path = "../../src/native/mac/juce_osx_ObjCHelpers.h"; sourceTree = "SOURCE_ROOT"; }; 42059626955C547DA6AD3196 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_ActiveXComponent.cpp"; path = "../../src/native/windows/juce_win32_ActiveXComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1824,8 +1824,8 @@ 13513EE40AD6BAB30E26C88B = { isa = PBXGroup; children = ( EE5F18DF1DED7617C4A41FF3, B2BCE9DDC8F0F54CA3D913E7, - 562A8671221397C9CAD1BB2A, 5249EFBE3B22E6FC1A7B6D42, + A257B76FCE9D594EAD41414C, 8280AA34B23B4D366711A9E7, C9561A66310DAD5EEB4A9462, B62991F8AEE7327BA8A5070F, @@ -1840,7 +1840,6 @@ 7DB37383434F45D8A7B674C3, CB16B2438EDCC10C499645E6, BEB35C6173793C1CB7AB6311, - 1B00957D2190CF28CF03E304, BA58B49B820A47F6F55CDACB, 930E58E13FC92BF70AC20EEF, 2F1812B26076D9CC1495D452, @@ -1854,6 +1853,7 @@ FE6E3F911679B0D7547577A3, 8BCE60CBC91DBAAB089958A1, 3F11593DC3A168A52FCC2DD9, + FC2C82760E717788B5A6E691, AB0F3F5A622CBB251F64945A, AD495FA1991295C722B46843 ); name = mac; sourceTree = ""; }; 64DE2D4534D79E74C40A0DEE = { isa = PBXGroup; children = ( @@ -2348,8 +2348,8 @@ C9FB7884928BF0D6140AF881, 5C9628DB3E0C0BA8809AE45D, 724DA2BCA5ABC5772604C3B4, - 140FD4605CC549620CC7F44D, 035B1F7B1505ABF24455690E, + 3C71EA297D7418FEBB52F9DD, 7A86E411B55E15DA7AF1FE67, BD86381924AE45021246ABA3, 306AB64E97A05B800349E7E2, @@ -2363,7 +2363,6 @@ D04EEEC7EAE7C806E95ED41C, 7EA440527972D6B7322EC307, CB9FE1DA1AFE5FBA9FF06061, - DEDFFA49B5CBF862CD6EDFD4, 26454A5DB5BAFD7901F17DA7, F41B46F970BA78762DCE67D1, B7A8CF6F889840BED05C8C27, @@ -2375,6 +2374,7 @@ 5E330E219B2D2944BCE95174, 275FBC09BE58E708A73B88C1, 6DA99BA218FB45568258841C, + 32F1C95EDEE7722797B8CEE8, 029A0E8B44DC17211722677D, 4B4E17467BC41E2166549998, 9686F29C29D1C26E353DE68A, diff --git a/Juce.jucer b/Juce.jucer index f876827119..6520e2f1c3 100644 --- a/Juce.jucer +++ b/Juce.jucer @@ -1346,10 +1346,10 @@ file="src/native/mac/juce_ios_Audio.cpp"/> - + - + getApplicationName()); + + if (currentProject != nullptr) + name = currentProject->getDocumentTitle() + " - " + name; + if (documentName.isNotEmpty()) name = documentName + " - " + name; diff --git a/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp b/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp index ffc4af1791..80d124e35c 100644 --- a/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp +++ b/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp @@ -308,7 +308,9 @@ bool ProjectContentComponent::perform (const InvocationInfo& info) if (project != nullptr) { ScopedPointer exporter (ProjectExporter::createPlatformDefaultExporter (*project)); - exporter->launchProject(); + + if (exporter != nullptr) + exporter->launchProject(); } break; @@ -316,7 +318,9 @@ bool ProjectContentComponent::perform (const InvocationInfo& info) if (project != nullptr && project->save (true, true) == FileBasedDocument::savedOk) { ScopedPointer exporter (ProjectExporter::createPlatformDefaultExporter (*project)); - exporter->launchProject(); + + if (exporter != nullptr) + exporter->launchProject(); } break; diff --git a/extras/Introjucer/Source/Project/jucer_ProjectExport_Android.h b/extras/Introjucer/Source/Project/jucer_ProjectExport_Android.h index a7d17f6429..115457a5a3 100644 --- a/extras/Introjucer/Source/Project/jucer_ProjectExport_Android.h +++ b/extras/Introjucer/Source/Project/jucer_ProjectExport_Android.h @@ -65,13 +65,13 @@ public: } //============================================================================== - bool isDefaultFormatForCurrentOS() + int getLaunchPreferenceOrderForCurrentOS() { - #if JUCE_ANDROID - return true; - #else - return false; - #endif + #if JUCE_ANDROID + return 1; + #else + return 0; + #endif } bool isPossibleForCurrentProject() { return project.isGUIApplication(); } diff --git a/extras/Introjucer/Source/Project/jucer_ProjectExport_MSVC.h b/extras/Introjucer/Source/Project/jucer_ProjectExport_MSVC.h index a6687ec584..8bf076a257 100644 --- a/extras/Introjucer/Source/Project/jucer_ProjectExport_MSVC.h +++ b/extras/Introjucer/Source/Project/jucer_ProjectExport_MSVC.h @@ -431,13 +431,13 @@ public: void launchProject() { getSLNFile().startAsProcess(); } - bool isDefaultFormatForCurrentOS() + int getLaunchPreferenceOrderForCurrentOS() { - #if JUCE_WINDOWS - return true; - #else - return false; - #endif + #if JUCE_WINDOWS + return 4; + #else + return 0; + #endif } static MSVCProjectExporterVC2008* createForSettings (Project& project, const ValueTree& settings) @@ -785,7 +785,14 @@ public: static const char* getName() { return "Visual Studio 2005"; } static const char* getValueTreeTypeName() { return "VS2005"; } - bool isDefaultFormatForCurrentOS() { return false; } + int getLaunchPreferenceOrderForCurrentOS() + { + #if JUCE_WINDOWS + return 2; + #else + return 0; + #endif + } static MSVCProjectExporterVC2005* createForSettings (Project& project, const ValueTree& settings) { @@ -817,7 +824,15 @@ public: static const char* getName() { return "Visual C++ 6.0"; } static const char* getValueTreeTypeName() { return "MSVC6"; } - bool isDefaultFormatForCurrentOS() { return false; } + int getLaunchPreferenceOrderForCurrentOS() + { + #if JUCE_WINDOWS + return 1; + #else + return 0; + #endif + } + void launchProject() { getDSWFile().startAsProcess(); } static MSVCProjectExporterVC6* createForSettings (Project& project, const ValueTree& settings) @@ -1078,7 +1093,15 @@ public: static const char* getName() { return "Visual Studio 2010"; } static const char* getValueTreeTypeName() { return "VS2010"; } - bool isDefaultFormatForCurrentOS() { return false; } + int getLaunchPreferenceOrderForCurrentOS() + { + #if JUCE_WINDOWS + return 3; + #else + return 0; + #endif + } + void launchProject() { getSLNFile().startAsProcess(); } static MSVCProjectExporterVC2010* createForSettings (Project& project, const ValueTree& settings) @@ -1235,63 +1258,77 @@ protected: XmlElement* group = projectXml.createNewChildElement ("ItemDefinitionGroup"); setConditionAttribute (*group, config); - XmlElement* midl = group->createNewChildElement ("Midl"); - midl->createNewChildElement ("PreprocessorDefinitions")->addTextElement (isDebug ? "_DEBUG;%(PreprocessorDefinitions)" - : "NDEBUG;%(PreprocessorDefinitions)"); - midl->createNewChildElement ("MkTypLibCompatible")->addTextElement ("true"); - midl->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); - midl->createNewChildElement ("TargetEnvironment")->addTextElement ("Win32"); - //midl->createNewChildElement ("TypeLibraryName")->addTextElement (""); - midl->createNewChildElement ("HeaderFileName"); - - XmlElement* cl = group->createNewChildElement ("ClCompile"); - cl->createNewChildElement ("Optimization")->addTextElement (isDebug ? "Disabled" : "MaxSpeed"); + { + XmlElement* midl = group->createNewChildElement ("Midl"); + midl->createNewChildElement ("PreprocessorDefinitions")->addTextElement (isDebug ? "_DEBUG;%(PreprocessorDefinitions)" + : "NDEBUG;%(PreprocessorDefinitions)"); + midl->createNewChildElement ("MkTypLibCompatible")->addTextElement ("true"); + midl->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); + midl->createNewChildElement ("TargetEnvironment")->addTextElement ("Win32"); + //midl->createNewChildElement ("TypeLibraryName")->addTextElement (""); + midl->createNewChildElement ("HeaderFileName"); + } - if (isDebug) - cl->createNewChildElement ("DebugInformationFormat")->addTextElement ("EditAndContinue"); - - StringArray includePaths (getHeaderSearchPaths (config)); - includePaths.add ("%(AdditionalIncludeDirectories)"); - cl->createNewChildElement ("AdditionalIncludeDirectories")->addTextElement (includePaths.joinIntoString (";")); - cl->createNewChildElement ("PreprocessorDefinitions")->addTextElement (getPreprocessorDefs (config, ";") + ";%(PreprocessorDefinitions)"); - cl->createNewChildElement ("RuntimeLibrary")->addTextElement (isRTAS() ? (isDebug ? "MultiThreadedDLLDebug" : "MultiThreadedDLL") - : (isDebug ? "MultiThreadedDebug" : "MultiThreaded")); - cl->createNewChildElement ("RuntimeTypeInfo")->addTextElement ("true"); - cl->createNewChildElement ("PrecompiledHeader"); - cl->createNewChildElement ("AssemblerListingLocation")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/")); - cl->createNewChildElement ("ObjectFileName")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/")); - cl->createNewChildElement ("ProgramDataBaseFileName")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/")); - cl->createNewChildElement ("WarningLevel")->addTextElement ("Level4"); - cl->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); - - XmlElement* res = group->createNewChildElement ("ResourceCompile"); - res->createNewChildElement ("PreprocessorDefinitions")->addTextElement (isDebug ? "_DEBUG;%(PreprocessorDefinitions)" - : "NDEBUG;%(PreprocessorDefinitions)"); - - XmlElement* link = group->createNewChildElement ("Link"); - link->createNewChildElement ("OutputFile")->addTextElement (FileHelpers::windowsStylePath (binariesPath + "/" + outputFileName)); - link->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); - link->createNewChildElement ("IgnoreSpecificDefaultLibraries")->addTextElement (isDebug ? "libcmt.lib; msvcrt.lib;;%(IgnoreSpecificDefaultLibraries)" - : "%(IgnoreSpecificDefaultLibraries)"); - link->createNewChildElement ("GenerateDebugInformation")->addTextElement (isDebug ? "true" : "false"); - link->createNewChildElement ("ProgramDatabaseFile")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".pdb")); - link->createNewChildElement ("SubSystem")->addTextElement (project.isCommandLineApp() ? "Console" : "Windows"); - link->createNewChildElement ("TargetMachine")->addTextElement ("MachineX86"); + { + XmlElement* cl = group->createNewChildElement ("ClCompile"); + cl->createNewChildElement ("Optimization")->addTextElement (isDebug ? "Disabled" : "MaxSpeed"); + + if (isDebug) + cl->createNewChildElement ("DebugInformationFormat")->addTextElement ("EditAndContinue"); + + StringArray includePaths (getHeaderSearchPaths (config)); + includePaths.add ("%(AdditionalIncludeDirectories)"); + cl->createNewChildElement ("AdditionalIncludeDirectories")->addTextElement (includePaths.joinIntoString (";")); + cl->createNewChildElement ("PreprocessorDefinitions")->addTextElement (getPreprocessorDefs (config, ";") + ";%(PreprocessorDefinitions)"); + cl->createNewChildElement ("RuntimeLibrary")->addTextElement (isRTAS() ? (isDebug ? "MultiThreadedDLLDebug" : "MultiThreadedDLL") + : (isDebug ? "MultiThreadedDebug" : "MultiThreaded")); + cl->createNewChildElement ("RuntimeTypeInfo")->addTextElement ("true"); + cl->createNewChildElement ("PrecompiledHeader"); + cl->createNewChildElement ("AssemblerListingLocation")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/")); + cl->createNewChildElement ("ObjectFileName")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/")); + cl->createNewChildElement ("ProgramDataBaseFileName")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/")); + cl->createNewChildElement ("WarningLevel")->addTextElement ("Level4"); + cl->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); + + const String extraFlags (replacePreprocessorTokens (config, getExtraCompilerFlags().toString()).trim()); + if (extraFlags.isNotEmpty()) + cl->createNewChildElement ("AdditionalOptions")->addTextElement (extraFlags + " %(AdditionalOptions)"); + } - if (! isDebug) { - link->createNewChildElement ("OptimizeReferences")->addTextElement ("true"); - link->createNewChildElement ("EnableCOMDATFolding")->addTextElement ("true"); + XmlElement* res = group->createNewChildElement ("ResourceCompile"); + res->createNewChildElement ("PreprocessorDefinitions")->addTextElement (isDebug ? "_DEBUG;%(PreprocessorDefinitions)" + : "NDEBUG;%(PreprocessorDefinitions)"); } - String extraLinkerOptions (getExtraLinkerFlags().toString()); - if (extraLinkerOptions.isNotEmpty()) - link->createNewChildElement ("AdditionalOptions")->addTextElement (replacePreprocessorTokens (config, extraLinkerOptions).trim() - + " %(AdditionalOptions)"); + { + XmlElement* link = group->createNewChildElement ("Link"); + link->createNewChildElement ("OutputFile")->addTextElement (FileHelpers::windowsStylePath (binariesPath + "/" + outputFileName)); + link->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); + link->createNewChildElement ("IgnoreSpecificDefaultLibraries")->addTextElement (isDebug ? "libcmt.lib; msvcrt.lib;;%(IgnoreSpecificDefaultLibraries)" + : "%(IgnoreSpecificDefaultLibraries)"); + link->createNewChildElement ("GenerateDebugInformation")->addTextElement (isDebug ? "true" : "false"); + link->createNewChildElement ("ProgramDatabaseFile")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".pdb")); + link->createNewChildElement ("SubSystem")->addTextElement (project.isCommandLineApp() ? "Console" : "Windows"); + link->createNewChildElement ("TargetMachine")->addTextElement ("MachineX86"); + + if (! isDebug) + { + link->createNewChildElement ("OptimizeReferences")->addTextElement ("true"); + link->createNewChildElement ("EnableCOMDATFolding")->addTextElement ("true"); + } + + String extraLinkerOptions (getExtraLinkerFlags().toString()); + if (extraLinkerOptions.isNotEmpty()) + link->createNewChildElement ("AdditionalOptions")->addTextElement (replacePreprocessorTokens (config, extraLinkerOptions).trim() + + " %(AdditionalOptions)"); + } - XmlElement* bsc = group->createNewChildElement ("Bscmake"); - bsc->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); - bsc->createNewChildElement ("OutputFile")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".bsc")); + { + XmlElement* bsc = group->createNewChildElement ("Bscmake"); + bsc->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); + bsc->createNewChildElement ("OutputFile")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".bsc")); + } } { @@ -1332,12 +1369,9 @@ protected: const String getProjectType() const { - if (project.isGUIApplication() || project.isCommandLineApp()) - return "Application"; - else if (project.isAudioPlugin() || project.isBrowserPlugin()) - return "DynamicLibrary"; - else if (project.isLibrary()) - return "StaticLibrary"; + if (project.isGUIApplication() || project.isCommandLineApp()) return "Application"; + else if (project.isAudioPlugin() || project.isBrowserPlugin()) return "DynamicLibrary"; + else if (project.isLibrary()) return "StaticLibrary"; jassertfalse; return String::empty; diff --git a/extras/Introjucer/Source/Project/jucer_ProjectExport_Make.h b/extras/Introjucer/Source/Project/jucer_ProjectExport_Make.h index 790b43bf09..72431069d2 100644 --- a/extras/Introjucer/Source/Project/jucer_ProjectExport_Make.h +++ b/extras/Introjucer/Source/Project/jucer_ProjectExport_Make.h @@ -60,13 +60,13 @@ public: } //============================================================================== - bool isDefaultFormatForCurrentOS() + int getLaunchPreferenceOrderForCurrentOS() { - #if JUCE_LINUX - return true; - #else - return false; - #endif + #if JUCE_LINUX + return 1; + #else + return 0; + #endif } bool isPossibleForCurrentProject() { return true; } diff --git a/extras/Introjucer/Source/Project/jucer_ProjectExport_XCode.h b/extras/Introjucer/Source/Project/jucer_ProjectExport_XCode.h index c2fd313c60..080f1ca8c7 100644 --- a/extras/Introjucer/Source/Project/jucer_ProjectExport_XCode.h +++ b/extras/Introjucer/Source/Project/jucer_ProjectExport_XCode.h @@ -73,13 +73,22 @@ public: //============================================================================== Value getObjCSuffix() { return getSetting ("objCExtraSuffix"); } - bool isDefaultFormatForCurrentOS() + int getLaunchPreferenceOrderForCurrentOS() { - #if JUCE_MAC - return ! iPhone; - #else + #if JUCE_MAC + return iPhone ? 1 : 2; + #else + return 0; + #endif + } + + bool isAvailableOnCurrentOS() + { + #if JUCE_MAC + return true; + #else return false; - #endif + #endif } bool isPossibleForCurrentProject() { return project.isGUIApplication() || ! iPhone; } diff --git a/extras/Introjucer/Source/Project/jucer_ProjectExporter.cpp b/extras/Introjucer/Source/Project/jucer_ProjectExporter.cpp index dcb36a2758..28514e22a1 100644 --- a/extras/Introjucer/Source/Project/jucer_ProjectExporter.cpp +++ b/extras/Introjucer/Source/Project/jucer_ProjectExporter.cpp @@ -104,15 +104,23 @@ ProjectExporter* ProjectExporter::createExporter (Project& project, const ValueT ProjectExporter* ProjectExporter::createPlatformDefaultExporter (Project& project) { + ScopedPointer best; + int bestPref = 0; + for (int i = 0; i < project.getNumExporters(); ++i) { ScopedPointer exp (project.createExporter (i)); - if (exp->isDefaultFormatForCurrentOS()) - return exp.release(); + const int pref = exp->getLaunchPreferenceOrderForCurrentOS(); + + if (pref > bestPref) + { + bestPref = pref; + best = exp; + } } - return 0; + return best.release(); } const File ProjectExporter::getTargetFolder() const diff --git a/extras/Introjucer/Source/Project/jucer_ProjectExporter.h b/extras/Introjucer/Source/Project/jucer_ProjectExporter.h index 92bfeb1bb8..009401ee04 100644 --- a/extras/Introjucer/Source/Project/jucer_ProjectExporter.h +++ b/extras/Introjucer/Source/Project/jucer_ProjectExporter.h @@ -48,7 +48,8 @@ public: static ProjectExporter* createPlatformDefaultExporter (Project& project); //============================================================================= - virtual bool isDefaultFormatForCurrentOS() = 0; + // return 0 if this can't be opened in the current OS, or a higher value, where higher numbers are more preferable. + virtual int getLaunchPreferenceOrderForCurrentOS() = 0; virtual bool isPossibleForCurrentProject() = 0; virtual bool usesMMFiles() const = 0; virtual void createPropertyEditors (Array & props); diff --git a/extras/JuceDemo/Source/demos/WidgetsDemo.cpp b/extras/JuceDemo/Source/demos/WidgetsDemo.cpp index 4662914004..72ee209680 100644 --- a/extras/JuceDemo/Source/demos/WidgetsDemo.cpp +++ b/extras/JuceDemo/Source/demos/WidgetsDemo.cpp @@ -1204,7 +1204,7 @@ public: demoComponent->performDemoMenuItem (result); } - static void alertBoxResultChosen (int result, WidgetsDemo* demoComponent) + static void alertBoxResultChosen (int result, WidgetsDemo*) { AlertWindow::showMessageBoxAsync (AlertWindow::InfoIcon, "Alert Box", diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index e567aa2de0..a98a06bf7e 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -270878,6 +270878,16 @@ namespace } } +ScopedAutoReleasePool::ScopedAutoReleasePool() +{ + pool = [[NSAutoreleasePool alloc] init]; +} + +ScopedAutoReleasePool::~ScopedAutoReleasePool() +{ + [((NSAutoreleasePool*) pool) release]; +} + #endif // __JUCE_OSX_OBJCHELPERS_JUCEHEADER__ /*** End of inlined file: juce_osx_ObjCHelpers.h ***/ @@ -273303,728 +273313,193 @@ void File::addToDock() const /*** End of inlined file: juce_mac_Files.mm ***/ -#if JUCE_IOS -/*** Start of inlined file: juce_ios_MiscUtilities.mm ***/ +/*** Start of inlined file: juce_mac_Debugging.mm ***/ // (This file gets included by juce_mac_NativeCode.mm, rather than being // compiled on its own). #if JUCE_INCLUDED_FILE -END_JUCE_NAMESPACE - -@interface JuceAppStartupDelegate : NSObject +void Logger::outputDebugString (const String& text) { + std::cerr << text << std::endl; } -- (void) applicationDidFinishLaunching: (UIApplication*) application; -- (void) applicationWillTerminate: (UIApplication*) application; - -@end - -@implementation JuceAppStartupDelegate - -- (void) applicationDidFinishLaunching: (UIApplication*) application +JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger() { - initialiseJuce_GUI(); + static char testResult = 0; - if (! JUCEApplication::createInstance()->initialiseApp (String::empty)) - exit (0); + if (testResult == 0) + { + struct kinfo_proc info; + int m[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; + size_t sz = sizeof (info); + sysctl (m, 4, &info, &sz, 0, 0); + testResult = ((info.kp_proc.p_flag & P_TRACED) != 0) ? 1 : -1; + } + + return testResult > 0; } -- (void) applicationWillTerminate: (UIApplication*) application +JUCE_API bool JUCE_CALLTYPE Process::isRunningUnderDebugger() { - JUCEApplication::appWillTerminateByForce(); + return juce_isRunningUnderDebugger(); } -@end +#endif -BEGIN_JUCE_NAMESPACE +/*** End of inlined file: juce_mac_Debugging.mm ***/ -int juce_iOSMain (int argc, const char* argv[]) -{ - return UIApplicationMain (argc, const_cast (argv), nil, @"JuceAppStartupDelegate"); -} +#if ! JUCE_ONLY_BUILD_CORE_LIBRARY + #if JUCE_IOS -ScopedAutoReleasePool::ScopedAutoReleasePool() -{ - pool = [[NSAutoreleasePool alloc] init]; -} +/*** Start of inlined file: juce_mac_Fonts.mm ***/ +// (This file gets included by juce_mac_NativeCode.mm, rather than being +// compiled on its own). +#if JUCE_INCLUDED_FILE -ScopedAutoReleasePool::~ScopedAutoReleasePool() -{ - [((NSAutoreleasePool*) pool) release]; -} +#if (JUCE_MAC && defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 \ + && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5) \ + || (JUCE_IOS && defined (__IPHONE_3_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_2) + #define JUCE_CORETEXT_AVAILABLE 1 +#endif -void LookAndFeel::playAlertSound() +#if JUCE_CORETEXT_AVAILABLE + +class MacTypeface : public Typeface { - //xxx - //AudioServicesPlaySystemSound (); -} +public: -#if ! JUCE_ONLY_BUILD_CORE_LIBRARY + MacTypeface (const Font& font) + : Typeface (font.getTypefaceName()), + fontRef (nullptr), + fontHeightToCGSizeFactor (1.0f), + renderingTransform (CGAffineTransformIdentity), + ctFontRef (nullptr), + attributedStringAtts (nullptr), + ascent (0.0f), + unitsToHeightScaleFactor (0.0f) + { + JUCE_AUTORELEASEPOOL + CFStringRef cfName = font.getTypefaceName().toCFString(); + ctFontRef = CTFontCreateWithName (cfName, 1024, nullptr); + CFRelease (cfName); -class iOSMessageBox; + if (ctFontRef != nullptr) + { + bool needsItalicTransform = false; -END_JUCE_NAMESPACE + if (font.isItalic()) + { + CTFontRef newFont = CTFontCreateCopyWithSymbolicTraits (ctFontRef, 0.0f, nullptr, + kCTFontItalicTrait, kCTFontItalicTrait); -@interface JuceAlertBoxDelegate : NSObject -{ -@public - iOSMessageBox* owner; -} + if (newFont != nullptr) + { + CFRelease (ctFontRef); + ctFontRef = newFont; + } + else + { + needsItalicTransform = true; // couldn't find a proper italic version, so fake it with a transform.. + } + } -- (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex; + if (font.isBold()) + { + CTFontRef newFont = CTFontCreateCopyWithSymbolicTraits (ctFontRef, 0.0f, nullptr, + kCTFontBoldTrait, kCTFontBoldTrait); + if (newFont != nullptr) + { + CFRelease (ctFontRef); + ctFontRef = newFont; + } + } -@end + ascent = std::abs ((float) CTFontGetAscent (ctFontRef)); + const float totalSize = ascent + std::abs ((float) CTFontGetDescent (ctFontRef)); + ascent /= totalSize; -BEGIN_JUCE_NAMESPACE + pathTransform = AffineTransform::identity.scale (1.0f / totalSize, 1.0f / totalSize); -class iOSMessageBox -{ -public: - iOSMessageBox (const String& title, const String& message, - NSString* button1, NSString* button2, NSString* button3, - ModalComponentManager::Callback* callback_, const bool isAsync_) - : result (0), delegate (nil), alert (nil), - callback (callback_), isYesNo (button3 != nil), isAsync (isAsync_) - { - delegate = [[JuceAlertBoxDelegate alloc] init]; - delegate->owner = this; + if (needsItalicTransform) + { + pathTransform = pathTransform.sheared (-0.15f, 0.0f); + renderingTransform.c = 0.15f; + } - alert = [[UIAlertView alloc] initWithTitle: juceStringToNS (title) - message: juceStringToNS (message) - delegate: delegate - cancelButtonTitle: button1 - otherButtonTitles: button2, button3, nil]; - [alert retain]; - [alert show]; - } + fontRef = CTFontCopyGraphicsFont (ctFontRef, nullptr); - ~iOSMessageBox() - { - [alert release]; - [delegate release]; + const int totalHeight = abs (CGFontGetAscent (fontRef)) + abs (CGFontGetDescent (fontRef)); + const float ctTotalHeight = abs (CTFontGetAscent (ctFontRef)) + abs (CTFontGetDescent (ctFontRef)); + unitsToHeightScaleFactor = 1.0f / ctTotalHeight; + fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight; + + const short zero = 0; + CFNumberRef numberRef = CFNumberCreate (0, kCFNumberShortType, &zero); + + CFStringRef keys[] = { kCTFontAttributeName, kCTLigatureAttributeName }; + CFTypeRef values[] = { ctFontRef, numberRef }; + attributedStringAtts = CFDictionaryCreate (nullptr, (const void**) &keys, (const void**) &values, numElementsInArray (keys), + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFRelease (numberRef); + } } - int getResult() + ~MacTypeface() { - jassert (callback == nullptr); - JUCE_AUTORELEASEPOOL + if (attributedStringAtts != nullptr) + CFRelease (attributedStringAtts); - while (! alert.hidden && alert.superview != nil) - [[NSRunLoop mainRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]]; + if (fontRef != nullptr) + CGFontRelease (fontRef); - return result; + if (ctFontRef != nullptr) + CFRelease (ctFontRef); } - void buttonClicked (const int buttonIndex) noexcept + float getAscent() const { return ascent; } + float getDescent() const { return 1.0f - ascent; } + + float getStringWidth (const String& text) { - result = buttonIndex; + float x = 0; - if (callback != nullptr) - callback->modalStateFinished (result); + if (ctFontRef != nullptr && text.isNotEmpty()) + { + CFStringRef cfText = text.toCFString(); + CFAttributedStringRef attribString = CFAttributedStringCreate (kCFAllocatorDefault, cfText, attributedStringAtts); + CFRelease (cfText); - if (isAsync) - delete this; - } + CTLineRef line = CTLineCreateWithAttributedString (attribString); + CFArrayRef runArray = CTLineGetGlyphRuns (line); -private: - int result; - JuceAlertBoxDelegate* delegate; - UIAlertView* alert; - ModalComponentManager::Callback* callback; - const bool isYesNo, isAsync; + for (CFIndex i = 0; i < CFArrayGetCount (runArray); ++i) + { + CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (runArray, i); + CFIndex length = CTRunGetGlyphCount (run); + HeapBlock advances (length); + CTRunGetAdvances (run, CFRangeMake (0, 0), advances); - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (iOSMessageBox); -}; + for (int j = 0; j < length; ++j) + x += (float) advances[j].width; + } -END_JUCE_NAMESPACE + CFRelease (line); + CFRelease (attribString); -@implementation JuceAlertBoxDelegate + x *= unitsToHeightScaleFactor; + } -- (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex -{ - owner->buttonClicked (buttonIndex); - alertView.hidden = true; -} + return x; + } -@end -BEGIN_JUCE_NAMESPACE + void getGlyphPositions (const String& text, Array & resultGlyphs, Array & xOffsets) + { + xOffsets.add (0); -void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent) -{ - JUCE_AUTORELEASEPOOL - iOSMessageBox mb (title, message, @"OK", nil, nil, 0, false); - (void) mb.getResult(); -} - -void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent) -{ - JUCE_AUTORELEASEPOOL - new iOSMessageBox (title, message, @"OK", nil, nil, 0, true); -} - -bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent, - ModalComponentManager::Callback* callback) -{ - ScopedPointer mb (new iOSMessageBox (title, message, @"Cancel", @"OK", nil, callback, callback != nullptr)); - - if (callback == nullptr) - return mb->getResult() == 1; - - mb.release(); - return false; -} - -int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent, - ModalComponentManager::Callback* callback) -{ - ScopedPointer mb (new iOSMessageBox (title, message, @"Cancel", @"Yes", @"No", callback, callback != nullptr)); - - if (callback == nullptr) - return mb->getResult(); - - mb.release(); - return 0; -} - -bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles) -{ - jassertfalse; // no such thing on the iphone! - return false; -} - -bool DragAndDropContainer::performExternalDragDropOfText (const String& text) -{ - jassertfalse; // no such thing on the iphone! - return false; -} - -void Desktop::setScreenSaverEnabled (const bool isEnabled) -{ - [[UIApplication sharedApplication] setIdleTimerDisabled: ! isEnabled]; -} - -bool Desktop::isScreenSaverEnabled() -{ - return ! [[UIApplication sharedApplication] isIdleTimerDisabled]; -} - -#endif - -#endif - -/*** End of inlined file: juce_ios_MiscUtilities.mm ***/ - - -#else - -/*** Start of inlined file: juce_mac_MiscUtilities.mm ***/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#if JUCE_INCLUDED_FILE - -ScopedAutoReleasePool::ScopedAutoReleasePool() -{ - pool = [[NSAutoreleasePool alloc] init]; -} - -ScopedAutoReleasePool::~ScopedAutoReleasePool() -{ - [((NSAutoreleasePool*) pool) release]; -} - -void LookAndFeel::playAlertSound() -{ - NSBeep(); -} - -#if ! JUCE_ONLY_BUILD_CORE_LIBRARY - -class OSXMessageBox : public AsyncUpdater -{ -public: - OSXMessageBox (AlertWindow::AlertIconType iconType_, - const String& title_, const String& message_, - NSString* button1_, NSString* button2_, NSString* button3_, - ModalComponentManager::Callback* callback_, - const bool runAsync) - : iconType (iconType_), title (title_), - message (message_), callback (callback_), - button1 ([button1_ retain]), - button2 ([button2_ retain]), - button3 ([button3_ retain]) - { - if (runAsync) - triggerAsyncUpdate(); - } - - ~OSXMessageBox() - { - [button1 release]; - [button2 release]; - [button3 release]; - } - - int getResult() const - { - JUCE_AUTORELEASEPOOL - NSInteger r = getRawResult(); - return r == NSAlertDefaultReturn ? 1 : (r == NSAlertOtherReturn ? 2 : 0); - } - - void handleAsyncUpdate() - { - const int result = getResult(); - - if (callback != nullptr) - callback->modalStateFinished (result); - - delete this; - } - -private: - AlertWindow::AlertIconType iconType; - String title, message; - ModalComponentManager::Callback* callback; - NSString* button1; - NSString* button2; - NSString* button3; - - NSInteger getRawResult() const - { - NSString* messageString = juceStringToNS (message); - NSString* titleString = juceStringToNS (title); - - switch (iconType) - { - case AlertWindow::InfoIcon: return NSRunInformationalAlertPanel (titleString, messageString, button1, button2, button3); - case AlertWindow::WarningIcon: return NSRunCriticalAlertPanel (titleString, messageString, button1, button2, button3); - default: return NSRunAlertPanel (titleString, messageString, button1, button2, button3); - } - } -}; - -void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent) -{ - OSXMessageBox box (iconType, title, message, @"OK", nil, nil, 0, false); - (void) box.getResult(); -} - -void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent) -{ - new OSXMessageBox (iconType, title, message, @"OK", nil, nil, 0, true); -} - -bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent, - ModalComponentManager::Callback* callback) -{ - ScopedPointer mb (new OSXMessageBox (iconType, title, message, - @"OK", @"Cancel", nil, callback, callback != nullptr)); - if (callback == nullptr) - return mb->getResult() == 1; - - mb.release(); - return false; -} - -int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent, - ModalComponentManager::Callback* callback) -{ - ScopedPointer mb (new OSXMessageBox (iconType, title, message, - @"Yes", @"Cancel", @"No", callback, callback != nullptr)); - if (callback == nullptr) - return mb->getResult(); - - mb.release(); - return 0; -} - -bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool /*canMoveFiles*/) -{ - if (files.size() == 0) - return false; - - MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource(0); - - if (draggingSource == nullptr) - { - jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event! - return false; - } - - Component* sourceComp = draggingSource->getComponentUnderMouse(); - - if (sourceComp == nullptr) - { - jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event! - return false; - } - - JUCE_AUTORELEASEPOOL - - NSView* view = (NSView*) sourceComp->getWindowHandle(); - - if (view == nil) - return false; - - NSPasteboard* pboard = [NSPasteboard pasteboardWithName: NSDragPboard]; - [pboard declareTypes: [NSArray arrayWithObject: NSFilenamesPboardType] - owner: nil]; - - NSMutableArray* filesArray = [NSMutableArray arrayWithCapacity: 4]; - for (int i = 0; i < files.size(); ++i) - [filesArray addObject: juceStringToNS (files[i])]; - - [pboard setPropertyList: filesArray - forType: NSFilenamesPboardType]; - - NSPoint dragPosition = [view convertPoint: [[[view window] currentEvent] locationInWindow] - fromView: nil]; - dragPosition.x -= 16; - dragPosition.y -= 16; - - [view dragImage: [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (files[0])] - at: dragPosition - offset: NSMakeSize (0, 0) - event: [[view window] currentEvent] - pasteboard: pboard - source: view - slideBack: YES]; - - return true; -} - -bool DragAndDropContainer::performExternalDragDropOfText (const String& /*text*/) -{ - jassertfalse; // not implemented! - return false; -} - -bool Desktop::canUseSemiTransparentWindows() noexcept -{ - return true; -} - -const Point MouseInputSource::getCurrentMousePosition() -{ - JUCE_AUTORELEASEPOOL - const NSPoint p ([NSEvent mouseLocation]); - return Point (roundToInt (p.x), roundToInt ([[[NSScreen screens] objectAtIndex: 0] frame].size.height - p.y)); -} - -void Desktop::setMousePosition (const Point& newPosition) -{ - // this rubbish needs to be done around the warp call, to avoid causing a - // bizarre glitch.. - CGAssociateMouseAndMouseCursorPosition (false); - CGWarpMouseCursorPosition (CGPointMake (newPosition.getX(), newPosition.getY())); - CGAssociateMouseAndMouseCursorPosition (true); -} - -Desktop::DisplayOrientation Desktop::getCurrentOrientation() const -{ - return upright; -} - -#ifndef __POWER__ // Some versions of the SDK omit this function.. - extern "C" { extern OSErr UpdateSystemActivity (UInt8); } -#endif - -class ScreenSaverDefeater : public Timer -{ -public: - ScreenSaverDefeater() - { - startTimer (10000); - timerCallback(); - } - - void timerCallback() - { - if (Process::isForegroundProcess()) - UpdateSystemActivity (1 /*UsrActivity*/); - } -}; - -static ScopedPointer screenSaverDefeater; - -void Desktop::setScreenSaverEnabled (const bool isEnabled) -{ - if (isEnabled) - screenSaverDefeater = nullptr; - else if (screenSaverDefeater == nullptr) - screenSaverDefeater = new ScreenSaverDefeater(); -} - -bool Desktop::isScreenSaverEnabled() -{ - return screenSaverDefeater == nullptr; -} - -class DisplaySettingsChangeCallback : public DeletedAtShutdown -{ -public: - DisplaySettingsChangeCallback() - { - CGDisplayRegisterReconfigurationCallback (displayReconfigurationCallBack, 0); - } - - ~DisplaySettingsChangeCallback() - { - CGDisplayRemoveReconfigurationCallback (displayReconfigurationCallBack, 0); - clearSingletonInstance(); - } - - static void displayReconfigurationCallBack (CGDirectDisplayID, CGDisplayChangeSummaryFlags, void*) - { - Desktop::getInstance().refreshMonitorSizes(); - } - - juce_DeclareSingleton_SingleThreaded_Minimal (DisplaySettingsChangeCallback); - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DisplaySettingsChangeCallback); -}; - -juce_ImplementSingleton_SingleThreaded (DisplaySettingsChangeCallback); - -void Desktop::getCurrentMonitorPositions (Array >& monitorCoords, const bool clipToWorkArea) -{ - JUCE_AUTORELEASEPOOL - - DisplaySettingsChangeCallback::getInstance(); - - monitorCoords.clear(); - NSArray* screens = [NSScreen screens]; - const CGFloat mainScreenBottom = [[[NSScreen screens] objectAtIndex: 0] frame].size.height; - - for (unsigned int i = 0; i < [screens count]; ++i) - { - NSScreen* s = (NSScreen*) [screens objectAtIndex: i]; - - NSRect r = clipToWorkArea ? [s visibleFrame] - : [s frame]; - - r.origin.y = mainScreenBottom - (r.origin.y + r.size.height); - - monitorCoords.add (convertToRectInt (r)); - } - - jassert (monitorCoords.size() > 0); -} - -#endif -#endif - -/*** End of inlined file: juce_mac_MiscUtilities.mm ***/ - - -#endif - - -/*** Start of inlined file: juce_mac_Debugging.mm ***/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#if JUCE_INCLUDED_FILE - -void Logger::outputDebugString (const String& text) -{ - std::cerr << text << std::endl; -} - -JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger() -{ - static char testResult = 0; - - if (testResult == 0) - { - struct kinfo_proc info; - int m[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; - size_t sz = sizeof (info); - sysctl (m, 4, &info, &sz, 0, 0); - testResult = ((info.kp_proc.p_flag & P_TRACED) != 0) ? 1 : -1; - } - - return testResult > 0; -} - -JUCE_API bool JUCE_CALLTYPE Process::isRunningUnderDebugger() -{ - return juce_isRunningUnderDebugger(); -} - -#endif - -/*** End of inlined file: juce_mac_Debugging.mm ***/ - -#if ! JUCE_ONLY_BUILD_CORE_LIBRARY - #if JUCE_IOS - -/*** Start of inlined file: juce_mac_Fonts.mm ***/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#if JUCE_INCLUDED_FILE - -#if (JUCE_MAC && defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 \ - && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5) \ - || (JUCE_IOS && defined (__IPHONE_3_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_2) - #define JUCE_CORETEXT_AVAILABLE 1 -#endif - -#if JUCE_CORETEXT_AVAILABLE - -class MacTypeface : public Typeface -{ -public: - - MacTypeface (const Font& font) - : Typeface (font.getTypefaceName()), - fontRef (nullptr), - fontHeightToCGSizeFactor (1.0f), - renderingTransform (CGAffineTransformIdentity), - ctFontRef (nullptr), - attributedStringAtts (nullptr), - ascent (0.0f), - unitsToHeightScaleFactor (0.0f) - { - JUCE_AUTORELEASEPOOL - CFStringRef cfName = font.getTypefaceName().toCFString(); - ctFontRef = CTFontCreateWithName (cfName, 1024, nullptr); - CFRelease (cfName); - - if (ctFontRef != nullptr) - { - bool needsItalicTransform = false; - - if (font.isItalic()) - { - CTFontRef newFont = CTFontCreateCopyWithSymbolicTraits (ctFontRef, 0.0f, nullptr, - kCTFontItalicTrait, kCTFontItalicTrait); - - if (newFont != nullptr) - { - CFRelease (ctFontRef); - ctFontRef = newFont; - } - else - { - needsItalicTransform = true; // couldn't find a proper italic version, so fake it with a transform.. - } - } - - if (font.isBold()) - { - CTFontRef newFont = CTFontCreateCopyWithSymbolicTraits (ctFontRef, 0.0f, nullptr, - kCTFontBoldTrait, kCTFontBoldTrait); - if (newFont != nullptr) - { - CFRelease (ctFontRef); - ctFontRef = newFont; - } - } - - ascent = std::abs ((float) CTFontGetAscent (ctFontRef)); - const float totalSize = ascent + std::abs ((float) CTFontGetDescent (ctFontRef)); - ascent /= totalSize; - - pathTransform = AffineTransform::identity.scale (1.0f / totalSize, 1.0f / totalSize); - - if (needsItalicTransform) - { - pathTransform = pathTransform.sheared (-0.15f, 0.0f); - renderingTransform.c = 0.15f; - } - - fontRef = CTFontCopyGraphicsFont (ctFontRef, nullptr); - - const int totalHeight = abs (CGFontGetAscent (fontRef)) + abs (CGFontGetDescent (fontRef)); - const float ctTotalHeight = abs (CTFontGetAscent (ctFontRef)) + abs (CTFontGetDescent (ctFontRef)); - unitsToHeightScaleFactor = 1.0f / ctTotalHeight; - fontHeightToCGSizeFactor = CGFontGetUnitsPerEm (fontRef) / (float) totalHeight; - - const short zero = 0; - CFNumberRef numberRef = CFNumberCreate (0, kCFNumberShortType, &zero); - - CFStringRef keys[] = { kCTFontAttributeName, kCTLigatureAttributeName }; - CFTypeRef values[] = { ctFontRef, numberRef }; - attributedStringAtts = CFDictionaryCreate (nullptr, (const void**) &keys, (const void**) &values, numElementsInArray (keys), - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFRelease (numberRef); - } - } - - ~MacTypeface() - { - if (attributedStringAtts != nullptr) - CFRelease (attributedStringAtts); - - if (fontRef != nullptr) - CGFontRelease (fontRef); - - if (ctFontRef != nullptr) - CFRelease (ctFontRef); - } - - float getAscent() const { return ascent; } - float getDescent() const { return 1.0f - ascent; } - - float getStringWidth (const String& text) - { - float x = 0; - - if (ctFontRef != nullptr && text.isNotEmpty()) - { - CFStringRef cfText = text.toCFString(); - CFAttributedStringRef attribString = CFAttributedStringCreate (kCFAllocatorDefault, cfText, attributedStringAtts); - CFRelease (cfText); - - CTLineRef line = CTLineCreateWithAttributedString (attribString); - CFArrayRef runArray = CTLineGetGlyphRuns (line); - - for (CFIndex i = 0; i < CFArrayGetCount (runArray); ++i) - { - CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (runArray, i); - CFIndex length = CTRunGetGlyphCount (run); - HeapBlock advances (length); - CTRunGetAdvances (run, CFRangeMake (0, 0), advances); - - for (int j = 0; j < length; ++j) - x += (float) advances[j].width; - } - - CFRelease (line); - CFRelease (attribString); - - x *= unitsToHeightScaleFactor; - } - - return x; - } - - void getGlyphPositions (const String& text, Array & resultGlyphs, Array & xOffsets) - { - xOffsets.add (0); - - if (ctFontRef != nullptr && text.isNotEmpty()) - { - float x = 0; + if (ctFontRef != nullptr && text.isNotEmpty()) + { + float x = 0; CFStringRef cfText = text.toCFString(); CFAttributedStringRef attribString = CFAttributedStringCreate (kCFAllocatorDefault, cfText, attributedStringAtts); @@ -276331,124 +275806,349 @@ BOOL UIViewComponentPeer::textViewReplaceCharacters (const Range& range, co { TextInputTarget* const target = findCurrentTextInputTarget(); - if (target != nullptr) - { - const Range currentSelection (target->getHighlightedRegion()); + if (target != nullptr) + { + const Range currentSelection (target->getHighlightedRegion()); + + if (range.getLength() == 1 && text.isEmpty()) // (detect backspace) + if (currentSelection.isEmpty()) + target->setHighlightedRegion (currentSelection.withStart (currentSelection.getStart() - 1)); + + if (text == "\r" || text == "\n" || text == "\r\n") + handleKeyPress (KeyPress::returnKey, text[0]); + else + target->insertTextAtCaret (text); + + updateHiddenTextContent (target); + } + + return NO; +} + +void UIViewComponentPeer::globalFocusChanged (Component*) +{ + TextInputTarget* const target = findCurrentTextInputTarget(); + + if (target != nullptr) + { + Component* comp = dynamic_cast (target); + + Point pos (component->getLocalPoint (comp, Point())); + view->hiddenTextView.frame = CGRectMake (pos.getX(), pos.getY(), 0, 0); + + updateHiddenTextContent (target); + [view->hiddenTextView becomeFirstResponder]; + } + else + { + [view->hiddenTextView resignFirstResponder]; + } +} + +void UIViewComponentPeer::drawRect (CGRect r) +{ + if (r.size.width < 1.0f || r.size.height < 1.0f) + return; + + CGContextRef cg = UIGraphicsGetCurrentContext(); + + if (! component->isOpaque()) + CGContextClearRect (cg, CGContextGetClipBoundingBox (cg)); + + CGContextConcatCTM (cg, CGAffineTransformMake (1, 0, 0, -1, 0, view.bounds.size.height)); + CoreGraphicsContext g (cg, view.bounds.size.height); + + insideDrawRect = true; + handlePaint (g); + insideDrawRect = false; +} + +bool UIViewComponentPeer::canBecomeKeyWindow() +{ + return (getStyleFlags() & JUCE_NAMESPACE::ComponentPeer::windowIgnoresKeyPresses) == 0; +} + +bool UIViewComponentPeer::windowShouldClose() +{ + if (! isValidPeer (this)) + return YES; + + handleUserClosingWindow(); + return NO; +} + +void UIViewComponentPeer::redirectMovedOrResized() +{ + handleMovedOrResized(); +} + +void Desktop::setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars) +{ + // TODO +} + +class AsyncRepaintMessage : public CallbackMessage +{ +public: + UIViewComponentPeer* const peer; + const Rectangle rect; + + AsyncRepaintMessage (UIViewComponentPeer* const peer_, const Rectangle& rect_) + : peer (peer_), rect (rect_) + { + } + + void messageCallback() + { + if (ComponentPeer::isValidPeer (peer)) + peer->repaint (rect); + } +}; + +void UIViewComponentPeer::repaint (const Rectangle& area) +{ + if (insideDrawRect || ! MessageManager::getInstance()->isThisTheMessageThread()) + { + (new AsyncRepaintMessage (this, area))->post(); + } + else + { + [view setNeedsDisplayInRect: convertToCGRect (area)]; + } +} + +void UIViewComponentPeer::performAnyPendingRepaintsNow() +{ +} + +ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo) +{ + return new UIViewComponentPeer (this, styleFlags, (UIView*) windowToAttachTo); +} + +const int KeyPress::spaceKey = ' '; +const int KeyPress::returnKey = 0x0d; +const int KeyPress::escapeKey = 0x1b; +const int KeyPress::backspaceKey = 0x7f; +const int KeyPress::leftKey = 0x1000; +const int KeyPress::rightKey = 0x1001; +const int KeyPress::upKey = 0x1002; +const int KeyPress::downKey = 0x1003; +const int KeyPress::pageUpKey = 0x1004; +const int KeyPress::pageDownKey = 0x1005; +const int KeyPress::endKey = 0x1006; +const int KeyPress::homeKey = 0x1007; +const int KeyPress::deleteKey = 0x1008; +const int KeyPress::insertKey = -1; +const int KeyPress::tabKey = 9; +const int KeyPress::F1Key = 0x2001; +const int KeyPress::F2Key = 0x2002; +const int KeyPress::F3Key = 0x2003; +const int KeyPress::F4Key = 0x2004; +const int KeyPress::F5Key = 0x2005; +const int KeyPress::F6Key = 0x2006; +const int KeyPress::F7Key = 0x2007; +const int KeyPress::F8Key = 0x2008; +const int KeyPress::F9Key = 0x2009; +const int KeyPress::F10Key = 0x200a; +const int KeyPress::F11Key = 0x200b; +const int KeyPress::F12Key = 0x200c; +const int KeyPress::F13Key = 0x200d; +const int KeyPress::F14Key = 0x200e; +const int KeyPress::F15Key = 0x200f; +const int KeyPress::F16Key = 0x2010; +const int KeyPress::numberPad0 = 0x30020; +const int KeyPress::numberPad1 = 0x30021; +const int KeyPress::numberPad2 = 0x30022; +const int KeyPress::numberPad3 = 0x30023; +const int KeyPress::numberPad4 = 0x30024; +const int KeyPress::numberPad5 = 0x30025; +const int KeyPress::numberPad6 = 0x30026; +const int KeyPress::numberPad7 = 0x30027; +const int KeyPress::numberPad8 = 0x30028; +const int KeyPress::numberPad9 = 0x30029; +const int KeyPress::numberPadAdd = 0x3002a; +const int KeyPress::numberPadSubtract = 0x3002b; +const int KeyPress::numberPadMultiply = 0x3002c; +const int KeyPress::numberPadDivide = 0x3002d; +const int KeyPress::numberPadSeparator = 0x3002e; +const int KeyPress::numberPadDecimalPoint = 0x3002f; +const int KeyPress::numberPadEquals = 0x30030; +const int KeyPress::numberPadDelete = 0x30031; +const int KeyPress::playKey = 0x30000; +const int KeyPress::stopKey = 0x30001; +const int KeyPress::fastForwardKey = 0x30002; +const int KeyPress::rewindKey = 0x30003; + +#endif + +/*** End of inlined file: juce_ios_UIViewComponentPeer.mm ***/ + + +/*** Start of inlined file: juce_ios_Windowing.mm ***/ +// (This file gets included by juce_mac_NativeCode.mm, rather than being +// compiled on its own). +#if JUCE_INCLUDED_FILE + +void LookAndFeel::playAlertSound() +{ + //xxx + //AudioServicesPlaySystemSound (); +} + +class iOSMessageBox; + +END_JUCE_NAMESPACE + +@interface JuceAlertBoxDelegate : NSObject +{ +@public + iOSMessageBox* owner; +} + +- (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex; + +@end - if (range.getLength() == 1 && text.isEmpty()) // (detect backspace) - if (currentSelection.isEmpty()) - target->setHighlightedRegion (currentSelection.withStart (currentSelection.getStart() - 1)); +BEGIN_JUCE_NAMESPACE - if (text == "\r" || text == "\n" || text == "\r\n") - handleKeyPress (KeyPress::returnKey, text[0]); - else - target->insertTextAtCaret (text); +class iOSMessageBox +{ +public: + iOSMessageBox (const String& title, const String& message, + NSString* button1, NSString* button2, NSString* button3, + ModalComponentManager::Callback* callback_, const bool isAsync_) + : result (0), delegate (nil), alert (nil), + callback (callback_), isYesNo (button3 != nil), isAsync (isAsync_) + { + delegate = [[JuceAlertBoxDelegate alloc] init]; + delegate->owner = this; - updateHiddenTextContent (target); + alert = [[UIAlertView alloc] initWithTitle: juceStringToNS (title) + message: juceStringToNS (message) + delegate: delegate + cancelButtonTitle: button1 + otherButtonTitles: button2, button3, nil]; + [alert retain]; + [alert show]; } - return NO; -} - -void UIViewComponentPeer::globalFocusChanged (Component*) -{ - TextInputTarget* const target = findCurrentTextInputTarget(); + ~iOSMessageBox() + { + [alert release]; + [delegate release]; + } - if (target != nullptr) + int getResult() { - Component* comp = dynamic_cast (target); + jassert (callback == nullptr); + JUCE_AUTORELEASEPOOL - Point pos (component->getLocalPoint (comp, Point())); - view->hiddenTextView.frame = CGRectMake (pos.getX(), pos.getY(), 0, 0); + while (! alert.hidden && alert.superview != nil) + [[NSRunLoop mainRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]]; - updateHiddenTextContent (target); - [view->hiddenTextView becomeFirstResponder]; + return result; } - else + + void buttonClicked (const int buttonIndex) noexcept { - [view->hiddenTextView resignFirstResponder]; - } -} + result = buttonIndex; -void UIViewComponentPeer::drawRect (CGRect r) -{ - if (r.size.width < 1.0f || r.size.height < 1.0f) - return; + if (callback != nullptr) + callback->modalStateFinished (result); - CGContextRef cg = UIGraphicsGetCurrentContext(); + if (isAsync) + delete this; + } - if (! component->isOpaque()) - CGContextClearRect (cg, CGContextGetClipBoundingBox (cg)); +private: + int result; + JuceAlertBoxDelegate* delegate; + UIAlertView* alert; + ModalComponentManager::Callback* callback; + const bool isYesNo, isAsync; - CGContextConcatCTM (cg, CGAffineTransformMake (1, 0, 0, -1, 0, view.bounds.size.height)); - CoreGraphicsContext g (cg, view.bounds.size.height); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (iOSMessageBox); +}; - insideDrawRect = true; - handlePaint (g); - insideDrawRect = false; -} +END_JUCE_NAMESPACE -bool UIViewComponentPeer::canBecomeKeyWindow() +@implementation JuceAlertBoxDelegate + +- (void) alertView: (UIAlertView*) alertView clickedButtonAtIndex: (NSInteger) buttonIndex { - return (getStyleFlags() & JUCE_NAMESPACE::ComponentPeer::windowIgnoresKeyPresses) == 0; + owner->buttonClicked (buttonIndex); + alertView.hidden = true; } -bool UIViewComponentPeer::windowShouldClose() -{ - if (! isValidPeer (this)) - return YES; +@end +BEGIN_JUCE_NAMESPACE - handleUserClosingWindow(); - return NO; +void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent) +{ + JUCE_AUTORELEASEPOOL + iOSMessageBox mb (title, message, @"OK", nil, nil, 0, false); + (void) mb.getResult(); } -void UIViewComponentPeer::redirectMovedOrResized() +void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent) { - handleMovedOrResized(); + JUCE_AUTORELEASEPOOL + new iOSMessageBox (title, message, @"OK", nil, nil, 0, true); } -void Desktop::setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars) +bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) { - // TODO + ScopedPointer mb (new iOSMessageBox (title, message, @"Cancel", @"OK", nil, callback, callback != nullptr)); + + if (callback == nullptr) + return mb->getResult() == 1; + + mb.release(); + return false; } -class AsyncRepaintMessage : public CallbackMessage +int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) { -public: - UIViewComponentPeer* const peer; - const Rectangle rect; + ScopedPointer mb (new iOSMessageBox (title, message, @"Cancel", @"Yes", @"No", callback, callback != nullptr)); - AsyncRepaintMessage (UIViewComponentPeer* const peer_, const Rectangle& rect_) - : peer (peer_), rect (rect_) - { - } + if (callback == nullptr) + return mb->getResult(); - void messageCallback() - { - if (ComponentPeer::isValidPeer (peer)) - peer->repaint (rect); - } -}; + mb.release(); + return 0; +} -void UIViewComponentPeer::repaint (const Rectangle& area) +bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles) { - if (insideDrawRect || ! MessageManager::getInstance()->isThisTheMessageThread()) - { - (new AsyncRepaintMessage (this, area))->post(); - } - else - { - [view setNeedsDisplayInRect: convertToCGRect (area)]; - } + jassertfalse; // no such thing on the iphone! + return false; } -void UIViewComponentPeer::performAnyPendingRepaintsNow() +bool DragAndDropContainer::performExternalDragDropOfText (const String& text) { + jassertfalse; // no such thing on the iphone! + return false; } -ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo) +void Desktop::setScreenSaverEnabled (const bool isEnabled) { - return new UIViewComponentPeer (this, styleFlags, (UIView*) windowToAttachTo); + [[UIApplication sharedApplication] setIdleTimerDisabled: ! isEnabled]; +} + +bool Desktop::isScreenSaverEnabled() +{ + return ! [[UIApplication sharedApplication] isIdleTimerDisabled]; } Image juce_createIconForFile (const File& file) @@ -276506,69 +276206,50 @@ void Desktop::getCurrentMonitorPositions (Array >& monitorCoord monitorCoords.add (UIViewComponentPeer::realScreenPosToRotated (convertToRectInt (r))); } -const int KeyPress::spaceKey = ' '; -const int KeyPress::returnKey = 0x0d; -const int KeyPress::escapeKey = 0x1b; -const int KeyPress::backspaceKey = 0x7f; -const int KeyPress::leftKey = 0x1000; -const int KeyPress::rightKey = 0x1001; -const int KeyPress::upKey = 0x1002; -const int KeyPress::downKey = 0x1003; -const int KeyPress::pageUpKey = 0x1004; -const int KeyPress::pageDownKey = 0x1005; -const int KeyPress::endKey = 0x1006; -const int KeyPress::homeKey = 0x1007; -const int KeyPress::deleteKey = 0x1008; -const int KeyPress::insertKey = -1; -const int KeyPress::tabKey = 9; -const int KeyPress::F1Key = 0x2001; -const int KeyPress::F2Key = 0x2002; -const int KeyPress::F3Key = 0x2003; -const int KeyPress::F4Key = 0x2004; -const int KeyPress::F5Key = 0x2005; -const int KeyPress::F6Key = 0x2006; -const int KeyPress::F7Key = 0x2007; -const int KeyPress::F8Key = 0x2008; -const int KeyPress::F9Key = 0x2009; -const int KeyPress::F10Key = 0x200a; -const int KeyPress::F11Key = 0x200b; -const int KeyPress::F12Key = 0x200c; -const int KeyPress::F13Key = 0x200d; -const int KeyPress::F14Key = 0x200e; -const int KeyPress::F15Key = 0x200f; -const int KeyPress::F16Key = 0x2010; -const int KeyPress::numberPad0 = 0x30020; -const int KeyPress::numberPad1 = 0x30021; -const int KeyPress::numberPad2 = 0x30022; -const int KeyPress::numberPad3 = 0x30023; -const int KeyPress::numberPad4 = 0x30024; -const int KeyPress::numberPad5 = 0x30025; -const int KeyPress::numberPad6 = 0x30026; -const int KeyPress::numberPad7 = 0x30027; -const int KeyPress::numberPad8 = 0x30028; -const int KeyPress::numberPad9 = 0x30029; -const int KeyPress::numberPadAdd = 0x3002a; -const int KeyPress::numberPadSubtract = 0x3002b; -const int KeyPress::numberPadMultiply = 0x3002c; -const int KeyPress::numberPadDivide = 0x3002d; -const int KeyPress::numberPadSeparator = 0x3002e; -const int KeyPress::numberPadDecimalPoint = 0x3002f; -const int KeyPress::numberPadEquals = 0x30030; -const int KeyPress::numberPadDelete = 0x30031; -const int KeyPress::playKey = 0x30000; -const int KeyPress::stopKey = 0x30001; -const int KeyPress::fastForwardKey = 0x30002; -const int KeyPress::rewindKey = 0x30003; +#endif + +/*** End of inlined file: juce_ios_Windowing.mm ***/ + + +/*** Start of inlined file: juce_ios_MessageManager.mm ***/ +// (This file gets included by juce_mac_NativeCode.mm, rather than being +// compiled on its own). +#if JUCE_INCLUDED_FILE + +END_JUCE_NAMESPACE + +@interface JuceAppStartupDelegate : NSObject +{ +} + +- (void) applicationDidFinishLaunching: (UIApplication*) application; +- (void) applicationWillTerminate: (UIApplication*) application; + +@end + +@implementation JuceAppStartupDelegate + +- (void) applicationDidFinishLaunching: (UIApplication*) application +{ + initialiseJuce_GUI(); -#endif + if (! JUCEApplication::createInstance()->initialiseApp (String::empty)) + exit (0); +} -/*** End of inlined file: juce_ios_UIViewComponentPeer.mm ***/ +- (void) applicationWillTerminate: (UIApplication*) application +{ + JUCEApplication::appWillTerminateByForce(); +} +@end -/*** Start of inlined file: juce_ios_MessageManager.mm ***/ -// (This file gets included by juce_mac_NativeCode.mm, rather than being -// compiled on its own). -#if JUCE_INCLUDED_FILE +BEGIN_JUCE_NAMESPACE + +int juce_iOSMain (int argc, const char* argv[]) +{ + return UIApplicationMain (argc, const_cast (argv), nil, @"JuceAppStartupDelegate"); +} struct CallbackMessagePayload { @@ -281229,993 +280910,1343 @@ END_JUCE_NAMESPACE && owner->hasNativeTitleBar()) JUCE_NAMESPACE::Component::getCurrentlyModalComponent()->inputAttemptWhenModal(); - return frameRect.size; + return frameRect.size; +} + +- (void) zoom: (id) sender +{ + isZooming = true; + [super zoom: sender]; + isZooming = false; + + owner->redirectMovedOrResized(); +} + +- (void) windowWillMove: (NSNotification*) notification +{ + (void) notification; + + if (JUCE_NAMESPACE::Component::getCurrentlyModalComponent() != nullptr + && owner->getComponent()->isCurrentlyBlockedByAnotherModalComponent() + && owner->hasNativeTitleBar()) + JUCE_NAMESPACE::Component::getCurrentlyModalComponent()->inputAttemptWhenModal(); +} + +@end + +BEGIN_JUCE_NAMESPACE + +ModifierKeys NSViewComponentPeer::currentModifiers; +ComponentPeer* NSViewComponentPeer::currentlyFocusedPeer = nullptr; +Array NSViewComponentPeer::keysCurrentlyDown; + +bool KeyPress::isKeyCurrentlyDown (const int keyCode) +{ + if (NSViewComponentPeer::keysCurrentlyDown.contains (keyCode)) + return true; + + if (keyCode >= 'A' && keyCode <= 'Z' + && NSViewComponentPeer::keysCurrentlyDown.contains ((int) CharacterFunctions::toLowerCase ((juce_wchar) keyCode))) + return true; + + if (keyCode >= 'a' && keyCode <= 'z' + && NSViewComponentPeer::keysCurrentlyDown.contains ((int) CharacterFunctions::toUpperCase ((juce_wchar) keyCode))) + return true; + + return false; +} + +void NSViewComponentPeer::updateModifiers (NSEvent* e) +{ + int m = 0; + + if (([e modifierFlags] & NSShiftKeyMask) != 0) m |= ModifierKeys::shiftModifier; + if (([e modifierFlags] & NSControlKeyMask) != 0) m |= ModifierKeys::ctrlModifier; + if (([e modifierFlags] & NSAlternateKeyMask) != 0) m |= ModifierKeys::altModifier; + if (([e modifierFlags] & NSCommandKeyMask) != 0) m |= ModifierKeys::commandModifier; + + currentModifiers = currentModifiers.withOnlyMouseButtons().withFlags (m); +} + +void NSViewComponentPeer::updateKeysDown (NSEvent* ev, bool isKeyDown) +{ + updateModifiers (ev); + int keyCode = getKeyCodeFromEvent (ev); + + if (keyCode != 0) + { + if (isKeyDown) + keysCurrentlyDown.addIfNotAlreadyThere (keyCode); + else + keysCurrentlyDown.removeValue (keyCode); + } +} + +const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() noexcept +{ + return NSViewComponentPeer::currentModifiers; +} + +void ModifierKeys::updateCurrentModifiers() noexcept +{ + currentModifiers = NSViewComponentPeer::currentModifiers; +} + +NSViewComponentPeer::NSViewComponentPeer (Component* const component_, + const int windowStyleFlags, + NSView* viewToAttachTo) + : ComponentPeer (component_, windowStyleFlags), + window (nil), + view (nil), + isSharedWindow (viewToAttachTo != nil), + fullScreen (false), + insideDrawRect (false), + #if USE_COREGRAPHICS_RENDERING + usingCoreGraphics (true), + #else + usingCoreGraphics (false), + #endif + recursiveToFrontCall (false) +{ + NSRect r = NSMakeRect (0, 0, (CGFloat) component->getWidth(), (CGFloat) component->getHeight()); + + view = [[JuceNSView alloc] initWithOwner: this withFrame: r]; + [view setPostsFrameChangedNotifications: YES]; + + if (isSharedWindow) + { + window = [viewToAttachTo window]; + [viewToAttachTo addSubview: view]; + } + else + { + r.origin.x = (CGFloat) component->getX(); + r.origin.y = (CGFloat) component->getY(); + r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height); + + window = [[JuceNSWindow alloc] initWithContentRect: r + styleMask: getNSWindowStyleMask (windowStyleFlags) + backing: NSBackingStoreBuffered + defer: YES]; + + [((JuceNSWindow*) window) setOwner: this]; + [window orderOut: nil]; + [window setDelegate: (JuceNSWindow*) window]; + [window setOpaque: component->isOpaque()]; + [window setHasShadow: ((windowStyleFlags & windowHasDropShadow) != 0)]; + + if (component->isAlwaysOnTop()) + [window setLevel: NSFloatingWindowLevel]; + + [window setContentView: view]; + [window setAutodisplay: YES]; + [window setAcceptsMouseMovedEvents: YES]; + + // We'll both retain and also release this on closing because plugin hosts can unexpectedly + // close the window for us, and also tend to get cause trouble if setReleasedWhenClosed is NO. + [window setReleasedWhenClosed: YES]; + [window retain]; + + [window setExcludedFromWindowsMenu: (windowStyleFlags & windowIsTemporary) != 0]; + [window setIgnoresMouseEvents: (windowStyleFlags & windowIgnoresMouseClicks) != 0]; + } + + const float alpha = component->getAlpha(); + if (alpha < 1.0f) + setAlpha (alpha); + + setTitle (component->getName()); +} + +NSViewComponentPeer::~NSViewComponentPeer() +{ + view->owner = nullptr; + [view removeFromSuperview]; + [view release]; + + if (! isSharedWindow) + { + [((JuceNSWindow*) window) setOwner: 0]; + [window close]; + [window release]; + } +} + +void* NSViewComponentPeer::getNativeHandle() const +{ + return view; +} + +void NSViewComponentPeer::setVisible (bool shouldBeVisible) +{ + if (isSharedWindow) + { + [view setHidden: ! shouldBeVisible]; + } + else + { + if (shouldBeVisible) + { + [window orderFront: nil]; + handleBroughtToFront(); + } + else + { + [window orderOut: nil]; + } + } +} + +void NSViewComponentPeer::setTitle (const String& title) +{ + JUCE_AUTORELEASEPOOL + + if (! isSharedWindow) + [window setTitle: juceStringToNS (title)]; +} + +void NSViewComponentPeer::setPosition (int x, int y) +{ + setBounds (x, y, component->getWidth(), component->getHeight(), false); +} + +void NSViewComponentPeer::setSize (int w, int h) +{ + setBounds (component->getX(), component->getY(), w, h, false); +} + +void NSViewComponentPeer::setBounds (int x, int y, int w, int h, bool isNowFullScreen) +{ + fullScreen = isNowFullScreen; + + NSRect r = NSMakeRect ((CGFloat) x, (CGFloat) y, (CGFloat) jmax (0, w), (CGFloat) jmax (0, h)); + + if (isSharedWindow) + { + r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height); + + if ([view frame].size.width != r.size.width + || [view frame].size.height != r.size.height) + [view setNeedsDisplay: true]; + + [view setFrame: r]; + } + else + { + r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height); + + [window setFrame: [window frameRectForContentRect: r] + display: true]; + } +} + +const Rectangle NSViewComponentPeer::getBounds (const bool global) const +{ + NSRect r = [view frame]; + + if (global && [view window] != nil) + { + r = [view convertRect: r toView: nil]; + NSRect wr = [[view window] frame]; + r.origin.x += wr.origin.x; + r.origin.y += wr.origin.y; + r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height; + } + else + { + r.origin.y = [[view superview] frame].size.height - r.origin.y - r.size.height; + } + + return Rectangle (convertToRectInt (r)); } -- (void) zoom: (id) sender +const Rectangle NSViewComponentPeer::getBounds() const { - isZooming = true; - [super zoom: sender]; - isZooming = false; - - owner->redirectMovedOrResized(); + return getBounds (! isSharedWindow); } -- (void) windowWillMove: (NSNotification*) notification +const Point NSViewComponentPeer::getScreenPosition() const { - (void) notification; + return getBounds (true).getPosition(); +} - if (JUCE_NAMESPACE::Component::getCurrentlyModalComponent() != nullptr - && owner->getComponent()->isCurrentlyBlockedByAnotherModalComponent() - && owner->hasNativeTitleBar()) - JUCE_NAMESPACE::Component::getCurrentlyModalComponent()->inputAttemptWhenModal(); +const Point NSViewComponentPeer::localToGlobal (const Point& relativePosition) +{ + return relativePosition + getScreenPosition(); } -@end +const Point NSViewComponentPeer::globalToLocal (const Point& screenPosition) +{ + return screenPosition - getScreenPosition(); +} -BEGIN_JUCE_NAMESPACE +NSRect NSViewComponentPeer::constrainRect (NSRect r) +{ + if (constrainer != nullptr) + { + NSRect current = [window frame]; + current.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - current.origin.y - current.size.height; -ModifierKeys NSViewComponentPeer::currentModifiers; -ComponentPeer* NSViewComponentPeer::currentlyFocusedPeer = nullptr; -Array NSViewComponentPeer::keysCurrentlyDown; + r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height; -bool KeyPress::isKeyCurrentlyDown (const int keyCode) -{ - if (NSViewComponentPeer::keysCurrentlyDown.contains (keyCode)) - return true; + Rectangle pos (convertToRectInt (r)); + Rectangle original (convertToRectInt (current)); - if (keyCode >= 'A' && keyCode <= 'Z' - && NSViewComponentPeer::keysCurrentlyDown.contains ((int) CharacterFunctions::toLowerCase ((juce_wchar) keyCode))) - return true; + #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_ALLOWED >= MAC_OS_X_VERSION_10_6 + if ([window inLiveResize]) + #else + if ([window respondsToSelector: @selector (inLiveResize)] + && [window performSelector: @selector (inLiveResize)]) + #endif + { + constrainer->checkBounds (pos, original, + Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), + false, false, true, true); + } + else + { + constrainer->checkBounds (pos, original, + Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), + pos.getY() != original.getY() && pos.getBottom() == original.getBottom(), + pos.getX() != original.getX() && pos.getRight() == original.getRight(), + pos.getY() == original.getY() && pos.getBottom() != original.getBottom(), + pos.getX() == original.getX() && pos.getRight() != original.getRight()); + } - if (keyCode >= 'a' && keyCode <= 'z' - && NSViewComponentPeer::keysCurrentlyDown.contains ((int) CharacterFunctions::toUpperCase ((juce_wchar) keyCode))) - return true; + r.origin.x = pos.getX(); + r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.size.height - pos.getY(); + r.size.width = pos.getWidth(); + r.size.height = pos.getHeight(); + } - return false; + return r; } -void NSViewComponentPeer::updateModifiers (NSEvent* e) +void NSViewComponentPeer::setAlpha (float newAlpha) { - int m = 0; - - if (([e modifierFlags] & NSShiftKeyMask) != 0) m |= ModifierKeys::shiftModifier; - if (([e modifierFlags] & NSControlKeyMask) != 0) m |= ModifierKeys::ctrlModifier; - if (([e modifierFlags] & NSAlternateKeyMask) != 0) m |= ModifierKeys::altModifier; - if (([e modifierFlags] & NSCommandKeyMask) != 0) m |= ModifierKeys::commandModifier; - - currentModifiers = currentModifiers.withOnlyMouseButtons().withFlags (m); + if (! isSharedWindow) + { + [window setAlphaValue: (CGFloat) newAlpha]; + } + else + { + #if defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_ALLOWED >= MAC_OS_X_VERSION_10_5 + [view setAlphaValue: (CGFloat) newAlpha]; + #else + if ([view respondsToSelector: @selector (setAlphaValue:)]) + { + // PITA dynamic invocation for 10.4 builds.. + NSInvocation* inv = [NSInvocation invocationWithMethodSignature: [view methodSignatureForSelector: @selector (setAlphaValue:)]]; + [inv setSelector: @selector (setAlphaValue:)]; + [inv setTarget: view]; + CGFloat cgNewAlpha = (CGFloat) newAlpha; + [inv setArgument: &cgNewAlpha atIndex: 2]; + [inv invoke]; + } + #endif + } } -void NSViewComponentPeer::updateKeysDown (NSEvent* ev, bool isKeyDown) +void NSViewComponentPeer::setMinimised (bool shouldBeMinimised) { - updateModifiers (ev); - int keyCode = getKeyCodeFromEvent (ev); - - if (keyCode != 0) + if (! isSharedWindow) { - if (isKeyDown) - keysCurrentlyDown.addIfNotAlreadyThere (keyCode); + if (shouldBeMinimised) + [window miniaturize: nil]; else - keysCurrentlyDown.removeValue (keyCode); + [window deminiaturize: nil]; } } -const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() noexcept +bool NSViewComponentPeer::isMinimised() const { - return NSViewComponentPeer::currentModifiers; + return [window isMiniaturized]; } -void ModifierKeys::updateCurrentModifiers() noexcept +void NSViewComponentPeer::setFullScreen (bool shouldBeFullScreen) { - currentModifiers = NSViewComponentPeer::currentModifiers; + if (! isSharedWindow) + { + Rectangle r (lastNonFullscreenBounds); + + if (isMinimised()) + setMinimised (false); + + if (fullScreen != shouldBeFullScreen) + { + if (shouldBeFullScreen && hasNativeTitleBar()) + { + fullScreen = true; + [window performZoom: nil]; + } + else + { + if (shouldBeFullScreen) + r = component->getParentMonitorArea(); + + // (can't call the component's setBounds method because that'll reset our fullscreen flag) + if (r != getComponent()->getBounds() && ! r.isEmpty()) + setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen); + } + } + } } -NSViewComponentPeer::NSViewComponentPeer (Component* const component_, - const int windowStyleFlags, - NSView* viewToAttachTo) - : ComponentPeer (component_, windowStyleFlags), - window (nil), - view (nil), - isSharedWindow (viewToAttachTo != nil), - fullScreen (false), - insideDrawRect (false), - #if USE_COREGRAPHICS_RENDERING - usingCoreGraphics (true), - #else - usingCoreGraphics (false), - #endif - recursiveToFrontCall (false) +bool NSViewComponentPeer::isFullScreen() const { - NSRect r = NSMakeRect (0, 0, (CGFloat) component->getWidth(), (CGFloat) component->getHeight()); + return fullScreen; +} - view = [[JuceNSView alloc] initWithOwner: this withFrame: r]; - [view setPostsFrameChangedNotifications: YES]; +bool NSViewComponentPeer::contains (const Point& position, bool trueIfInAChildWindow) const +{ + if (! (isPositiveAndBelow (position.getX(), component->getWidth()) + && isPositiveAndBelow (position.getY(), component->getHeight()))) + return false; - if (isSharedWindow) - { - window = [viewToAttachTo window]; - [viewToAttachTo addSubview: view]; - } - else - { - r.origin.x = (CGFloat) component->getX(); - r.origin.y = (CGFloat) component->getY(); - r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height); + NSRect frameRect = [view frame]; - window = [[JuceNSWindow alloc] initWithContentRect: r - styleMask: getNSWindowStyleMask (windowStyleFlags) - backing: NSBackingStoreBuffered - defer: YES]; + NSView* v = [view hitTest: NSMakePoint (frameRect.origin.x + position.getX(), + frameRect.origin.y + frameRect.size.height - position.getY())]; - [((JuceNSWindow*) window) setOwner: this]; - [window orderOut: nil]; - [window setDelegate: (JuceNSWindow*) window]; - [window setOpaque: component->isOpaque()]; - [window setHasShadow: ((windowStyleFlags & windowHasDropShadow) != 0)]; + if (trueIfInAChildWindow) + return v != nil; - if (component->isAlwaysOnTop()) - [window setLevel: NSFloatingWindowLevel]; + return v == view; +} - [window setContentView: view]; - [window setAutodisplay: YES]; - [window setAcceptsMouseMovedEvents: YES]; +const BorderSize NSViewComponentPeer::getFrameSize() const +{ + BorderSize b; - // We'll both retain and also release this on closing because plugin hosts can unexpectedly - // close the window for us, and also tend to get cause trouble if setReleasedWhenClosed is NO. - [window setReleasedWhenClosed: YES]; - [window retain]; + if (! isSharedWindow) + { + NSRect v = [view convertRect: [view frame] toView: nil]; + NSRect w = [window frame]; - [window setExcludedFromWindowsMenu: (windowStyleFlags & windowIsTemporary) != 0]; - [window setIgnoresMouseEvents: (windowStyleFlags & windowIgnoresMouseClicks) != 0]; + b.setTop ((int) (w.size.height - (v.origin.y + v.size.height))); + b.setBottom ((int) v.origin.y); + b.setLeft ((int) v.origin.x); + b.setRight ((int) (w.size.width - (v.origin.x + v.size.width))); } - const float alpha = component->getAlpha(); - if (alpha < 1.0f) - setAlpha (alpha); + return b; +} + +bool NSViewComponentPeer::setAlwaysOnTop (bool alwaysOnTop) +{ + if (! isSharedWindow) + [window setLevel: alwaysOnTop ? NSFloatingWindowLevel + : NSNormalWindowLevel]; + return true; +} + +void NSViewComponentPeer::toFront (bool makeActiveWindow) +{ + if (isSharedWindow) + [[view superview] addSubview: view + positioned: NSWindowAbove + relativeTo: nil]; + + if (window != nil && component->isVisible()) + { + if (makeActiveWindow) + [window makeKeyAndOrderFront: nil]; + else + [window orderFront: nil]; - setTitle (component->getName()); + if (! recursiveToFrontCall) + { + recursiveToFrontCall = true; + Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate(); + handleBroughtToFront(); + recursiveToFrontCall = false; + } + } } -NSViewComponentPeer::~NSViewComponentPeer() +void NSViewComponentPeer::toBehind (ComponentPeer* other) { - view->owner = nullptr; - [view removeFromSuperview]; - [view release]; + NSViewComponentPeer* const otherPeer = dynamic_cast (other); + jassert (otherPeer != nullptr); // wrong type of window? - if (! isSharedWindow) + if (otherPeer != nullptr) { - [((JuceNSWindow*) window) setOwner: 0]; - [window close]; - [window release]; + if (isSharedWindow) + { + [[view superview] addSubview: view + positioned: NSWindowBelow + relativeTo: otherPeer->view]; + } + else + { + [window orderWindow: NSWindowBelow + relativeTo: [otherPeer->window windowNumber]]; + } } } -void* NSViewComponentPeer::getNativeHandle() const +void NSViewComponentPeer::setIcon (const Image& /*newIcon*/) { - return view; + // to do.. } -void NSViewComponentPeer::setVisible (bool shouldBeVisible) +void NSViewComponentPeer::viewFocusGain() { - if (isSharedWindow) + if (currentlyFocusedPeer != this) { - [view setHidden: ! shouldBeVisible]; + if (ComponentPeer::isValidPeer (currentlyFocusedPeer)) + currentlyFocusedPeer->handleFocusLoss(); + + currentlyFocusedPeer = this; + handleFocusGain(); } - else +} + +void NSViewComponentPeer::viewFocusLoss() +{ + if (currentlyFocusedPeer == this) { - if (shouldBeVisible) + currentlyFocusedPeer = nullptr; + handleFocusLoss(); + } +} + +void juce_HandleProcessFocusChange() +{ + NSViewComponentPeer::keysCurrentlyDown.clear(); + + if (NSViewComponentPeer::isValidPeer (NSViewComponentPeer::currentlyFocusedPeer)) + { + if (Process::isForegroundProcess()) { - [window orderFront: nil]; - handleBroughtToFront(); + NSViewComponentPeer::currentlyFocusedPeer->handleFocusGain(); + + ModalComponentManager::getInstance()->bringModalComponentsToFront(); } else { - [window orderOut: nil]; + NSViewComponentPeer::currentlyFocusedPeer->handleFocusLoss(); + + // turn kiosk mode off if we lose focus.. + Desktop::getInstance().setKioskModeComponent (nullptr); } } } -void NSViewComponentPeer::setTitle (const String& title) +bool NSViewComponentPeer::isFocused() const { - JUCE_AUTORELEASEPOOL - - if (! isSharedWindow) - [window setTitle: juceStringToNS (title)]; + return isSharedWindow ? this == currentlyFocusedPeer + : [window isKeyWindow]; } -void NSViewComponentPeer::setPosition (int x, int y) +void NSViewComponentPeer::grabFocus() { - setBounds (x, y, component->getWidth(), component->getHeight(), false); + if (window != nil) + { + [window makeKeyWindow]; + [window makeFirstResponder: view]; + + viewFocusGain(); + } } -void NSViewComponentPeer::setSize (int w, int h) +void NSViewComponentPeer::textInputRequired (const Point&) { - setBounds (component->getX(), component->getY(), w, h, false); } -void NSViewComponentPeer::setBounds (int x, int y, int w, int h, bool isNowFullScreen) +bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) { - fullScreen = isNowFullScreen; + String unicode (nsStringToJuce ([ev characters])); + String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers])); + int keyCode = getKeyCodeFromEvent (ev); - NSRect r = NSMakeRect ((CGFloat) x, (CGFloat) y, (CGFloat) jmax (0, w), (CGFloat) jmax (0, h)); + //DBG ("unicode: " + unicode + " " + String::toHexString ((int) unicode[0])); + //DBG ("unmodified: " + unmodified + " " + String::toHexString ((int) unmodified[0])); - if (isSharedWindow) + if (unicode.isNotEmpty() || keyCode != 0) { - r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height); + if (isKeyDown) + { + bool used = false; - if ([view frame].size.width != r.size.width - || [view frame].size.height != r.size.height) - [view setNeedsDisplay: true]; + while (unicode.length() > 0) + { + juce_wchar textCharacter = unicode[0]; + unicode = unicode.substring (1); - [view setFrame: r]; - } - else - { - r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - (r.origin.y + r.size.height); + if (([ev modifierFlags] & NSCommandKeyMask) != 0) + textCharacter = 0; - [window setFrame: [window frameRectForContentRect: r] - display: true]; + used = handleKeyUpOrDown (true) || used; + used = handleKeyPress (keyCode, textCharacter) || used; + } + + return used; + } + else + { + if (handleKeyUpOrDown (false)) + return true; + } } + + return false; } -const Rectangle NSViewComponentPeer::getBounds (const bool global) const +bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) { - NSRect r = [view frame]; + updateKeysDown (ev, true); + bool used = handleKeyEvent (ev, true); - if (global && [view window] != nil) - { - r = [view convertRect: r toView: nil]; - NSRect wr = [[view window] frame]; - r.origin.x += wr.origin.x; - r.origin.y += wr.origin.y; - r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height; - } - else + if (([ev modifierFlags] & NSCommandKeyMask) != 0) { - r.origin.y = [[view superview] frame].size.height - r.origin.y - r.size.height; + // for command keys, the key-up event is thrown away, so simulate one.. + updateKeysDown (ev, false); + used = (isValidPeer (this) && handleKeyEvent (ev, false)) || used; } - return Rectangle (convertToRectInt (r)); + // (If we're running modally, don't allow unused keystrokes to be passed + // along to other blocked views..) + if (Component::getCurrentlyModalComponent() != nullptr) + used = true; + + return used; } -const Rectangle NSViewComponentPeer::getBounds() const +bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev) { - return getBounds (! isSharedWindow); + updateKeysDown (ev, false); + return handleKeyEvent (ev, false) + || Component::getCurrentlyModalComponent() != nullptr; } -const Point NSViewComponentPeer::getScreenPosition() const +void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) { - return getBounds (true).getPosition(); + keysCurrentlyDown.clear(); + handleKeyUpOrDown (true); + + updateModifiers (ev); + handleModifierKeysChange(); } -const Point NSViewComponentPeer::localToGlobal (const Point& relativePosition) +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 +bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) { - return relativePosition + getScreenPosition(); + if ([ev type] == NSKeyDown) + return redirectKeyDown (ev); + else if ([ev type] == NSKeyUp) + return redirectKeyUp (ev); + + return false; } +#endif -const Point NSViewComponentPeer::globalToLocal (const Point& screenPosition) +void NSViewComponentPeer::sendMouseEvent (NSEvent* ev) { - return screenPosition - getScreenPosition(); + updateModifiers (ev); + handleMouseEvent (0, getMousePos (ev, view), currentModifiers, getMouseTime (ev)); } -NSRect NSViewComponentPeer::constrainRect (NSRect r) +void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) { - if (constrainer != nullptr) - { - NSRect current = [window frame]; - current.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - current.origin.y - current.size.height; + currentModifiers = currentModifiers.withFlags (getModifierForButtonNumber ([ev buttonNumber])); + sendMouseEvent (ev); +} - r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height; +void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) +{ + currentModifiers = currentModifiers.withoutFlags (getModifierForButtonNumber ([ev buttonNumber])); + sendMouseEvent (ev); + showArrowCursorIfNeeded(); +} - Rectangle pos (convertToRectInt (r)); - Rectangle original (convertToRectInt (current)); +void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) +{ + currentModifiers = currentModifiers.withFlags (getModifierForButtonNumber ([ev buttonNumber])); + sendMouseEvent (ev); +} - #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_ALLOWED >= MAC_OS_X_VERSION_10_6 - if ([window inLiveResize]) - #else - if ([window respondsToSelector: @selector (inLiveResize)] - && [window performSelector: @selector (inLiveResize)]) - #endif - { - constrainer->checkBounds (pos, original, - Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), - false, false, true, true); - } - else - { - constrainer->checkBounds (pos, original, - Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), - pos.getY() != original.getY() && pos.getBottom() == original.getBottom(), - pos.getX() != original.getX() && pos.getRight() == original.getRight(), - pos.getY() == original.getY() && pos.getBottom() != original.getBottom(), - pos.getX() == original.getX() && pos.getRight() != original.getRight()); - } +void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) +{ + currentModifiers = currentModifiers.withoutMouseButtons(); + sendMouseEvent (ev); + showArrowCursorIfNeeded(); +} - r.origin.x = pos.getX(); - r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.size.height - pos.getY(); - r.size.width = pos.getWidth(); - r.size.height = pos.getHeight(); - } +void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) +{ + Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate(); + currentModifiers = currentModifiers.withoutMouseButtons(); + sendMouseEvent (ev); +} - return r; +void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) +{ + currentModifiers = currentModifiers.withoutMouseButtons(); + sendMouseEvent (ev); } -void NSViewComponentPeer::setAlpha (float newAlpha) +void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) { - if (! isSharedWindow) + updateModifiers (ev); + + float x = 0, y = 0; + + @try { - [window setAlphaValue: (CGFloat) newAlpha]; + x = [ev deviceDeltaX] * 0.5f; + y = [ev deviceDeltaY] * 0.5f; } - else + @catch (...) + {} + + if (x == 0 && y == 0) { - #if defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_ALLOWED >= MAC_OS_X_VERSION_10_5 - [view setAlphaValue: (CGFloat) newAlpha]; - #else - if ([view respondsToSelector: @selector (setAlphaValue:)]) - { - // PITA dynamic invocation for 10.4 builds.. - NSInvocation* inv = [NSInvocation invocationWithMethodSignature: [view methodSignatureForSelector: @selector (setAlphaValue:)]]; - [inv setSelector: @selector (setAlphaValue:)]; - [inv setTarget: view]; - CGFloat cgNewAlpha = (CGFloat) newAlpha; - [inv setArgument: &cgNewAlpha atIndex: 2]; - [inv invoke]; - } - #endif + x = [ev deltaX] * 10.0f; + y = [ev deltaY] * 10.0f; } + + handleMouseWheel (0, getMousePos (ev, view), getMouseTime (ev), x, y); } -void NSViewComponentPeer::setMinimised (bool shouldBeMinimised) +void NSViewComponentPeer::showArrowCursorIfNeeded() { - if (! isSharedWindow) + MouseInputSource& mouse = Desktop::getInstance().getMainMouseSource(); + + if (mouse.getComponentUnderMouse() == nullptr + && Desktop::getInstance().findComponentAt (mouse.getScreenPosition()) == nullptr) { - if (shouldBeMinimised) - [window miniaturize: nil]; - else - [window deminiaturize: nil]; + [[NSCursor arrowCursor] set]; } } -bool NSViewComponentPeer::isMinimised() const +BOOL NSViewComponentPeer::sendDragCallback (const int type, id sender) { - return [window isMiniaturized]; -} + NSString* bestType + = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]]; -void NSViewComponentPeer::setFullScreen (bool shouldBeFullScreen) -{ - if (! isSharedWindow) - { - Rectangle r (lastNonFullscreenBounds); + if (bestType == nil) + return false; - if (isMinimised()) - setMinimised (false); + NSPoint p = [view convertPoint: [sender draggingLocation] fromView: nil]; + const Point pos ((int) p.x, (int) ([view frame].size.height - p.y)); - if (fullScreen != shouldBeFullScreen) + NSPasteboard* pasteBoard = [sender draggingPasteboard]; + StringArray files; + + NSString* iTunesPasteboardType = @"CorePasteboardFlavorType 0x6974756E"; // 'itun' + + if (bestType == NSFilesPromisePboardType + && [[pasteBoard types] containsObject: iTunesPasteboardType]) + { + id list = [pasteBoard propertyListForType: iTunesPasteboardType]; + + if ([list isKindOfClass: [NSDictionary class]]) { - if (shouldBeFullScreen && hasNativeTitleBar()) - { - fullScreen = true; - [window performZoom: nil]; - } - else + NSDictionary* iTunesDictionary = (NSDictionary*) list; + NSArray* tracks = [iTunesDictionary valueForKey: @"Tracks"]; + NSEnumerator* enumerator = [tracks objectEnumerator]; + NSDictionary* track; + + while ((track = [enumerator nextObject]) != nil) { - if (shouldBeFullScreen) - r = component->getParentMonitorArea(); + NSURL* url = [NSURL URLWithString: [track valueForKey: @"Location"]]; - // (can't call the component's setBounds method because that'll reset our fullscreen flag) - if (r != getComponent()->getBounds() && ! r.isEmpty()) - setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen); + if ([url isFileURL]) + files.add (nsStringToJuce ([url path])); } } } -} + else + { + id list = [pasteBoard propertyListForType: NSFilenamesPboardType]; -bool NSViewComponentPeer::isFullScreen() const -{ - return fullScreen; -} + if ([list isKindOfClass: [NSArray class]]) + { + NSArray* items = (NSArray*) [pasteBoard propertyListForType: NSFilenamesPboardType]; -bool NSViewComponentPeer::contains (const Point& position, bool trueIfInAChildWindow) const -{ - if (! (isPositiveAndBelow (position.getX(), component->getWidth()) - && isPositiveAndBelow (position.getY(), component->getHeight()))) - return false; + for (unsigned int i = 0; i < [items count]; ++i) + files.add (nsStringToJuce ((NSString*) [items objectAtIndex: i])); + } + } - NSRect frameRect = [view frame]; + if (files.size() > 0) + { + switch (type) + { + case 0: handleFileDragMove (files, pos); break; + case 1: handleFileDragExit (files); break; + case 2: handleFileDragDrop (files, pos); break; + default: jassertfalse; break; + } - NSView* v = [view hitTest: NSMakePoint (frameRect.origin.x + position.getX(), - frameRect.origin.y + frameRect.size.height - position.getY())]; + return true; + } - if (trueIfInAChildWindow) - return v != nil; + return false; +} - return v == view; +bool NSViewComponentPeer::isOpaque() +{ + return component == nullptr || component->isOpaque(); } -const BorderSize NSViewComponentPeer::getFrameSize() const +void NSViewComponentPeer::drawRect (NSRect r) { - BorderSize b; + if (r.size.width < 1.0f || r.size.height < 1.0f) + return; - if (! isSharedWindow) + CGContextRef cg = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; + + if (! component->isOpaque()) + CGContextClearRect (cg, CGContextGetClipBoundingBox (cg)); + + #if USE_COREGRAPHICS_RENDERING + if (usingCoreGraphics) { - NSRect v = [view convertRect: [view frame] toView: nil]; - NSRect w = [window frame]; + CoreGraphicsContext context (cg, (float) [view frame].size.height); - b.setTop ((int) (w.size.height - (v.origin.y + v.size.height))); - b.setBottom ((int) v.origin.y); - b.setLeft ((int) v.origin.x); - b.setRight ((int) (w.size.width - (v.origin.x + v.size.width))); + insideDrawRect = true; + handlePaint (context); + insideDrawRect = false; } + else + #endif + { + Image temp (getComponent()->isOpaque() ? Image::RGB : Image::ARGB, + (int) (r.size.width + 0.5f), + (int) (r.size.height + 0.5f), + ! getComponent()->isOpaque()); - return b; -} + const int xOffset = -roundToInt (r.origin.x); + const int yOffset = -roundToInt ([view frame].size.height - (r.origin.y + r.size.height)); -bool NSViewComponentPeer::setAlwaysOnTop (bool alwaysOnTop) -{ - if (! isSharedWindow) - [window setLevel: alwaysOnTop ? NSFloatingWindowLevel - : NSNormalWindowLevel]; - return true; -} + const NSRect* rects = nullptr; + NSInteger numRects = 0; + [view getRectsBeingDrawn: &rects count: &numRects]; -void NSViewComponentPeer::toFront (bool makeActiveWindow) -{ - if (isSharedWindow) - [[view superview] addSubview: view - positioned: NSWindowAbove - relativeTo: nil]; + const Rectangle clipBounds (temp.getBounds()); - if (window != nil && component->isVisible()) - { - if (makeActiveWindow) - [window makeKeyAndOrderFront: nil]; - else - [window orderFront: nil]; + RectangleList clip; + for (int i = 0; i < numRects; ++i) + { + clip.addWithoutMerging (clipBounds.getIntersection (Rectangle (roundToInt (rects[i].origin.x) + xOffset, + roundToInt ([view frame].size.height - (rects[i].origin.y + rects[i].size.height)) + yOffset, + roundToInt (rects[i].size.width), + roundToInt (rects[i].size.height)))); + } - if (! recursiveToFrontCall) + if (! clip.isEmpty()) { - recursiveToFrontCall = true; - Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate(); - handleBroughtToFront(); - recursiveToFrontCall = false; + LowLevelGraphicsSoftwareRenderer context (temp, xOffset, yOffset, clip); + + insideDrawRect = true; + handlePaint (context); + insideDrawRect = false; + + CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); + CGImageRef image = CoreGraphicsImage::createImage (temp, false, colourSpace, false); + CGColorSpaceRelease (colourSpace); + CGContextDrawImage (cg, CGRectMake (r.origin.x, r.origin.y, temp.getWidth(), temp.getHeight()), image); + CGImageRelease (image); } } } -void NSViewComponentPeer::toBehind (ComponentPeer* other) +StringArray NSViewComponentPeer::getAvailableRenderingEngines() { - NSViewComponentPeer* const otherPeer = dynamic_cast (other); - jassert (otherPeer != nullptr); // wrong type of window? + StringArray s (ComponentPeer::getAvailableRenderingEngines()); - if (otherPeer != nullptr) - { - if (isSharedWindow) - { - [[view superview] addSubview: view - positioned: NSWindowBelow - relativeTo: otherPeer->view]; - } - else - { - [window orderWindow: NSWindowBelow - relativeTo: [otherPeer->window windowNumber]]; - } - } + #if USE_COREGRAPHICS_RENDERING + s.add ("CoreGraphics Renderer"); + #endif + + return s; } -void NSViewComponentPeer::setIcon (const Image& /*newIcon*/) +int NSViewComponentPeer::getCurrentRenderingEngine() const { - // to do.. + return usingCoreGraphics ? 1 : 0; } -void NSViewComponentPeer::viewFocusGain() +void NSViewComponentPeer::setCurrentRenderingEngine (int index) { - if (currentlyFocusedPeer != this) + #if USE_COREGRAPHICS_RENDERING + if (usingCoreGraphics != (index > 0)) { - if (ComponentPeer::isValidPeer (currentlyFocusedPeer)) - currentlyFocusedPeer->handleFocusLoss(); - - currentlyFocusedPeer = this; - handleFocusGain(); + usingCoreGraphics = index > 0; + [view setNeedsDisplay: true]; } + #endif } -void NSViewComponentPeer::viewFocusLoss() +bool NSViewComponentPeer::canBecomeKeyWindow() { - if (currentlyFocusedPeer == this) - { - currentlyFocusedPeer = nullptr; - handleFocusLoss(); - } + return (getStyleFlags() & JUCE_NAMESPACE::ComponentPeer::windowIgnoresKeyPresses) == 0; } -void juce_HandleProcessFocusChange() +void NSViewComponentPeer::becomeKeyWindow() { - NSViewComponentPeer::keysCurrentlyDown.clear(); - - if (NSViewComponentPeer::isValidPeer (NSViewComponentPeer::currentlyFocusedPeer)) - { - if (Process::isForegroundProcess()) - { - NSViewComponentPeer::currentlyFocusedPeer->handleFocusGain(); - - ModalComponentManager::getInstance()->bringModalComponentsToFront(); - } - else - { - NSViewComponentPeer::currentlyFocusedPeer->handleFocusLoss(); - - // turn kiosk mode off if we lose focus.. - Desktop::getInstance().setKioskModeComponent (nullptr); - } - } + handleBroughtToFront(); + grabFocus(); } -bool NSViewComponentPeer::isFocused() const +bool NSViewComponentPeer::windowShouldClose() { - return isSharedWindow ? this == currentlyFocusedPeer - : [window isKeyWindow]; + if (! isValidPeer (this)) + return YES; + + handleUserClosingWindow(); + return NO; } -void NSViewComponentPeer::grabFocus() +void NSViewComponentPeer::updateFullscreenStatus() { - if (window != nil) + if (hasNativeTitleBar()) { - [window makeKeyWindow]; - [window makeFirstResponder: view]; + const Rectangle screen (getFrameSize().subtractedFrom (component->getParentMonitorArea())); + const Rectangle window (component->getScreenBounds()); - viewFocusGain(); + fullScreen = std::abs (screen.getX() - window.getX()) <= 2 + && std::abs (screen.getY() - window.getY()) <= 2 + && std::abs (screen.getRight() - window.getRight()) <= 2 + && std::abs (screen.getBottom() - window.getBottom()) <= 2; } } -void NSViewComponentPeer::textInputRequired (const Point&) +void NSViewComponentPeer::redirectMovedOrResized() { + updateFullscreenStatus(); + handleMovedOrResized(); } -bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown) +void NSViewComponentPeer::viewMovedToWindow() { - String unicode (nsStringToJuce ([ev characters])); - String unmodified (nsStringToJuce ([ev charactersIgnoringModifiers])); - int keyCode = getKeyCodeFromEvent (ev); - - //DBG ("unicode: " + unicode + " " + String::toHexString ((int) unicode[0])); - //DBG ("unmodified: " + unmodified + " " + String::toHexString ((int) unmodified[0])); - - if (unicode.isNotEmpty() || keyCode != 0) - { - if (isKeyDown) - { - bool used = false; - - while (unicode.length() > 0) - { - juce_wchar textCharacter = unicode[0]; - unicode = unicode.substring (1); - - if (([ev modifierFlags] & NSCommandKeyMask) != 0) - textCharacter = 0; - - used = handleKeyUpOrDown (true) || used; - used = handleKeyPress (keyCode, textCharacter) || used; - } - - return used; - } - else - { - if (handleKeyUpOrDown (false)) - return true; - } - } - - return false; + if (isSharedWindow) + window = [view window]; } -bool NSViewComponentPeer::redirectKeyDown (NSEvent* ev) +void Desktop::createMouseInputSources() { - updateKeysDown (ev, true); - bool used = handleKeyEvent (ev, true); - - if (([ev modifierFlags] & NSCommandKeyMask) != 0) - { - // for command keys, the key-up event is thrown away, so simulate one.. - updateKeysDown (ev, false); - used = (isValidPeer (this) && handleKeyEvent (ev, false)) || used; - } - - // (If we're running modally, don't allow unused keystrokes to be passed - // along to other blocked views..) - if (Component::getCurrentlyModalComponent() != nullptr) - used = true; - - return used; + mouseSources.add (new MouseInputSource (0, true)); } -bool NSViewComponentPeer::redirectKeyUp (NSEvent* ev) +void Desktop::setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars) { - updateKeysDown (ev, false); - return handleKeyEvent (ev, false) - || Component::getCurrentlyModalComponent() != nullptr; + #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 + if (enableOrDisable) + { + [NSApp setPresentationOptions: (allowMenusAndBars ? (NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar) + : (NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar))]; + kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false)); + } + else + { + [NSApp setPresentationOptions: NSApplicationPresentationDefault]; + } + #else + if (enableOrDisable) + { + SetSystemUIMode (kUIModeAllSuppressed, allowMenusAndBars ? kUIOptionAutoShowMenuBar : 0); + kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false)); + } + else + { + SetSystemUIMode (kUIModeNormal, 0); + } + #endif } -void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev) +void NSViewComponentPeer::repaint (const Rectangle& area) { - keysCurrentlyDown.clear(); - handleKeyUpOrDown (true); + if (insideDrawRect) + { + class AsyncRepaintMessage : public CallbackMessage + { + public: + AsyncRepaintMessage (NSViewComponentPeer* const peer_, const Rectangle& rect_) + : peer (peer_), rect (rect_) + { + } - updateModifiers (ev); - handleModifierKeysChange(); -} + void messageCallback() + { + if (ComponentPeer::isValidPeer (peer)) + peer->repaint (rect); + } -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 -bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) -{ - if ([ev type] == NSKeyDown) - return redirectKeyDown (ev); - else if ([ev type] == NSKeyUp) - return redirectKeyUp (ev); + private: + NSViewComponentPeer* const peer; + const Rectangle rect; + }; - return false; + (new AsyncRepaintMessage (this, area))->post(); + } + else + { + [view setNeedsDisplayInRect: NSMakeRect ((CGFloat) area.getX(), [view frame].size.height - (CGFloat) area.getBottom(), + (CGFloat) area.getWidth(), (CGFloat) area.getHeight())]; + } } -#endif -void NSViewComponentPeer::sendMouseEvent (NSEvent* ev) +void NSViewComponentPeer::performAnyPendingRepaintsNow() { - updateModifiers (ev); - handleMouseEvent (0, getMousePos (ev, view), currentModifiers, getMouseTime (ev)); + [view displayIfNeeded]; } -void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) +ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo) { - currentModifiers = currentModifiers.withFlags (getModifierForButtonNumber ([ev buttonNumber])); - sendMouseEvent (ev); + return new NSViewComponentPeer (this, styleFlags, (NSView*) windowToAttachTo); } -void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) -{ - currentModifiers = currentModifiers.withoutFlags (getModifierForButtonNumber ([ev buttonNumber])); - sendMouseEvent (ev); - showArrowCursorIfNeeded(); -} +const int KeyPress::spaceKey = ' '; +const int KeyPress::returnKey = 0x0d; +const int KeyPress::escapeKey = 0x1b; +const int KeyPress::backspaceKey = 0x7f; +const int KeyPress::leftKey = NSLeftArrowFunctionKey; +const int KeyPress::rightKey = NSRightArrowFunctionKey; +const int KeyPress::upKey = NSUpArrowFunctionKey; +const int KeyPress::downKey = NSDownArrowFunctionKey; +const int KeyPress::pageUpKey = NSPageUpFunctionKey; +const int KeyPress::pageDownKey = NSPageDownFunctionKey; +const int KeyPress::endKey = NSEndFunctionKey; +const int KeyPress::homeKey = NSHomeFunctionKey; +const int KeyPress::deleteKey = NSDeleteFunctionKey; +const int KeyPress::insertKey = -1; +const int KeyPress::tabKey = 9; +const int KeyPress::F1Key = NSF1FunctionKey; +const int KeyPress::F2Key = NSF2FunctionKey; +const int KeyPress::F3Key = NSF3FunctionKey; +const int KeyPress::F4Key = NSF4FunctionKey; +const int KeyPress::F5Key = NSF5FunctionKey; +const int KeyPress::F6Key = NSF6FunctionKey; +const int KeyPress::F7Key = NSF7FunctionKey; +const int KeyPress::F8Key = NSF8FunctionKey; +const int KeyPress::F9Key = NSF9FunctionKey; +const int KeyPress::F10Key = NSF10FunctionKey; +const int KeyPress::F11Key = NSF1FunctionKey; +const int KeyPress::F12Key = NSF12FunctionKey; +const int KeyPress::F13Key = NSF13FunctionKey; +const int KeyPress::F14Key = NSF14FunctionKey; +const int KeyPress::F15Key = NSF15FunctionKey; +const int KeyPress::F16Key = NSF16FunctionKey; +const int KeyPress::numberPad0 = 0x30020; +const int KeyPress::numberPad1 = 0x30021; +const int KeyPress::numberPad2 = 0x30022; +const int KeyPress::numberPad3 = 0x30023; +const int KeyPress::numberPad4 = 0x30024; +const int KeyPress::numberPad5 = 0x30025; +const int KeyPress::numberPad6 = 0x30026; +const int KeyPress::numberPad7 = 0x30027; +const int KeyPress::numberPad8 = 0x30028; +const int KeyPress::numberPad9 = 0x30029; +const int KeyPress::numberPadAdd = 0x3002a; +const int KeyPress::numberPadSubtract = 0x3002b; +const int KeyPress::numberPadMultiply = 0x3002c; +const int KeyPress::numberPadDivide = 0x3002d; +const int KeyPress::numberPadSeparator = 0x3002e; +const int KeyPress::numberPadDecimalPoint = 0x3002f; +const int KeyPress::numberPadEquals = 0x30030; +const int KeyPress::numberPadDelete = 0x30031; +const int KeyPress::playKey = 0x30000; +const int KeyPress::stopKey = 0x30001; +const int KeyPress::fastForwardKey = 0x30002; +const int KeyPress::rewindKey = 0x30003; + +#endif -void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) -{ - currentModifiers = currentModifiers.withFlags (getModifierForButtonNumber ([ev buttonNumber])); - sendMouseEvent (ev); -} +/*** End of inlined file: juce_mac_NSViewComponentPeer.mm ***/ -void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) -{ - currentModifiers = currentModifiers.withoutMouseButtons(); - sendMouseEvent (ev); - showArrowCursorIfNeeded(); -} -void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) -{ - Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate(); - currentModifiers = currentModifiers.withoutMouseButtons(); - sendMouseEvent (ev); -} +/*** Start of inlined file: juce_mac_Windowing.mm ***/ +// (This file gets included by juce_mac_NativeCode.mm, rather than being +// compiled on its own). +#if JUCE_INCLUDED_FILE -void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) +void LookAndFeel::playAlertSound() { - currentModifiers = currentModifiers.withoutMouseButtons(); - sendMouseEvent (ev); + NSBeep(); } -void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) +class OSXMessageBox : public AsyncUpdater { - updateModifiers (ev); - - float x = 0, y = 0; - - @try +public: + OSXMessageBox (AlertWindow::AlertIconType iconType_, + const String& title_, const String& message_, + NSString* button1_, NSString* button2_, NSString* button3_, + ModalComponentManager::Callback* callback_, + const bool runAsync) + : iconType (iconType_), title (title_), + message (message_), callback (callback_), + button1 ([button1_ retain]), + button2 ([button2_ retain]), + button3 ([button3_ retain]) { - x = [ev deviceDeltaX] * 0.5f; - y = [ev deviceDeltaY] * 0.5f; + if (runAsync) + triggerAsyncUpdate(); } - @catch (...) - {} - if (x == 0 && y == 0) + ~OSXMessageBox() { - x = [ev deltaX] * 10.0f; - y = [ev deltaY] * 10.0f; + [button1 release]; + [button2 release]; + [button3 release]; } - handleMouseWheel (0, getMousePos (ev, view), getMouseTime (ev), x, y); -} - -void NSViewComponentPeer::showArrowCursorIfNeeded() -{ - MouseInputSource& mouse = Desktop::getInstance().getMainMouseSource(); - - if (mouse.getComponentUnderMouse() == nullptr - && Desktop::getInstance().findComponentAt (mouse.getScreenPosition()) == nullptr) + int getResult() const { - [[NSCursor arrowCursor] set]; + JUCE_AUTORELEASEPOOL + NSInteger r = getRawResult(); + return r == NSAlertDefaultReturn ? 1 : (r == NSAlertOtherReturn ? 2 : 0); } -} - -BOOL NSViewComponentPeer::sendDragCallback (const int type, id sender) -{ - NSString* bestType - = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]]; - if (bestType == nil) - return false; + void handleAsyncUpdate() + { + const int result = getResult(); - NSPoint p = [view convertPoint: [sender draggingLocation] fromView: nil]; - const Point pos ((int) p.x, (int) ([view frame].size.height - p.y)); + if (callback != nullptr) + callback->modalStateFinished (result); - NSPasteboard* pasteBoard = [sender draggingPasteboard]; - StringArray files; + delete this; + } - NSString* iTunesPasteboardType = @"CorePasteboardFlavorType 0x6974756E"; // 'itun' +private: + AlertWindow::AlertIconType iconType; + String title, message; + ModalComponentManager::Callback* callback; + NSString* button1; + NSString* button2; + NSString* button3; - if (bestType == NSFilesPromisePboardType - && [[pasteBoard types] containsObject: iTunesPasteboardType]) + NSInteger getRawResult() const { - id list = [pasteBoard propertyListForType: iTunesPasteboardType]; + NSString* messageString = juceStringToNS (message); + NSString* titleString = juceStringToNS (title); - if ([list isKindOfClass: [NSDictionary class]]) + switch (iconType) { - NSDictionary* iTunesDictionary = (NSDictionary*) list; - NSArray* tracks = [iTunesDictionary valueForKey: @"Tracks"]; - NSEnumerator* enumerator = [tracks objectEnumerator]; - NSDictionary* track; - - while ((track = [enumerator nextObject]) != nil) - { - NSURL* url = [NSURL URLWithString: [track valueForKey: @"Location"]]; - - if ([url isFileURL]) - files.add (nsStringToJuce ([url path])); - } + case AlertWindow::InfoIcon: return NSRunInformationalAlertPanel (titleString, messageString, button1, button2, button3); + case AlertWindow::WarningIcon: return NSRunCriticalAlertPanel (titleString, messageString, button1, button2, button3); + default: return NSRunAlertPanel (titleString, messageString, button1, button2, button3); } } - else - { - id list = [pasteBoard propertyListForType: NSFilenamesPboardType]; - - if ([list isKindOfClass: [NSArray class]]) - { - NSArray* items = (NSArray*) [pasteBoard propertyListForType: NSFilenamesPboardType]; +}; - for (unsigned int i = 0; i < [items count]; ++i) - files.add (nsStringToJuce ((NSString*) [items objectAtIndex: i])); - } - } +void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent) +{ + OSXMessageBox box (iconType, title, message, @"OK", nil, nil, 0, false); + (void) box.getResult(); +} - if (files.size() > 0) - { - switch (type) - { - case 0: handleFileDragMove (files, pos); break; - case 1: handleFileDragExit (files); break; - case 2: handleFileDragDrop (files, pos); break; - default: jassertfalse; break; - } +void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent) +{ + new OSXMessageBox (iconType, title, message, @"OK", nil, nil, 0, true); +} - return true; - } +bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) +{ + ScopedPointer mb (new OSXMessageBox (iconType, title, message, + @"OK", @"Cancel", nil, callback, callback != nullptr)); + if (callback == nullptr) + return mb->getResult() == 1; + mb.release(); return false; } -bool NSViewComponentPeer::isOpaque() +int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) { - return component == nullptr || component->isOpaque(); + ScopedPointer mb (new OSXMessageBox (iconType, title, message, + @"Yes", @"Cancel", @"No", callback, callback != nullptr)); + if (callback == nullptr) + return mb->getResult(); + + mb.release(); + return 0; } -void NSViewComponentPeer::drawRect (NSRect r) +bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool /*canMoveFiles*/) { - if (r.size.width < 1.0f || r.size.height < 1.0f) - return; - - CGContextRef cg = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; + if (files.size() == 0) + return false; - if (! component->isOpaque()) - CGContextClearRect (cg, CGContextGetClipBoundingBox (cg)); + MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource(0); - #if USE_COREGRAPHICS_RENDERING - if (usingCoreGraphics) + if (draggingSource == nullptr) { - CoreGraphicsContext context (cg, (float) [view frame].size.height); - - insideDrawRect = true; - handlePaint (context); - insideDrawRect = false; + jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event! + return false; } - else - #endif - { - Image temp (getComponent()->isOpaque() ? Image::RGB : Image::ARGB, - (int) (r.size.width + 0.5f), - (int) (r.size.height + 0.5f), - ! getComponent()->isOpaque()); - const int xOffset = -roundToInt (r.origin.x); - const int yOffset = -roundToInt ([view frame].size.height - (r.origin.y + r.size.height)); + Component* sourceComp = draggingSource->getComponentUnderMouse(); - const NSRect* rects = nullptr; - NSInteger numRects = 0; - [view getRectsBeingDrawn: &rects count: &numRects]; + if (sourceComp == nullptr) + { + jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event! + return false; + } - const Rectangle clipBounds (temp.getBounds()); + JUCE_AUTORELEASEPOOL - RectangleList clip; - for (int i = 0; i < numRects; ++i) - { - clip.addWithoutMerging (clipBounds.getIntersection (Rectangle (roundToInt (rects[i].origin.x) + xOffset, - roundToInt ([view frame].size.height - (rects[i].origin.y + rects[i].size.height)) + yOffset, - roundToInt (rects[i].size.width), - roundToInt (rects[i].size.height)))); - } + NSView* view = (NSView*) sourceComp->getWindowHandle(); - if (! clip.isEmpty()) - { - LowLevelGraphicsSoftwareRenderer context (temp, xOffset, yOffset, clip); + if (view == nil) + return false; + + NSPasteboard* pboard = [NSPasteboard pasteboardWithName: NSDragPboard]; + [pboard declareTypes: [NSArray arrayWithObject: NSFilenamesPboardType] + owner: nil]; - insideDrawRect = true; - handlePaint (context); - insideDrawRect = false; + NSMutableArray* filesArray = [NSMutableArray arrayWithCapacity: 4]; + for (int i = 0; i < files.size(); ++i) + [filesArray addObject: juceStringToNS (files[i])]; - CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); - CGImageRef image = CoreGraphicsImage::createImage (temp, false, colourSpace, false); - CGColorSpaceRelease (colourSpace); - CGContextDrawImage (cg, CGRectMake (r.origin.x, r.origin.y, temp.getWidth(), temp.getHeight()), image); - CGImageRelease (image); - } - } -} + [pboard setPropertyList: filesArray + forType: NSFilenamesPboardType]; -StringArray NSViewComponentPeer::getAvailableRenderingEngines() -{ - StringArray s (ComponentPeer::getAvailableRenderingEngines()); + NSPoint dragPosition = [view convertPoint: [[[view window] currentEvent] locationInWindow] + fromView: nil]; + dragPosition.x -= 16; + dragPosition.y -= 16; - #if USE_COREGRAPHICS_RENDERING - s.add ("CoreGraphics Renderer"); - #endif + [view dragImage: [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (files[0])] + at: dragPosition + offset: NSMakeSize (0, 0) + event: [[view window] currentEvent] + pasteboard: pboard + source: view + slideBack: YES]; - return s; + return true; } -int NSViewComponentPeer::getCurrentRenderingEngine() const +bool DragAndDropContainer::performExternalDragDropOfText (const String& /*text*/) { - return usingCoreGraphics ? 1 : 0; + jassertfalse; // not implemented! + return false; } -void NSViewComponentPeer::setCurrentRenderingEngine (int index) +bool Desktop::canUseSemiTransparentWindows() noexcept { - #if USE_COREGRAPHICS_RENDERING - if (usingCoreGraphics != (index > 0)) - { - usingCoreGraphics = index > 0; - [view setNeedsDisplay: true]; - } - #endif + return true; } -bool NSViewComponentPeer::canBecomeKeyWindow() +const Point MouseInputSource::getCurrentMousePosition() { - return (getStyleFlags() & JUCE_NAMESPACE::ComponentPeer::windowIgnoresKeyPresses) == 0; + JUCE_AUTORELEASEPOOL + const NSPoint p ([NSEvent mouseLocation]); + return Point (roundToInt (p.x), roundToInt ([[[NSScreen screens] objectAtIndex: 0] frame].size.height - p.y)); } -void NSViewComponentPeer::becomeKeyWindow() +void Desktop::setMousePosition (const Point& newPosition) { - handleBroughtToFront(); - grabFocus(); + // this rubbish needs to be done around the warp call, to avoid causing a + // bizarre glitch.. + CGAssociateMouseAndMouseCursorPosition (false); + CGWarpMouseCursorPosition (CGPointMake (newPosition.getX(), newPosition.getY())); + CGAssociateMouseAndMouseCursorPosition (true); } -bool NSViewComponentPeer::windowShouldClose() +Desktop::DisplayOrientation Desktop::getCurrentOrientation() const { - if (! isValidPeer (this)) - return YES; - - handleUserClosingWindow(); - return NO; + return upright; } -void NSViewComponentPeer::updateFullscreenStatus() +#ifndef __POWER__ // Some versions of the SDK omit this function.. + extern "C" { extern OSErr UpdateSystemActivity (UInt8); } +#endif + +class ScreenSaverDefeater : public Timer { - if (hasNativeTitleBar()) +public: + ScreenSaverDefeater() { - const Rectangle screen (getFrameSize().subtractedFrom (component->getParentMonitorArea())); - const Rectangle window (component->getScreenBounds()); + startTimer (10000); + timerCallback(); + } - fullScreen = std::abs (screen.getX() - window.getX()) <= 2 - && std::abs (screen.getY() - window.getY()) <= 2 - && std::abs (screen.getRight() - window.getRight()) <= 2 - && std::abs (screen.getBottom() - window.getBottom()) <= 2; + void timerCallback() + { + if (Process::isForegroundProcess()) + UpdateSystemActivity (1 /*UsrActivity*/); } -} +}; -void NSViewComponentPeer::redirectMovedOrResized() -{ - updateFullscreenStatus(); - handleMovedOrResized(); -} +static ScopedPointer screenSaverDefeater; -void NSViewComponentPeer::viewMovedToWindow() +void Desktop::setScreenSaverEnabled (const bool isEnabled) { - if (isSharedWindow) - window = [view window]; + if (isEnabled) + screenSaverDefeater = nullptr; + else if (screenSaverDefeater == nullptr) + screenSaverDefeater = new ScreenSaverDefeater(); } -void Desktop::createMouseInputSources() +bool Desktop::isScreenSaverEnabled() { - mouseSources.add (new MouseInputSource (0, true)); + return screenSaverDefeater == nullptr; } -void Desktop::setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars) +class DisplaySettingsChangeCallback : public DeletedAtShutdown { - #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 - if (enableOrDisable) - { - [NSApp setPresentationOptions: (allowMenusAndBars ? (NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar) - : (NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar))]; - kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false)); - } - else +public: + DisplaySettingsChangeCallback() { - [NSApp setPresentationOptions: NSApplicationPresentationDefault]; + CGDisplayRegisterReconfigurationCallback (displayReconfigurationCallBack, 0); } - #else - if (enableOrDisable) + + ~DisplaySettingsChangeCallback() { - SetSystemUIMode (kUIModeAllSuppressed, allowMenusAndBars ? kUIOptionAutoShowMenuBar : 0); - kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false)); + CGDisplayRemoveReconfigurationCallback (displayReconfigurationCallBack, 0); + clearSingletonInstance(); } - else + + static void displayReconfigurationCallBack (CGDirectDisplayID, CGDisplayChangeSummaryFlags, void*) { - SetSystemUIMode (kUIModeNormal, 0); + Desktop::getInstance().refreshMonitorSizes(); } - #endif -} -void NSViewComponentPeer::repaint (const Rectangle& area) + juce_DeclareSingleton_SingleThreaded_Minimal (DisplaySettingsChangeCallback); + +private: + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DisplaySettingsChangeCallback); +}; + +juce_ImplementSingleton_SingleThreaded (DisplaySettingsChangeCallback); + +void Desktop::getCurrentMonitorPositions (Array >& monitorCoords, const bool clipToWorkArea) { - if (insideDrawRect) - { - class AsyncRepaintMessage : public CallbackMessage - { - public: - AsyncRepaintMessage (NSViewComponentPeer* const peer_, const Rectangle& rect_) - : peer (peer_), rect (rect_) - { - } + JUCE_AUTORELEASEPOOL - void messageCallback() - { - if (ComponentPeer::isValidPeer (peer)) - peer->repaint (rect); - } + DisplaySettingsChangeCallback::getInstance(); - private: - NSViewComponentPeer* const peer; - const Rectangle rect; - }; + monitorCoords.clear(); + NSArray* screens = [NSScreen screens]; + const CGFloat mainScreenBottom = [[[NSScreen screens] objectAtIndex: 0] frame].size.height; - (new AsyncRepaintMessage (this, area))->post(); - } - else + for (unsigned int i = 0; i < [screens count]; ++i) { - [view setNeedsDisplayInRect: NSMakeRect ((CGFloat) area.getX(), [view frame].size.height - (CGFloat) area.getBottom(), - (CGFloat) area.getWidth(), (CGFloat) area.getHeight())]; - } -} + NSScreen* s = (NSScreen*) [screens objectAtIndex: i]; -void NSViewComponentPeer::performAnyPendingRepaintsNow() -{ - [view displayIfNeeded]; -} + NSRect r = clipToWorkArea ? [s visibleFrame] + : [s frame]; -ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo) -{ - return new NSViewComponentPeer (this, styleFlags, (NSView*) windowToAttachTo); + r.origin.y = mainScreenBottom - (r.origin.y + r.size.height); + + monitorCoords.add (convertToRectInt (r)); + } + + jassert (monitorCoords.size() > 0); } Image juce_createIconForFile (const File& file) @@ -282224,7 +282255,9 @@ Image juce_createIconForFile (const File& file) NSImage* image = [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (file.getFullPathName())]; - CoreGraphicsImage* result = new CoreGraphicsImage (Image::ARGB, (int) [image size].width, (int) [image size].height, true); + CoreGraphicsImage* result = new CoreGraphicsImage (Image::ARGB, + (int) [image size].width, + (int) [image size].height, true); [NSGraphicsContext saveGraphicsState]; [NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithGraphicsPort: result->context flipped: false]]; @@ -282256,63 +282289,9 @@ String SystemClipboard::getTextFromClipboard() : nsStringToJuce (text); } -const int KeyPress::spaceKey = ' '; -const int KeyPress::returnKey = 0x0d; -const int KeyPress::escapeKey = 0x1b; -const int KeyPress::backspaceKey = 0x7f; -const int KeyPress::leftKey = NSLeftArrowFunctionKey; -const int KeyPress::rightKey = NSRightArrowFunctionKey; -const int KeyPress::upKey = NSUpArrowFunctionKey; -const int KeyPress::downKey = NSDownArrowFunctionKey; -const int KeyPress::pageUpKey = NSPageUpFunctionKey; -const int KeyPress::pageDownKey = NSPageDownFunctionKey; -const int KeyPress::endKey = NSEndFunctionKey; -const int KeyPress::homeKey = NSHomeFunctionKey; -const int KeyPress::deleteKey = NSDeleteFunctionKey; -const int KeyPress::insertKey = -1; -const int KeyPress::tabKey = 9; -const int KeyPress::F1Key = NSF1FunctionKey; -const int KeyPress::F2Key = NSF2FunctionKey; -const int KeyPress::F3Key = NSF3FunctionKey; -const int KeyPress::F4Key = NSF4FunctionKey; -const int KeyPress::F5Key = NSF5FunctionKey; -const int KeyPress::F6Key = NSF6FunctionKey; -const int KeyPress::F7Key = NSF7FunctionKey; -const int KeyPress::F8Key = NSF8FunctionKey; -const int KeyPress::F9Key = NSF9FunctionKey; -const int KeyPress::F10Key = NSF10FunctionKey; -const int KeyPress::F11Key = NSF1FunctionKey; -const int KeyPress::F12Key = NSF12FunctionKey; -const int KeyPress::F13Key = NSF13FunctionKey; -const int KeyPress::F14Key = NSF14FunctionKey; -const int KeyPress::F15Key = NSF15FunctionKey; -const int KeyPress::F16Key = NSF16FunctionKey; -const int KeyPress::numberPad0 = 0x30020; -const int KeyPress::numberPad1 = 0x30021; -const int KeyPress::numberPad2 = 0x30022; -const int KeyPress::numberPad3 = 0x30023; -const int KeyPress::numberPad4 = 0x30024; -const int KeyPress::numberPad5 = 0x30025; -const int KeyPress::numberPad6 = 0x30026; -const int KeyPress::numberPad7 = 0x30027; -const int KeyPress::numberPad8 = 0x30028; -const int KeyPress::numberPad9 = 0x30029; -const int KeyPress::numberPadAdd = 0x3002a; -const int KeyPress::numberPadSubtract = 0x3002b; -const int KeyPress::numberPadMultiply = 0x3002c; -const int KeyPress::numberPadDivide = 0x3002d; -const int KeyPress::numberPadSeparator = 0x3002e; -const int KeyPress::numberPadDecimalPoint = 0x3002f; -const int KeyPress::numberPadEquals = 0x30030; -const int KeyPress::numberPadDelete = 0x30031; -const int KeyPress::playKey = 0x30000; -const int KeyPress::stopKey = 0x30001; -const int KeyPress::fastForwardKey = 0x30002; -const int KeyPress::rewindKey = 0x30003; - #endif -/*** End of inlined file: juce_mac_NSViewComponentPeer.mm ***/ +/*** End of inlined file: juce_mac_Windowing.mm ***/ /*** Start of inlined file: juce_mac_MouseCursor.mm ***/ diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 8c0bd759bb..793a9c999c 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 54 -#define JUCE_BUILDNUMBER 8 +#define JUCE_BUILDNUMBER 9 /** Current Juce version number. diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index b7440774c8..8fa603b203 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 54 -#define JUCE_BUILDNUMBER 8 +#define JUCE_BUILDNUMBER 9 /** Current Juce version number. diff --git a/src/native/mac/juce_ios_MessageManager.mm b/src/native/mac/juce_ios_MessageManager.mm index 05c760139c..a70b08ce17 100644 --- a/src/native/mac/juce_ios_MessageManager.mm +++ b/src/native/mac/juce_ios_MessageManager.mm @@ -27,6 +27,43 @@ // compiled on its own). #if JUCE_INCLUDED_FILE +//============================================================================== +END_JUCE_NAMESPACE + +@interface JuceAppStartupDelegate : NSObject +{ +} + +- (void) applicationDidFinishLaunching: (UIApplication*) application; +- (void) applicationWillTerminate: (UIApplication*) application; + +@end + +@implementation JuceAppStartupDelegate + +- (void) applicationDidFinishLaunching: (UIApplication*) application +{ + initialiseJuce_GUI(); + + if (! JUCEApplication::createInstance()->initialiseApp (String::empty)) + exit (0); +} + +- (void) applicationWillTerminate: (UIApplication*) application +{ + JUCEApplication::appWillTerminateByForce(); +} + +@end + +BEGIN_JUCE_NAMESPACE + +int juce_iOSMain (int argc, const char* argv[]) +{ + return UIApplicationMain (argc, const_cast (argv), nil, @"JuceAppStartupDelegate"); +} + +//============================================================================== struct CallbackMessagePayload { MessageCallbackFunction* function; diff --git a/src/native/mac/juce_ios_UIViewComponentPeer.mm b/src/native/mac/juce_ios_UIViewComponentPeer.mm index 2416f38e04..15e742d361 100644 --- a/src/native/mac/juce_ios_UIViewComponentPeer.mm +++ b/src/native/mac/juce_ios_UIViewComponentPeer.mm @@ -1004,64 +1004,6 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo) return new UIViewComponentPeer (this, styleFlags, (UIView*) windowToAttachTo); } -//============================================================================== -Image juce_createIconForFile (const File& file) -{ - return Image::null; -} - -//============================================================================== -void SystemClipboard::copyTextToClipboard (const String& text) -{ - [[UIPasteboard generalPasteboard] setValue: juceStringToNS (text) - forPasteboardType: @"public.text"]; -} - -String SystemClipboard::getTextFromClipboard() -{ - NSString* text = [[UIPasteboard generalPasteboard] valueForPasteboardType: @"public.text"]; - - return text == nil ? String::empty - : nsStringToJuce (text); -} - -//============================================================================== -void Desktop::createMouseInputSources() -{ - for (int i = 0; i < 10; ++i) - mouseSources.add (new MouseInputSource (i, false)); -} - -bool Desktop::canUseSemiTransparentWindows() noexcept -{ - return true; -} - -const Point MouseInputSource::getCurrentMousePosition() -{ - return juce_lastMousePos; -} - -void Desktop::setMousePosition (const Point&) -{ -} - -Desktop::DisplayOrientation Desktop::getCurrentOrientation() const -{ - return convertToJuceOrientation ([[UIApplication sharedApplication] statusBarOrientation]); -} - -void Desktop::getCurrentMonitorPositions (Array >& monitorCoords, const bool clipToWorkArea) -{ - JUCE_AUTORELEASEPOOL - monitorCoords.clear(); - - CGRect r = clipToWorkArea ? [[UIScreen mainScreen] applicationFrame] - : [[UIScreen mainScreen] bounds]; - - monitorCoords.add (UIViewComponentPeer::realScreenPosToRotated (convertToRectInt (r))); -} - //============================================================================== const int KeyPress::spaceKey = ' '; const int KeyPress::returnKey = 0x0d; diff --git a/src/native/mac/juce_ios_MiscUtilities.mm b/src/native/mac/juce_ios_Windowing.mm similarity index 80% rename from src/native/mac/juce_ios_MiscUtilities.mm rename to src/native/mac/juce_ios_Windowing.mm index 799ec0d1b4..6d472332fb 100644 --- a/src/native/mac/juce_ios_MiscUtilities.mm +++ b/src/native/mac/juce_ios_Windowing.mm @@ -28,53 +28,6 @@ #if JUCE_INCLUDED_FILE -//============================================================================== -END_JUCE_NAMESPACE - -@interface JuceAppStartupDelegate : NSObject -{ -} - -- (void) applicationDidFinishLaunching: (UIApplication*) application; -- (void) applicationWillTerminate: (UIApplication*) application; - -@end - -@implementation JuceAppStartupDelegate - -- (void) applicationDidFinishLaunching: (UIApplication*) application -{ - initialiseJuce_GUI(); - - if (! JUCEApplication::createInstance()->initialiseApp (String::empty)) - exit (0); -} - -- (void) applicationWillTerminate: (UIApplication*) application -{ - JUCEApplication::appWillTerminateByForce(); -} - -@end - -BEGIN_JUCE_NAMESPACE - -int juce_iOSMain (int argc, const char* argv[]) -{ - return UIApplicationMain (argc, const_cast (argv), nil, @"JuceAppStartupDelegate"); -} - -//============================================================================== -ScopedAutoReleasePool::ScopedAutoReleasePool() -{ - pool = [[NSAutoreleasePool alloc] init]; -} - -ScopedAutoReleasePool::~ScopedAutoReleasePool() -{ - [((NSAutoreleasePool*) pool) release]; -} - //============================================================================== void LookAndFeel::playAlertSound() { @@ -82,9 +35,6 @@ void LookAndFeel::playAlertSound() //AudioServicesPlaySystemSound (); } -//============================================================================== -#if ! JUCE_ONLY_BUILD_CORE_LIBRARY - //============================================================================== class iOSMessageBox; @@ -245,7 +195,62 @@ bool Desktop::isScreenSaverEnabled() return ! [[UIApplication sharedApplication] isIdleTimerDisabled]; } +//============================================================================== +Image juce_createIconForFile (const File& file) +{ + return Image::null; +} -#endif +//============================================================================== +void SystemClipboard::copyTextToClipboard (const String& text) +{ + [[UIPasteboard generalPasteboard] setValue: juceStringToNS (text) + forPasteboardType: @"public.text"]; +} + +String SystemClipboard::getTextFromClipboard() +{ + NSString* text = [[UIPasteboard generalPasteboard] valueForPasteboardType: @"public.text"]; + + return text == nil ? String::empty + : nsStringToJuce (text); +} + +//============================================================================== +void Desktop::createMouseInputSources() +{ + for (int i = 0; i < 10; ++i) + mouseSources.add (new MouseInputSource (i, false)); +} + +bool Desktop::canUseSemiTransparentWindows() noexcept +{ + return true; +} + +const Point MouseInputSource::getCurrentMousePosition() +{ + return juce_lastMousePos; +} + +void Desktop::setMousePosition (const Point&) +{ +} + +Desktop::DisplayOrientation Desktop::getCurrentOrientation() const +{ + return convertToJuceOrientation ([[UIApplication sharedApplication] statusBarOrientation]); +} + +void Desktop::getCurrentMonitorPositions (Array >& monitorCoords, const bool clipToWorkArea) +{ + JUCE_AUTORELEASEPOOL + monitorCoords.clear(); + + CGRect r = clipToWorkArea ? [[UIScreen mainScreen] applicationFrame] + : [[UIScreen mainScreen] bounds]; + + monitorCoords.add (UIViewComponentPeer::realScreenPosToRotated (convertToRectInt (r))); +} #endif diff --git a/src/native/mac/juce_mac_NSViewComponentPeer.mm b/src/native/mac/juce_mac_NSViewComponentPeer.mm index 7af1fbb2e7..7eda3a4dce 100644 --- a/src/native/mac/juce_mac_NSViewComponentPeer.mm +++ b/src/native/mac/juce_mac_NSViewComponentPeer.mm @@ -1719,46 +1719,6 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo) return new NSViewComponentPeer (this, styleFlags, (NSView*) windowToAttachTo); } -//============================================================================== -Image juce_createIconForFile (const File& file) -{ - JUCE_AUTORELEASEPOOL - - NSImage* image = [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (file.getFullPathName())]; - - CoreGraphicsImage* result = new CoreGraphicsImage (Image::ARGB, (int) [image size].width, (int) [image size].height, true); - - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithGraphicsPort: result->context flipped: false]]; - - [image drawAtPoint: NSMakePoint (0, 0) - fromRect: NSMakeRect (0, 0, [image size].width, [image size].height) - operation: NSCompositeSourceOver fraction: 1.0f]; - - [[NSGraphicsContext currentContext] flushGraphics]; - [NSGraphicsContext restoreGraphicsState]; - - return Image (result); -} - -//============================================================================== -void SystemClipboard::copyTextToClipboard (const String& text) -{ - [[NSPasteboard generalPasteboard] declareTypes: [NSArray arrayWithObject: NSStringPboardType] - owner: nil]; - - [[NSPasteboard generalPasteboard] setString: juceStringToNS (text) - forType: NSStringPboardType]; -} - -String SystemClipboard::getTextFromClipboard() -{ - NSString* text = [[NSPasteboard generalPasteboard] stringForType: NSStringPboardType]; - - return text == nil ? String::empty - : nsStringToJuce (text); -} - //============================================================================== const int KeyPress::spaceKey = ' '; const int KeyPress::returnKey = 0x0d; diff --git a/src/native/mac/juce_mac_NativeCode.mm b/src/native/mac/juce_mac_NativeCode.mm index dc512f19b5..c0a90b6d82 100644 --- a/src/native/mac/juce_mac_NativeCode.mm +++ b/src/native/mac/juce_mac_NativeCode.mm @@ -118,13 +118,6 @@ BEGIN_JUCE_NAMESPACE #include "juce_mac_Threads.mm" #include "../common/juce_posix_SharedCode.h" #include "juce_mac_Files.mm" - -#if JUCE_IOS - #include "juce_ios_MiscUtilities.mm" -#else - #include "juce_mac_MiscUtilities.mm" -#endif - #include "juce_mac_Debugging.mm" #if ! JUCE_ONLY_BUILD_CORE_LIBRARY @@ -132,6 +125,7 @@ BEGIN_JUCE_NAMESPACE #include "juce_mac_Fonts.mm" #include "juce_mac_CoreGraphicsContext.mm" #include "juce_ios_UIViewComponentPeer.mm" + #include "juce_ios_Windowing.mm" #include "juce_ios_MessageManager.mm" #include "juce_mac_FileChooser.mm" #include "juce_mac_OpenGLComponent.mm" @@ -143,6 +137,7 @@ BEGIN_JUCE_NAMESPACE #include "juce_mac_Fonts.mm" // (must go before juce_mac_CoreGraphicsContext.mm) #include "juce_mac_CoreGraphicsContext.mm" #include "juce_mac_NSViewComponentPeer.mm" + #include "juce_mac_Windowing.mm" #include "juce_mac_MouseCursor.mm" #include "juce_mac_NSViewComponent.mm" #include "juce_mac_AppleRemote.mm" diff --git a/src/native/mac/juce_mac_MiscUtilities.mm b/src/native/mac/juce_mac_Windowing.mm similarity index 85% rename from src/native/mac/juce_mac_MiscUtilities.mm rename to src/native/mac/juce_mac_Windowing.mm index 4625fa55c1..ded8321013 100644 --- a/src/native/mac/juce_mac_MiscUtilities.mm +++ b/src/native/mac/juce_mac_Windowing.mm @@ -28,26 +28,12 @@ #if JUCE_INCLUDED_FILE -//============================================================================== -ScopedAutoReleasePool::ScopedAutoReleasePool() -{ - pool = [[NSAutoreleasePool alloc] init]; -} - -ScopedAutoReleasePool::~ScopedAutoReleasePool() -{ - [((NSAutoreleasePool*) pool) release]; -} - //============================================================================== void LookAndFeel::playAlertSound() { NSBeep(); } -//============================================================================== -#if ! JUCE_ONLY_BUILD_CORE_LIBRARY - //============================================================================== class OSXMessageBox : public AsyncUpdater { @@ -336,5 +322,46 @@ void Desktop::getCurrentMonitorPositions (Array >& monitorCoords jassert (monitorCoords.size() > 0); } -#endif +//============================================================================== +Image juce_createIconForFile (const File& file) +{ + JUCE_AUTORELEASEPOOL + + NSImage* image = [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (file.getFullPathName())]; + + CoreGraphicsImage* result = new CoreGraphicsImage (Image::ARGB, + (int) [image size].width, + (int) [image size].height, true); + + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithGraphicsPort: result->context flipped: false]]; + + [image drawAtPoint: NSMakePoint (0, 0) + fromRect: NSMakeRect (0, 0, [image size].width, [image size].height) + operation: NSCompositeSourceOver fraction: 1.0f]; + + [[NSGraphicsContext currentContext] flushGraphics]; + [NSGraphicsContext restoreGraphicsState]; + + return Image (result); +} + +//============================================================================== +void SystemClipboard::copyTextToClipboard (const String& text) +{ + [[NSPasteboard generalPasteboard] declareTypes: [NSArray arrayWithObject: NSStringPboardType] + owner: nil]; + + [[NSPasteboard generalPasteboard] setString: juceStringToNS (text) + forType: NSStringPboardType]; +} + +String SystemClipboard::getTextFromClipboard() +{ + NSString* text = [[NSPasteboard generalPasteboard] stringForType: NSStringPboardType]; + + return text == nil ? String::empty + : nsStringToJuce (text); +} + #endif diff --git a/src/native/mac/juce_osx_ObjCHelpers.h b/src/native/mac/juce_osx_ObjCHelpers.h index dbd0894868..468e5fe51a 100644 --- a/src/native/mac/juce_osx_ObjCHelpers.h +++ b/src/native/mac/juce_osx_ObjCHelpers.h @@ -63,5 +63,16 @@ namespace } } +//============================================================================== +ScopedAutoReleasePool::ScopedAutoReleasePool() +{ + pool = [[NSAutoreleasePool alloc] init]; +} + +ScopedAutoReleasePool::~ScopedAutoReleasePool() +{ + [((NSAutoreleasePool*) pool) release]; +} + #endif // __JUCE_OSX_OBJCHELPERS_JUCEHEADER__