From cb39f9b4c7addc200d63edb6bb6459b4796ad9d0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?IOhannes=20m=20zm=C3=B6lnig=20=28Debian/GNU=29?= Date: Mon, 30 Aug 2021 11:23:15 +0200 Subject: [PATCH] New upstream version 6.1.0~ds0 --- BREAKING-CHANGES.txt | 386 + CMakeLists.txt | 45 +- ChangeList.txt | 33 +- LICENSE.md | 4 +- README.md | 21 +- docs/Accessibility.md | 48 + docs/CMake API.md | 114 +- docs/JUCE Module Format.md | 14 +- docs/Linux Dependencies.md | 6 +- docs/doxygen/Makefile | 2 +- examples/Assets/DSPDemos_Common.h | 22 +- examples/Assets/DemoUtilities.h | 2 +- examples/Assets/WavefrontObjParser.h | 4 +- examples/Audio/AudioPlaybackDemo.h | 25 +- examples/Audio/AudioRecordingDemo.h | 10 +- examples/Audio/MPEDemo.h | 2 +- examples/BLOCKS/BlocksDrawingDemo.h | 699 - examples/BLOCKS/BlocksMonitorDemo.h | 1036 -- examples/BLOCKS/BlocksSynthDemo.h | 866 -- examples/BLOCKS/CMakeLists.txt | 24 - examples/CMake/ConsoleApp/CMakeLists.txt | 2 +- examples/CMake/GuiApp/CMakeLists.txt | 2 +- examples/CMakeLists.txt | 3 +- examples/DSP/IIRFilterDemo.h | 6 +- examples/DSP/SIMDRegisterDemo.h | 6 +- .../Builds/Android/app/CMakeLists.txt | 329 +- .../Android/app/src/main/AndroidManifest.xml | 2 +- .../app/src/main/assets/DSPDemos_Common.h | 22 +- .../app/src/main/assets/DemoUtilities.h | 2 +- .../app/src/main/assets/WavefrontObjParser.h | 4 +- .../DemoRunner/Builds/Android/build.gradle | 6 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../DemoRunner/Builds/LinuxMakefile/Makefile | 10 +- .../DemoRunner.xcodeproj/project.pbxproj | 1465 +- .../DemoRunner/Builds/MacOSX/Info-App.plist | 6 +- .../VisualStudio2015/DemoRunner_App.vcxproj | 255 +- .../DemoRunner_App.vcxproj.filters | 510 +- .../Builds/VisualStudio2015/resources.rc | 6 +- .../VisualStudio2017/DemoRunner_App.vcxproj | 255 +- .../DemoRunner_App.vcxproj.filters | 510 +- .../Builds/VisualStudio2017/resources.rc | 6 +- .../VisualStudio2019/DemoRunner_App.vcxproj | 255 +- .../DemoRunner_App.vcxproj.filters | 510 +- .../Builds/VisualStudio2019/resources.rc | 6 +- .../iOS/DemoRunner.xcodeproj/project.pbxproj | 1456 +- examples/DemoRunner/Builds/iOS/Info-App.plist | 13 +- examples/DemoRunner/CMakeLists.txt | 17 +- examples/DemoRunner/DemoRunner.jucer | 18 +- .../DemoRunner/JuceLibraryCode/JuceHeader.h | 7 +- .../include_juce_blocks_basics.cpp | 8 - .../DemoRunner/Source/Demos/DemoPIPs1.cpp | 12 +- .../DemoRunner/Source/Demos/DemoPIPs2.cpp | 14 +- .../DemoRunner/Source/Demos/IntroScreen.h | 9 + examples/DemoRunner/Source/Demos/JUCEDemos.h | 1 + examples/DemoRunner/Source/Main.cpp | 24 +- .../DemoRunner/Source/UI/MainComponent.cpp | 118 +- .../DemoRunner/Source/UI/SettingsContent.h | 194 +- examples/GUI/AccessibilityDemo.h | 1477 ++ examples/GUI/CameraDemo.h | 6 +- examples/GUI/DialogsDemo.h | 202 +- examples/GUI/FontsDemo.h | 8 +- examples/GUI/GraphicsDemo.h | 33 +- examples/GUI/ImagesDemo.h | 1 + examples/GUI/KeyMappingsDemo.h | 5 + examples/GUI/MDIDemo.h | 52 +- examples/GUI/MenusDemo.h | 12 + examples/GUI/OpenGLAppDemo.h | 125 +- examples/GUI/OpenGLDemo.h | 147 +- examples/GUI/PropertiesDemo.h | 2 +- examples/GUI/VideoDemo.h | 15 +- examples/GUI/WidgetsDemo.h | 48 +- examples/Plugins/ArpeggiatorPluginDemo.h | 2 +- examples/Plugins/AudioPluginDemo.h | 7 +- examples/Plugins/DSPModulePluginDemo.h | 225 +- examples/Plugins/GainPluginDemo.h | 2 +- .../Plugins/InterAppAudioEffectPluginDemo.h | 39 +- examples/Plugins/MidiLoggerPluginDemo.h | 4 +- examples/Plugins/MultiOutSynthPluginDemo.h | 30 +- examples/Plugins/NoiseGatePluginDemo.h | 2 +- .../Plugins/ReaperEmbeddedViewPluginDemo.h | 425 + examples/Plugins/SamplerPluginDemo.h | 19 +- examples/Plugins/SurroundPluginDemo.h | 2 +- examples/Plugins/extern/LICENSE.md | 19 + .../Plugins/extern/reaper_plugin_fx_embed.h | 140 + .../Plugins/extern/reaper_vst3_interfaces.h | 31 + examples/Utilities/InAppPurchasesDemo.h | 4 +- examples/Utilities/OSCDemo.h | 10 +- examples/Utilities/PushNotificationsDemo.h | 116 +- examples/Utilities/ValueTreesDemo.h | 1 + examples/Utilities/XMLandJSONDemo.h | 9 +- .../Builds/Android/app/CMakeLists.txt | 220 +- .../Builds/Android/build.gradle | 6 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../Builds/LinuxMakefile/Makefile | 4 +- .../project.pbxproj | 796 +- .../AudioPerformanceTest_App.vcxproj | 161 +- .../AudioPerformanceTest_App.vcxproj.filters | 327 +- .../project.pbxproj | 845 +- .../Builds/iOS/Info-App.plist | 4 +- .../JuceLibraryCode/JuceHeader.h | 2 +- extras/AudioPluginHost/AudioPluginHost.jucer | 6 +- .../Builds/Android/app/CMakeLists.txt | 237 +- .../main/assets/AudioLiveScrollingDisplay.h | 72 + .../app/src/main/assets/Box2DTests/AddPair.h | 51 + .../src/main/assets/Box2DTests/ApplyForce.h | 183 + .../src/main/assets/Box2DTests/BodyTypes.h | 159 + .../src/main/assets/Box2DTests/Breakable.h | 155 + .../app/src/main/assets/Box2DTests/Bridge.h | 125 + .../src/main/assets/Box2DTests/BulletTest.h | 136 + .../src/main/assets/Box2DTests/Cantilever.h | 211 + .../app/src/main/assets/Box2DTests/Car.h | 286 + .../app/src/main/assets/Box2DTests/Chain.h | 74 + .../assets/Box2DTests/CharacterCollision.h | 253 + .../assets/Box2DTests/CollisionFiltering.h | 176 + .../assets/Box2DTests/CollisionProcessing.h | 188 + .../main/assets/Box2DTests/CompoundShapes.h | 143 + .../app/src/main/assets/Box2DTests/Confined.h | 167 + .../main/assets/Box2DTests/ContinuousTest.h | 137 + .../src/main/assets/Box2DTests/DistanceTest.h | 135 + .../app/src/main/assets/Box2DTests/Dominos.h | 215 + .../src/main/assets/Box2DTests/DumpShell.h | 267 + .../main/assets/Box2DTests/DynamicTreeTest.h | 357 + .../src/main/assets/Box2DTests/EdgeShapes.h | 249 + .../app/src/main/assets/Box2DTests/EdgeTest.h | 109 + .../app/src/main/assets/Box2DTests/Gears.h | 187 + .../main/assets/Box2DTests/OneSidedPlatform.h | 120 + .../app/src/main/assets/Box2DTests/Pinball.h | 169 + .../main/assets/Box2DTests/PolyCollision.h | 122 + .../src/main/assets/Box2DTests/PolyShapes.h | 295 + .../src/main/assets/Box2DTests/Prismatic.h | 107 + .../app/src/main/assets/Box2DTests/Pulleys.h | 106 + .../app/src/main/assets/Box2DTests/Pyramid.h | 89 + .../app/src/main/assets/Box2DTests/RayCast.h | 440 + .../app/src/main/assets/Box2DTests/Revolute.h | 166 + .../app/src/main/assets/Box2DTests/Rope.h | 101 + .../src/main/assets/Box2DTests/RopeJoint.h | 145 + .../src/main/assets/Box2DTests/SensorTest.h | 181 + .../src/main/assets/Box2DTests/ShapeEditing.h | 105 + .../src/main/assets/Box2DTests/SliderCrank.h | 156 + .../src/main/assets/Box2DTests/SphereStack.h | 86 + .../main/assets/Box2DTests/TestEntries.cpp | 125 + .../src/main/assets/Box2DTests/TheoJansen.h | 256 + .../app/src/main/assets/Box2DTests/Tiles.h | 156 + .../src/main/assets/Box2DTests/TimeOfImpact.h | 131 + .../app/src/main/assets/Box2DTests/Tumbler.h | 99 + .../main/assets/Box2DTests/VaryingFriction.h | 124 + .../assets/Box2DTests/VaryingRestitution.h | 69 + .../main/assets/Box2DTests/VerticalStack.h | 165 + .../app/src/main/assets/Box2DTests/Web.h | 209 + .../app/src/main/assets/DSPDemos_Common.h | 691 + .../app/src/main/assets/DemoUtilities.h | 255 + .../Notifications/images/ic_stat_name.png | Bin 0 -> 351 bytes .../Notifications/images/ic_stat_name10.png | Bin 0 -> 1156 bytes .../Notifications/images/ic_stat_name2.png | Bin 0 -> 204 bytes .../Notifications/images/ic_stat_name3.png | Bin 0 -> 292 bytes .../Notifications/images/ic_stat_name4.png | Bin 0 -> 341 bytes .../Notifications/images/ic_stat_name5.png | Bin 0 -> 337 bytes .../Notifications/images/ic_stat_name6.png | Bin 0 -> 1059 bytes .../Notifications/images/ic_stat_name7.png | Bin 0 -> 543 bytes .../Notifications/images/ic_stat_name8.png | Bin 0 -> 928 bytes .../Notifications/images/ic_stat_name9.png | Bin 0 -> 915 bytes .../Notifications/sounds/demonstrative.caf | Bin 0 -> 190178 bytes .../Notifications/sounds/demonstrative.mp3 | Bin 0 -> 127059 bytes .../assets/Notifications/sounds/isntit.caf | Bin 0 -> 20654 bytes .../assets/Notifications/sounds/isntit.mp3 | Bin 0 -> 11284 bytes .../Notifications/sounds/jinglebellssms.caf | Bin 0 -> 116568 bytes .../Notifications/sounds/jinglebellssms.mp3 | Bin 0 -> 24116 bytes .../assets/Notifications/sounds/served.caf | Bin 0 -> 13922 bytes .../assets/Notifications/sounds/served.mp3 | Bin 0 -> 6687 bytes .../assets/Notifications/sounds/solemn.caf | Bin 0 -> 114902 bytes .../assets/Notifications/sounds/solemn.mp3 | Bin 0 -> 75650 bytes .../app/src/main/assets/Purchases/Ed.png | Bin 0 -> 139106 bytes .../app/src/main/assets/Purchases/Ed0.ogg | Bin 0 -> 7771 bytes .../app/src/main/assets/Purchases/Ed1.ogg | Bin 0 -> 11553 bytes .../app/src/main/assets/Purchases/Ed2.ogg | Bin 0 -> 8351 bytes .../app/src/main/assets/Purchases/Fabian.png | Bin 0 -> 90415 bytes .../app/src/main/assets/Purchases/Fabian0.ogg | Bin 0 -> 10287 bytes .../app/src/main/assets/Purchases/Fabian1.ogg | Bin 0 -> 15211 bytes .../app/src/main/assets/Purchases/Fabian2.ogg | Bin 0 -> 10763 bytes .../app/src/main/assets/Purchases/JB.png | Bin 0 -> 79173 bytes .../app/src/main/assets/Purchases/JB0.ogg | Bin 0 -> 8340 bytes .../app/src/main/assets/Purchases/JB1.ogg | Bin 0 -> 13545 bytes .../app/src/main/assets/Purchases/JB2.ogg | Bin 0 -> 8943 bytes .../app/src/main/assets/Purchases/Jules.png | Bin 0 -> 81743 bytes .../app/src/main/assets/Purchases/Jules0.ogg | Bin 0 -> 8277 bytes .../app/src/main/assets/Purchases/Jules1.ogg | Bin 0 -> 12303 bytes .../app/src/main/assets/Purchases/Jules2.ogg | Bin 0 -> 9912 bytes .../app/src/main/assets/Purchases/Lukasz.png | Bin 0 -> 120402 bytes .../app/src/main/assets/Purchases/Lukasz0.ogg | Bin 0 -> 14767 bytes .../app/src/main/assets/Purchases/Lukasz1.ogg | Bin 0 -> 21756 bytes .../app/src/main/assets/Purchases/Lukasz2.ogg | Bin 0 -> 13962 bytes .../app/src/main/assets/Purchases/Robot.png | Bin 0 -> 31502 bytes .../app/src/main/assets/Purchases/Robot0.ogg | Bin 0 -> 9224 bytes .../app/src/main/assets/Purchases/Robot1.ogg | Bin 0 -> 16365 bytes .../app/src/main/assets/Purchases/Robot2.ogg | Bin 0 -> 11029 bytes .../app/src/main/assets/Purchases/icon.png | Bin 0 -> 70933 bytes .../assets/Signing/InAppPurchase.keystore | Bin 0 -> 2271 bytes .../app/src/main/assets/Signing/README.txt | 5 + .../app/src/main/assets/WavefrontObjParser.h | 365 + .../app/src/main/assets/cassette_recorder.wav | Bin 0 -> 37902 bytes .../Android/app/src/main/assets/cello.wav | Bin 0 -> 46348 bytes .../app/src/main/assets/demo table data.xml | 49 + .../app/src/main/assets/google-services.json | 40 + .../app/src/main/assets/guitar_amp.wav | Bin 0 -> 90246 bytes .../Android/app/src/main/assets/icons.zip | Bin 0 -> 83876 bytes .../Android/app/src/main/assets/juce_icon.png | Bin 0 -> 45854 bytes .../src/main/assets/juce_icon_template.png | Bin 0 -> 18827 bytes .../app/src/main/assets/juce_module_info | 38 + .../app/src/main/assets/portmeirion.jpg | Bin 0 -> 145904 bytes .../Android/app/src/main/assets/power.png | Bin 0 -> 27122 bytes .../Android/app/src/main/assets/proaudio.path | Bin 0 -> 452 bytes .../Android/app/src/main/assets/reverb_ir.wav | Bin 0 -> 648404 bytes .../Android/app/src/main/assets/singing.ogg | Bin 0 -> 15354 bytes .../Android/app/src/main/assets/teapot.obj | 2866 ++++ .../app/src/main/assets/tile_background.png | Bin 0 -> 151 bytes .../Android/app/src/main/assets/treedemo.xml | 50 + .../Builds/Android/build.gradle | 6 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../Builds/LinuxMakefile/Makefile | 10 +- .../AudioPluginHost.xcodeproj/project.pbxproj | 1185 +- .../Builds/MacOSX/Info-App.plist | 2 + .../AudioPluginHost_App.vcxproj | 174 +- .../AudioPluginHost_App.vcxproj.filters | 354 +- .../AudioPluginHost_App.vcxproj | 174 +- .../AudioPluginHost_App.vcxproj.filters | 354 +- .../AudioPluginHost_App.vcxproj | 174 +- .../AudioPluginHost_App.vcxproj.filters | 354 +- .../AudioPluginHost.xcodeproj/project.pbxproj | 1219 +- .../AudioPluginHost/Builds/iOS/Info-App.plist | 4 +- extras/AudioPluginHost/CMakeLists.txt | 3 +- .../JuceLibraryCode/BinaryData.cpp | 724 - .../JuceLibraryCode/BinaryData.h | 30 - .../JuceLibraryCode/JuceHeader.h | 3 +- extras/AudioPluginHost/Source/HostStartup.cpp | 119 + .../Source/Plugins/InternalPlugins.cpp | 5 +- .../Source/Plugins/PluginGraph.cpp | 81 +- .../Source/Plugins/PluginGraph.h | 5 +- .../Source/UI/GraphEditorPanel.cpp | 46 +- .../Source/UI/MainHostWindow.cpp | 180 +- .../Source/UI/MainHostWindow.h | 36 +- .../AudioPluginHost/Source/UI/PluginWindow.h | 18 +- extras/BLOCKS/Makefile | 24 - extras/BLOCKS/standalone_sdk/README.md | 68 - .../BLOCKS/standalone_sdk/SDK/BlocksHeader.h | 15 - .../standalone_sdk/SDK/Build/Linux/Makefile | 46 - .../BLOCKS-SDK.xcodeproj/project.pbxproj | 299 - .../SDK/Build/Windows/BLOCKS-SDK.sln | 28 - .../SDK/Build/Windows/BLOCKS-SDK.vcxproj | 150 - .../examples/BlockFinder/BlockFinder.cpp | 49 - .../examples/BlockFinder/BlockFinder.h | 39 - .../examples/BlockFinder/Linux/Makefile | 72 - .../examples/BlockFinder/Linux/main.cpp | 49 - .../BlockFinder.xcodeproj/project.pbxproj | 368 - .../examples/BlockFinder/MacOS/Makefile | 72 - .../examples/BlockFinder/MacOS/main.mm | 36 - .../BlockFinder/Windows/BlockFinder.sln | 41 - .../BlockFinder/Windows/BlockFinder.vcxproj | 172 - .../examples/BlockFinder/Windows/main.cpp | 49 - extras/BinaryBuilder/BinaryBuilder.jucer | 2 +- .../Builds/LinuxMakefile/Makefile | 4 +- .../BinaryBuilder.xcodeproj/project.pbxproj | 437 +- .../BinaryBuilder_ConsoleApp.vcxproj | 17 +- .../BinaryBuilder_ConsoleApp.vcxproj.filters | 13 +- .../JuceLibraryCode/JuceHeader.h | 2 +- extras/Build/CMake/JUCECheckAtomic.cmake | 9 +- extras/Build/CMake/JUCEConfig.cmake.in | 1 - extras/Build/CMake/JUCEHelperTargets.cmake | 6 +- extras/Build/CMake/JUCEModuleSupport.cmake | 592 + extras/Build/CMake/JUCEUtils.cmake | 766 +- extras/Build/CMake/copyDir.cmake | 2 +- .../CMake/juce_runtime_arch_detection.cpp | 2 +- .../Build/juce_build_tools/juce_build_tools.h | 2 +- .../utils/juce_BinaryResourceFile.cpp | 6 +- .../utils/juce_BuildHelperFunctions.cpp | 64 +- .../juce_build_tools/utils/juce_Icons.cpp | 4 +- .../utils/juce_PlistOptions.cpp | 45 +- .../utils/juce_PlistOptions.h | 7 +- .../juce_build_tools/utils/juce_ProjectType.h | 2 +- .../utils/juce_RelativePath.h | 2 +- .../utils/juce_VersionNumbers.cpp | 17 +- .../utils/juce_VersionNumbers.h | 7 +- extras/Build/juceaide/CMakeLists.txt | 3 + extras/Build/juceaide/Main.cpp | 35 +- .../Builds/Android/app/CMakeLists.txt | 234 +- .../Builds/Android/build.gradle | 6 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../Builds/LinuxMakefile/Makefile | 4 +- .../Builds/MacOSX/Info-App.plist | 2 + .../project.pbxproj | 1068 +- .../NetworkGraphicsDemo_App.vcxproj | 172 +- .../NetworkGraphicsDemo_App.vcxproj.filters | 348 +- .../Builds/iOS/Info-App.plist | 4 +- .../project.pbxproj | 1119 +- .../JuceLibraryCode/BinaryData.cpp | 2 + .../JuceLibraryCode/JuceHeader.h | 2 +- .../NetworkGraphicsDemo.jucer | 8 +- .../Source/SlaveComponent.h | 2 + extras/Projucer/Builds/LinuxMakefile/Makefile | 26 +- extras/Projucer/Builds/MacOSX/Info-App.plist | 6 +- .../MacOSX/Projucer.xcodeproj/project.pbxproj | 4026 ++---- .../VisualStudio2015/Projucer_App.vcxproj | 98 +- .../Projucer_App.vcxproj.filters | 231 +- .../Builds/VisualStudio2015/resources.rc | 6 +- .../VisualStudio2017/Projucer_App.vcxproj | 98 +- .../Projucer_App.vcxproj.filters | 231 +- .../Builds/VisualStudio2017/resources.rc | 6 +- .../VisualStudio2019/Projucer_App.vcxproj | 98 +- .../Projucer_App.vcxproj.filters | 231 +- .../Builds/VisualStudio2019/resources.rc | 6 +- extras/Projucer/CMakeLists.txt | 4 - .../Projucer/JuceLibraryCode/BinaryData.cpp | 330 +- extras/Projucer/JuceLibraryCode/BinaryData.h | 7 +- extras/Projucer/JuceLibraryCode/JuceHeader.h | 6 +- extras/Projucer/Projucer.jucer | 76 +- .../StartPage/jucer_ContentComponents.h | 40 +- .../StartPage/jucer_NewProjectWizard.cpp | 100 +- .../StartPage/jucer_NewProjectWizard.h | 7 +- .../StartPage/jucer_StartPageComponent.cpp | 26 +- .../StartPage/jucer_StartPageTreeHolder.h | 24 +- .../UserAccount/jucer_LicenseController.h | 2 +- .../UserAccount/jucer_LicenseQueryThread.h | 14 +- .../UserAccount/jucer_LoginFormComponent.h | 17 +- .../jucer_EditorColourSchemeWindowComponent.h | 45 +- .../jucer_GlobalPathsWindowComponent.h | 15 +- .../Windows/jucer_PIPCreatorWindowComponent.h | 23 +- .../jucer_TranslationToolWindowComponent.h | 59 +- .../Source/Application/jucer_Application.cpp | 276 +- .../Source/Application/jucer_Application.h | 19 +- .../Source/Application/jucer_AutoUpdater.cpp | 80 +- .../Source/Application/jucer_AutoUpdater.h | 3 + .../Source/Application/jucer_CommandIDs.h | 17 +- .../Source/Application/jucer_CommandLine.cpp | 15 +- .../Source/Application/jucer_CommonHeaders.h | 2 +- .../Source/Application/jucer_Headers.h | 6 - .../Source/Application/jucer_Main.cpp | 21 - .../Source/Application/jucer_MainWindow.cpp | 369 +- .../Source/Application/jucer_MainWindow.h | 11 +- .../BinaryData/Icons/juce-logo-with-text.svg | 143 - .../CodeEditor/jucer_LiveBuildCodeEditor.h | 743 - .../CodeEditor/jucer_OpenDocumentManager.cpp | 213 +- .../CodeEditor/jucer_OpenDocumentManager.h | 37 +- .../CodeEditor/jucer_SourceCodeEditor.cpp | 74 +- .../CodeEditor/jucer_SourceCodeEditor.h | 14 +- .../Components/jucer_ComboBoxHandler.h | 50 +- .../Components/jucer_ComponentTypeHandler.cpp | 4 +- .../Components/jucer_ComponentTypeHandler.h | 2 +- .../Components/jucer_SliderHandler.h | 22 +- .../Components/jucer_TabbedComponentHandler.h | 26 +- .../Components/jucer_TextEditorHandler.h | 28 +- .../Components/jucer_ToggleButtonHandler.h | 2 +- .../Documents/jucer_ButtonDocument.cpp | 2 +- .../Documents/jucer_ComponentDocument.cpp | 2 +- .../PaintElements/jucer_ColouredElement.cpp | 12 +- .../PaintElements/jucer_FillType.h | 7 +- .../jucer_ImageResourceProperty.h | 18 +- .../PaintElements/jucer_PaintElement.cpp | 7 +- .../PaintElements/jucer_PaintElement.h | 2 +- .../PaintElements/jucer_PaintElementGroup.cpp | 2 +- .../PaintElements/jucer_PaintElementPath.cpp | 82 +- .../PaintElements/jucer_PaintElementPath.h | 6 +- .../jucer_PaintElementUndoableAction.h | 6 +- .../Properties/jucer_PositionPropertyBase.h | 236 +- .../UI/jucer_ComponentLayoutEditor.cpp | 8 +- .../UI/jucer_PaintRoutineEditor.cpp | 2 +- .../UI/jucer_ResourceEditorPanel.cpp | 19 +- .../ComponentEditor/jucer_BinaryResources.cpp | 37 +- .../ComponentEditor/jucer_BinaryResources.h | 17 +- .../ComponentEditor/jucer_ComponentLayout.cpp | 6 +- .../ComponentEditor/jucer_ComponentLayout.h | 2 +- .../ComponentEditor/jucer_JucerDocument.cpp | 123 +- .../ComponentEditor/jucer_PaintRoutine.cpp | 4 +- .../ComponentEditor/jucer_PaintRoutine.h | 2 +- .../Licenses/jucer_LicenseController.cpp | 4 +- .../UI/jucer_ComponentListComponent.h | 10 +- .../UI/jucer_ErrorListComponent.h | 363 - .../LiveBuildEngine/jucer_ActivityList.h | 111 - .../LiveBuildEngine/jucer_ClassDatabase.h | 731 - .../jucer_ClientServerMessages.h | 295 - .../jucer_CompileEngineClient.cpp | 907 -- .../jucer_CompileEngineClient.h | 155 - .../LiveBuildEngine/jucer_CompileEngineDLL.h | 201 - .../jucer_CompileEngineServer.cpp | 307 - .../jucer_CompileEngineSettings.h | 109 - .../Source/LiveBuildEngine/jucer_CppHelpers.h | 283 - .../LiveBuildEngine/jucer_DiagnosticMessage.h | 208 - .../jucer_DownloadCompileEngineThread.cpp | 166 - .../Source/LiveBuildEngine/jucer_ErrorList.h | 120 - .../jucer_LiveCodeBuilderDLL.h | 50 - .../Source/LiveBuildEngine/jucer_MessageIDs.h | 63 - .../LiveBuildEngine/jucer_ProjectBuildInfo.h | 101 - .../LiveBuildEngine/jucer_SourceCodeRange.h | 105 - .../Modules/jucer_AvailableModulesList.h | 42 +- .../Source/Project/Modules/jucer_Modules.cpp | 37 +- .../Source/Project/Modules/jucer_Modules.h | 2 + .../UI/Sidebar/jucer_ExporterTreeItems.h | 64 +- .../Project/UI/Sidebar/jucer_FileTreeItems.h | 173 +- .../Project/UI/Sidebar/jucer_LiveBuildTab.h | 277 - .../UI/Sidebar/jucer_ModuleTreeItems.h | 20 +- .../Project/UI/Sidebar/jucer_ProjectTab.h | 286 - .../UI/Sidebar/jucer_ProjectTreeItemBase.h | 7 +- .../Source/Project/UI/Sidebar/jucer_Sidebar.h | 560 + .../Project/UI/Sidebar/jucer_TabComponents.h | 254 - .../Project/UI/jucer_ContentViewComponent.h | 112 + .../Project/UI/jucer_ContentViewComponents.h | 186 +- .../Project/UI/jucer_HeaderComponent.cpp | 155 +- .../Source/Project/UI/jucer_HeaderComponent.h | 14 +- .../UI/jucer_ProjectContentComponent.cpp | 835 +- .../UI/jucer_ProjectContentComponent.h | 102 +- .../UI/jucer_ProjectMessagesComponent.h | 36 +- .../Project/UI/jucer_UserAvatarComponent.h | 14 + .../Projucer/Source/Project/jucer_Project.cpp | 173 +- .../Projucer/Source/Project/jucer_Project.h | 25 +- .../jucer_ProjectExport_Android.h | 136 +- .../ProjectSaving/jucer_ProjectExport_CLion.h | 6 +- .../jucer_ProjectExport_CodeBlocks.h | 5 + .../ProjectSaving/jucer_ProjectExport_MSVC.h | 59 +- .../ProjectSaving/jucer_ProjectExport_Make.h | 9 +- .../ProjectSaving/jucer_ProjectExport_Xcode.h | 1096 +- .../ProjectSaving/jucer_ProjectExporter.cpp | 14 +- .../ProjectSaving/jucer_ProjectExporter.h | 4 + .../ProjectSaving/jucer_ProjectSaver.cpp | 44 +- .../Source/ProjectSaving/jucer_ProjectSaver.h | 26 +- .../ProjectSaving/jucer_XcodeProjectParser.h | 12 +- .../Utility/Helpers/jucer_MiscUtilities.cpp | 9 +- .../Utility/Helpers/jucer_NewFileWizard.cpp | 145 +- .../Utility/Helpers/jucer_NewFileWizard.h | 8 +- .../Source/Utility/Helpers/jucer_PresetIDs.h | 19 +- .../Helpers/jucer_TranslationHelpers.h | 4 +- .../Utility/Helpers/jucer_VersionInfo.cpp | 15 +- .../jucer_FilePathPropertyComponent.h | 26 +- .../Source/Utility/UI/jucer_Icons.cpp | 986 +- .../Projucer/Source/Utility/UI/jucer_Icons.h | 9 +- .../Utility/UI/jucer_JucerTreeViewBase.cpp | 35 +- .../Utility/UI/jucer_JucerTreeViewBase.h | 52 +- .../Utility/UI/jucer_ProjucerLookAndFeel.cpp | 13 +- .../Builds/LinuxMakefile/Makefile | 10 +- .../UnitTestRunner.xcodeproj/project.pbxproj | 1230 +- .../UnitTestRunner_ConsoleApp.vcxproj | 255 +- .../UnitTestRunner_ConsoleApp.vcxproj.filters | 510 +- .../UnitTestRunner_ConsoleApp.vcxproj | 255 +- .../UnitTestRunner_ConsoleApp.vcxproj.filters | 510 +- extras/UnitTestRunner/CMakeLists.txt | 1 - .../JuceLibraryCode/JuceHeader.h | 3 +- .../include_juce_blocks_basics.cpp | 8 - extras/UnitTestRunner/UnitTestRunner.jucer | 11 +- .../WindowsDLL_StaticLibrary.vcxproj | 172 +- .../WindowsDLL_StaticLibrary.vcxproj.filters | 348 +- .../WindowsDLL/JuceLibraryCode/JuceHeader.h | 2 +- modules/CMakeLists.txt | 1 - .../juce_ThreadedAnalyticsDestination.cpp | 4 +- modules/juce_analytics/juce_analytics.h | 3 +- .../audio_play_head/juce_AudioPlayHead.h | 64 +- .../buffers/juce_AudioChannelSet.cpp | 2 + .../buffers/juce_AudioChannelSet.h | 12 + .../buffers/juce_AudioDataConverters.cpp | 2 + .../buffers/juce_AudioSampleBuffer.h | 156 +- .../buffers/juce_FloatVectorOperations.cpp | 4 +- .../juce_audio_basics/juce_audio_basics.cpp | 11 + modules/juce_audio_basics/juce_audio_basics.h | 3 +- .../midi/juce_MidiBuffer.cpp | 107 +- .../juce_audio_basics/midi/juce_MidiBuffer.h | 12 +- .../midi}/juce_MidiDataConcatenator.h | 0 .../juce_audio_basics/midi/juce_MidiFile.cpp | 17 +- .../juce_audio_basics/midi/juce_MidiFile.h | 6 +- .../midi/juce_MidiKeyboardState.cpp | 4 +- .../midi/juce_MidiMessage.cpp | 14 +- .../juce_audio_basics/midi/juce_MidiMessage.h | 6 +- .../juce_audio_basics/midi/juce_MidiRPN.cpp | 2 +- .../midi/ump/juce_UMP.h} | 37 +- .../midi}/ump/juce_UMPConversion.h | 0 .../midi}/ump/juce_UMPConverters.h | 0 .../midi}/ump/juce_UMPDispatcher.h | 10 +- .../midi}/ump/juce_UMPFactory.h | 0 .../midi}/ump/juce_UMPIterator.h | 2 +- .../ump/juce_UMPMidi1ToBytestreamTranslator.h | 0 .../juce_UMPMidi1ToMidi2DefaultTranslator.cpp | 0 .../juce_UMPMidi1ToMidi2DefaultTranslator.h | 0 .../midi}/ump/juce_UMPProtocols.h | 0 .../midi}/ump/juce_UMPReceiver.h | 0 .../midi}/ump/juce_UMPSysEx7.cpp | 0 .../midi}/ump/juce_UMPSysEx7.h | 0 .../midi/ump/juce_UMPTests.cpp | 1018 ++ .../midi}/ump/juce_UMPUtils.cpp | 0 .../midi}/ump/juce_UMPUtils.h | 0 .../midi}/ump/juce_UMPView.cpp | 0 .../midi}/ump/juce_UMPView.h | 0 .../midi}/ump/juce_UMPacket.h | 0 .../midi}/ump/juce_UMPackets.h | 0 .../mpe/juce_MPEInstrument.cpp | 2 + .../mpe/juce_MPESynthesiser.cpp | 7 +- .../juce_audio_basics/mpe/juce_MPEUtils.cpp | 2 +- .../sources/juce_BufferingAudioSource.cpp | 158 +- .../sources/juce_BufferingAudioSource.h | 19 +- .../sources/juce_MemoryAudioSource.cpp | 171 +- .../juce_audio_basics/utilities/juce_ADSR.h | 153 +- .../utilities/juce_ADSR_test.cpp | 243 + .../utilities/juce_GenericInterpolator.h | 2 +- .../utilities/juce_IIRFilter.cpp | 40 +- .../utilities/juce_IIRFilter.h | 51 +- .../utilities/juce_Interpolators.cpp | 2 +- .../utilities/juce_LagrangeInterpolator.cpp | 2 +- .../juce_audio_basics/utilities/juce_Reverb.h | 4 + .../utilities/juce_SmoothedValue.h | 4 +- .../audio_io/juce_AudioDeviceManager.cpp | 42 +- .../audio_io/juce_AudioDeviceManager.h | 1 + .../audio_io/juce_AudioIODeviceType.cpp | 4 +- .../juce_audio_devices/juce_audio_devices.cpp | 46 +- .../juce_audio_devices/juce_audio_devices.h | 13 +- .../midi_io/juce_MidiDevices.h | 4 +- .../midi_io/ump/juce_UMPTests.cpp | 10 +- .../native/juce_android_Oboe.cpp | 4 +- .../native/juce_ios_Audio.cpp | 2 +- .../native/juce_linux_JackAudio.cpp | 6 +- .../native/juce_linux_Midi.cpp | 54 +- .../native/juce_mac_CoreAudio.cpp | 108 +- .../native/juce_mac_CoreMidi.mm | 175 +- .../native/juce_win32_ASIO.cpp | 18 +- .../native/juce_win32_DirectSound.cpp | 47 +- .../native/juce_win32_Midi.cpp | 68 +- .../native/juce_win32_WASAPI.cpp | 79 +- .../native/oboe/CMakeLists.txt | 8 +- .../juce_audio_devices/native/oboe/LICENSE | 0 .../native/oboe/{readme.md => README.md} | 2 +- .../native/oboe/include/oboe/AudioStream.h | 20 +- .../oboe/include/oboe/AudioStreamBase.h | 16 +- .../oboe/include/oboe/AudioStreamBuilder.h | 41 +- .../native/oboe/include/oboe/Definitions.h | 32 +- .../native/oboe/include/oboe/Version.h | 4 +- .../native/oboe/src/aaudio/AAudioExtensions.h | 172 + .../native/oboe/src/aaudio/AAudioLoader.cpp | 34 +- .../native/oboe/src/aaudio/AAudioLoader.h | 22 +- .../oboe/src/aaudio/AudioStreamAAudio.cpp | 113 +- .../oboe/src/aaudio/AudioStreamAAudio.h | 13 +- .../native/oboe/src/common/AudioStream.cpp | 14 +- .../oboe/src/common/AudioStreamBuilder.cpp | 31 +- .../src/common/DataConversionFlowGraph.cpp | 24 + .../oboe/src/common/FilterAudioStream.cpp | 2 +- .../oboe/src/common/FilterAudioStream.h | 21 +- .../native/oboe/src/common/QuirksManager.cpp | 58 +- .../native/oboe/src/common/QuirksManager.h | 10 + .../oboe/src/common/SourceI24Caller.cpp | 56 + .../native/oboe/src/common/SourceI24Caller.h | 52 + .../oboe/src/common/SourceI32Caller.cpp | 47 + .../native/oboe/src/common/SourceI32Caller.h | 52 + .../native/oboe/src/common/Utilities.cpp | 8 + .../oboe/src/flowgraph/FlowgraphUtilities.h | 55 + .../oboe/src/flowgraph/ManyToMultiConverter.h | 2 +- .../native/oboe/src/flowgraph/RampLinear.cpp | 4 + .../native/oboe/src/flowgraph/SinkFloat.cpp | 2 +- .../native/oboe/src/flowgraph/SinkFloat.h | 1 + .../native/oboe/src/flowgraph/SinkI32.cpp | 55 + .../native/oboe/src/flowgraph/SinkI32.h | 42 + .../native/oboe/src/flowgraph/SourceFloat.cpp | 8 +- .../native/oboe/src/flowgraph/SourceFloat.h | 1 + .../native/oboe/src/flowgraph/SourceI32.cpp | 54 + .../native/oboe/src/flowgraph/SourceI32.h | 44 + .../oboe/src/opensles/AudioStreamBuffered.h | 2 +- .../oboe/src/opensles/AudioStreamOpenSLES.cpp | 4 - .../oboe/src/opensles/AudioStreamOpenSLES.h | 5 +- .../oboe/src/opensles/OpenSLESUtilities.cpp | 2 + .../codecs/juce_AiffAudioFormat.cpp | 12 +- .../codecs/juce_CoreAudioFormat.cpp | 13 +- .../codecs/juce_FlacAudioFormat.cpp | 9 +- .../codecs/juce_MP3AudioFormat.cpp | 10 +- .../codecs/juce_OggVorbisAudioFormat.cpp | 14 +- .../codecs/juce_WavAudioFormat.cpp | 4 +- .../codecs/juce_WindowsMediaAudioFormat.cpp | 36 +- .../codecs/juce_WindowsMediaAudioFormat.h | 2 +- .../format/juce_AudioFormatReader.cpp | 6 +- .../format/juce_AudioFormatReader.h | 7 +- .../format/juce_AudioFormatWriter.cpp | 16 +- .../juce_BufferingAudioFormatReader.cpp | 190 +- .../format/juce_BufferingAudioFormatReader.h | 29 +- .../juce_audio_formats/juce_audio_formats.h | 5 +- .../AAX/juce_AAX_Wrapper.cpp | 58 +- .../juce_audio_plugin_client/AUResources.r | 10 + .../RTAS/juce_RTAS_Wrapper.cpp | 2 +- .../Standalone/juce_StandaloneFilterApp.cpp | 2 +- .../Standalone/juce_StandaloneFilterWindow.h | 276 +- .../Unity/juce_UnityPluginInterface.h | 2 +- .../Unity/juce_Unity_Wrapper.cpp | 4 +- .../VST/juce_VST_Wrapper.cpp | 445 +- .../VST/juce_VST_Wrapper.mm | 8 +- .../VST3/juce_VST3_Wrapper.cpp | 1163 +- .../juce_audio_plugin_client.h | 5 +- .../juce_audio_plugin_client_AU_2.mm | 4 +- .../utility/juce_IncludeSystemHeaders.h | 2 +- .../utility/juce_LinuxMessageThread.h | 103 + .../utility/juce_PluginHostType.h | 439 - .../utility/juce_PluginUtilities.cpp | 69 +- .../utility/juce_WindowsHooks.h | 107 +- .../format/juce_AudioPluginFormatManager.cpp | 12 +- .../format_types/VST3_SDK/JUCE_README.md | 6 + .../format_types/VST3_SDK/LICENSE.txt | 2 +- .../format_types/VST3_SDK/README.md | 255 +- .../format_types/VST3_SDK/base/LICENSE.txt | 2 +- .../format_types/VST3_SDK/base/README.md | 5 +- .../VST3_SDK/base/source/baseiids.cpp | 2 +- .../base/source/classfactoryhelpers.h | 2 +- .../VST3_SDK/base/source/fbuffer.cpp | 7 +- .../VST3_SDK/base/source/fbuffer.h | 6 +- .../VST3_SDK/base/source/fdebug.cpp | 167 +- .../VST3_SDK/base/source/fdebug.h | 19 +- .../VST3_SDK/base/source/fobject.cpp | 20 +- .../VST3_SDK/base/source/fobject.h | 52 +- .../VST3_SDK/base/source/fstreamer.cpp | 8 +- .../VST3_SDK/base/source/fstreamer.h | 4 +- .../VST3_SDK/base/source/fstring.cpp | 91 +- .../VST3_SDK/base/source/fstring.h | 29 +- .../VST3_SDK/base/source/updatehandler.cpp | 44 +- .../VST3_SDK/base/source/updatehandler.h | 16 +- .../VST3_SDK/base/thread/include/flock.h | 8 +- .../VST3_SDK/base/thread/source/flock.cpp | 4 +- .../VST3_SDK/pluginterfaces/LICENSE.txt | 2 +- .../VST3_SDK/pluginterfaces/README.md | 7 +- .../pluginterfaces/base/conststringtable.h | 1 - .../VST3_SDK/pluginterfaces/base/falignpush.h | 4 +- .../VST3_SDK/pluginterfaces/base/fplatform.h | 43 +- .../VST3_SDK/pluginterfaces/base/fstrdefs.h | 4 +- .../VST3_SDK/pluginterfaces/base/ftypes.h | 8 +- .../VST3_SDK/pluginterfaces/base/funknown.cpp | 54 +- .../VST3_SDK/pluginterfaces/base/funknown.h | 181 +- .../VST3_SDK/pluginterfaces/base/fvariant.h | 8 +- .../VST3_SDK/pluginterfaces/base/ibstream.h | 12 +- .../VST3_SDK/pluginterfaces/base/icloneable.h | 5 +- .../pluginterfaces/base/ipersistent.h | 17 +- .../pluginterfaces/base/ipluginbase.h | 115 +- .../pluginterfaces/base/istringresult.h | 12 +- .../pluginterfaces/base/iupdatehandler.h | 8 +- .../pluginterfaces/base/smartpointer.h | 12 +- .../pluginterfaces/base/typesizecheck.h | 40 +- .../VST3_SDK/pluginterfaces/base/ustring.cpp | 9 +- .../VST3_SDK/pluginterfaces/base/ustring.h | 68 +- .../VST3_SDK/pluginterfaces/gui/iplugview.h | 47 +- .../gui/iplugviewcontentscalesupport.h | 5 +- .../pluginterfaces/vst/ivstattributes.h | 41 +- .../pluginterfaces/vst/ivstaudioprocessor.h | 236 +- .../pluginterfaces/vst/ivstautomationstate.h | 6 +- .../vst/ivstchannelcontextinfo.h | 44 +- .../pluginterfaces/vst/ivstcomponent.h | 71 +- .../pluginterfaces/vst/ivstcontextmenu.h | 48 +- .../pluginterfaces/vst/ivsteditcontroller.h | 429 +- .../VST3_SDK/pluginterfaces/vst/ivstevents.h | 59 +- .../pluginterfaces/vst/ivsthostapplication.h | 47 +- .../pluginterfaces/vst/ivstinterappaudio.h | 20 +- .../VST3_SDK/pluginterfaces/vst/ivstmessage.h | 19 +- .../pluginterfaces/vst/ivstmidicontrollers.h | 14 +- .../pluginterfaces/vst/ivstmidilearn.h | 55 +- .../pluginterfaces/vst/ivstnoteexpression.h | 78 +- .../pluginterfaces/vst/ivstparameterchanges.h | 39 +- .../vst/ivstparameterfunctionname.h | 143 + .../pluginterfaces/vst/ivstphysicalui.h | 59 +- .../vst/ivstpluginterfacesupport.h | 15 +- .../pluginterfaces/vst/ivstplugview.h | 6 +- .../vst/ivstprefetchablesupport.h | 32 +- .../pluginterfaces/vst/ivstprocesscontext.h | 81 +- .../pluginterfaces/vst/ivstrepresentation.h | 42 +- .../pluginterfaces/vst/ivsttestplugprovider.h | 22 +- .../VST3_SDK/pluginterfaces/vst/ivstunits.h | 76 +- .../VST3_SDK/pluginterfaces/vst/vstspeaker.h | 392 +- .../VST3_SDK/pluginterfaces/vst/vsttypes.h | 31 +- .../VST3_SDK/public.sdk/LICENSE.txt | 2 +- .../VST3_SDK/public.sdk/README.md | 9 +- .../public.sdk/source/common/memorystream.cpp | 10 +- .../public.sdk/source/common/memorystream.h | 15 +- .../public.sdk/source/common/pluginview.cpp | 4 +- .../public.sdk/source/common/pluginview.h | 47 +- .../source/vst/hosting/hostclasses.cpp | 59 +- .../source/vst/hosting/hostclasses.h | 8 +- .../vst/hosting/pluginterfacesupport.cpp | 7 +- .../source/vst/hosting/pluginterfacesupport.h | 2 +- .../VST3_SDK/public.sdk/source/vst/vstbus.cpp | 2 +- .../VST3_SDK/public.sdk/source/vst/vstbus.h | 22 +- .../public.sdk/source/vst/vstcomponent.cpp | 6 +- .../public.sdk/source/vst/vstcomponent.h | 10 +- .../source/vst/vstcomponentbase.cpp | 56 +- .../public.sdk/source/vst/vstcomponentbase.h | 31 +- .../source/vst/vsteditcontroller.cpp | 78 +- .../public.sdk/source/vst/vsteditcontroller.h | 38 +- .../public.sdk/source/vst/vstinitiids.cpp | 9 +- .../public.sdk/source/vst/vstparameters.cpp | 39 +- .../public.sdk/source/vst/vstparameters.h | 26 +- .../public.sdk/source/vst/vstpresetfile.cpp | 12 +- .../public.sdk/source/vst/vstpresetfile.h | 27 +- .../format_types/juce_AU_Shared.h | 68 +- .../juce_AudioUnitPluginFormat.mm | 403 +- .../format_types/juce_LADSPAPluginFormat.cpp | 10 +- .../format_types/juce_LADSPAPluginFormat.h | 2 +- .../juce_LegacyAudioParameter.cpp | 10 +- .../format_types/juce_VST3Common.h | 477 +- .../format_types/juce_VST3Headers.h | 21 +- .../format_types/juce_VST3PluginFormat.cpp | 1608 ++- .../format_types/juce_VST3PluginFormat.h | 11 +- .../format_types/juce_VSTMidiEventList.h | 15 +- .../format_types/juce_VSTPluginFormat.cpp | 274 +- .../juce_audio_processors.cpp | 120 +- .../juce_audio_processors.h | 10 +- .../processors/juce_AudioPluginInstance.cpp | 2 + .../processors/juce_AudioPluginInstance.h | 17 +- .../processors/juce_AudioProcessor.cpp | 55 +- .../processors/juce_AudioProcessor.h | 19 +- .../processors/juce_AudioProcessorEditor.cpp | 75 +- .../processors/juce_AudioProcessorEditor.h | 67 +- .../juce_AudioProcessorEditorHostContext.h | 68 + .../processors/juce_AudioProcessorGraph.cpp | 78 +- .../processors/juce_AudioProcessorGraph.h | 2 + .../processors/juce_AudioProcessorListener.h | 31 +- .../processors/juce_AudioProcessorParameter.h | 2 + .../juce_AudioProcessorParameterGroup.cpp | 2 +- .../juce_GenericAudioProcessorEditor.cpp | 6 +- .../processors/juce_PluginDescription.cpp | 29 +- .../processors/juce_PluginDescription.h | 26 +- .../scanning/juce_KnownPluginList.cpp | 9 +- .../scanning/juce_PluginListComponent.cpp | 8 +- .../juce_AudioProcessorValueTreeState.cpp | 8 +- .../utilities/juce_ExtensionsVisitor.h | 86 + .../utilities/juce_PluginHostType.cpp | 312 + .../utilities/juce_PluginHostType.h | 245 + .../utilities/juce_VST3ClientExtensions.h | 95 + .../utilities}/juce_VSTCallbackHandler.h | 5 + .../audio_cd/juce_AudioCDReader.h | 2 +- .../gui/juce_AudioAppComponent.h | 8 +- .../gui/juce_AudioDeviceSelectorComponent.cpp | 27 +- .../gui/juce_AudioDeviceSelectorComponent.h | 5 +- .../gui/juce_AudioThumbnail.h | 2 +- modules/juce_audio_utils/juce_audio_utils.cpp | 2 +- modules/juce_audio_utils/juce_audio_utils.h | 3 +- ...oid_BluetoothMidiDevicePairingDialogue.cpp | 10 +- .../native/juce_mac_AudioCDReader.mm | 4 +- ..._mac_BluetoothMidiDevicePairingDialogue.mm | 8 +- .../players/juce_AudioProcessorPlayer.cpp | 369 +- .../players/juce_AudioProcessorPlayer.h | 25 +- modules/juce_blocks_basics/README.txt | 9 - .../juce_blocks_basics/blocks/juce_Block.cpp | 128 - .../juce_blocks_basics/blocks/juce_Block.h | 552 - .../blocks/juce_BlockConfigManager.h | 358 - .../blocks/juce_BlocksVersion.cpp | 237 - .../blocks/juce_BlocksVersion.h | 87 - .../blocks/juce_ControlButton.h | 141 - .../juce_blocks_basics/blocks/juce_LEDGrid.h | 105 - .../juce_blocks_basics/blocks/juce_LEDRow.h | 64 - .../blocks/juce_TouchList.h | 152 - .../blocks/juce_TouchSurface.h | 138 - .../juce_LittleFootFunctions.dox | 785 - .../juce_blocks_basics/juce_blocks_basics.cpp | 44 - .../juce_blocks_basics/juce_blocks_basics.h | 85 - .../littlefoot/LittleFoot Language README.txt | 125 - .../littlefoot/juce_LittleFootCompiler.h | 2454 ---- .../littlefoot/juce_LittleFootRemoteHeap.h | 455 - .../littlefoot/juce_LittleFootRunner.h | 877 -- .../protocol/Protocol Format.txt | 96 - .../protocol/juce_BitPackingUtilities.h | 289 - .../protocol/juce_BlockModels.h | 367 - .../protocol/juce_BlocksProtocolDefinitions.h | 612 - .../protocol/juce_HostPacketBuilder.h | 325 - .../protocol/juce_HostPacketDecoder.h | 383 - .../internal/juce_BandwidthStatsLogger.cpp | 101 - .../internal/juce_BlockImplementation.cpp | 1151 -- .../internal/juce_BlockSerialReader.cpp | 130 - .../internal/juce_ConnectedDeviceGroup.cpp | 785 - .../juce_DepreciatedVersionReader.cpp | 139 - .../topology/internal/juce_Detector.cpp | 797 - .../topology/internal/juce_DetectorHolder.cpp | 70 - .../topology/internal/juce_DeviceInfo.cpp | 50 - .../internal/juce_MIDIDeviceDetector.cpp | 183 - .../internal/juce_MidiDeviceConnection.cpp | 113 - .../topology/juce_BlockGraph.cpp | 112 - .../topology/juce_BlockGraph.h | 66 - .../topology/juce_PhysicalTopologySource.cpp | 204 - .../topology/juce_PhysicalTopologySource.h | 98 - .../topology/juce_RuleBasedTopologySource.cpp | 126 - .../topology/juce_RuleBasedTopologySource.h | 90 - .../topology/juce_Topology.h | 120 - .../topology/juce_TopologySource.h | 87 - .../visualisers/juce_BitmapLEDProgram.cpp | 87 - .../visualisers/juce_DrumPadLEDProgram.cpp | 881 -- .../visualisers/juce_DrumPadLEDProgram.h | 126 - modules/juce_box2d/juce_box2d.cpp | 2 + modules/juce_box2d/juce_box2d.h | 3 +- .../containers/juce_AbstractFifo.cpp | 4 + .../juce_core/containers/juce_AbstractFifo.h | 8 +- modules/juce_core/containers/juce_Array.h | 16 +- .../juce_core/containers/juce_ArrayBase.cpp | 6 +- modules/juce_core/containers/juce_ArrayBase.h | 49 +- .../juce_core/containers/juce_DynamicObject.h | 2 +- .../containers/juce_LinkedListPointer.h | 7 + .../juce_core/containers/juce_OwnedArray.cpp | 4 +- .../juce_core/containers/juce_PropertySet.cpp | 2 +- .../containers/juce_ReferenceCountedArray.cpp | 4 +- modules/juce_core/containers/juce_Variant.cpp | 640 +- modules/juce_core/containers/juce_Variant.h | 14 +- modules/juce_core/files/juce_File.cpp | 28 +- .../juce_core/javascript/juce_Javascript.cpp | 2 +- modules/juce_core/juce_core.cpp | 35 +- modules/juce_core/juce_core.h | 6 +- modules/juce_core/logging/juce_Logger.cpp | 2 +- modules/juce_core/maths/juce_Expression.cpp | 16 +- .../juce_core/memory/juce_AllocationHooks.cpp | 6 +- modules/juce_core/memory/juce_HeapBlock.h | 2 +- modules/juce_core/memory/juce_Memory.h | 24 +- modules/juce_core/memory/juce_MemoryBlock.cpp | 13 +- modules/juce_core/memory/juce_MemoryBlock.h | 13 +- modules/juce_core/misc/juce_Functional.h | 53 + .../native/juce_BasicNativeHeaders.h | 7 +- .../native/juce_android_JNIHelpers.h | 19 +- .../juce_core/native/juce_android_Network.cpp | 27 +- .../native/juce_android_SystemStats.cpp | 2 +- .../juce_core/native/juce_curl_Network.cpp | 32 +- .../juce_core/native/juce_intel_SharedCode.h | 108 + .../native/juce_linux_CommonFile.cpp | 5 +- modules/juce_core/native/juce_linux_Files.cpp | 12 +- .../juce_core/native/juce_linux_Network.cpp | 59 +- .../native/juce_linux_SystemStats.cpp | 162 +- modules/juce_core/native/juce_mac_CFHelpers.h | 63 + .../native/juce_mac_ClangBugWorkaround.h | 41 - modules/juce_core/native/juce_mac_Files.mm | 2 +- modules/juce_core/native/juce_mac_Network.mm | 32 +- ...x_ObjCHelpers.h => juce_mac_ObjCHelpers.h} | 57 +- .../juce_core/native/juce_mac_SystemStats.mm | 101 +- .../juce_core/native/juce_posix_IPAddress.h | 29 +- .../juce_core/native/juce_posix_NamedPipe.cpp | 4 + .../juce_core/native/juce_posix_SharedCode.h | 74 +- .../native/juce_wasm_SystemStats.cpp | 87 + .../juce_core/native/juce_win32_ComSmartPtr.h | 63 +- modules/juce_core/native/juce_win32_Files.cpp | 16 +- .../juce_core/native/juce_win32_Network.cpp | 38 +- .../native/juce_win32_SystemStats.cpp | 61 +- .../juce_core/native/juce_win32_Threads.cpp | 42 +- modules/juce_core/network/juce_NamedPipe.cpp | 3 + modules/juce_core/network/juce_Socket.cpp | 11 +- modules/juce_core/network/juce_URL.cpp | 184 +- modules/juce_core/network/juce_URL.h | 369 +- .../juce_core/network/juce_WebInputStream.cpp | 32 +- .../juce_core/network/juce_WebInputStream.h | 149 +- .../juce_core/streams/juce_OutputStream.cpp | 2 +- .../juce_core/system/juce_CompilerSupport.h | 39 +- .../juce_core/system/juce_CompilerWarnings.h | 2 +- modules/juce_core/system/juce_PlatformDefs.h | 40 +- .../juce_core/system/juce_StandardHeader.h | 12 +- modules/juce_core/system/juce_SystemStats.cpp | 8 +- modules/juce_core/system/juce_SystemStats.h | 2 + .../juce_core/system/juce_TargetPlatform.h | 7 +- modules/juce_core/text/juce_Base64.cpp | 3 +- .../juce_core/text/juce_CharPointer_ASCII.h | 5 +- .../juce_core/text/juce_CharPointer_UTF16.h | 7 + .../juce_core/text/juce_CharPointer_UTF32.h | 3 + .../juce_core/text/juce_CharPointer_UTF8.h | 7 + .../text/juce_CharacterFunctions.cpp | 395 +- .../juce_core/text/juce_CharacterFunctions.h | 114 +- modules/juce_core/text/juce_String.cpp | 2 + modules/juce_core/text/juce_String.h | 92 +- modules/juce_core/text/juce_StringArray.h | 3 +- modules/juce_core/text/juce_TextDiff.cpp | 3 + .../juce_core/threads/juce_ChildProcess.cpp | 2 +- .../juce_core/threads/juce_CriticalSection.h | 4 +- modules/juce_core/threads/juce_Process.h | 2 +- modules/juce_core/threads/juce_Thread.cpp | 23 +- modules/juce_core/threads/juce_Thread.h | 1 + .../threads/juce_TimeSliceThread.cpp | 2 +- .../juce_core/threads/juce_WaitableEvent.cpp | 2 +- modules/juce_core/xml/juce_XmlDocument.cpp | 19 +- modules/juce_core/xml/juce_XmlDocument.h | 2 - modules/juce_core/xml/juce_XmlElement.h | 216 +- .../zip/juce_GZIPDecompressorInputStream.cpp | 2 +- modules/juce_cryptography/juce_cryptography.h | 3 +- .../app_properties/juce_PropertiesFile.cpp | 4 +- .../juce_data_structures.h | 3 +- .../values/juce_ValueTree.cpp | 17 +- modules/juce_dsp/containers/juce_AudioBlock.h | 40 +- .../containers/juce_FixedSizeFunction.h | 5 +- .../juce_dsp/frequency/juce_Convolution.cpp | 2 + modules/juce_dsp/frequency/juce_Convolution.h | 18 +- .../frequency/juce_Convolution_test.cpp | 7 +- modules/juce_dsp/frequency/juce_FFT.cpp | 16 +- modules/juce_dsp/frequency/juce_FFT.h | 6 + modules/juce_dsp/frequency/juce_FFT_test.cpp | 2 +- modules/juce_dsp/juce_dsp.h | 2 +- modules/juce_dsp/maths/juce_Matrix.h | 2 +- .../native/juce_fallback_SIMDNativeOps.h | 5 +- .../processors/juce_BallisticsFilter.h | 2 +- .../juce_dsp/processors/juce_DryWetMixer.cpp | 242 +- .../juce_dsp/processors/juce_DryWetMixer.h | 2 + modules/juce_dsp/processors/juce_FIRFilter.h | 3 +- .../processors/juce_FirstOrderTPTFilter.cpp | 1 + .../processors/juce_FirstOrderTPTFilter.h | 2 +- .../juce_dsp/processors/juce_IIRFilter.cpp | 383 +- modules/juce_dsp/processors/juce_IIRFilter.h | 278 +- .../juce_dsp/processors/juce_IIRFilter_Impl.h | 22 +- .../processors/juce_LinkwitzRileyFilter.h | 2 +- .../juce_dsp/processors/juce_Oversampling.cpp | 4 +- modules/juce_dsp/processors/juce_Panner.h | 5 +- .../processors/juce_ProcessorDuplicator.h | 2 +- .../processors/juce_StateVariableFilter.h | 2 +- .../processors/juce_StateVariableTPTFilter.h | 2 +- modules/juce_dsp/widgets/juce_Bias.h | 4 +- modules/juce_dsp/widgets/juce_Chorus.cpp | 11 +- modules/juce_dsp/widgets/juce_Chorus.h | 9 +- modules/juce_dsp/widgets/juce_Gain.h | 2 + modules/juce_events/juce_events.cpp | 7 +- modules/juce_events/juce_events.h | 6 +- .../messages/juce_ApplicationBase.cpp | 6 +- .../messages/juce_CallbackMessage.h | 2 +- .../messages/juce_Initialisation.h | 13 +- .../messages/juce_MessageManager.cpp | 53 +- .../messages/juce_MessageManager.h | 3 +- .../juce_ScopedLowPowerModeDisabler.cpp | 54 + .../native/juce_ScopedLowPowerModeDisabler.h} | 32 +- .../native/juce_android_Messaging.cpp | 9 - .../native/juce_linux_Messaging.cpp | 5 +- .../native/juce_mac_MessageManager.mm | 456 +- .../native/juce_osx_MessageQueue.h | 13 +- .../native/juce_win32_HiddenMessageWindow.h | 2 - .../native/juce_win32_Messaging.cpp | 6 +- .../native/juce_win32_WinRTWrapper.cpp | 59 +- .../native/juce_win32_WinRTWrapper.h | 96 +- modules/juce_graphics/colour/juce_Colour.cpp | 26 +- modules/juce_graphics/colour/juce_Colour.h | 8 +- .../juce_graphics/colour/juce_PixelFormats.h | 103 +- .../contexts/juce_GraphicsContext.h | 2 +- .../juce_graphics/fonts/juce_TextLayout.cpp | 91 +- modules/juce_graphics/fonts/juce_TextLayout.h | 35 +- .../juce_graphics/geometry/juce_EdgeTable.cpp | 4 + modules/juce_graphics/geometry/juce_Path.cpp | 2 +- .../geometry/juce_PathIterator.cpp | 16 +- .../image_formats/juce_GIFLoader.cpp | 7 +- .../image_formats/juce_JPEGLoader.cpp | 8 +- .../image_formats/juce_PNGLoader.cpp | 9 +- modules/juce_graphics/images/juce_Image.cpp | 2 +- modules/juce_graphics/juce_graphics.cpp | 6 +- modules/juce_graphics/juce_graphics.h | 3 +- .../native/juce_RenderingHelpers.h | 6 +- .../native/juce_android_Fonts.cpp | 2 +- .../juce_graphics/native/juce_linux_Fonts.cpp | 5 +- .../native/juce_mac_CoreGraphicsContext.mm | 32 +- .../native/juce_mac_CoreGraphicsHelpers.h | 44 +- .../juce_graphics/native/juce_mac_Fonts.mm | 378 +- .../native/juce_mac_IconHelpers.cpp | 30 +- .../juce_win32_DirectWriteTypeLayout.cpp | 41 +- .../native/juce_win32_DirectWriteTypeface.cpp | 41 +- .../juce_graphics/native/juce_win32_Fonts.cpp | 20 +- .../enums/juce_AccessibilityActions.h | 119 + .../enums/juce_AccessibilityEvent.h | 81 + .../enums/juce_AccessibilityRole.h | 71 + .../juce_AccessibilityCellInterface.h | 61 + .../juce_AccessibilityTableInterface.h | 54 + .../juce_AccessibilityTextInterface.h | 81 + .../juce_AccessibilityValueInterface.h | 222 + .../juce_AccessibilityHandler.cpp | 337 + .../accessibility/juce_AccessibilityHandler.h | 325 + .../accessibility/juce_AccessibilityState.h | 227 + .../juce_gui_basics/buttons/juce_Button.cpp | 87 +- modules/juce_gui_basics/buttons/juce_Button.h | 2 + .../juce_ApplicationCommandManager.cpp | 10 +- .../commands/juce_KeyPressMappingSet.cpp | 2 +- .../components/juce_Component.cpp | 494 +- .../components/juce_Component.h | 444 +- .../components/juce_ComponentTraverser.h | 72 + .../components/juce_FocusTraverser.cpp | 359 + .../components/juce_FocusTraverser.h | 93 + .../components/juce_ModalComponentManager.cpp | 35 +- .../components/juce_ModalComponentManager.h | 41 +- .../juce_gui_basics/desktop/juce_Desktop.cpp | 6 +- .../juce_gui_basics/desktop/juce_Displays.cpp | 24 +- .../juce_gui_basics/desktop/juce_Displays.h | 59 +- .../drawables/juce_Drawable.cpp | 20 +- .../drawables/juce_DrawableImage.cpp | 32 +- .../drawables/juce_DrawableImage.h | 8 + .../drawables/juce_DrawableText.cpp | 21 + .../drawables/juce_DrawableText.h | 2 + .../drawables/juce_SVGParser.cpp | 12 +- .../filebrowser/juce_FileBrowserComponent.cpp | 10 +- .../filebrowser/juce_FileBrowserComponent.h | 2 + .../filebrowser/juce_FileChooser.cpp | 12 +- .../filebrowser/juce_FileChooser.h | 34 +- .../filebrowser/juce_FileChooserDialogBox.cpp | 8 +- .../filebrowser/juce_FileChooserDialogBox.h | 37 +- .../filebrowser/juce_FileListComponent.cpp | 13 +- .../filebrowser/juce_FileListComponent.h | 1 + .../juce_FileSearchPathListComponent.cpp | 33 +- .../juce_FileSearchPathListComponent.h | 1 + .../filebrowser/juce_FileTreeComponent.cpp | 9 +- .../filebrowser/juce_FilenameComponent.cpp | 34 +- .../filebrowser/juce_FilenameComponent.h | 38 +- .../juce_ImagePreviewComponent.cpp | 6 + .../filebrowser/juce_ImagePreviewComponent.h | 3 +- modules/juce_gui_basics/juce_gui_basics.cpp | 100 +- modules/juce_gui_basics/juce_gui_basics.h | 27 +- .../keyboard/juce_KeyboardFocusTraverser.cpp | 279 +- .../keyboard/juce_KeyboardFocusTraverser.h | 73 +- .../layout/juce_ComponentAnimator.cpp | 1 + .../layout/juce_ConcertinaPanel.cpp | 6 + .../layout/juce_ConcertinaPanel.h | 4 + .../layout/juce_GroupComponent.cpp | 6 + .../layout/juce_GroupComponent.h | 2 + .../layout/juce_MultiDocumentPanel.cpp | 231 +- .../layout/juce_MultiDocumentPanel.h | 81 +- .../juce_gui_basics/layout/juce_ScrollBar.cpp | 38 +- .../juce_gui_basics/layout/juce_ScrollBar.h | 7 + .../juce_gui_basics/layout/juce_SidePanel.cpp | 34 +- .../juce_gui_basics/layout/juce_SidePanel.h | 30 +- .../layout/juce_TabbedButtonBar.cpp | 8 +- .../layout/juce_TabbedButtonBar.h | 2 + .../layout/juce_TabbedComponent.cpp | 6 + .../layout/juce_TabbedComponent.h | 2 + .../juce_gui_basics/layout/juce_Viewport.cpp | 1 + .../juce_gui_basics/layout/juce_Viewport.h | 4 +- .../lookandfeel/juce_LookAndFeel.cpp | 2 +- .../lookandfeel/juce_LookAndFeel_V2.cpp | 14 +- .../lookandfeel/juce_LookAndFeel_V2.h | 2 +- .../lookandfeel/juce_LookAndFeel_V4.cpp | 10 +- .../lookandfeel/juce_LookAndFeel_V4.h | 2 +- .../menus/juce_BurgerMenuComponent.cpp | 6 + .../menus/juce_BurgerMenuComponent.h | 2 + .../menus/juce_MenuBarComponent.cpp | 253 +- .../menus/juce_MenuBarComponent.h | 30 +- .../juce_gui_basics/menus/juce_PopupMenu.cpp | 354 +- .../juce_gui_basics/menus/juce_PopupMenu.h | 4 +- .../misc/juce_BubbleComponent.h | 8 +- .../misc/juce_DropShadower.cpp | 12 +- .../juce_gui_basics/misc/juce_DropShadower.h | 4 +- .../misc/juce_JUCESplashScreen.cpp | 8 + .../misc/juce_JUCESplashScreen.h | 4 + .../mouse/juce_MouseInputSource.cpp | 5 +- .../juce_AccessibilityTextHelpers.h | 111 + .../juce_android_Accessibility.cpp | 867 ++ .../accessibility/juce_ios_Accessibility.mm | 532 + .../accessibility/juce_mac_Accessibility.mm | 949 ++ .../juce_mac_AccessibilitySharedCode.mm | 260 + .../juce_win32_Accessibility.cpp | 301 + .../juce_win32_AccessibilityElement.cpp | 553 + .../juce_win32_AccessibilityElement.h | 80 + .../juce_win32_UIAExpandCollapseProvider.h | 86 + .../juce_win32_UIAGridItemProvider.h | 105 + .../juce_win32_UIAGridProvider.h | 94 + .../accessibility/juce_win32_UIAHelpers.h | 105 + .../juce_win32_UIAInvokeProvider.h | 62 + .../juce_win32_UIAProviderBase.h | 41 +- .../accessibility/juce_win32_UIAProviders.h | 43 + .../juce_win32_UIARangeValueProvider.h | 140 + .../juce_win32_UIASelectionProvider.h | 256 + .../juce_win32_UIATextProvider.h | 592 + .../juce_win32_UIAToggleProvider.h | 80 + .../juce_win32_UIATransformProvider.h | 125 + .../juce_win32_UIAValueProvider.h | 86 + .../juce_win32_UIAWindowProvider.h | 197 + .../juce_win32_WindowsUIAWrapper.h | 158 + .../app/com/rmsl/juce/ComponentPeerView.java | 114 +- .../native/juce_android_ContentSharer.cpp | 11 +- .../native/juce_android_FileChooser.cpp | 10 +- .../native/juce_android_Windowing.cpp | 1185 +- .../native/juce_ios_ContentSharer.cpp | 4 +- .../native/juce_ios_FileChooser.mm | 27 +- .../native/juce_ios_UIViewComponentPeer.mm | 247 +- .../native/juce_ios_Windowing.mm | 189 +- .../native/juce_linux_FileChooser.cpp | 15 +- .../native/juce_linux_Windowing.cpp | 185 +- .../native/juce_mac_FileChooser.mm | 19 +- .../native/juce_mac_MainMenu.mm | 6 +- .../native/juce_mac_NSViewComponentPeer.mm | 581 +- .../native/juce_mac_Windowing.mm | 178 +- .../native/juce_win32_DragAndDrop.cpp | 34 +- .../native/juce_win32_FileChooser.cpp | 214 +- ...uce_win32_ScopedThreadDPIAwarenessSetter.h | 25 +- .../native/juce_win32_Windowing.cpp | 1308 +- .../native/x11/juce_linux_X11_DragAndDrop.cpp | 81 +- .../native/x11/juce_linux_X11_Symbols.cpp | 10 +- .../native/x11/juce_linux_X11_Symbols.h | 6 +- .../native/x11/juce_linux_XWindowSystem.cpp | 735 +- .../native/x11/juce_linux_XWindowSystem.h | 132 +- .../positioning/juce_RelativePoint.cpp | 2 +- .../positioning/juce_RelativeRectangle.cpp | 2 +- .../juce_ChoicePropertyComponent.cpp | 85 +- .../properties/juce_ChoicePropertyComponent.h | 5 +- .../juce_MultiChoicePropertyComponent.cpp | 3 +- .../properties/juce_PropertyPanel.cpp | 4 +- .../juce_gui_basics/widgets/juce_ComboBox.cpp | 46 +- .../juce_gui_basics/widgets/juce_ComboBox.h | 2 + .../widgets/juce_ImageComponent.cpp | 24 + .../widgets/juce_ImageComponent.h | 2 + .../juce_gui_basics/widgets/juce_Label.cpp | 126 +- modules/juce_gui_basics/widgets/juce_Label.h | 4 +- .../juce_gui_basics/widgets/juce_ListBox.cpp | 245 +- .../juce_gui_basics/widgets/juce_ListBox.h | 8 + .../widgets/juce_ProgressBar.cpp | 50 + .../widgets/juce_ProgressBar.h | 2 + .../juce_gui_basics/widgets/juce_Slider.cpp | 106 +- modules/juce_gui_basics/widgets/juce_Slider.h | 5 + .../widgets/juce_TableHeaderComponent.cpp | 8 +- .../widgets/juce_TableHeaderComponent.h | 2 + .../widgets/juce_TableListBox.cpp | 133 +- .../widgets/juce_TableListBox.h | 3 +- .../widgets/juce_TextEditor.cpp | 415 +- .../juce_gui_basics/widgets/juce_TextEditor.h | 51 +- .../juce_gui_basics/widgets/juce_Toolbar.cpp | 8 +- .../juce_gui_basics/widgets/juce_Toolbar.h | 2 + .../widgets/juce_ToolbarItemComponent.cpp | 11 + .../widgets/juce_ToolbarItemComponent.h | 2 + .../widgets/juce_ToolbarItemPalette.cpp | 6 + .../widgets/juce_ToolbarItemPalette.h | 2 + .../juce_gui_basics/widgets/juce_TreeView.cpp | 1140 +- .../juce_gui_basics/widgets/juce_TreeView.h | 215 +- .../windows/juce_AlertWindow.cpp | 241 +- .../windows/juce_AlertWindow.h | 112 +- .../windows/juce_CallOutBox.cpp | 8 +- .../juce_gui_basics/windows/juce_CallOutBox.h | 2 + .../windows/juce_ComponentPeer.cpp | 31 +- .../windows/juce_ComponentPeer.h | 15 +- .../windows/juce_DialogWindow.cpp | 21 +- .../windows/juce_DialogWindow.h | 17 +- .../windows/juce_MessageBoxOptions.h | 141 + .../windows/juce_NativeMessageBox.h | 130 +- .../windows/juce_ResizableWindow.cpp | 34 +- .../windows/juce_ThreadWithProgressWindow.cpp | 2 +- .../windows/juce_TooltipWindow.cpp | 23 +- .../windows/juce_TooltipWindow.h | 4 + .../windows/juce_TopLevelWindow.cpp | 9 +- .../windows/juce_TopLevelWindow.h | 2 + .../code_editor/juce_CodeEditorComponent.cpp | 226 +- .../code_editor/juce_CodeEditorComponent.h | 7 +- .../documents/juce_FileBasedDocument.cpp | 1185 +- .../documents/juce_FileBasedDocument.h | 154 +- .../embedding/juce_ActiveXControlComponent.h | 2 +- .../embedding/juce_HWNDComponent.h | 3 + .../juce_ScopedDPIAwarenessDisabler.h | 3 - .../embedding/juce_XEmbedComponent.h | 2 +- modules/juce_gui_extra/juce_gui_extra.cpp | 33 +- modules/juce_gui_extra/juce_gui_extra.h | 3 +- .../misc/juce_KeyMappingEditorComponent.cpp | 24 +- .../misc/juce_LiveConstantEditor.cpp | 2 +- .../misc/juce_LiveConstantEditor.h | 24 +- .../misc/juce_PushNotifications.h | 2 +- .../misc/juce_SystemTrayIconComponent.cpp | 2 +- .../misc/juce_SystemTrayIconComponent.h | 4 +- .../juce_android_WebBrowserComponent.cpp | 2 +- .../native/juce_ios_PushNotifications.cpp | 4 +- .../juce_linux_X11_WebBrowserComponent.cpp | 6 +- .../native/juce_linux_XEmbedComponent.cpp | 4 - .../native/juce_mac_AppleRemote.mm | 19 +- .../native/juce_mac_NSViewComponent.mm | 142 +- .../native/juce_mac_PushNotifications.cpp | 4 +- .../native/juce_mac_SystemTrayIcon.cpp | 8 +- .../native/juce_mac_WebBrowserComponent.mm | 196 +- .../native/juce_win32_ActiveXComponent.cpp | 14 +- .../native/juce_win32_HWNDComponent.cpp | 47 +- .../native/juce_win32_WebBrowserComponent.cpp | 73 +- modules/juce_opengl/juce_opengl.cpp | 90 +- modules/juce_opengl/juce_opengl.h | 78 +- .../native/juce_MissingGLDefinitions.h | 170 - .../native/juce_OpenGLExtensions.h | 181 +- modules/juce_opengl/native/juce_OpenGL_ios.h | 1 + .../native/juce_OpenGL_linux_X11.h | 15 +- modules/juce_opengl/native/juce_OpenGL_osx.h | 2 - .../juce_opengl/native/juce_OpenGL_win32.h | 33 +- .../juce_opengl/opengl/juce_OpenGLContext.cpp | 50 +- .../juce_opengl/opengl/juce_OpenGLContext.h | 3 + .../opengl/juce_OpenGLFrameBuffer.cpp | 10 +- .../opengl/juce_OpenGLGraphicsContext.cpp | 36 +- .../juce_opengl/opengl/juce_OpenGLHelpers.cpp | 110 +- .../juce_opengl/opengl/juce_OpenGLHelpers.h | 5 + .../opengl/juce_OpenGLShaderProgram.cpp | 18 +- .../juce_opengl/opengl/juce_OpenGLTexture.cpp | 18 +- modules/juce_opengl/opengl/juce_gl.cpp | 4075 ++++++ modules/juce_opengl/opengl/juce_gl.h | 12008 ++++++++++++++++ modules/juce_opengl/opengl/juce_gles2.cpp | 1418 ++ modules/juce_opengl/opengl/juce_gles2.h | 5270 +++++++ modules/juce_opengl/opengl/juce_khrplatform.h | 290 + modules/juce_opengl/opengl/juce_wgl.h | 647 + modules/juce_osc/juce_osc.h | 3 +- modules/juce_osc/osc/juce_OSCSender.cpp | 4 +- .../juce_product_unlocking.h | 3 +- .../marketplace/juce_OnlineUnlockForm.cpp | 6 +- .../marketplace/juce_OnlineUnlockStatus.cpp | 4 +- modules/juce_video/juce_video.h | 3 +- .../native/juce_android_CameraDevice.h | 48 +- .../juce_video/native/juce_android_Video.h | 14 +- .../juce_video/native/juce_ios_CameraDevice.h | 27 +- .../juce_video/native/juce_mac_CameraDevice.h | 3 +- modules/juce_video/native/juce_mac_Video.h | 9 +- .../native/juce_win32_CameraDevice.h | 70 +- modules/juce_video/native/juce_win32_Video.h | 28 +- .../playback/juce_VideoComponent.cpp | 4 +- .../juce_video/playback/juce_VideoComponent.h | 2 +- 1182 files changed, 88821 insertions(+), 56791 deletions(-) create mode 100644 docs/Accessibility.md delete mode 100644 examples/BLOCKS/BlocksDrawingDemo.h delete mode 100644 examples/BLOCKS/BlocksMonitorDemo.h delete mode 100644 examples/BLOCKS/BlocksSynthDemo.h delete mode 100644 examples/BLOCKS/CMakeLists.txt delete mode 100644 examples/DemoRunner/JuceLibraryCode/include_juce_blocks_basics.cpp create mode 100644 examples/GUI/AccessibilityDemo.h create mode 100644 examples/Plugins/ReaperEmbeddedViewPluginDemo.h create mode 100644 examples/Plugins/extern/LICENSE.md create mode 100644 examples/Plugins/extern/reaper_plugin_fx_embed.h create mode 100644 examples/Plugins/extern/reaper_vst3_interfaces.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/AudioLiveScrollingDisplay.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/AddPair.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/ApplyForce.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/BodyTypes.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Breakable.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Bridge.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/BulletTest.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Cantilever.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Car.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Chain.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/CharacterCollision.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/CollisionFiltering.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/CollisionProcessing.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/CompoundShapes.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Confined.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/ContinuousTest.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/DistanceTest.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Dominos.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/DumpShell.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/DynamicTreeTest.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/EdgeShapes.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/EdgeTest.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Gears.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/OneSidedPlatform.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Pinball.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/PolyCollision.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/PolyShapes.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Prismatic.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Pulleys.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Pyramid.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/RayCast.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Revolute.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Rope.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/RopeJoint.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/SensorTest.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/ShapeEditing.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/SliderCrank.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/SphereStack.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/TestEntries.cpp create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/TheoJansen.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Tiles.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/TimeOfImpact.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Tumbler.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/VaryingFriction.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/VaryingRestitution.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/VerticalStack.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Box2DTests/Web.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/DSPDemos_Common.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/DemoUtilities.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/images/ic_stat_name.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/images/ic_stat_name10.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/images/ic_stat_name2.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/images/ic_stat_name3.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/images/ic_stat_name4.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/images/ic_stat_name5.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/images/ic_stat_name6.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/images/ic_stat_name7.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/images/ic_stat_name8.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/images/ic_stat_name9.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/sounds/demonstrative.caf create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/sounds/demonstrative.mp3 create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/sounds/isntit.caf create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/sounds/isntit.mp3 create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/sounds/jinglebellssms.caf create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/sounds/jinglebellssms.mp3 create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/sounds/served.caf create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/sounds/served.mp3 create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/sounds/solemn.caf create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Notifications/sounds/solemn.mp3 create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Ed.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Ed0.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Ed1.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Ed2.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Fabian.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Fabian0.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Fabian1.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Fabian2.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/JB.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/JB0.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/JB1.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/JB2.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Jules.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Jules0.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Jules1.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Jules2.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Lukasz.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Lukasz0.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Lukasz1.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Lukasz2.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Robot.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Robot0.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Robot1.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/Robot2.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Purchases/icon.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Signing/InAppPurchase.keystore create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/Signing/README.txt create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/WavefrontObjParser.h create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/cassette_recorder.wav create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/cello.wav create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/demo table data.xml create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/google-services.json create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/guitar_amp.wav create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/icons.zip create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/juce_icon.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/juce_icon_template.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/juce_module_info create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/portmeirion.jpg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/power.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/proaudio.path create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/reverb_ir.wav create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/singing.ogg create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/teapot.obj create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/tile_background.png create mode 100644 extras/AudioPluginHost/Builds/Android/app/src/main/assets/treedemo.xml delete mode 100644 extras/AudioPluginHost/JuceLibraryCode/BinaryData.cpp delete mode 100644 extras/AudioPluginHost/JuceLibraryCode/BinaryData.h delete mode 100644 extras/BLOCKS/Makefile delete mode 100644 extras/BLOCKS/standalone_sdk/README.md delete mode 100644 extras/BLOCKS/standalone_sdk/SDK/BlocksHeader.h delete mode 100644 extras/BLOCKS/standalone_sdk/SDK/Build/Linux/Makefile delete mode 100644 extras/BLOCKS/standalone_sdk/SDK/Build/MacOS/BLOCKS-SDK.xcodeproj/project.pbxproj delete mode 100644 extras/BLOCKS/standalone_sdk/SDK/Build/Windows/BLOCKS-SDK.sln delete mode 100644 extras/BLOCKS/standalone_sdk/SDK/Build/Windows/BLOCKS-SDK.vcxproj delete mode 100644 extras/BLOCKS/standalone_sdk/examples/BlockFinder/BlockFinder.cpp delete mode 100644 extras/BLOCKS/standalone_sdk/examples/BlockFinder/BlockFinder.h delete mode 100644 extras/BLOCKS/standalone_sdk/examples/BlockFinder/Linux/Makefile delete mode 100644 extras/BLOCKS/standalone_sdk/examples/BlockFinder/Linux/main.cpp delete mode 100644 extras/BLOCKS/standalone_sdk/examples/BlockFinder/MacOS/BlockFinder.xcodeproj/project.pbxproj delete mode 100644 extras/BLOCKS/standalone_sdk/examples/BlockFinder/MacOS/Makefile delete mode 100644 extras/BLOCKS/standalone_sdk/examples/BlockFinder/MacOS/main.mm delete mode 100644 extras/BLOCKS/standalone_sdk/examples/BlockFinder/Windows/BlockFinder.sln delete mode 100644 extras/BLOCKS/standalone_sdk/examples/BlockFinder/Windows/BlockFinder.vcxproj delete mode 100644 extras/BLOCKS/standalone_sdk/examples/BlockFinder/Windows/main.cpp create mode 100644 extras/Build/CMake/JUCEModuleSupport.cmake delete mode 100644 extras/Projucer/Source/BinaryData/Icons/juce-logo-with-text.svg delete mode 100644 extras/Projucer/Source/CodeEditor/jucer_LiveBuildCodeEditor.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/UI/jucer_ErrorListComponent.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_ActivityList.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_ClassDatabase.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_ClientServerMessages.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.cpp delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineDLL.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineServer.cpp delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineSettings.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_CppHelpers.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_DiagnosticMessage.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_DownloadCompileEngineThread.cpp delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_ErrorList.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_LiveCodeBuilderDLL.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_MessageIDs.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_ProjectBuildInfo.h delete mode 100644 extras/Projucer/Source/LiveBuildEngine/jucer_SourceCodeRange.h delete mode 100644 extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h delete mode 100644 extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTab.h create mode 100644 extras/Projucer/Source/Project/UI/Sidebar/jucer_Sidebar.h delete mode 100644 extras/Projucer/Source/Project/UI/Sidebar/jucer_TabComponents.h create mode 100644 extras/Projucer/Source/Project/UI/jucer_ContentViewComponent.h delete mode 100644 extras/UnitTestRunner/JuceLibraryCode/include_juce_blocks_basics.cpp rename modules/{juce_audio_devices/native => juce_audio_basics/midi}/juce_MidiDataConcatenator.h (100%) rename modules/{juce_blocks_basics/visualisers/juce_BitmapLEDProgram.h => juce_audio_basics/midi/ump/juce_UMP.h} (61%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPConversion.h (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPConverters.h (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPDispatcher.h (93%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPFactory.h (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPIterator.h (95%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPMidi1ToBytestreamTranslator.h (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPMidi1ToMidi2DefaultTranslator.cpp (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPMidi1ToMidi2DefaultTranslator.h (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPProtocols.h (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPReceiver.h (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPSysEx7.cpp (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPSysEx7.h (100%) create mode 100644 modules/juce_audio_basics/midi/ump/juce_UMPTests.cpp rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPUtils.cpp (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPUtils.h (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPView.cpp (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPView.h (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPacket.h (100%) rename modules/{juce_audio_devices/midi_io => juce_audio_basics/midi}/ump/juce_UMPackets.h (100%) create mode 100644 modules/juce_audio_basics/utilities/juce_ADSR_test.cpp mode change 100755 => 100644 modules/juce_audio_devices/native/juce_win32_WASAPI.cpp mode change 100755 => 100644 modules/juce_audio_devices/native/oboe/LICENSE rename modules/juce_audio_devices/native/oboe/{readme.md => README.md} (91%) create mode 100644 modules/juce_audio_devices/native/oboe/src/aaudio/AAudioExtensions.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/SourceI24Caller.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/SourceI24Caller.h create mode 100644 modules/juce_audio_devices/native/oboe/src/common/SourceI32Caller.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/common/SourceI32Caller.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/FlowgraphUtilities.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI32.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI32.h create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI32.cpp create mode 100644 modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI32.h create mode 100644 modules/juce_audio_plugin_client/utility/juce_LinuxMessageThread.h delete mode 100644 modules/juce_audio_plugin_client/utility/juce_PluginHostType.h create mode 100644 modules/juce_audio_processors/format_types/VST3_SDK/JUCE_README.md create mode 100644 modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstparameterfunctionname.h create mode 100644 modules/juce_audio_processors/processors/juce_AudioProcessorEditorHostContext.h create mode 100644 modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h create mode 100644 modules/juce_audio_processors/utilities/juce_PluginHostType.cpp create mode 100644 modules/juce_audio_processors/utilities/juce_PluginHostType.h create mode 100644 modules/juce_audio_processors/utilities/juce_VST3ClientExtensions.h rename modules/{juce_audio_plugin_client/VST => juce_audio_processors/utilities}/juce_VSTCallbackHandler.h (92%) delete mode 100644 modules/juce_blocks_basics/README.txt delete mode 100644 modules/juce_blocks_basics/blocks/juce_Block.cpp delete mode 100644 modules/juce_blocks_basics/blocks/juce_Block.h delete mode 100644 modules/juce_blocks_basics/blocks/juce_BlockConfigManager.h delete mode 100644 modules/juce_blocks_basics/blocks/juce_BlocksVersion.cpp delete mode 100644 modules/juce_blocks_basics/blocks/juce_BlocksVersion.h delete mode 100644 modules/juce_blocks_basics/blocks/juce_ControlButton.h delete mode 100644 modules/juce_blocks_basics/blocks/juce_LEDGrid.h delete mode 100644 modules/juce_blocks_basics/blocks/juce_LEDRow.h delete mode 100644 modules/juce_blocks_basics/blocks/juce_TouchList.h delete mode 100644 modules/juce_blocks_basics/blocks/juce_TouchSurface.h delete mode 100644 modules/juce_blocks_basics/juce_LittleFootFunctions.dox delete mode 100644 modules/juce_blocks_basics/juce_blocks_basics.cpp delete mode 100644 modules/juce_blocks_basics/juce_blocks_basics.h delete mode 100644 modules/juce_blocks_basics/littlefoot/LittleFoot Language README.txt delete mode 100644 modules/juce_blocks_basics/littlefoot/juce_LittleFootCompiler.h delete mode 100644 modules/juce_blocks_basics/littlefoot/juce_LittleFootRemoteHeap.h delete mode 100644 modules/juce_blocks_basics/littlefoot/juce_LittleFootRunner.h delete mode 100644 modules/juce_blocks_basics/protocol/Protocol Format.txt delete mode 100644 modules/juce_blocks_basics/protocol/juce_BitPackingUtilities.h delete mode 100644 modules/juce_blocks_basics/protocol/juce_BlockModels.h delete mode 100644 modules/juce_blocks_basics/protocol/juce_BlocksProtocolDefinitions.h delete mode 100644 modules/juce_blocks_basics/protocol/juce_HostPacketBuilder.h delete mode 100644 modules/juce_blocks_basics/protocol/juce_HostPacketDecoder.h delete mode 100644 modules/juce_blocks_basics/topology/internal/juce_BandwidthStatsLogger.cpp delete mode 100644 modules/juce_blocks_basics/topology/internal/juce_BlockImplementation.cpp delete mode 100644 modules/juce_blocks_basics/topology/internal/juce_BlockSerialReader.cpp delete mode 100644 modules/juce_blocks_basics/topology/internal/juce_ConnectedDeviceGroup.cpp delete mode 100644 modules/juce_blocks_basics/topology/internal/juce_DepreciatedVersionReader.cpp delete mode 100644 modules/juce_blocks_basics/topology/internal/juce_Detector.cpp delete mode 100644 modules/juce_blocks_basics/topology/internal/juce_DetectorHolder.cpp delete mode 100644 modules/juce_blocks_basics/topology/internal/juce_DeviceInfo.cpp delete mode 100644 modules/juce_blocks_basics/topology/internal/juce_MIDIDeviceDetector.cpp delete mode 100644 modules/juce_blocks_basics/topology/internal/juce_MidiDeviceConnection.cpp delete mode 100644 modules/juce_blocks_basics/topology/juce_BlockGraph.cpp delete mode 100644 modules/juce_blocks_basics/topology/juce_BlockGraph.h delete mode 100644 modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp delete mode 100644 modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.h delete mode 100644 modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.cpp delete mode 100644 modules/juce_blocks_basics/topology/juce_RuleBasedTopologySource.h delete mode 100644 modules/juce_blocks_basics/topology/juce_Topology.h delete mode 100644 modules/juce_blocks_basics/topology/juce_TopologySource.h delete mode 100644 modules/juce_blocks_basics/visualisers/juce_BitmapLEDProgram.cpp delete mode 100644 modules/juce_blocks_basics/visualisers/juce_DrumPadLEDProgram.cpp delete mode 100644 modules/juce_blocks_basics/visualisers/juce_DrumPadLEDProgram.h create mode 100644 modules/juce_core/misc/juce_Functional.h create mode 100644 modules/juce_core/native/juce_intel_SharedCode.h create mode 100644 modules/juce_core/native/juce_mac_CFHelpers.h delete mode 100644 modules/juce_core/native/juce_mac_ClangBugWorkaround.h rename modules/juce_core/native/{juce_osx_ObjCHelpers.h => juce_mac_ObjCHelpers.h} (90%) create mode 100644 modules/juce_core/native/juce_wasm_SystemStats.cpp create mode 100644 modules/juce_events/native/juce_ScopedLowPowerModeDisabler.cpp rename modules/{juce_blocks_basics/blocks/juce_StatusLight.h => juce_events/native/juce_ScopedLowPowerModeDisabler.h} (61%) create mode 100644 modules/juce_gui_basics/accessibility/enums/juce_AccessibilityActions.h create mode 100644 modules/juce_gui_basics/accessibility/enums/juce_AccessibilityEvent.h create mode 100644 modules/juce_gui_basics/accessibility/enums/juce_AccessibilityRole.h create mode 100644 modules/juce_gui_basics/accessibility/interfaces/juce_AccessibilityCellInterface.h create mode 100644 modules/juce_gui_basics/accessibility/interfaces/juce_AccessibilityTableInterface.h create mode 100644 modules/juce_gui_basics/accessibility/interfaces/juce_AccessibilityTextInterface.h create mode 100644 modules/juce_gui_basics/accessibility/interfaces/juce_AccessibilityValueInterface.h create mode 100644 modules/juce_gui_basics/accessibility/juce_AccessibilityHandler.cpp create mode 100644 modules/juce_gui_basics/accessibility/juce_AccessibilityHandler.h create mode 100644 modules/juce_gui_basics/accessibility/juce_AccessibilityState.h create mode 100644 modules/juce_gui_basics/components/juce_ComponentTraverser.h create mode 100644 modules/juce_gui_basics/components/juce_FocusTraverser.cpp create mode 100644 modules/juce_gui_basics/components/juce_FocusTraverser.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_AccessibilityTextHelpers.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_android_Accessibility.cpp create mode 100644 modules/juce_gui_basics/native/accessibility/juce_ios_Accessibility.mm create mode 100644 modules/juce_gui_basics/native/accessibility/juce_mac_Accessibility.mm create mode 100644 modules/juce_gui_basics/native/accessibility/juce_mac_AccessibilitySharedCode.mm create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_Accessibility.cpp create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_AccessibilityElement.cpp create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_AccessibilityElement.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_UIAExpandCollapseProvider.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_UIAGridItemProvider.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_UIAGridProvider.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_UIAHelpers.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_UIAInvokeProvider.h rename extras/Projucer/Source/LiveBuildEngine/jucer_DownloadCompileEngineThread.h => modules/juce_gui_basics/native/accessibility/juce_win32_UIAProviderBase.h (58%) create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_UIAProviders.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_UIARangeValueProvider.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_UIASelectionProvider.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_UIATextProvider.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_UIAToggleProvider.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_UIATransformProvider.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_UIAValueProvider.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_UIAWindowProvider.h create mode 100644 modules/juce_gui_basics/native/accessibility/juce_win32_WindowsUIAWrapper.h rename extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineServer.h => modules/juce_gui_basics/native/juce_win32_ScopedThreadDPIAwarenessSetter.h (61%) create mode 100644 modules/juce_gui_basics/windows/juce_MessageBoxOptions.h delete mode 100644 modules/juce_opengl/native/juce_MissingGLDefinitions.h create mode 100644 modules/juce_opengl/opengl/juce_gl.cpp create mode 100644 modules/juce_opengl/opengl/juce_gl.h create mode 100644 modules/juce_opengl/opengl/juce_gles2.cpp create mode 100644 modules/juce_opengl/opengl/juce_gles2.h create mode 100644 modules/juce_opengl/opengl/juce_khrplatform.h create mode 100644 modules/juce_opengl/opengl/juce_wgl.h diff --git a/BREAKING-CHANGES.txt b/BREAKING-CHANGES.txt index 8b3cdcbf..74c6edbd 100644 --- a/BREAKING-CHANGES.txt +++ b/BREAKING-CHANGES.txt @@ -1,6 +1,392 @@ JUCE breaking changes ===================== +Version 6.1.0 +============= + +Change +------ +juce::gl::loadFunctions() no longer loads extension functions. + +Possible Issues +--------------- +Code that depended on extension functions being loaded automatically may cease +to function correctly. + +Workaround +---------- +Extension functions can now be loaded using juce::gl::loadExtensions(). + +Rationale +--------- +There are a great number of extension functions, and on some systems these can +be slow to load (i.e. a second or so). Projects that do not require these +extension functions should not have to pay for this unnecessary overhead. Now, +only core functions will be loaded by default, and extensions can be loaded +explicitly in projects that require such functionality. + + +Change +------ +Thread::setPriority() will no longer set a realtime scheduling policy for all +threads with non-zero priorities on POSIX systems. + +Possible Issues +--------------- +Threads that implicitly relied on using a realtime policy will no longer +request a realtime policy if their priority is 7 or lower. + +Workaround +---------- +For threads that require a realtime policy on POSIX systems, request a priority +of 8 or higher by calling Thread::setPriority() or +Thread::setCurrentThreadPriority(). + +Rationale +--------- +By default, new Thread instances have a priority of 5. Previously, non-zero +priorities corresponded to realtime scheduling policies, meaning that new +Threads would use the realtime scheduling policy unless they explicitly +requested a priority of 0. However, most threads do not and should not require +realtime scheduling. Setting a realtime policy on all newly-created threads may +degrade performance, as multiple realtime threads will end up fighting for +limited resources. + + +Change +------ +The JUCE_GLSL_VERSION preprocessor definition has been removed. + +Possible Issues +--------------- +Code which used this definition will no longer compile. + +Workaround +---------- +Use OpenGLHelpers::getGLSLVersionString to retrieve a version string which is +consistent with the capabilities of the current OpenGL context. + +Rationale +--------- +A compile-time version string is not very useful, as OpenGL versions and +capabilities can change at runtime. Replacing this macro with a function allows +querying the capabilities of the current context at runtime. + + +Change +------ +The minimum support CMake version is now 3.15. + +Possible Issues +--------------- +It will no longer be possible to configure JUCE projects with CMake versions +between 3.12 and 3.14 inclusive. + +Workaround +---------- +No workaround is available. + +Rationale +--------- +Moving to 3.15 allows us to use target_link_directories and +target_link_options, which were introduced in 3.13, which in turn allows us to +provide support for bundled precompiled libraries in modules. Plugins already +required CMake 3.15, so this change just brings other target types in line with +the requirements for plugins. + + +Change +------ +The default value of JUCE_MODAL_LOOPS_PERMITTED has been changed from 1 to 0. + +Possible Issues +--------------- +With JUCE_MODAL_LOOPS_PERMITTED set to 0 code that previously relied upon modal +loops will need to be rewritten to use asynchronous versions of the modal +functions. There is no non-modal alternative to +AlterWindow::showNativeDialogBox and the previously modal behaviour of the +MultiDocumentPanel destructor has changed. + +Workaround +---------- +Set JUCE_MODAL_LOOPS_PERMITTED back to 1. + +Rationale +--------- +Modal operations are a frequent source of problems, particularly when used in +plug-ins. On Android modal loops are not possible, so people wanting to target +Android often have an unwelcome surprise when then have to rewrite what they +assumed to be platform independent code. Changing the default addresses these +problems. + + +Change +------ +The minimum supported C++ standard is now C++14 and the oldest supported +compilers on macOS and Linux are now Xcode 9.2, GCC 5.0 and Clang 3.4. + +Possible Issues +--------------- +Older compilers will no longer be able to compile JUCE. People using Xcode 8.5 +on OS X 10.11 will need to update the operating system to OS X 10.12 to be able +to use Xcode 9.2. + +Workaround +---------- +No workaround is available. + +Rationale +--------- +This compiler upgrade will allow the use of C++14 within the framework. + + +Change +------ +Platform GL headers are no longer included in juce_opengl.h + +Possible Issues +--------------- +Projects depending on symbols declared in these headers may fail to build. + +Workaround +---------- +The old platform-supplied headers have been replaced with a new juce_gl.h +header which is generated using the XML registry files supplied by Khronos. +This custom header declares GL symbols in the juce::gl namespace. If your code +only needs to be JUCE-compatible, you can explicitly qualify each name with +`juce::gl::`. If you need your code to build with different extension-loader +libraries (GLEW, GL3W etc.) you can make all GL symbols visible without +additional qualification with `using namespace juce::gl`. + +Rationale +--------- +Using our own GL headers allows us to generate platform-independent headers +which include symbols for all specified OpenGL versions and extensions. Note +that although the function signatures exist, they may not resolve to a function +at runtime. If your code uses commands from an extension or recent GL version, +you should check each function pointer against `nullptr` before attempting to +use it. To avoid repeatedly checking, you could query a subset of functions +after calling gl::loadFunctions() and cache the results. Supplying custom GL +headers also allows us to use C++ techniques (namespaces, references), making +the headers safer than the platform-defined headers. Platform headers are +generally written in C, and export a significant portion of their symbols as +preprocessor definitions. + + +Change +------ +The functions `getComponentAsyncLayerBackedViewDisabled` +and `setComponentAsyncLayerBackedViewDisabled` were moved into the juce +namespace. + +Possible Issues +--------------- +Code that declares these functions may fail to link. + +Workaround +---------- +Move declarations of these functions into the juce namespace. + +Rationale +--------- +Although the names of these functions are unlikely to collide with functions +from other libraries, we can make such collisions much more unlikely by keeping +JUCE code in the juce namespace. + + +Change +------ +The `juce_blocks_basics` module was removed. + +Possible Issues +--------------- +Projects depending on `juce_blocks_basics` will not build. + +Workaround +---------- +The BLOCKS API is now located in a separate repository: +https://github.com/WeAreROLI/roli_blocks_basics +Projects which used to depend on `juce_blocks_basics` can use +`roli_blocks_basics` instead. + +Rationale +--------- +ROLI is no longer involved with the development of JUCE. Therefore, development +on the BLOCKS API has been moved out of the JUCE repository, and to a new +repository managed by ROLI. + + +Change +------ +The live build functionality of the Projucer has been removed. + +Possible Issues +--------------- +You will no longer be able to use live build in the Projucer. + +Workaround +---------- +None. + +Rationale +--------- +Keeping the live build compatible with the latest compilers on all our +supported platforms is a very substantial maintenance burden, but very few +people are using this feature of the Projucer. Removing the live build will +simplify the code and our release process. + + +Change +------ +`Component::createFocusTraverser()` has been renamed to +`Component::createKeyboardFocusTraverser()` and now returns a `std::unique_ptr` +instead of a raw pointer. `Component::createFocusTraverser()` is a new method +for controlling basic focus traversal and not keyboard focus traversal. + +Possible Issues +--------------- +Derived Components that override the old method will no longer compile. + +Workaround +---------- +Override the new method. Be careful to override +`createKeyboardFocusTraverser()` and not `createFocusTraverser()` to ensure +that the behaviour is the same. + +Rationale +--------- +The ownership of this method is now clearer as the previous code relied on the +caller deleting the object. The name has changed to accomodate the new +`Component::createFocusTraverser()` method that returns an object for +determining basic focus traversal, of which keyboard focus is generally a +subset. + + +Change +------ +PluginDescription::uid has been deprecated and replaced with a new 'uniqueId' +data member. + +Possible Issues +--------------- +Code using the old data member will need to be updated in order to compile. + +Workaround +---------- +Code that used to use 'uid' to identify plugins should switch to using +'uniqueId', with some caveats - see "Rationale" for details. + +Rationale +--------- +The 'uniqueId' member has the benefit of being consistent for +a given VST3 across Windows, macOS, and Linux. However, the value of the +uniqueId may differ from the value of the old uid on some platforms. The value +of the old 'uid' member can now be found in the 'deprecatedUid' member, which +should allow clients to implement logic such as checking a saved uid against +the new uniqueId, and falling back to the deprecatedUid. This should allow +hosts to gracefully upgrade from the old uid values to the new values. + + +Version 6.0.8 +============= + +Change +------ +Calling AudioProcessorEditor::setResizeLimits() will no longer implicitly add a +ResizableCornerComponent to the editor if it has not already been set as +resizable. + +Possible Issues +--------------- +Code which previously relied on calling this method to set up the corner +resizer will no longer work. + +Workaround +---------- +Explicitly call AudioProcessorEditor::setResizable() with the second argument +set to true to enable the corner resizer. + +Rationale +--------- +The previous behaviour was undocumented and potentially confusing. There is now +a single method to control the behaviour of the editor's corner resizer to +avoid any ambiguity. + + +Change +------ +The implementations of `getValue` and `setValue` in `AUInstanceParameter` now +properly take the ranges of discrete parameters into account. + +Possible Issues +--------------- +This issue affects JUCE Audio Unit hosts. Automation data previously saved for +a discrete parameter with a non-zero minimum value may not set the parameter to +the same values as previous JUCE versions. Note that previously, `getValue` on +a hosted discrete parameter may have returned out-of-range values, and +`setValue` may have only mapped to a portion of the parameter range. As a +result, automation recorded for affected parameters was likely already behaving +unexpectedly. + +Workaround +---------- +There is no workaround. + +Rationale +--------- +The old behaviour was incorrect, and was causing issues in plugin validators +and other hosts. Hosts expect `getValue` to return a normalised parameter +value. If this function returns an out-of-range value (including Inf and NaN) +this is likely to break assumptions made by the host, leading to crashes, +corrupted project data, or other defects. + + +Change +------ +AudioProcessorListener::audioProcessorChanged gained a new parameter describing +the nature of any change. + +Possible Issues +--------------- +Code using the old function signature will not build until updated to use +the new signature. + +Workaround +---------- +Listeners should add the new parameter to any overrides of +audioProcessorChanged. + +Rationale +--------- +The new function signature means that wrappers can be smarter about the +requests that they make to hosts whenever some aspect of the processor changes. +In particular, plugin wrappers can now distinguish between changes to latency, +parameter attributes, and the current program. This means that hosts will no +longer assume parameters have changed when `setLatencySamples` is called. + + +Change +------ +CharacterFunctions::readDoubleValue now returns values consistent with other +C++ number parsing libraries. Parsing values smaller than the minimum number +respresentable in a double will return (+/-)0.0 and parsing values larger than +the maximum number respresentable in a double will return (+/-)inf. + +Possible Issues +--------------- +Code reading very large or very small numbers may receive values of 0.0 and inf +rather than nan. + +Workaround +---------- +Where you may be using std::isnan to check the validity of the result you can +instead use std::isfinite. + +Rationale +--------- +The new behaviour is consistent with other string parsing libraries. + + Version 6.0.6 ============= diff --git a/CMakeLists.txt b/CMakeLists.txt index 07ae7158..9f87e803 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,18 +21,44 @@ # # ============================================================================== -cmake_minimum_required(VERSION 3.12) +cmake_minimum_required(VERSION 3.15) -project(JUCE VERSION 6.0.7 LANGUAGES C CXX) +project(JUCE VERSION 6.1.0 LANGUAGES C CXX) + +include(CMakeDependentOption) set_property(GLOBAL PROPERTY USE_FOLDERS YES) set(JUCE_MODULES_DIR "${JUCE_SOURCE_DIR}/modules" CACHE INTERNAL "The path to JUCE modules") -include(extras/Build/CMake/JUCEUtils.cmake) +# This option will disable most of the JUCE helper functions and tools. This option exists to +# facilitate existing CMake builds which handle things like bundle creation, icons, plists, and +# binary data independently of JUCE. This option is not recommended - use at your own risk! -juce_disable_default_flags() +option(JUCE_MODULES_ONLY "Only configure the JUCE modules" OFF) + +include(extras/Build/CMake/JUCEModuleSupport.cmake) + +# This option controls whether dummy targets are added to the build, where these targets contain all +# of the source files for each JUCE module. If you're planning to use an IDE and want to be able to +# browse all of JUCE's source files, this may be useful. However, it will increase the size of +# generated IDE projects and might slow down configuration a bit. If you enable this, you should +# probably also add `set_property(GLOBAL PROPERTY USE_FOLDERS YES)` to your top level CMakeLists, +# otherwise the module sources will be added directly to the top level of the project, instead of in +# a nice 'Modules' subfolder. + +cmake_dependent_option(JUCE_ENABLE_MODULE_SOURCE_GROUPS + "Show all module sources in IDE projects" OFF + "NOT JUCE_MODULES_ONLY" OFF) + +add_subdirectory(modules) + +if(JUCE_MODULES_ONLY) + return() +endif() + +include(extras/Build/CMake/JUCEUtils.cmake) set_directory_properties(PROPERTIES JUCE_COMPANY_NAME "JUCE" @@ -46,17 +72,8 @@ set_property(GLOBAL PROPERTY JUCE_COPY_PLUGIN_AFTER_BUILD ${JUCE_COPY_PLUGIN_AFT set(CMAKE_CXX_EXTENSIONS FALSE) -# This option controls whether dummy targets are added to the build, where these targets contain all -# of the source files for each JUCE module. If you're planning to use an IDE and want to be able to -# browse all of JUCE's source files, this may be useful. However, it will increase the size of -# generated IDE projects and might slow down configuration a bit. If you enable this, you should -# probably also add `set_property(GLOBAL PROPERTY USE_FOLDERS YES)` to your top level CMakeLists, -# otherwise the module sources will be added directly to the top level of the project, instead of in -# a nice 'Modules' subfolder. - -option(JUCE_ENABLE_MODULE_SOURCE_GROUPS "Show all module sources in IDE projects" OFF) +juce_disable_default_flags() -add_subdirectory(modules) add_subdirectory(extras/Build) # If you want to build the JUCE examples with VST2/AAX support, you'll need to make the VST2/AAX diff --git a/ChangeList.txt b/ChangeList.txt index 6b0c2428..dac8d8b2 100644 --- a/ChangeList.txt +++ b/ChangeList.txt @@ -1,7 +1,38 @@ == Major JUCE features and updates == This file just lists the more notable headline features. For more detailed info -about minor changes and bugfixes, please see the git log! +about changes and bugfixes please see the git log and BREAKING-CHANGES.txt. + +Version 6.1.0 + - Added accessibility support + - Enabled use of VST3 plug-in extensions + - Improved OpenGL function loading + - Updated to C++14 + - Added support for macOS Monterey and iOS 15 + - Added async versions of all modal functions + - Fixed some VST3 threading issues + - Added cross-platform-compatible VST3 UID hash + - Improved MinGW compatibility + - Fixed some issues with BufferingAudioReader + - Improved TextEditor repainting + - Added support for larger ASIO buffers + - Updated Android Oboe to 1.6.1 + - Improved modal dismissing + - Improved assertion handling on macOS ARM + +Version 6.0.8 + - Fixed a macOS graphics invalidation region issue + - Improved the handling of modal dialog dismissal + - Fixed audio glitching in CoreAudio before microphone permission is granted + - Improved AUv3 resizing and initialisation + - Fixed some string to double conversions + - Improved iOS split view behaviour + - Added Display::safeAreaInserts + - Improved assertion behaviour on macOS ARM + - Multiple resizing and display scaling fixes + - Added more information to audioProcessorChanged callbacks + - Fixed some DSP convolution issues + - Added host detection on macOS ARM Version 6.0.7 - Fixed a macOS drawing issue diff --git a/LICENSE.md b/LICENSE.md index 7c7554bd..75e59b30 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -24,8 +24,8 @@ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. -The juce_audio_basics, juce_audio_devices, juce_blocks_basics, juce_core and -juce_events modules are permissively licensed under the terms of the [ISC +The juce_audio_basics, juce_audio_devices, juce_core and juce_events modules +are permissively licensed under the terms of the [ISC license](http://www.isc.org/downloads/software-support-policy/isc-license). For more information, visit the website: diff --git a/README.md b/README.md index 8e4098ae..b2cc3b9e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![alt text](https://assets.juce.com/juce/JUCE_banner.png "JUCE") +![alt text](https://assets.juce.com/juce/JUCE_banner_github.png "JUCE") JUCE is an open-source cross-platform C++ application framework used for rapidly developing high quality desktop and mobile applications, including VST, AU (and AUv3), @@ -36,13 +36,12 @@ For further help getting started, please refer to the JUCE ### CMake -Version 3.15 or higher is required for plugin projects, and strongly -recommended for other project types. To use CMake, you will need to install it, +Version 3.15 or higher is required. To use CMake, you will need to install it, either from your system package manager or from the [official download page](https://cmake.org/download/). For comprehensive documentation on JUCE's -CMake API, see the [JUCE CMake documentation](/docs/CMake%20API.md). For examples -which may be useful as starting points for new CMake projects, see the [CMake -examples directory](/examples/CMake). +CMake API, see the [JUCE CMake documentation](/docs/CMake%20API.md). For +examples which may be useful as starting points for new CMake projects, see the +[CMake examples directory](/examples/CMake). #### Building Examples @@ -58,9 +57,9 @@ of the target you wish to build. #### Building JUCE Projects -- __macOS/iOS__: macOS 10.11 and Xcode 7.3.1 -- __Windows__: Windows 8.1 and Visual Studio 2015 64-bit -- __Linux__: GCC 4.8 (for a full list of dependencies, see +- __macOS/iOS__: Xcode 9.2 (macOS 10.12.6) +- __Windows__: Windows 8.1 and Visual Studio 2015 Update 3 64-bit +- __Linux__: g++ 5.0 or Clang 3.4 (for a full list of dependencies, see [here](/docs/Linux%20Dependencies.md)). - __Android__: Android Studio on Windows, macOS or Linux @@ -83,8 +82,8 @@ but if you would like to contribute any changes please contact us. ## License -The core JUCE modules (juce_audio_basics, juce_audio_devices, juce_blocks_basics, juce_core -and juce_events) are permissively licensed under the terms of the +The core JUCE modules (juce_audio_basics, juce_audio_devices, juce_core and juce_events) +are permissively licensed under the terms of the [ISC license](http://www.isc.org/downloads/software-support-policy/isc-license/). Other modules are covered by a [GPL/Commercial license](https://www.gnu.org/licenses/gpl-3.0.en.html). diff --git a/docs/Accessibility.md b/docs/Accessibility.md new file mode 100644 index 00000000..e15970b4 --- /dev/null +++ b/docs/Accessibility.md @@ -0,0 +1,48 @@ +# JUCE Accessibility + +## What is supported? + +Currently JUCE supports VoiceOver on macOS and Narrator on Windows. The JUCE +accessibility API exposes the following to these clients: + + - Title, description, and help text for UI elements + - Programmatic access to UI elements and text + - Interaction with UI elements + - Full UI keyboard navigation + - Posting notifications to listening clients + +## Customising Behaviour + +By default any visible and enabled `Component` is accessible to screen reader +clients and exposes some basic information such as title, description, help +text and its position in the hierarchy of UI elements. + +The `setTitle()`, `setDescription()` and `setHelpText()` methods can be used +to customise the text that will be read out by accessibility clients when +interacting with UI elements and the `setExplicitFocusOrder()`, +`setFocusContainerType()` and `createFocusTraverser()` methods can be used to +control the parent/child relationships and the order of navigation between UI +elements. + +## Custom Components + +For further customisation of accessibility behaviours the `AccessibilityHandler` +class provides a unified API to the underlying native accessibility libraries. + +This class wraps a component with a given role specified by the +`AccessibilityRole` enum and takes a list of optional actions and interfaces to +provide programmatic access and control over the UI element. Its state is used +to convey further information to accessibility clients via the +`getCurrentState()` method. + +To implement the desired behaviours for a custom component, subclass +`AccessibilityHandler` and return an instance of this from the +`Component::createAccessibilityHandler()` method. + +## Further Reading + + - [NSAccessibility protocol](https://developer.apple.com/documentation/appkit/nsaccessibility?language=objc) + - [UI Automation for Win32 applications](https://docs.microsoft.com/en-us/windows/win32/winauto/entry-uiauto-win32) + - A talk giving an overview of this feature from ADC 2020 can be found on + YouTube at https://youtu.be/BqrEv4ApH3U + diff --git a/docs/CMake API.md b/docs/CMake API.md index 86907215..e15bbe2c 100644 --- a/docs/CMake API.md +++ b/docs/CMake API.md @@ -2,9 +2,7 @@ ## System Requirements -- Console and GUI projects require CMake 3.12 or higher. -- Plugin projects require CMake 3.15 or higher. -- All iOS targets require CMake 3.14 or higher (3.15 or higher for plugins targeting iOS). +- All project types require CMake 3.15 or higher. - Android targets are not currently supported. - WebView2 on Windows via JUCE_USE_WIN_WEBVIEW2 flag in juce_gui_extra is not currently supported. @@ -122,32 +120,37 @@ provisioning profiles, which is achieved by passing the `-allowProvisioningUpdat #### Archiving for iOS CMake's out-of-the-box archiving behaviour doesn't always work as expected, especially for targets -that depend on static libraries (such as targets added with `juce_add_binary_data`). Xcode may -generate these libraries into a 'DerivedData' directory, but then omit this directory from the -library search paths later in the build. - -If the "Product -> Archive" action isn't working, the following steps may help correct the issue: - -- On your static library, explicitly set the `ARCHIVE_OUTPUT_DIRECTORY` property. - ``` - set_target_properties(my_static_lib_target PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "./") - ``` -- Now, the Archive build should complete without linker errors, but the archived product may still - be hidden in the Organizer window. To fix this issue, set the following properties on the target - representing the actual iOS app. If your target was added with `juce_add_gui_app`, pass the same - target name. Otherwise, if your target was added with `juce_add_plugin` you may need to append - `_Standalone` to the target name, to specify the standalone plugin target. - ``` - set_target_properties(my_ios_app_target PROPERTIES - XCODE_ATTRIBUTE_INSTALL_PATH "$(LOCAL_APPS_DIR)" - XCODE_ATTRIBUTE_SKIP_INSTALL "NO") - ``` +that depend on custom static libraries. Xcode may generate these libraries into a 'DerivedData' +directory, but then omit this directory from the library search paths later in the build. + +If the "Product -> Archive" action isn't working due to missing staticlibs, try setting the +`ARCHIVE_OUTPUT_DIRECTORY` property explicitly: + + set_target_properties(my_static_lib_target PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "./") + +Note that the static library produced by `juce_add_binary_data` automatically sets this property. ### Building universal binaries for macOS Building universal binaries that will run on both arm64 and x86_64 can be achieved by configuring the CMake project with `"-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64"`. +### Building with Clang on Windows + +Clang-cl (Clang with MSVC-like command-line) should work by default. If you are generating a Visual +Studio project, and have installed the LLVM package which is distributed with Visual Studio, then +you can configure a Clang-cl build by passing "-T ClangCL" on your configuration commandline. + +If you wish to use Clang with GNU-like command-line instead, you can pass +`-DCMAKE_CXX_COMPILER=clang++` and `-DCMAKE_C_COMPILER=clang` on your configuration commandline. +clang++ and clang must be on your `PATH` for this to work. Only more recent versions of CMake +support Clang's GNU-like command-line on Windows. CMake 3.12 is not supported, CMake 3.15 has +support, CMake 3.20 or higher is recommended. Note that CMake doesn't seem to automatically link a +runtime library when building in this configuration, but this can be remedied by setting the +`MSVC_RUNTIME_LIBRARY` property. See the [official +documentation](https://cmake.org/cmake/help/v3.15/prop_tgt/MSVC_RUNTIME_LIBRARY.html) of this +property for usage recommendations. + ### A note about compile definitions Module options and plugin options that would previously have been set in the Projucer can be set on @@ -197,13 +200,18 @@ included JUCE in your own project. #### `JUCE_ENABLE_MODULE_SOURCE_GROUPS` -This option controls whether dummy targets are added to the build, where these targets contain all -of the source files for each module added with `juce_add_module(s)`. If you're planning to use an -IDE and want to be able to browse all of JUCE's source files, this may be useful. However, it will -increase the size of generated IDE projects and might slow down configuration a bit. If you enable -this, you should probably also add `set_property(GLOBAL PROPERTY USE_FOLDERS YES)` to your top level -CMakeLists, otherwise the module sources will be added directly to the top level of the project, -instead of in a nice 'Modules' subfolder. +This option will make module source files browsable in IDE projects. It has no effect in non-IDE +projects. This option is off by default, as it will increase the size of generated IDE projects and +might slow down configuration a bit. If you enable this, you should probably also add +`set_property(GLOBAL PROPERTY USE_FOLDERS YES)` to your top level CMakeLists as this is required for +source grouping to work. + +Source groupings are a little sensitive to the project layout. As such, you should always ensure +that the call to `juce_add_module` which adds a specific module happens *before* calling +`juce_add_*` to add any dependent targets. + +The modules will be placed in a group named "JUCE Modules" within the group for each target, +alongside the "Source Files" and "Header Files" groups. #### `JUCE_COPY_PLUGIN_AFTER_BUILD` @@ -241,7 +249,15 @@ attributes directly to these creation functions, rather than adding them later. - `VERSION` - A version number string in the format "major.minor.bugfix". If not specified, the `VERSION` of - the project containing the target will be used instead. + the project containing the target will be used instead. On Apple platforms, this is the + user-facing version string. This option corresponds to the `CFBundleShortVersionString` field in + the target's plist. + +- `BUILD_VERSION` + - A version number string in the format "major.minor.bugfix". If not specified, this will match + the `VERSION` of the target. On Apple platforms, this is the private version string used to + distinguish between App Store builds. This option corresponds to the `CFBundleVersion` field in + the target's plist. - `BUNDLE_ID` - An identifier string in the form "com.yourcompany.productname" which should uniquely identify @@ -281,6 +297,9 @@ attributes directly to these creation functions, rather than adding them later. - `STATUS_BAR_HIDDEN` - May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. + - `REQUIRES_FULL_SCREEN` + - May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. + - `BACKGROUND_AUDIO_ENABLED` - May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. @@ -315,6 +334,12 @@ attributes directly to these creation functions, rather than adding them later. is specified, the ICON_BIG and ICON_SMALL arguments will not have an effect on iOS, and a launch storyboard will not be used. +- `TARGETED_DEVICE_FAMILY` + - Specifies the device families on which the product must be capable of running. Allowed values + are "1", "2", and "1,2"; these correspond to "iPhone/iPod touch", "iPad", and "iPhone/iPod and + iPad" respectively. This will default to "1,2", meaning that the target will target iPhone, + iPod, and iPad. + - `ICON_BIG`, `ICON_SMALL` - Paths to image files that will be used to generate app icons. If only one of these parameters is specified, then that image will be used for all icon resolutions. If both arguments are @@ -490,7 +515,7 @@ attributes directly to these creation functions, rather than adding them later. in GarageBand. - `AAX_CATEGORY` - - Should be one of: `AAX_ePlugInCategory_None`, `AAX_ePlugInCategory_EQ`, + - Should be one or more of: `AAX_ePlugInCategory_None`, `AAX_ePlugInCategory_EQ`, `AAX_ePlugInCategory_Dynamics`, `AAX_ePlugInCategory_PitchShift`, `AAX_ePlugInCategory_Reverb`, `AAX_ePlugInCategory_Delay`, `AAX_ePlugInCategory_Modulation`, `AAX_ePlugInCategory_Harmonic`, `AAX_ePlugInCategory_NoiseReduction`, `AAX_ePlugInCategory_Dither`, @@ -593,14 +618,33 @@ disabled by setting the compile definitions `DONT_SET_USING_JUCE_NAMESPACE` and JuceHeader.h is optional. Instead, module headers can be included directly in source files that require them. +#### `juce_enable_copy_plugin_step` + + juce_enable_copy_plugin_step() + +As an alternative to the JUCE_COPY_PLUGIN_AFTER_BUILD property, you may call this function to +manually enable post-build copy on a plugin. The argument to this function should be a target +previously created with `juce_add_plugin`. + +JUCE_COPY_PLUGIN_AFTER_BUILD will cause plugins to be installed immediately after building. This is +not always appropriate, if extra build steps (such as signing or modifying the plugin bundle) must +be executed before the install. In such cases, you should leave JUCE_COPY_PLUGIN_AFTER_BUILD +disabled, use `add_custom_command(TARGET POST_BUILD)` to add your own post-build steps, and then +finally call `juce_enable_copy_plugin_step`. + +If your custom build steps need to use the location of the plugin artefact, you can extract this +by querying the property `JUCE_PLUGIN_ARTEFACT_FILE` on a plugin target (*not* the shared code +target!). + #### `juce_set__sdk_path` juce_set_aax_sdk_path() juce_set_vst2_sdk_path() + juce_set_vst3_sdk_path() -Call these functions from your CMakeLists to set up your local AAX and/or VST2 SDKs. These functions -should be called *before* adding any targets that may depend on the AAX/VST2 SDKs (plugin -hosts, VST2/AAX plugins etc.). +Call these functions from your CMakeLists to set up your local AAX, VST2, and VST3 SDKs. These +functions should be called *before* adding any targets that may depend on the AAX/VST2/VST3 SDKs +(plugin hosts, AAX/VST2/VST3 plugins etc.). #### `juce_add_module` diff --git a/docs/JUCE Module Format.md b/docs/JUCE Module Format.md index 911b3e2d..c342b61d 100644 --- a/docs/JUCE Module Format.md +++ b/docs/JUCE Module Format.md @@ -99,8 +99,11 @@ windowsLibs, linuxLibs and mingwLibs keywords in the module declaration (see the section). - OS X - - libs/MacOSX/{arch}, where {arch} is the architecture you are targeting in Xcode ("x86_64" or - "i386", for example). + - libs/MacOSX - to support multiple architectures, you may place libraries built as universal + binaries at this location. For backwards compatibility, the Projucer will also include the + directories libs/MacOSX/{arch}, where {arch} is the architecture you are targeting in Xcode + ("x86_64" or "i386", for example). When building with CMake, only libraries built as universal + binaries are supported and the arch subfolders are ignored. - Visual Studio - libs/VisualStudio{year}/{arch}/{run-time}, where {year} is the four digit year of the Visual Studio @@ -116,8 +119,11 @@ section). - libs/MinGW/{arch}, where {arch} can take the same values as Linux. - iOS - - libs/iOS/{arch}, where {arch} is the architecture you are targeting in Xcode ("arm64" or - "x86_64", for example). + - libs/iOS - to support multiple architectures, you may place libraries built as universal + binaries at this location. For backwards compatibility, the Projucer will also include the + directories libs/iOS/{arch}, where {arch} is the architecture you are targeting in Xcode + ("arm64" or "x86_64", for example). When building with CMake, only libraries built as universal + binaries are supported and the arch subfolders are ignored. - Android - libs/Android/{arch}, where {arch} is the architecture provided by the Android Studio variable diff --git a/docs/Linux Dependencies.md b/docs/Linux Dependencies.md index 107bce18..13528b2f 100644 --- a/docs/Linux Dependencies.md +++ b/docs/Linux Dependencies.md @@ -25,6 +25,9 @@ or - libasound2-dev - libjack-jackd2-dev (unless `JUCE_JACK=0`) +#### juce_audio_processors +- ladspa-sdk (unless `JUCE_PLUGINHOST_LADSPA=0`) + #### juce_core - libcurl4-openssl-dev (unless `JUCE_USE_CURL=0`) @@ -41,7 +44,7 @@ or - libxrender-dev (unless `JUCE_USE_XRENDER=0`) #### juce_gui_extra -- webkit2gtk-4.0 (unless `JUCE_WEB_BROWSER=0`) +- libwebkit2gtk-4.0-dev (unless `JUCE_WEB_BROWSER=0`) #### juce_opengl - libglu1-mesa-dev @@ -51,6 +54,7 @@ The full command is as follows: sudo apt update sudo apt install libasound2-dev libjack-jackd2-dev \ + ladspa-sdk \ libcurl4-openssl-dev \ libfreetype6-dev \ libx11-dev libxcomposite-dev libxcursor-dev libxcursor-dev libxext-dev libxinerama-dev libxrandr-dev libxrender-dev \ diff --git a/docs/doxygen/Makefile b/docs/doxygen/Makefile index 82604faf..401debef 100644 --- a/docs/doxygen/Makefile +++ b/docs/doxygen/Makefile @@ -2,7 +2,7 @@ SHELL := /bin/bash SOURCE_FILES := $(shell find ../../modules -type f -name "juce_*.h" -or -name "juce_*.dox" | sed 's/ /\\ /g') -.PHONEY: clean +.PHONY: clean doc/index.html: build/juce_modules.dox Doxyfile doxygen diff --git a/examples/Assets/DSPDemos_Common.h b/examples/Assets/DSPDemos_Common.h index 5bb3d966..841a7c76 100644 --- a/examples/Assets/DSPDemos_Common.h +++ b/examples/Assets/DSPDemos_Common.h @@ -590,14 +590,13 @@ private: if (fileChooser != nullptr) return; - SafePointer safeThis (this); - if (! RuntimePermissions::isGranted (RuntimePermissions::readExternalStorage)) { + SafePointer safeThis (this); RuntimePermissions::request (RuntimePermissions::readExternalStorage, [safeThis] (bool granted) mutable { - if (granted) + if (safeThis != nullptr && granted) safeThis->openFile(); }); return; @@ -606,22 +605,23 @@ private: fileChooser.reset (new FileChooser ("Select an audio file...", File(), "*.wav;*.mp3;*.aif")); fileChooser->launchAsync (FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles, - [safeThis] (const FileChooser& fc) mutable + [this] (const FileChooser& fc) mutable { - if (safeThis == nullptr) - return; - if (fc.getURLResults().size() > 0) { auto u = fc.getURLResult(); - if (! safeThis->audioFileReader.loadURL (u)) - NativeMessageBox::showOkCancelBox (AlertWindow::WarningIcon, "Error loading file", "Unable to load audio file", nullptr, nullptr); + if (! audioFileReader.loadURL (u)) + NativeMessageBox::showAsync (MessageBoxOptions() + .withIconType (MessageBoxIconType::WarningIcon) + .withTitle ("Error loading file") + .withMessage ("Unable to load audio file"), + nullptr); else - safeThis->thumbnailComp.setCurrentURL (u); + thumbnailComp.setCurrentURL (u); } - safeThis->fileChooser = nullptr; + fileChooser = nullptr; }, nullptr); } diff --git a/examples/Assets/DemoUtilities.h b/examples/Assets/DemoUtilities.h index 2901ac4d..96cf595a 100644 --- a/examples/Assets/DemoUtilities.h +++ b/examples/Assets/DemoUtilities.h @@ -59,7 +59,7 @@ inline File getExamplesDirectory() noexcept return mo.toString(); #elif defined PIP_JUCE_EXAMPLES_DIRECTORY_STRING - return File { PIP_JUCE_EXAMPLES_DIRECTORY_STRING }; + return File { CharPointer_UTF8 { PIP_JUCE_EXAMPLES_DIRECTORY_STRING } }; #else auto currentFile = File::getSpecialLocation (File::SpecialLocationType::currentApplicationFile); auto exampleDir = currentFile.getParentDirectory().getChildFile ("examples"); diff --git a/examples/Assets/WavefrontObjParser.h b/examples/Assets/WavefrontObjParser.h index 72c1db44..396c9c7a 100644 --- a/examples/Assets/WavefrontObjParser.h +++ b/examples/Assets/WavefrontObjParser.h @@ -143,7 +143,7 @@ private: static float parseFloat (String::CharPointerType& t) { - t = t.findEndOfWhitespace(); + t.incrementToEndOfWhitespace(); return (float) CharacterFunctions::readDoubleValue (t); } @@ -211,7 +211,7 @@ private: { TripleIndex i; - t = t.findEndOfWhitespace(); + t.incrementToEndOfWhitespace(); i.vertexIndex = t.getIntValue32() - 1; t = findEndOfFaceToken (t); diff --git a/examples/Audio/AudioPlaybackDemo.h b/examples/Audio/AudioPlaybackDemo.h index 8837cea5..deeb4673 100644 --- a/examples/Audio/AudioPlaybackDemo.h +++ b/examples/Audio/AudioPlaybackDemo.h @@ -296,6 +296,7 @@ public: directoryList.setDirectory (File::getSpecialLocation (File::userHomeDirectory), true, true); + fileTreeComp.setTitle ("Files"); fileTreeComp.setColour (FileTreeComponent::backgroundColourId, Colours::lightgrey.withAlpha (0.6f)); fileTreeComp.addListener (this); @@ -497,14 +498,13 @@ private: { if (btn == &chooseFileButton && fileChooser.get() == nullptr) { - SafePointer safeThis (this); - if (! RuntimePermissions::isGranted (RuntimePermissions::readExternalStorage)) { + SafePointer safeThis (this); RuntimePermissions::request (RuntimePermissions::readExternalStorage, [safeThis] (bool granted) mutable { - if (granted) + if (safeThis != nullptr && granted) safeThis->buttonClicked (&safeThis->chooseFileButton); }); return; @@ -515,24 +515,27 @@ private: fileChooser.reset (new FileChooser ("Select an audio file...", File(), "*.wav;*.mp3;*.aif")); fileChooser->launchAsync (FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles, - [safeThis] (const FileChooser& fc) mutable + [this] (const FileChooser& fc) mutable { - if (safeThis != nullptr && fc.getURLResults().size() > 0) + if (fc.getURLResults().size() > 0) { auto u = fc.getURLResult(); - safeThis->showAudioResource (std::move (u)); + showAudioResource (std::move (u)); } - safeThis->fileChooser = nullptr; + fileChooser = nullptr; }, nullptr); } else { - NativeMessageBox::showMessageBoxAsync (AlertWindow::WarningIcon, "Enable Code Signing", - "You need to enable code-signing for your iOS project and enable \"iCloud Documents\" " - "permissions to be able to open audio files on your iDevice. See: " - "https://forum.juce.com/t/native-ios-android-file-choosers"); + NativeMessageBox::showAsync (MessageBoxOptions() + .withIconType (MessageBoxIconType::WarningIcon) + .withTitle ("Enable Code Signing") + .withMessage ("You need to enable code-signing for your iOS project and enable \"iCloud Documents\" " + "permissions to be able to open audio files on your iDevice. See: " + "https://forum.juce.com/t/native-ios-android-file-choosers"), + nullptr); } } } diff --git a/examples/Audio/AudioRecordingDemo.h b/examples/Audio/AudioRecordingDemo.h index b6265c74..e04db4b3 100644 --- a/examples/Audio/AudioRecordingDemo.h +++ b/examples/Audio/AudioRecordingDemo.h @@ -359,11 +359,11 @@ private: fileToShare.deleteFile(); if (! success && error.isNotEmpty()) - { - NativeMessageBox::showMessageBoxAsync (AlertWindow::WarningIcon, - "Sharing Error", - error); - } + NativeMessageBox::showAsync (MessageBoxOptions() + .withIconType (MessageBoxIconType::WarningIcon) + .withTitle ("Sharing Error") + .withMessage (error), + nullptr); }); #endif diff --git a/examples/Audio/MPEDemo.h b/examples/Audio/MPEDemo.h index 1962e56b..f8f5c702 100644 --- a/examples/Audio/MPEDemo.h +++ b/examples/Audio/MPEDemo.h @@ -524,7 +524,7 @@ private: void handleInvalidLegacyModeParameters() const { - AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, + AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon, "Invalid legacy mode channel layout", "Cannot set legacy mode start/end channel:\n" "The end channel must not be less than the start channel!", diff --git a/examples/BLOCKS/BlocksDrawingDemo.h b/examples/BLOCKS/BlocksDrawingDemo.h deleted file mode 100644 index c072c9bb..00000000 --- a/examples/BLOCKS/BlocksDrawingDemo.h +++ /dev/null @@ -1,699 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE examples. - Copyright (c) 2020 - Raw Material Software Limited - - The code included in this file is provided under the terms of the ISC license - http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or - without fee is hereby granted provided that the above copyright notice and - this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, - WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR - PURPOSE, ARE DISCLAIMED. - - ============================================================================== -*/ - -/******************************************************************************* - The block below describes the properties of this PIP. A PIP is a short snippet - of code that can be read by the Projucer and used to generate a JUCE project. - - BEGIN_JUCE_PIP_METADATA - - name: BlocksDrawingDemo - version: 1.0.0 - vendor: JUCE - website: http://juce.com - description: Blocks application to draw shapes. - - dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, - juce_audio_processors, juce_audio_utils, juce_blocks_basics, - juce_core, juce_data_structures, juce_events, juce_graphics, - juce_gui_basics, juce_gui_extra - exporters: xcode_mac, vs2019, linux_make, xcode_iphone - - moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 - - type: Component - mainClass: BlocksDrawingDemo - - useLocalCopy: 1 - - END_JUCE_PIP_METADATA - -*******************************************************************************/ - -#pragma once - - -//============================================================================== -/** - Represents a single LED on a Lightpad -*/ -struct LEDComponent : public Component -{ - LEDComponent() : ledColour (Colours::black) { setInterceptsMouseClicks (false, false); } - - void setColour (Colour newColour) - { - ledColour = newColour; - repaint(); - } - - void paint (Graphics& g) override - { - g.setColour (ledColour); - g.fillEllipse (getLocalBounds().toFloat()); - } - - Colour ledColour; -}; - -//============================================================================== -/** - A component that is used to represent a Lightpad on-screen -*/ -class DrawableLightpadComponent : public Component -{ -public: - DrawableLightpadComponent () - { - for (auto x = 0; x < 15; ++x) - for (auto y = 0; y < 15; ++y) - addAndMakeVisible (leds.add (new LEDComponent())); - } - - void paint (Graphics& g) override - { - auto r = getLocalBounds().toFloat(); - - // Clip the drawing area to only draw in the block area - { - Path clipArea; - clipArea.addRoundedRectangle (r, r.getWidth() / 20.0f); - - g.reduceClipRegion (clipArea); - } - - // Fill a black square for the Lightpad - g.fillAll (Colours::black); - } - - void resized() override - { - auto r = getLocalBounds().reduced (10); - - auto circleWidth = r.getWidth() / 15; - auto circleHeight = r.getHeight() / 15; - - for (auto x = 0; x < 15; ++x) - for (auto y = 0; y < 15; ++y) - leds.getUnchecked ((x * 15) + y)->setBounds (r.getX() + (x * circleWidth), - r.getY() + (y * circleHeight), - circleWidth, circleHeight); - } - - void mouseDown (const MouseEvent& e) override - { - for (auto x = 0; x < 15; ++x) - for (auto y = 0; y < 15; ++y) - if (leds.getUnchecked ((x * 15) + y)->getBounds().contains (e.position.toInt())) - listeners.call ([&] (Listener& l) { l.ledClicked (x, y, e.pressure); }); - } - - void mouseDrag (const MouseEvent& e) override - { - for (auto x = 0; x < 15; ++x) - { - for (auto y = 0; y < 15; ++y) - { - if (leds.getUnchecked ((x * 15) + y)->getBounds().contains (e.position.toInt())) - { - auto t = e.eventTime; - - if (lastLED == Point (x, y) && t.toMilliseconds() - lastMouseEventTime.toMilliseconds() < 50) - return; - - listeners.call ([&] (Listener& l) { l.ledClicked (x, y, e.pressure); }); - - lastLED = { x, y }; - lastMouseEventTime = t; - } - } - } - } - - //============================================================================== - /** Sets the colour of one of the LEDComponents */ - void setLEDColour (int x, int y, Colour c) - { - x = jmin (x, 14); - y = jmin (y, 14); - - leds.getUnchecked ((x * 15) + y)->setColour (c); - } - - //============================================================================== - struct Listener - { - virtual ~Listener() {} - - /** Called when an LEDComponent has been clicked */ - virtual void ledClicked (int x, int y, float z) = 0; - }; - - void addListener (Listener* l) { listeners.add (l); } - void removeListener (Listener* l) { listeners.remove (l); } - -private: - OwnedArray leds; - ListenerList listeners; - - Time lastMouseEventTime; - Point lastLED; -}; - -//============================================================================== -/** - A struct that handles the setup and layout of the DrumPadGridProgram -*/ -struct ColourGrid -{ - ColourGrid (int cols, int rows) - : numColumns (cols), - numRows (rows) - { - constructGridFillArray(); - } - - /** Creates a GridFill object for each pad in the grid and sets its colour - and fill before adding it to an array of GridFill objects - */ - void constructGridFillArray() - { - gridFillArray.clear(); - - auto counter = 0; - - for (auto i = 0; i < numColumns; ++i) - { - for (auto j = 0; j < numRows; ++j) - { - DrumPadGridProgram::GridFill fill; - Colour colourToUse = colourArray.getUnchecked (counter); - - fill.colour = colourToUse.withBrightness (colourToUse == currentColour ? 1.0f : 0.1f); - - if (colourToUse == Colours::black) - fill.fillType = DrumPadGridProgram::GridFill::FillType::hollow; - else - fill.fillType = DrumPadGridProgram::GridFill::FillType::filled; - - gridFillArray.add (fill); - - if (++counter == colourArray.size()) - counter = 0; - } - } - } - - /** Sets which colour should be active for a given touch co-ordinate. Returns - true if the colour has changed - */ - bool setActiveColourForTouch (int x, int y) - { - auto colourHasChanged = false; - - auto xindex = x / 5; - auto yindex = y / 5; - - auto newColour = colourArray.getUnchecked ((yindex * 3) + xindex); - if (currentColour != newColour) - { - currentColour = newColour; - constructGridFillArray(); - colourHasChanged = true; - } - - return colourHasChanged; - } - - //============================================================================== - int numColumns, numRows; - - Array gridFillArray; - - Array colourArray = { Colours::white, Colours::red, Colours::green, - Colours::blue, Colours::hotpink, Colours::orange, - Colours::magenta, Colours::cyan, Colours::black }; - - Colour currentColour = Colours::hotpink; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ColourGrid) -}; - -//============================================================================== -/** - The main component -*/ -class BlocksDrawingDemo : public Component, - public TopologySource::Listener, - private TouchSurface::Listener, - private ControlButton::Listener, - private DrawableLightpadComponent::Listener, - private Timer -{ -public: - //============================================================================== - BlocksDrawingDemo() - { - activeLeds.clear(); - - // Register MainContentComponent as a listener to the PhysicalTopologySource object - topologySource.addListener (this); - - infoLabel.setText ("Connect a Lightpad Block to draw.", dontSendNotification); - infoLabel.setJustificationType (Justification::centred); - addAndMakeVisible (infoLabel); - - addAndMakeVisible (lightpadComponent); - lightpadComponent.setVisible (false); - lightpadComponent.addListener (this); - - clearButton.setButtonText ("Clear"); - clearButton.onClick = [this] { clearLEDs(); }; - clearButton.setAlwaysOnTop (true); - addAndMakeVisible (clearButton); - - brightnessSlider.setRange (0.0, 1.0); - brightnessSlider.setValue (1.0); - brightnessSlider.setAlwaysOnTop (true); - brightnessSlider.setTextBoxStyle (Slider::TextEntryBoxPosition::NoTextBox, false, 0, 0); - brightnessSlider.onValueChange = [this] - { - brightnessLED.setColour (layout.currentColour - .withBrightness (layout.currentColour == Colours::black ? 0.0f - : static_cast (brightnessSlider.getValue()))); - }; - addAndMakeVisible (brightnessSlider); - - brightnessLED.setAlwaysOnTop (true); - brightnessLED.setColour (layout.currentColour.withBrightness (static_cast (brightnessSlider.getValue()))); - addAndMakeVisible (brightnessLED); - - #if JUCE_IOS - connectButton.setButtonText ("Connect"); - connectButton.onClick = [] { BluetoothMidiDevicePairingDialogue::open(); }; - connectButton.setAlwaysOnTop (true); - addAndMakeVisible (connectButton); - #endif - - setSize (600, 600); - - topologyChanged(); - } - - ~BlocksDrawingDemo() override - { - if (activeBlock != nullptr) - detachActiveBlock(); - - lightpadComponent.removeListener (this); - topologySource.removeListener (this); - } - - void resized() override - { - infoLabel.centreWithSize (getWidth(), 100); - - auto bounds = getLocalBounds().reduced (20); - - // top buttons - auto topButtonArea = bounds.removeFromTop (getHeight() / 20); - - topButtonArea.removeFromLeft (20); - clearButton.setBounds (topButtonArea.removeFromLeft (80)); - - #if JUCE_IOS - topButtonArea.removeFromRight (20); - connectButton.setBounds (topButtonArea.removeFromRight (80)); - #endif - - bounds.removeFromTop (20); - - auto orientation = Desktop::getInstance().getCurrentOrientation(); - - if (orientation == Desktop::DisplayOrientation::upright - || orientation == Desktop::DisplayOrientation::upsideDown) - { - auto brightnessControlBounds = bounds.removeFromBottom (getHeight() / 10); - - brightnessSlider.setSliderStyle (Slider::SliderStyle::LinearHorizontal); - brightnessLED.setBounds (brightnessControlBounds.removeFromLeft (getHeight() / 10)); - brightnessSlider.setBounds (brightnessControlBounds); - } - else - { - auto brightnessControlBounds = bounds.removeFromRight (getWidth() / 10); - - brightnessSlider.setSliderStyle (Slider::SliderStyle::LinearVertical); - brightnessLED.setBounds (brightnessControlBounds.removeFromTop (getWidth() / 10)); - brightnessSlider.setBounds (brightnessControlBounds); - } - - // lightpad component - auto sideLength = jmin (bounds.getWidth() - 40, bounds.getHeight() - 40); - lightpadComponent.centreWithSize (sideLength, sideLength); - } - - /** Overridden from TopologySource::Listener. Called when the topology changes */ - void topologyChanged() override - { - lightpadComponent.setVisible (false); - infoLabel.setVisible (true); - - // Reset the activeBlock object - if (activeBlock != nullptr) - detachActiveBlock(); - - // Get the array of currently connected Block objects from the PhysicalTopologySource - auto blocks = topologySource.getCurrentTopology().blocks; - - // Iterate over the array of Block objects - for (auto b : blocks) - { - // Find the first Lightpad - if (b->getType() == Block::Type::lightPadBlock) - { - activeBlock = b; - - // Register MainContentComponent as a listener to the touch surface - if (auto surface = activeBlock->getTouchSurface()) - surface->addListener (this); - - // Register MainContentComponent as a listener to any buttons - for (auto button : activeBlock->getButtons()) - button->addListener (this); - - // Get the LEDGrid object from the Lightpad and set its program to the program for the current mode - if (auto grid = activeBlock->getLEDGrid()) - { - // Work out scale factors to translate X and Y touches to LED indexes - scaleX = (float) (grid->getNumColumns() - 1) / (float) activeBlock->getWidth(); - scaleY = (float) (grid->getNumRows() - 1) / (float) activeBlock->getHeight(); - - setLEDProgram (*activeBlock); - } - - // Make the on screen Lightpad component visible - lightpadComponent.setVisible (true); - infoLabel.setVisible (false); - - break; - } - } - } - -private: - //============================================================================== - /** Overridden from TouchSurface::Listener. Called when a Touch is received on the Lightpad */ - void touchChanged (TouchSurface&, const TouchSurface::Touch& touch) override - { - // Translate X and Y touch events to LED indexes - auto xLed = roundToInt (touch.x * scaleX); - auto yLed = roundToInt (touch.y * scaleY); - - if (currentMode == colourPalette) - { - if (layout.setActiveColourForTouch (xLed, yLed)) - { - if (auto* colourPaletteProgram = getPaletteProgram()) - { - colourPaletteProgram->setGridFills (layout.numColumns, layout.numRows, layout.gridFillArray); - brightnessLED.setColour (layout.currentColour - .withBrightness (layout.currentColour == Colours::black ? 0.0f - : static_cast (brightnessSlider.getValue()))); - } - } - } - else if (currentMode == canvas) - { - drawLED ((uint32) xLed, (uint32) yLed, touch.z, layout.currentColour); - } - } - - /** Overridden from ControlButton::Listener. Called when a button on the Lightpad is pressed */ - void buttonPressed (ControlButton&, Block::Timestamp) override {} - - /** Overridden from ControlButton::Listener. Called when a button on the Lightpad is released */ - void buttonReleased (ControlButton&, Block::Timestamp) override - { - if (currentMode == canvas) - { - // Wait 500ms to see if there is a second press - if (! isTimerRunning()) - startTimer (500); - else - doublePress = true; - } - else if (currentMode == colourPalette) - { - // Switch to canvas mode and set the LEDGrid program - currentMode = canvas; - setLEDProgram (*activeBlock); - } - } - - void ledClicked (int x, int y, float z) override - { - drawLED ((uint32) x, (uint32) y, - z == 0.0f ? static_cast (brightnessSlider.getValue()) - : z * static_cast (brightnessSlider.getValue()), layout.currentColour); - } - - void timerCallback() override - { - if (doublePress) - { - clearLEDs(); - - // Reset the doublePress flag - doublePress = false; - } - else - { - // Switch to colour palette mode and set the LEDGrid program - currentMode = colourPalette; - setLEDProgram (*activeBlock); - } - - stopTimer(); - } - - /** Removes TouchSurface and ControlButton listeners and sets activeBlock to nullptr */ - void detachActiveBlock() - { - if (auto surface = activeBlock->getTouchSurface()) - surface->removeListener (this); - - for (auto button : activeBlock->getButtons()) - button->removeListener (this); - - activeBlock = nullptr; - } - - /** Sets the LEDGrid Program for the selected mode */ - void setLEDProgram (Block& block) - { - if (currentMode == canvas) - { - block.setProgram (std::make_unique(block)); - - // Redraw any previously drawn LEDs - redrawLEDs(); - } - else if (currentMode == colourPalette) - { - block.setProgram (std::make_unique (block)); - - // Setup the grid layout - if (auto* program = getPaletteProgram()) - program->setGridFills (layout.numColumns, layout.numRows, layout.gridFillArray); - } - } - - void clearLEDs() - { - if (auto* canvasProgram = getCanvasProgram()) - { - // Clear the LED grid - for (uint32 x = 0; x < 15; ++x) - { - for (uint32 y = 0; y < 15; ++ y) - { - canvasProgram->setLED (x, y, Colours::black); - lightpadComponent.setLEDColour ((int) x, (int) y, Colours::black); - } - } - - // Clear the ActiveLED array - activeLeds.clear(); - } - } - - /** Sets an LED on the Lightpad for a given touch co-ordinate and pressure */ - void drawLED (uint32 x0, uint32 y0, float z, Colour drawColour) - { - if (auto* canvasProgram = getCanvasProgram()) - { - // Check if the activeLeds array already contains an ActiveLED object for this LED - auto index = getLEDAt (x0, y0); - - // If the colour is black then just set the LED to black and return - if (drawColour == Colours::black) - { - if (index >= 0) - { - canvasProgram->setLED (x0, y0, Colours::black); - lightpadComponent.setLEDColour ((int) x0, (int) y0, Colours::black); - activeLeds.remove (index); - } - - return; - } - - // If there is no ActiveLED object for this LED then create one, - // add it to the array, set the LED on the Block and return - if (index < 0) - { - ActiveLED led; - led.x = x0; - led.y = y0; - led.colour = drawColour; - led.brightness = z; - - activeLeds.add (led); - canvasProgram->setLED (led.x, led.y, led.colour.withBrightness (led.brightness)); - - lightpadComponent.setLEDColour ((int) led.x, (int) led.y, led.colour.withBrightness (led.brightness)); - - return; - } - - // Get the ActiveLED object for this LED - auto currentLed = activeLeds.getReference (index); - - // If the LED colour is the same as the draw colour, add the brightnesses together. - // If it is different, blend the colours - if (currentLed.colour == drawColour) - currentLed.brightness = jmin (currentLed.brightness + z, 1.0f); - else - currentLed.colour = currentLed.colour.interpolatedWith (drawColour, z); - - - // Set the LED on the Block and change the ActiveLED object in the activeLeds array - if (canvasProgram != nullptr) - canvasProgram->setLED (currentLed.x, currentLed.y, currentLed.colour.withBrightness (currentLed.brightness)); - - lightpadComponent.setLEDColour ((int) currentLed.x, (int) currentLed.y, currentLed.colour.withBrightness (currentLed.brightness)); - - activeLeds.set (index, currentLed); - } - } - - /** Redraws the LEDs on the Lightpad from the activeLeds array */ - void redrawLEDs() - { - if (auto* canvasProgram = getCanvasProgram()) - { - // Iterate over the activeLeds array and set the LEDs on the Block - for (auto led : activeLeds) - { - canvasProgram->setLED (led.x, led.y, led.colour.withBrightness (led.brightness)); - lightpadComponent.setLEDColour ((int) led.x, (int) led.y, led.colour.withBrightness (led.brightness)); - } - } - } - - //============================================================================== - BitmapLEDProgram* getCanvasProgram() - { - if (activeBlock != nullptr) - return dynamic_cast (activeBlock->getProgram()); - - return nullptr; - } - - DrumPadGridProgram* getPaletteProgram() - { - if (activeBlock != nullptr) - return dynamic_cast (activeBlock->getProgram()); - - return nullptr; - } - - //============================================================================== - /** - A struct that represents an active LED on the Lightpad. - Has a position, colour and brightness. - */ - struct ActiveLED - { - uint32 x, y; - Colour colour; - float brightness; - - /** Returns true if this LED occupies the given co-ordinates */ - bool occupies (uint32 xPos, uint32 yPos) const - { - return xPos == x && yPos == y; - } - }; - - Array activeLeds; - - int getLEDAt (uint32 x, uint32 y) const - { - for (auto i = 0; i < activeLeds.size(); ++i) - if (activeLeds.getReference (i).occupies (x, y)) - return i; - - return -1; - } - - //============================================================================== - enum DisplayMode - { - colourPalette = 0, - canvas - }; - - DisplayMode currentMode = colourPalette; - - //============================================================================== - ColourGrid layout { 3, 3 }; - PhysicalTopologySource topologySource; - Block::Ptr activeBlock; - - float scaleX = 0.0f; - float scaleY = 0.0f; - - bool doublePress = false; - - Label infoLabel; - DrawableLightpadComponent lightpadComponent; - TextButton clearButton; - LEDComponent brightnessLED; - Slider brightnessSlider; - - #if JUCE_IOS - TextButton connectButton; - #endif - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BlocksDrawingDemo) -}; diff --git a/examples/BLOCKS/BlocksMonitorDemo.h b/examples/BLOCKS/BlocksMonitorDemo.h deleted file mode 100644 index c1ca368e..00000000 --- a/examples/BLOCKS/BlocksMonitorDemo.h +++ /dev/null @@ -1,1036 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE examples. - Copyright (c) 2020 - Raw Material Software Limited - - The code included in this file is provided under the terms of the ISC license - http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or - without fee is hereby granted provided that the above copyright notice and - this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, - WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR - PURPOSE, ARE DISCLAIMED. - - ============================================================================== -*/ - -/******************************************************************************* - The block below describes the properties of this PIP. A PIP is a short snippet - of code that can be read by the Projucer and used to generate a JUCE project. - - BEGIN_JUCE_PIP_METADATA - - name: BlocksMonitorDemo - version: 1.0.0 - vendor: JUCE - website: http://juce.com - description: Application to monitor Blocks devices. - - dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, - juce_audio_processors, juce_audio_utils, juce_blocks_basics, - juce_core, juce_data_structures, juce_events, juce_graphics, - juce_gui_basics, juce_gui_extra - exporters: xcode_mac, vs2019, linux_make, xcode_iphone - - moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 - - type: Component - mainClass: BlocksMonitorDemo - - useLocalCopy: 1 - - END_JUCE_PIP_METADATA - -*******************************************************************************/ - -#pragma once - - -//============================================================================== -/** - Base class that renders a Block on the screen -*/ -class BlockComponent : public Component, - public SettableTooltipClient, - private TouchSurface::Listener, - private ControlButton::Listener, - private Timer -{ -public: - BlockComponent (Block::Ptr blockToUse) - : block (blockToUse) - { - updateStatsAndTooltip(); - - // Register BlockComponent as a listener to the touch surface - if (auto touchSurface = block->getTouchSurface()) - touchSurface->addListener (this); - - // Register BlockComponent as a listener to any buttons - for (auto button : block->getButtons()) - button->addListener (this); - - // If this is a Lightpad then set the grid program to be blank - if (block->getLEDGrid() != nullptr) - block->setProgram (std::make_unique(*block)); - - // If this is a Lightpad then redraw it at 25Hz - if (block->getType() == Block::lightPadBlock) - startTimerHz (25); - - // Make sure the component can't go offscreen if it is draggable - constrainer.setMinimumOnscreenAmounts (50, 50, 50, 50); - } - - ~BlockComponent() override - { - // Remove any listeners - if (auto touchSurface = block->getTouchSurface()) - touchSurface->removeListener (this); - - for (auto button : block->getButtons()) - button->removeListener (this); - } - - /** Called periodically to update the tooltip with information about the Block */ - void updateStatsAndTooltip() - { - // Get the battery level of this Block and inform any subclasses - auto batteryLevel = block->getBatteryLevel(); - handleBatteryLevelUpdate (batteryLevel); - - // Update the tooltip - setTooltip ("Name = " + block->getDeviceDescription() + "\n" - + "UID = " + String (block->uid) + "\n" - + "Serial number = " + block->serialNumber + "\n" - + "Battery level = " + String ((int) (batteryLevel * 100)) + "%" - + (block->isBatteryCharging() ? "++" - : "--")); - } - - /** Subclasses should override this to paint the Block object on the screen */ - void paint (Graphics&) override = 0; - - /** Subclasses can override this to receive button down events from the Block */ - virtual void handleButtonPressed (ControlButton::ButtonFunction, uint32) {} - - /** Subclasses can override this to receive button up events from the Block */ - virtual void handleButtonReleased (ControlButton::ButtonFunction, uint32) {} - - /** Subclasses can override this to receive touch events from the Block */ - virtual void handleTouchChange (TouchSurface::Touch) {} - - /** Subclasses can override this to battery level updates from the Block */ - virtual void handleBatteryLevelUpdate (float) {} - - /** The Block object that this class represents */ - Block::Ptr block; - - //============================================================================== - /** Returns an integer index corresponding to a physical position on the hardware - for each type of Control Block. */ - static int controlButtonFunctionToIndex (ControlButton::ButtonFunction f) - { - using CB = ControlButton; - - static Array map[] = - { - { CB::mode, CB::button0, CB::velocitySensitivity }, - { CB::volume, CB::button1, CB::glideSensitivity }, - { CB::scale, CB::button2, CB::slideSensitivity, CB::click }, - { CB::chord, CB::button3, CB::pressSensitivity, CB::snap }, - { CB::arp, CB::button4, CB::liftSensitivity, CB::back }, - { CB::sustain, CB::button5, CB::fixedVelocity, CB::playOrPause }, - { CB::octave, CB::button6, CB::glideLock, CB::record }, - { CB::love, CB::button7, CB::pianoMode, CB::learn }, - { CB::up }, - { CB::down } - }; - - for (int i = 0; i < numElementsInArray (map); ++i) - if (map[i].contains (f)) - return i; - - return -1; - } - - Point getOffsetForPort (Block::ConnectionPort port) - { - using e = Block::ConnectionPort::DeviceEdge; - - switch (rotation) - { - case 0: - { - switch (port.edge) - { - case e::north: - return { static_cast (port.index), 0.0f }; - case e::east: - return { static_cast (block->getWidth()), static_cast (port.index) }; - case e::south: - return { static_cast (port.index), static_cast (block->getHeight()) }; - case e::west: - return { 0.0f, static_cast (port.index) }; - default: - break; - } - - break; - } - case 90: - { - switch (port.edge) - { - case e::north: - return { 0.0f, static_cast (port.index) }; - case e::east: - return { static_cast (-1.0f - (float) port.index), static_cast (block->getWidth()) }; - case e::south: - return { static_cast (0.0f - (float) block->getHeight()), static_cast (port.index) }; - case e::west: - return { static_cast (-1.0f - (float) port.index), 0.0f }; - default: - break; - } - - break; - } - case 180: - { - switch (port.edge) - { - case e::north: - return { static_cast (-1.0f - (float) port.index), 0.0f }; - case e::east: - return { static_cast (0.0f - (float) block->getWidth()), static_cast (-1.0f - (float) port.index) }; - case e::south: - return { static_cast (-1.0f - (float) port.index), static_cast (0.0f - (float) block->getHeight()) }; - case e::west: - return { 0.0f, static_cast (-1.0f - (float) port.index) }; - default: - break; - } - - break; - } - case 270: - { - switch (port.edge) - { - case e::north: - return { 0.0f, static_cast (-1.0f - (float) port.index) }; - case e::east: - return { static_cast (port.index), static_cast (0 - (float) block->getWidth()) }; - case e::south: - return { static_cast (block->getHeight()), static_cast (-1.0f - (float) port.index) }; - case e::west: - return { static_cast (port.index), 0.0f }; - default: - break; - } - - break; - } - - default: - break; - } - - return {}; - } - - int rotation = 0; - Point topLeft = { 0.0f, 0.0f }; - -private: - /** Used to call repaint() periodically */ - void timerCallback() override { repaint(); } - - /** Overridden from TouchSurface::Listener */ - void touchChanged (TouchSurface&, const TouchSurface::Touch& t) override { handleTouchChange (t); } - - /** Overridden from ControlButton::Listener */ - void buttonPressed (ControlButton& b, Block::Timestamp t) override { handleButtonPressed (b.getType(), t); } - - /** Overridden from ControlButton::Listener */ - void buttonReleased (ControlButton& b, Block::Timestamp t) override { handleButtonReleased (b.getType(), t); } - - /** Overridden from MouseListener. Prepares the master Block component for dragging. */ - void mouseDown (const MouseEvent& e) override - { - if (block->isMasterBlock()) - componentDragger.startDraggingComponent (this, e); - } - - /** Overridden from MouseListener. Drags the master Block component */ - void mouseDrag (const MouseEvent& e) override - { - if (block->isMasterBlock()) - { - componentDragger.dragComponent (this, e, &constrainer); - getParentComponent()->resized(); - } - } - - ComponentDragger componentDragger; - ComponentBoundsConstrainer constrainer; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BlockComponent) -}; - -//============================================================================== -/** - Class that renders a Lightpad on the screen -*/ -class LightpadComponent : public BlockComponent -{ -public: - LightpadComponent (Block::Ptr blockToUse) - : BlockComponent (blockToUse) - {} - - void paint (Graphics& g) override - { - auto r = getLocalBounds().toFloat(); - - // clip the drawing area to only draw in the block area - { - Path clipArea; - clipArea.addRoundedRectangle (r, r.getWidth() / 20.0f); - - g.reduceClipRegion (clipArea); - } - - // Fill a black square for the Lightpad - g.fillAll (Colours::black); - - // size ration between physical and on-screen blocks - Point ratio (r.getWidth() / (float) block->getWidth(), - r.getHeight() / (float) block->getHeight()); - - auto maxCircleSize = (float) block->getWidth() / 3.0f; - - // iterate over the list of current touches and draw them on the onscreen Block - for (auto touch : touches) - { - auto circleSize = touch.touch.z * maxCircleSize; - - Point touchPosition (touch.touch.x, - touch.touch.y); - - auto blob = Rectangle (circleSize, circleSize) - .withCentre (touchPosition) * ratio; - - ColourGradient cg (colourArray[touch.touch.index], blob.getCentreX(), blob.getCentreY(), - Colours::transparentBlack, blob.getRight(), blob.getBottom(), - true); - - g.setGradientFill (cg); - g.fillEllipse (blob); - } - } - - void handleTouchChange (TouchSurface::Touch touch) override { touches.updateTouch (touch); } - -private: - /** An Array of colours to use for touches */ - Array colourArray = { Colours::red, - Colours::blue, - Colours::green, - Colours::yellow, - Colours::white, - Colours::hotpink, - Colours::mediumpurple }; - - /** A list of current Touch events */ - TouchList touches; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LightpadComponent) -}; - - -//============================================================================== -/** - Class that renders a Control Block on the screen -*/ -class ControlBlockComponent : public BlockComponent -{ -public: - ControlBlockComponent (Block::Ptr blockToUse) - : BlockComponent (blockToUse), - numLeds (block->getLEDRow()->getNumLEDs()) - { - addAndMakeVisible (roundedRectangleButton); - - // Display the battery level on the LEDRow - auto numLedsToTurnOn = static_cast ((float) numLeds * block->getBatteryLevel()); - - // add LEDs - for (auto i = 0; i < numLeds; ++i) - { - auto ledComponent = new LEDComponent(); - ledComponent->setOnState (i < numLedsToTurnOn); - - addAndMakeVisible (leds.add (ledComponent)); - } - - previousNumLedsOn = numLedsToTurnOn; - - // add buttons - for (auto i = 0; i < 8; ++i) - addAndMakeVisible (circleButtons[i]); - } - - void resized() override - { - auto r = getLocalBounds().reduced (10); - - auto rowHeight = r.getHeight() / 5; - auto ledWidth = (r.getWidth() - 70) / numLeds; - auto buttonWidth = (r.getWidth() - 40) / 5; - - auto row = r; - - auto ledRow = row.removeFromTop (rowHeight) .withSizeKeepingCentre (r.getWidth(), ledWidth); - auto buttonRow1 = row.removeFromTop (rowHeight * 2).withSizeKeepingCentre (r.getWidth(), buttonWidth); - auto buttonRow2 = row.removeFromTop (rowHeight * 2).withSizeKeepingCentre (r.getWidth(), buttonWidth); - - for (auto* led : leds) - { - led->setBounds (ledRow.removeFromLeft (ledWidth).reduced (2)); - ledRow.removeFromLeft (5); - } - - for (auto i = 0; i < 5; ++i) - { - circleButtons[i].setBounds (buttonRow1.removeFromLeft (buttonWidth).reduced (2)); - buttonRow1.removeFromLeft (10); - } - - for (auto i = 5; i < 8; ++i) - { - circleButtons[i].setBounds (buttonRow2.removeFromLeft (buttonWidth).reduced (2)); - buttonRow2.removeFromLeft (10); - } - - roundedRectangleButton.setBounds (buttonRow2); - } - - void paint (Graphics& g) override - { - auto r = getLocalBounds().toFloat(); - - // Fill a black rectangle for the Control Block - g.setColour (Colours::black); - g.fillRoundedRectangle (r, r.getWidth() / 20.0f); - } - - void handleButtonPressed (ControlButton::ButtonFunction function, uint32) override - { - displayButtonInteraction (controlButtonFunctionToIndex (function), true); - } - - void handleButtonReleased (ControlButton::ButtonFunction function, uint32) override - { - displayButtonInteraction (controlButtonFunctionToIndex (function), false); - } - - void handleBatteryLevelUpdate (float batteryLevel) override - { - // Update the number of LEDs that are on to represent the battery level - auto numLedsOn = static_cast ((float) numLeds * batteryLevel); - - if (numLedsOn != previousNumLedsOn) - for (auto i = 0; i < numLeds; ++i) - leds.getUnchecked (i)->setOnState (i < numLedsOn); - - previousNumLedsOn = numLedsOn; - repaint(); - } - -private: - //============================================================================== - /** - Base class that renders a Control Block button - */ - struct ControlBlockSubComponent : public Component, - public TooltipClient - { - ControlBlockSubComponent (Colour componentColourToUse) - : componentColour (componentColourToUse) - {} - - /** Subclasses should override this to paint the button on the screen */ - void paint (Graphics&) override = 0; - - /** Sets the colour of the button */ - void setColour (Colour c) { componentColour = c; } - - /** Sets the on state of the button */ - void setOnState (bool isOn) - { - onState = isOn; - repaint(); - } - - /** Returns the Control Block tooltip */ - String getTooltip() override - { - for (Component* comp = this; comp != nullptr; comp = comp->getParentComponent()) - if (auto* sttc = dynamic_cast (comp)) - return sttc->getTooltip(); - - return {}; - } - - //============================================================================== - Colour componentColour; - bool onState = false; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ControlBlockSubComponent) - }; - - /** - Class that renders a Control Block LED on the screen - */ - struct LEDComponent : public ControlBlockSubComponent - { - LEDComponent() : ControlBlockSubComponent (Colours::green) {} - - void paint (Graphics& g) override - { - g.setColour (componentColour.withAlpha (onState ? 1.0f : 0.2f)); - g.fillEllipse (getLocalBounds().toFloat()); - } - }; - - /** - Class that renders a Control Block single circular button on the screen - */ - struct CircleButtonComponent : public ControlBlockSubComponent - { - CircleButtonComponent() : ControlBlockSubComponent (Colours::blue) {} - - void paint (Graphics& g) override - { - g.setColour (componentColour.withAlpha (onState ? 1.0f : 0.2f)); - g.fillEllipse (getLocalBounds().toFloat()); - } - }; - - /** - Class that renders a Control Block rounded rectangular button containing two buttons - on the screen - */ - struct RoundedRectangleButtonComponent : public ControlBlockSubComponent - { - RoundedRectangleButtonComponent() : ControlBlockSubComponent (Colours::blue) {} - - void paint (Graphics& g) override - { - auto r = getLocalBounds().toFloat(); - - g.setColour (componentColour.withAlpha (0.2f)); - g.fillRoundedRectangle (r.toFloat(), 20.0f); - g.setColour (componentColour.withAlpha (1.0f)); - - // is a button pressed? - if (doubleButtonOnState[0] || doubleButtonOnState[1]) - { - auto semiButtonWidth = r.getWidth() / 2.0f; - - auto semiButtonBounds = r.withWidth (semiButtonWidth) - .withX (doubleButtonOnState[1] ? semiButtonWidth : 0) - .reduced (5.0f, 2.0f); - - g.fillEllipse (semiButtonBounds); - } - } - - void setPressedState (bool isPressed, int button) - { - doubleButtonOnState[button] = isPressed; - repaint(); - } - - private: - bool doubleButtonOnState[2] = { false, false }; - }; - - /** Displays a button press or release interaction for a button at a given index */ - void displayButtonInteraction (int buttonIndex, bool isPressed) - { - if (! isPositiveAndBelow (buttonIndex, 10)) - return; - - if (buttonIndex >= 8) - roundedRectangleButton.setPressedState (isPressed, buttonIndex == 8); - else - circleButtons[buttonIndex].setOnState (isPressed); - } - - //============================================================================== - int numLeds; - OwnedArray leds; - CircleButtonComponent circleButtons[8]; - RoundedRectangleButtonComponent roundedRectangleButton; - int previousNumLedsOn; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ControlBlockComponent) -}; - -//============================================================================== -/** - The main component where the Block components will be displayed -*/ -class BlocksMonitorDemo : public Component, - public TopologySource::Listener, - private Timer -{ -public: - BlocksMonitorDemo() - { - noBlocksLabel.setText ("No BLOCKS connected...", dontSendNotification); - noBlocksLabel.setJustificationType (Justification::centred); - - zoomOutButton.setButtonText ("+"); - zoomOutButton.onClick = [this] { blockUnitInPixels = (int) ((float) blockUnitInPixels * 1.05f); resized(); }; - zoomOutButton.setAlwaysOnTop (true); - - zoomInButton.setButtonText ("-"); - zoomInButton.onClick = [this] { blockUnitInPixels = (int) ((float) blockUnitInPixels * 0.95f); resized(); }; - zoomInButton.setAlwaysOnTop (true); - - // Register BlocksMonitorDemo as a listener to the PhysicalTopologySource object - topologySource.addListener (this); - - startTimer (10000); - - addAndMakeVisible (noBlocksLabel); - addAndMakeVisible (zoomOutButton); - addAndMakeVisible (zoomInButton); - - #if JUCE_IOS - connectButton.setButtonText ("Connect"); - connectButton.onClick = [] { BluetoothMidiDevicePairingDialogue::open(); }; - connectButton.setAlwaysOnTop (true); - addAndMakeVisible (connectButton); - #endif - - setSize (600, 600); - - topologyChanged(); - } - - ~BlocksMonitorDemo() override - { - topologySource.removeListener (this); - } - - void paint (Graphics&) override {} - - void resized() override - { - #if JUCE_IOS - connectButton.setBounds (getRight() - 100, 20, 80, 30); - #endif - - noBlocksLabel.setVisible (false); - auto numBlockComponents = blockComponents.size(); - - // If there are no currently connected Blocks then display some text on the screen - if (masterBlockComponent == nullptr || numBlockComponents == 0) - { - noBlocksLabel.setVisible (true); - noBlocksLabel.setBounds (0, (getHeight() / 2) - 50, getWidth(), 100); - return; - } - - zoomOutButton.setBounds (10, getHeight() - 40, 40, 30); - zoomInButton.setBounds (zoomOutButton.getRight(), zoomOutButton.getY(), 40, 30); - - if (isInitialResized) - { - // Work out the area needed in terms of Block units - Rectangle maxArea; - for (auto blockComponent : blockComponents) - { - auto topLeft = blockComponent->topLeft; - auto rotation = blockComponent->rotation; - auto blockSize = 0; - - if (rotation == 180) - blockSize = blockComponent->block->getWidth(); - else if (rotation == 90) - blockSize = blockComponent->block->getHeight(); - - if (topLeft.x - (float) blockSize < maxArea.getX()) - maxArea.setX (topLeft.x - (float) blockSize); - - blockSize = 0; - if (rotation == 0) - blockSize = blockComponent->block->getWidth(); - else if (rotation == 270) - blockSize = blockComponent->block->getHeight(); - - if (topLeft.x + (float) blockSize > maxArea.getRight()) - maxArea.setWidth (topLeft.x + (float) blockSize); - - blockSize = 0; - if (rotation == 180) - blockSize = blockComponent->block->getHeight(); - else if (rotation == 270) - blockSize = blockComponent->block->getWidth(); - - if (topLeft.y - (float) blockSize < maxArea.getY()) - maxArea.setY (topLeft.y - (float) blockSize); - - blockSize = 0; - if (rotation == 0) - blockSize = blockComponent->block->getHeight(); - else if (rotation == 90) - blockSize = blockComponent->block->getWidth(); - - if (topLeft.y + (float) blockSize > maxArea.getBottom()) - maxArea.setHeight (topLeft.y + (float) blockSize); - } - - auto totalWidth = std::abs (maxArea.getX()) + maxArea.getWidth(); - auto totalHeight = std::abs (maxArea.getY()) + maxArea.getHeight(); - - blockUnitInPixels = static_cast (jmin (((float) getHeight() / totalHeight) - 50, ((float) getWidth() / totalWidth) - 50)); - - masterBlockComponent->centreWithSize (masterBlockComponent->block->getWidth() * blockUnitInPixels, - masterBlockComponent->block->getHeight() * blockUnitInPixels); - - isInitialResized = false; - } - else - { - masterBlockComponent->setSize (masterBlockComponent->block->getWidth() * blockUnitInPixels, masterBlockComponent->block->getHeight() * blockUnitInPixels); - } - - for (auto blockComponent : blockComponents) - { - if (blockComponent == masterBlockComponent) - continue; - - blockComponent->setBounds (masterBlockComponent->getX() + static_cast (blockComponent->topLeft.x * (float) blockUnitInPixels), - masterBlockComponent->getY() + static_cast (blockComponent->topLeft.y * (float) blockUnitInPixels), - blockComponent->block->getWidth() * blockUnitInPixels, - blockComponent->block->getHeight() * blockUnitInPixels); - - if (blockComponent->rotation != 0) - blockComponent->setTransform (AffineTransform::rotation (static_cast (degreesToRadians (blockComponent->rotation)), - static_cast (blockComponent->getX()), - static_cast (blockComponent->getY()))); - } - } - - /** Overridden from TopologySource::Listener, called when the topology changes */ - void topologyChanged() override - { - // Clear the array of Block components - blockComponents.clear(); - masterBlockComponent = nullptr; - - // Get the current topology - auto topology = topologySource.getCurrentTopology(); - - // Create a BlockComponent object for each Block object and store a pointer to the master - for (auto& block : topology.blocks) - { - if (auto* blockComponent = createBlockComponent (block)) - { - addAndMakeVisible (blockComponents.add (blockComponent)); - - if (blockComponent->block->isMasterBlock()) - masterBlockComponent = blockComponent; - } - } - - // Must have a master Block! - if (topology.blocks.size() > 0) - jassert (masterBlockComponent != nullptr); - - // Calculate the relative position and rotation for each Block - positionBlocks (topology); - - // Update the display - isInitialResized = true; - resized(); - } - -private: - /** Creates a BlockComponent object for a new Block and adds it to the content component */ - BlockComponent* createBlockComponent (Block::Ptr newBlock) - { - auto type = newBlock->getType(); - - if (type == Block::lightPadBlock) - return new LightpadComponent (newBlock); - - if (type == Block::loopBlock || type == Block::liveBlock - || type == Block::touchBlock || type == Block::developerControlBlock) - return new ControlBlockComponent (newBlock); - - // Should only be connecting a Lightpad or Control Block! - jassertfalse; - return nullptr; - } - - /** Periodically updates the displayed BlockComponent tooltips */ - void timerCallback() override - { - for (auto c : blockComponents) - c->updateStatsAndTooltip(); - } - - /** Calculates the position and rotation of each connected Block relative to the master Block */ - void positionBlocks (BlockTopology topology) - { - if (masterBlockComponent == nullptr) - return; - - Array blocksConnectedToMaster; - - auto maxDelta = std::numeric_limits::max(); - auto maxLoops = 50; - - // Store all the connections to the master Block - Array masterBlockConnections; - for (auto connection : topology.connections) - if (connection.device1 == masterBlockComponent->block->uid || connection.device2 == masterBlockComponent->block->uid) - masterBlockConnections.add (connection); - - // Position all the Blocks that are connected to the master Block - while (maxDelta > 0.001f && --maxLoops) - { - maxDelta = 0.0f; - - // Loop through each connection on the master Block - for (auto connection : masterBlockConnections) - { - // Work out whether the master Block is device 1 or device 2 in the BlockDeviceConnection struct - bool isDevice1 = true; - if (masterBlockComponent->block->uid == connection.device2) - isDevice1 = false; - - // Get the connected ports - auto masterPort = isDevice1 ? connection.connectionPortOnDevice1 : connection.connectionPortOnDevice2; - auto otherPort = isDevice1 ? connection.connectionPortOnDevice2 : connection.connectionPortOnDevice1; - - for (auto otherBlockComponent : blockComponents) - { - // Get the other block - if (otherBlockComponent->block->uid == (isDevice1 ? connection.device2 : connection.device1)) - { - blocksConnectedToMaster.addIfNotAlreadyThere (otherBlockComponent); - - // Get the rotation of the other Block relative to the master Block - otherBlockComponent->rotation = getRotation (masterPort.edge, otherPort.edge); - - // Get the offsets for the connected ports - auto masterBlockOffset = masterBlockComponent->getOffsetForPort (masterPort); - auto otherBlockOffset = otherBlockComponent->topLeft + otherBlockComponent->getOffsetForPort (otherPort); - - // Work out the distance between the two connected ports - auto delta = masterBlockOffset - otherBlockOffset; - - // Move the other block half the distance to the connection - otherBlockComponent->topLeft += delta / 2.0f; - - // Work out whether we are close enough for the loop to end - maxDelta = jmax (maxDelta, std::abs (delta.x), std::abs (delta.y)); - } - } - } - } - - // Check if there are any Blocks that have not been positioned yet - Array unpositionedBlocks; - - for (auto blockComponent : blockComponents) - if (blockComponent != masterBlockComponent && ! blocksConnectedToMaster.contains (blockComponent)) - unpositionedBlocks.add (blockComponent); - - if (unpositionedBlocks.size() > 0) - { - // Reset the loop conditions - maxDelta = std::numeric_limits::max(); - maxLoops = 50; - - // Position all the remaining Blocks - while (maxDelta > 0.001f && --maxLoops) - { - maxDelta = 0.0f; - - // Loop through each unpositioned Block - for (auto blockComponent : unpositionedBlocks) - { - // Store all the connections to this Block - Array blockConnections; - for (auto connection : topology.connections) - if (connection.device1 == blockComponent->block->uid || connection.device2 == blockComponent->block->uid) - blockConnections.add (connection); - - // Loop through each connection on this Block - for (auto connection : blockConnections) - { - // Work out whether this Block is device 1 or device 2 in the BlockDeviceConnection struct - auto isDevice1 = true; - if (blockComponent->block->uid == connection.device2) - isDevice1 = false; - - // Get the connected ports - auto thisPort = isDevice1 ? connection.connectionPortOnDevice1 : connection.connectionPortOnDevice2; - auto otherPort = isDevice1 ? connection.connectionPortOnDevice2 : connection.connectionPortOnDevice1; - - // Get the other Block - for (auto otherBlockComponent : blockComponents) - { - if (otherBlockComponent->block->uid == (isDevice1 ? connection.device2 : connection.device1)) - { - // Get the rotation - auto rotation = getRotation (otherPort.edge, thisPort.edge) + otherBlockComponent->rotation; - if (rotation > 360) - rotation -= 360; - - blockComponent->rotation = rotation; - - // Get the offsets for the connected ports - auto otherBlockOffset = (otherBlockComponent->topLeft + otherBlockComponent->getOffsetForPort (otherPort)); - auto thisBlockOffset = (blockComponent->topLeft + blockComponent->getOffsetForPort (thisPort)); - - // Work out the distance between the two connected ports - auto delta = otherBlockOffset - thisBlockOffset; - - // Move this block half the distance to the connection - blockComponent->topLeft += delta / 2.0f; - - // Work out whether we are close enough for the loop to end - maxDelta = jmax (maxDelta, std::abs (delta.x), std::abs (delta.y)); - } - } - } - } - } - } - } - - /** Returns a rotation in degrees based on the connected edges of two blocks */ - int getRotation (Block::ConnectionPort::DeviceEdge staticEdge, Block::ConnectionPort::DeviceEdge rotatedEdge) - { - using edge = Block::ConnectionPort::DeviceEdge; - - switch (staticEdge) - { - case edge::north: - { - switch (rotatedEdge) - { - case edge::north: - return 180; - case edge::south: - return 0; - case edge::east: - return 90; - case edge::west: - return 270; - default: - break; - } - - break; - } - case edge::south: - { - switch (rotatedEdge) - { - case edge::north: - return 0; - case edge::south: - return 180; - case edge::east: - return 270; - case edge::west: - return 90; - default: - break; - } - - break; - } - case edge::east: - { - switch (rotatedEdge) - { - case edge::north: - return 270; - case edge::south: - return 90; - case edge::east: - return 180; - case edge::west: - return 0; - default: - break; - } - - break; - } - - case edge::west: - { - switch (rotatedEdge) - { - case edge::north: - return 90; - case edge::south: - return 270; - case edge::east: - return 0; - case edge::west: - return 180; - default: - break; - } - - break; - } - - default: - break; - } - - return 0; - } - - //============================================================================== - TooltipWindow tooltipWindow; - - PhysicalTopologySource topologySource; - OwnedArray blockComponents; - BlockComponent* masterBlockComponent = nullptr; - - Label noBlocksLabel; - - TextButton zoomOutButton; - TextButton zoomInButton; - - int blockUnitInPixels; - bool isInitialResized; - - #if JUCE_IOS - TextButton connectButton; - #endif - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BlocksMonitorDemo) -}; diff --git a/examples/BLOCKS/BlocksSynthDemo.h b/examples/BLOCKS/BlocksSynthDemo.h deleted file mode 100644 index 99541038..00000000 --- a/examples/BLOCKS/BlocksSynthDemo.h +++ /dev/null @@ -1,866 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE examples. - Copyright (c) 2020 - Raw Material Software Limited - - The code included in this file is provided under the terms of the ISC license - http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or - without fee is hereby granted provided that the above copyright notice and - this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, - WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR - PURPOSE, ARE DISCLAIMED. - - ============================================================================== -*/ - -/******************************************************************************* - The block below describes the properties of this PIP. A PIP is a short snippet - of code that can be read by the Projucer and used to generate a JUCE project. - - BEGIN_JUCE_PIP_METADATA - - name: BlocksSynthDemo - version: 1.0.0 - vendor: JUCE - website: http://juce.com - description: Blocks synthesiser application. - - dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, - juce_audio_processors, juce_audio_utils, juce_blocks_basics, - juce_core, juce_data_structures, juce_events, juce_graphics, - juce_gui_basics, juce_gui_extra - exporters: xcode_mac, vs2019, linux_make, xcode_iphone - - moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 - - type: Component - mainClass: BlocksSynthDemo - - useLocalCopy: 1 - - END_JUCE_PIP_METADATA - -*******************************************************************************/ - -#pragma once - - -//============================================================================== -/** - Base class for oscillators -*/ -class OscillatorBase : public SynthesiserVoice -{ -public: - OscillatorBase() - { - amplitude.reset (getSampleRate(), 0.1); - phaseIncrement.reset (getSampleRate(), 0.1); - } - - void startNote (int midiNoteNumber, float velocity, SynthesiserSound*, int) override - { - frequency = MidiMessage::getMidiNoteInHertz (midiNoteNumber); - phaseIncrement.setTargetValue (((MathConstants::twoPi) * frequency) / sampleRate); - amplitude.setTargetValue (velocity); - - // Store the initial note and work out the maximum frequency deviations for pitch bend - initialNote = midiNoteNumber; - maxFreq = MidiMessage::getMidiNoteInHertz (initialNote + 4) - frequency; - minFreq = frequency - MidiMessage::getMidiNoteInHertz (initialNote - 4); - } - - void stopNote (float, bool) override - { - clearCurrentNote(); - amplitude.setTargetValue (0.0); - } - - void pitchWheelMoved (int newValue) override - { - // Change the phase increment based on pitch bend amount - auto frequencyOffset = ((newValue > 0 ? maxFreq : minFreq) * (newValue / 127.0)); - phaseIncrement.setTargetValue (((MathConstants::twoPi) * (frequency + frequencyOffset)) / sampleRate); - } - - void controllerMoved (int, int) override {} - - void channelPressureChanged (int newChannelPressureValue) override - { - // Set the amplitude based on pressure value - amplitude.setTargetValue (newChannelPressureValue / 127.0); - } - - void renderNextBlock (AudioBuffer& outputBuffer, int startSample, int numSamples) override - { - while (--numSamples >= 0) - { - auto output = getSample() * amplitude.getNextValue(); - - for (auto i = outputBuffer.getNumChannels(); --i >= 0;) - outputBuffer.addSample (i, startSample, static_cast (output)); - - ++startSample; - } - } - - using SynthesiserVoice::renderNextBlock; - - /** Returns the next sample */ - double getSample() - { - auto output = renderWaveShape (phasePos); - - phasePos += phaseIncrement.getNextValue(); - - if (phasePos > MathConstants::twoPi) - phasePos -= MathConstants::twoPi; - - return output; - } - - /** Subclasses should override this to say whether they can play the given sound */ - bool canPlaySound (SynthesiserSound*) override = 0; - - /** Subclasses should override this to render a waveshape */ - virtual double renderWaveShape (const double currentPhase) = 0; - -private: - SmoothedValue amplitude, phaseIncrement; - - double frequency = 0.0; - double phasePos = 0.0; - double sampleRate = 44100.0; - - int initialNote = 0; - double maxFreq = 0.0, minFreq = 0.0; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OscillatorBase) -}; - -//============================================================================== -/** - Sine sound struct - applies to MIDI channel 1 -*/ -struct SineSound : public SynthesiserSound -{ - SineSound () {} - - bool appliesToNote (int) override { return true; } - - bool appliesToChannel (int midiChannel) override { return (midiChannel == 1); } - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SineSound) -}; - -/** - Sine voice struct that renders a sin waveshape -*/ -struct SineVoice : public OscillatorBase -{ - SineVoice() {} - - bool canPlaySound (SynthesiserSound* sound) override { return dynamic_cast (sound) != nullptr; } - - double renderWaveShape (const double currentPhase) override { return sin (currentPhase); } - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SineVoice) -}; - -//============================================================================== -/** - Square sound struct - applies to MIDI channel 2 -*/ -struct SquareSound : public SynthesiserSound -{ - SquareSound() {} - - bool appliesToNote (int) override { return true; } - - bool appliesToChannel (int midiChannel) override { return (midiChannel == 2); } - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SquareSound) -}; - -/** - Square voice struct that renders a square waveshape -*/ -struct SquareVoice : public OscillatorBase -{ - SquareVoice() {} - - bool canPlaySound (SynthesiserSound* sound) override { return dynamic_cast (sound) != nullptr; } - - double renderWaveShape (const double currentPhase) override { return (currentPhase < MathConstants::pi ? 0.0 : 1.0); } - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SquareVoice) -}; - -//============================================================================== -/** - Sawtooth sound - applies to MIDI channel 3 -*/ -struct SawSound : public SynthesiserSound -{ - SawSound() {} - - bool appliesToNote (int) override { return true; } - - bool appliesToChannel (int midiChannel) override { return (midiChannel == 3); } - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SawSound) -}; - -/** - Sawtooth voice that renders a sawtooth waveshape -*/ -struct SawVoice : public OscillatorBase -{ - SawVoice() {} - - bool canPlaySound (SynthesiserSound* sound) override { return dynamic_cast (sound) != nullptr; } - - double renderWaveShape (const double currentPhase) override { return (1.0 / MathConstants::pi) * currentPhase - 1.0; } - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SawVoice) -}; - -//============================================================================== -/** - Triangle sound - applies to MIDI channel 4 -*/ -struct TriangleSound : public SynthesiserSound -{ - TriangleSound() {} - - bool appliesToNote (int) override { return true; } - - bool appliesToChannel (int midiChannel) override { return (midiChannel == 4); } - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TriangleSound) -}; - -/** - Triangle voice that renders a triangle waveshape -*/ -struct TriangleVoice : public OscillatorBase -{ - TriangleVoice() {} - - bool canPlaySound (SynthesiserSound* sound) override { return dynamic_cast (sound) != nullptr; } - - double renderWaveShape (const double currentPhase) override - { - return currentPhase < MathConstants::pi ? -1.0 + (2.0 / MathConstants::pi) * currentPhase - : 3.0 - (2.0 / MathConstants::pi) * currentPhase; - } - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TriangleVoice) -}; - -//============================================================================== -/** - Class to handle the Audio functionality -*/ -class Audio : public AudioIODeviceCallback -{ -public: - Audio() - { - // Set up the audio device manager - #ifndef JUCE_DEMO_RUNNER - audioDeviceManager.initialiseWithDefaultDevices (0, 2); - #endif - - audioDeviceManager.addAudioCallback (this); - - // Set up the synthesiser and add each of the waveshapes - synthesiser.clearVoices(); - synthesiser.clearSounds(); - - synthesiser.addVoice (new SineVoice()); - synthesiser.addVoice (new SquareVoice()); - synthesiser.addVoice (new SawVoice()); - synthesiser.addVoice (new TriangleVoice()); - - synthesiser.addSound (new SineSound()); - synthesiser.addSound (new SquareSound()); - synthesiser.addSound (new SawSound()); - synthesiser.addSound (new TriangleSound()); - } - - ~Audio() override - { - audioDeviceManager.removeAudioCallback (this); - } - - /** Audio callback */ - void audioDeviceIOCallback (const float** /*inputChannelData*/, int /*numInputChannels*/, - float** outputChannelData, int numOutputChannels, int numSamples) override - { - AudioBuffer sampleBuffer (outputChannelData, numOutputChannels, numSamples); - sampleBuffer.clear(); - - synthesiser.renderNextBlock (sampleBuffer, MidiBuffer(), 0, numSamples); - } - - void audioDeviceAboutToStart (AudioIODevice* device) override - { - synthesiser.setCurrentPlaybackSampleRate (device->getCurrentSampleRate()); - } - - void audioDeviceStopped() override {} - - /** Called to turn a synthesiser note on */ - void noteOn (int channel, int noteNum, float velocity) - { - synthesiser.noteOn (channel, noteNum, velocity); - } - - /** Called to turn a synthesiser note off */ - void noteOff (int channel, int noteNum, float velocity) - { - synthesiser.noteOff (channel, noteNum, velocity, false); - } - - /** Called to turn all synthesiser notes off */ - void allNotesOff() - { - for (auto i = 1; i < 5; ++i) - synthesiser.allNotesOff (i, false); - } - - /** Send pressure change message to synthesiser */ - void pressureChange (int channel, float newPressure) - { - synthesiser.handleChannelPressure (channel, static_cast (newPressure * 127)); - } - - /** Send pitch change message to synthesiser */ - void pitchChange (int channel, float pitchChange) - { - synthesiser.handlePitchWheel (channel, static_cast (pitchChange * 127)); - } - -private: - #ifndef JUCE_DEMO_RUNNER - AudioDeviceManager audioDeviceManager; - #else - AudioDeviceManager& audioDeviceManager { getSharedAudioDeviceManager (0, 2) }; - #endif - Synthesiser synthesiser; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Audio) -}; - -//============================================================================== -/** - A Program to draw moving waveshapes onto the LEDGrid -*/ -class WaveshapeProgram : public Block::Program -{ -public: - WaveshapeProgram (Block& b) : Program (b) {} - - /** Sets the waveshape type to display on the grid */ - void setWaveshapeType (uint8 type) - { - block.setDataByte (0, type); - } - - /** Generates the Y coordinates for 1.5 cycles of each of the four waveshapes and stores them - at the correct offsets in the shared data heap. */ - void generateWaveshapes() - { - uint8 sineWaveY[45]; - uint8 squareWaveY[45]; - uint8 sawWaveY[45]; - uint8 triangleWaveY[45]; - - // Set current phase position to 0 and work out the required phase increment for one cycle - auto currentPhase = 0.0; - auto phaseInc = (1.0 / 30.0) * MathConstants::twoPi; - - for (auto x = 0; x < 30; ++x) - { - // Scale and offset the sin output to the Lightpad display - auto sineOutput = std::sin (currentPhase); - sineWaveY[x] = static_cast (roundToInt ((sineOutput * 6.5) + 7.0)); - - // Square wave output, set flags for when vertical line should be drawn - if (currentPhase < MathConstants::pi) - { - if (x == 0) - squareWaveY[x] = 255; - else - squareWaveY[x] = 1; - } - else - { - if (x > 0 && squareWaveY[x - 1] == 1) - squareWaveY[x - 1] = 255; - - squareWaveY[x] = 13; - } - - // Saw wave output, set flags for when vertical line should be drawn - sawWaveY[x] = 14 - ((x / 2) % 15); - - if (sawWaveY[x] == 0 && sawWaveY[x - 1] != 255) - sawWaveY[x] = 255; - - // Triangle wave output - triangleWaveY[x] = x < 15 ? static_cast (x) : static_cast (14 - (x % 15)); - - // Add half cycle to end of array so it loops correctly - if (x < 15) - { - sineWaveY[x + 30] = sineWaveY[x]; - squareWaveY[x + 30] = squareWaveY[x]; - sawWaveY[x + 30] = sawWaveY[x]; - triangleWaveY[x + 30] = triangleWaveY[x]; - } - - // Increment the current phase - currentPhase += phaseInc; - } - - // Store the values for each of the waveshapes at the correct offsets in the shared data heap - for (uint8 i = 0; i < 45; ++i) - { - block.setDataByte (sineWaveOffset + i, sineWaveY[i]); - block.setDataByte (squareWaveOffset + i, squareWaveY[i]); - block.setDataByte (sawWaveOffset + i, sawWaveY[i]); - block.setDataByte (triangleWaveOffset + i, triangleWaveY[i]); - } - } - - String getLittleFootProgram() override - { - return R"littlefoot( - - #heapsize: 256 - - int yOffset; - - void drawLEDCircle (int x0, int y0) - { - blendPixel (0xffff0000, x0, y0); - - int minLedIndex = 0; - int maxLedIndex = 14; - - blendPixel (0xff660000, min (x0 + 1, maxLedIndex), y0); - blendPixel (0xff660000, max (x0 - 1, minLedIndex), y0); - blendPixel (0xff660000, x0, min (y0 + 1, maxLedIndex)); - blendPixel (0xff660000, x0, max (y0 - 1, minLedIndex)); - - blendPixel (0xff1a0000, min (x0 + 1, maxLedIndex), min (y0 + 1, maxLedIndex)); - blendPixel (0xff1a0000, min (x0 + 1, maxLedIndex), max (y0 - 1, minLedIndex)); - blendPixel (0xff1a0000, max (x0 - 1, minLedIndex), min (y0 + 1, maxLedIndex)); - blendPixel (0xff1a0000, max (x0 - 1, minLedIndex), max (y0 - 1, minLedIndex)); - } - - void repaint() - { - // Clear LEDs to black - fillRect (0xff000000, 0, 0, 15, 15); - - // Get the waveshape type - int type = getHeapByte (0); - - // Calculate the heap offset - int offset = 1 + (type * 45) + yOffset; - - for (int x = 0; x < 15; ++x) - { - // Get the corresponding Y coordinate for each X coordinate - int y = getHeapByte (offset + x); - - // Draw a vertical line if flag is set or draw an LED circle - if (y == 255) - { - for (int i = 0; i < 15; ++i) - drawLEDCircle (x, i); - } - else if (x % 2 == 0) - { - drawLEDCircle (x, y); - } - } - - // Increment and wrap the Y offset to draw a 'moving' waveshape - if (++yOffset == 30) - yOffset = 0; - } - - )littlefoot"; - } - -private: - //============================================================================== - /** Shared data heap is laid out as below. There is room for the waveshape type and - the Y coordinates for 1.5 cycles of each of the four waveshapes. */ - - static constexpr uint32 waveshapeType = 0; // 1 byte - static constexpr uint32 sineWaveOffset = 1; // 1 byte * 45 - static constexpr uint32 squareWaveOffset = 46; // 1 byte * 45 - static constexpr uint32 sawWaveOffset = 91; // 1 byte * 45 - static constexpr uint32 triangleWaveOffset = 136; // 1 byte * 45 - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WaveshapeProgram) -}; - -//============================================================================== -/** - A struct that handles the setup and layout of the DrumPadGridProgram -*/ -struct SynthGrid -{ - SynthGrid (int cols, int rows) - : numColumns (cols), - numRows (rows) - { - constructGridFillArray(); - } - - /** Creates a GridFill object for each pad in the grid and sets its colour - and fill before adding it to an array of GridFill objects - */ - void constructGridFillArray() - { - gridFillArray.clear(); - - for (auto i = 0; i < numRows; ++i) - { - for (auto j = 0; j < numColumns; ++j) - { - DrumPadGridProgram::GridFill fill; - - auto padNum = (i * 5) + j; - - fill.colour = notes.contains (padNum) ? baseGridColour - : tonics.contains (padNum) ? Colours::white - : Colours::black; - fill.fillType = DrumPadGridProgram::GridFill::FillType::gradient; - gridFillArray.add (fill); - } - } - } - - int getNoteNumberForPad (int x, int y) const - { - auto xIndex = x / 3; - auto yIndex = y / 3; - - return 60 + ((4 - yIndex) * 5) + xIndex; - } - - //============================================================================== - int numColumns, numRows; - float width, height; - - Array gridFillArray; - Colour baseGridColour = Colours::green; - Colour touchColour = Colours::red; - - Array tonics = { 4, 12, 20 }; - Array notes = { 1, 3, 6, 7, 9, 11, 14, 15, 17, 19, 22, 24 }; - - //============================================================================== - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SynthGrid) -}; - -//============================================================================== -/** - The main component -*/ -class BlocksSynthDemo : public Component, - public TopologySource::Listener, - private TouchSurface::Listener, - private ControlButton::Listener, - private Timer -{ -public: - BlocksSynthDemo() - { - // Register BlocksSynthDemo as a listener to the PhysicalTopologySource object - topologySource.addListener (this); - - #if JUCE_IOS - connectButton.setButtonText ("Connect"); - connectButton.onClick = [] { BluetoothMidiDevicePairingDialogue::open(); }; - addAndMakeVisible (connectButton); - #endif - - setSize (600, 400); - - topologyChanged(); - } - - ~BlocksSynthDemo() override - { - if (activeBlock != nullptr) - detachActiveBlock(); - - topologySource.removeListener (this); - } - - void paint (Graphics& g) override - { - g.setColour (getLookAndFeel().findColour (Label::textColourId)); - g.drawText ("Connect a Lightpad Block to play.", - getLocalBounds(), Justification::centred, false); - } - - void resized() override - { - #if JUCE_IOS - connectButton.setBounds (getRight() - 100, 20, 80, 30); - #endif - } - - /** Overridden from TopologySource::Listener, called when the topology changes */ - void topologyChanged() override - { - // Reset the activeBlock object - if (activeBlock != nullptr) - detachActiveBlock(); - - // Get the array of currently connected Block objects from the PhysicalTopologySource - auto blocks = topologySource.getBlocks(); - - // Iterate over the array of Block objects - for (auto b : blocks) - { - // Find the first Lightpad - if (b->getType() == Block::Type::lightPadBlock) - { - activeBlock = b; - - // Register BlocksSynthDemo as a listener to the touch surface - if (auto surface = activeBlock->getTouchSurface()) - surface->addListener (this); - - // Register BlocksSynthDemo as a listener to any buttons - for (auto button : activeBlock->getButtons()) - button->addListener (this); - - // Get the LEDGrid object from the Lightpad and set its program to the program for the current mode - if (auto grid = activeBlock->getLEDGrid()) - { - // Work out scale factors to translate X and Y touches to LED indexes - scaleX = static_cast (grid->getNumColumns() - 1) / (float) activeBlock->getWidth(); - scaleY = static_cast (grid->getNumRows() - 1) / (float) activeBlock->getHeight(); - - setLEDProgram (*activeBlock); - } - - break; - } - } - } - -private: - /** Overridden from TouchSurface::Listener. Called when a Touch is received on the Lightpad */ - void touchChanged (TouchSurface&, const TouchSurface::Touch& touch) override - { - if (currentMode == waveformSelectionMode && touch.isTouchStart && allowTouch) - { - if (auto* waveshapeProgram = getWaveshapeProgram()) - { - // Change the displayed waveshape to the next one - ++waveshapeMode; - - if (waveshapeMode > 3) - waveshapeMode = 0; - - waveshapeProgram->setWaveshapeType (static_cast (waveshapeMode)); - - allowTouch = false; - startTimer (250); - } - } - else if (currentMode == playMode) - { - if (auto* gridProgram = getGridProgram()) - { - // Translate X and Y touch events to LED indexes - auto xLed = roundToInt (touch.startX * scaleX); - auto yLed = roundToInt (touch.startY * scaleY); - - // Limit the number of touches per second - constexpr auto maxNumTouchMessagesPerSecond = 100; - auto now = Time::getCurrentTime(); - clearOldTouchTimes (now); - - auto midiChannel = waveshapeMode + 1; - - // Send the touch event to the DrumPadGridProgram and Audio class - if (touch.isTouchStart) - { - gridProgram->startTouch (touch.startX, touch.startY); - audio.noteOn (midiChannel, layout.getNoteNumberForPad (xLed, yLed), touch.z); - } - else if (touch.isTouchEnd) - { - gridProgram->endTouch (touch.startX, touch.startY); - audio.noteOff (midiChannel, layout.getNoteNumberForPad (xLed, yLed), 1.0); - } - else - { - if (touchMessageTimesInLastSecond.size() > maxNumTouchMessagesPerSecond / 3) - return; - - gridProgram->sendTouch (touch.x, touch.y, touch.z, - layout.touchColour); - - // Send pitch change and pressure values to the Audio class - audio.pitchChange (midiChannel, (touch.x - touch.startX) / (float) activeBlock->getWidth()); - audio.pressureChange (midiChannel, touch.z); - } - - touchMessageTimesInLastSecond.add (now); - } - } - } - - /** Overridden from ControlButton::Listener. Called when a button on the Lightpad is pressed */ - void buttonPressed (ControlButton&, Block::Timestamp) override {} - - /** Overridden from ControlButton::Listener. Called when a button on the Lightpad is released */ - void buttonReleased (ControlButton&, Block::Timestamp) override - { - // Turn any active synthesiser notes off - audio.allNotesOff(); - - // Switch modes - if (currentMode == waveformSelectionMode) - currentMode = playMode; - else if (currentMode == playMode) - currentMode = waveformSelectionMode; - - // Set the LEDGrid program to the new mode - setLEDProgram (*activeBlock); - } - - /** Clears the old touch times */ - void clearOldTouchTimes (const Time now) - { - for (auto i = touchMessageTimesInLastSecond.size(); --i >= 0;) - if (touchMessageTimesInLastSecond.getReference(i) < now - RelativeTime::seconds (0.33)) - touchMessageTimesInLastSecond.remove (i); - } - - /** Removes TouchSurface and ControlButton listeners and sets activeBlock to nullptr */ - void detachActiveBlock() - { - if (auto surface = activeBlock->getTouchSurface()) - surface->removeListener (this); - - for (auto button : activeBlock->getButtons()) - button->removeListener (this); - - activeBlock = nullptr; - } - - /** Sets the LEDGrid Program for the selected mode */ - void setLEDProgram (Block& block) - { - if (currentMode == waveformSelectionMode) - { - // Set the LEDGrid program - block.setProgram (std::make_unique(block)); - - // Initialise the program - if (auto* waveshapeProgram = getWaveshapeProgram()) - { - waveshapeProgram->setWaveshapeType (static_cast (waveshapeMode)); - waveshapeProgram->generateWaveshapes(); - } - } - else if (currentMode == playMode) - { - // Set the LEDGrid program - auto error = block.setProgram (std::make_unique(block)); - - if (error.failed()) - { - DBG (error.getErrorMessage()); - jassertfalse; - } - - // Setup the grid layout - if (auto* gridProgram = getGridProgram()) - gridProgram->setGridFills (layout.numColumns, layout.numRows, layout.gridFillArray); - } - } - - /** Stops touch events from triggering multiple waveshape mode changes */ - void timerCallback() override { allowTouch = true; } - - //============================================================================== - DrumPadGridProgram* getGridProgram() - { - if (activeBlock != nullptr) - return dynamic_cast (activeBlock->getProgram()); - - return nullptr; - } - - WaveshapeProgram* getWaveshapeProgram() - { - if (activeBlock != nullptr) - return dynamic_cast (activeBlock->getProgram()); - - return nullptr; - } - - //============================================================================== - enum BlocksSynthMode - { - waveformSelectionMode = 0, - playMode - }; - - BlocksSynthMode currentMode = playMode; - - //============================================================================== - Audio audio; - - SynthGrid layout { 5, 5 }; - PhysicalTopologySource topologySource; - Block::Ptr activeBlock; - - Array