1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00

WebBrowserComponent: Improve native integrations

This commit is contained in:
attila 2024-04-08 17:39:34 +02:00 committed by Anthony Nicholls
parent 624fed2c7f
commit 5f638157f7
63 changed files with 5155 additions and 1288 deletions

View file

@ -4,6 +4,38 @@
## Change ## Change
The `WebBrowserComponent::pageAboutToLoad()` function on Android now only
receives callbacks for entire page navigation events, as opposed to every
resource fetch operation. Returning `false` from the function now prevents
this operation from taking any effect, as opposed to producing potentially
visible error messages.
**Possible Issues**
Code that previously depended on the ability to allow or fail resource
requests on Android may fail to work correctly.
**Workaround**
Navigating to webpages can still be prevented by returning `false` from this
function, similarly to other platforms.
Resource requests sent to the domain returned by
`WebBrowserComponent::getResourceProviderRoot()` can be served or rejected by
using the `WebBrowserComponent::ResourceProvider` feature.
Resource requests sent to other domains can not be controlled on Android
anymore.
**Rationale**
Prior to this change there was no way to reject a page load operation without
any visible effect, like there was on the other platforms. The fine grained per
resource control was not possible on other platforms. This change makes the
Android implementation more consistent with the other platforms.
## Change
The minimum supported compilers and deployment targets have been updated, with The minimum supported compilers and deployment targets have been updated, with
the new minimums listed in the top level [README](README.md). the new minimums listed in the top level [README](README.md).

View file

@ -123,6 +123,12 @@ if(JUCE_BUILD_EXAMPLES)
add_subdirectory(examples) add_subdirectory(examples)
endif() endif()
string(CONCAT webview2_option_message "Location that overrides the default directory where our "
"FindWebView2 script is looking for the "
"*Microsoft.Web.WebView2* directory")
option(JUCE_WEBVIEW2_PACKAGE_LOCATION ${webview2_option_message} "")
# ================================================================================================== # ==================================================================================================
# Install configuration # Install configuration

View file

@ -232,6 +232,15 @@ option is enabled, which may improve build times for established products that u
handle plugin bundle structures, icons, plists, and so on. If this option is enabled, then handle plugin bundle structures, icons, plists, and so on. If this option is enabled, then
`JUCE_ENABLE_MODULE_SOURCE_GROUPS` will have no effect. `JUCE_ENABLE_MODULE_SOURCE_GROUPS` will have no effect.
#### `JUCE_WEBVIEW2_PACKAGE_LOCATION`
You can ask JUCE to link the WebView2 library statically to your target on Windows, by specifying
the `NEEDS_WEBVIEW2` option when creating your target. In this case JUCE will search for the
WebView2 package on your system. The default search location is
`%userprofile%\AppData\Local\PackageManagement\NuGet\Packages`. This location can be overriden by
specifying this option. The provided location should contain the `*Microsoft.Web.WebView2*`
directory.
### Functions ### Functions
#### `juce_add_<target>` #### `juce_add_<target>`
@ -406,6 +415,11 @@ attributes directly to these creation functions, rather than adding them later.
are set on a JUCE target. By default, we don't link Webkit because you might not need it, but are set on a JUCE target. By default, we don't link Webkit because you might not need it, but
if you get linker or include errors that reference Webkit, just set this argument to `TRUE`. if you get linker or include errors that reference Webkit, just set this argument to `TRUE`.
`NEEDS_WEBVIEW2`
- On Windows, JUCE may or may not need to link to WebView2 depending on the compile definitions that
are set on a JUCE target. By default, we don't link WebView2 because you might not need it, but
if you get linker or include errors that reference WebView2, just set this argument to `TRUE`.
`NEEDS_STORE_KIT` `NEEDS_STORE_KIT`
- On macOS, JUCE may or may not need to link to StoreKit depending on the compile definitions that - On macOS, JUCE may or may not need to link to StoreKit depending on the compile definitions that
are set on a JUCE target. By default, we don't link StoreKit because you might not need it, but are set on a JUCE target. By default, we don't link StoreKit because you might not need it, but

View file

@ -1077,6 +1077,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/misc/juce_EnumHelpers.h" "../../../../../modules/juce_core/misc/juce_EnumHelpers.h"
"../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp" "../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp"
"../../../../../modules/juce_core/misc/juce_Functional.h" "../../../../../modules/juce_core/misc/juce_Functional.h"
"../../../../../modules/juce_core/misc/juce_OptionsHelpers.h"
"../../../../../modules/juce_core/misc/juce_Result.cpp" "../../../../../modules/juce_core/misc/juce_Result.cpp"
"../../../../../modules/juce_core/misc/juce_Result.h" "../../../../../modules/juce_core/misc/juce_Result.h"
"../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp" "../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp"
@ -1983,6 +1984,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/detail/juce_WebControlRelayEvents.h"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h"
"../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"
@ -2014,6 +2016,8 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.h"
"../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp" "../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp" "../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm" "../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm"
@ -3171,6 +3175,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/misc/juce_EnumHelpers.h" "../../../../../modules/juce_core/misc/juce_EnumHelpers.h"
"../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp" "../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp"
"../../../../../modules/juce_core/misc/juce_Functional.h" "../../../../../modules/juce_core/misc/juce_Functional.h"
"../../../../../modules/juce_core/misc/juce_OptionsHelpers.h"
"../../../../../modules/juce_core/misc/juce_Result.cpp" "../../../../../modules/juce_core/misc/juce_Result.cpp"
"../../../../../modules/juce_core/misc/juce_Result.h" "../../../../../modules/juce_core/misc/juce_Result.h"
"../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp" "../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp"
@ -4077,6 +4082,7 @@ set_source_files_properties(
"../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/detail/juce_WebControlRelayEvents.h"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h"
"../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"
@ -4108,6 +4114,8 @@ set_source_files_properties(
"../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.h"
"../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp" "../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp" "../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm" "../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm"

View file

@ -2657,6 +2657,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -3405,6 +3408,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -3860,6 +3864,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -3879,6 +3884,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/>
@ -3965,5 +3971,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -650,6 +650,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -3379,6 +3382,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -5355,6 +5361,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -6720,6 +6729,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -6777,6 +6789,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -2657,6 +2657,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -3405,6 +3408,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -3860,6 +3864,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -3879,6 +3884,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/>
@ -3965,5 +3971,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -650,6 +650,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -3379,6 +3382,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -5355,6 +5361,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -6720,6 +6729,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -6777,6 +6789,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -2657,6 +2657,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -3405,6 +3408,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -3860,6 +3864,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -3879,6 +3884,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/>
@ -3965,5 +3971,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -650,6 +650,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -3379,6 +3382,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -5355,6 +5361,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -6720,6 +6729,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -6777,6 +6789,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -953,6 +953,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/misc/juce_EnumHelpers.h" "../../../../../modules/juce_core/misc/juce_EnumHelpers.h"
"../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp" "../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp"
"../../../../../modules/juce_core/misc/juce_Functional.h" "../../../../../modules/juce_core/misc/juce_Functional.h"
"../../../../../modules/juce_core/misc/juce_OptionsHelpers.h"
"../../../../../modules/juce_core/misc/juce_Result.cpp" "../../../../../modules/juce_core/misc/juce_Result.cpp"
"../../../../../modules/juce_core/misc/juce_Result.h" "../../../../../modules/juce_core/misc/juce_Result.h"
"../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp" "../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp"
@ -1762,6 +1763,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/detail/juce_WebControlRelayEvents.h"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h"
"../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"
@ -1793,6 +1795,8 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.h"
"../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp" "../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp" "../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm" "../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm"
@ -2747,6 +2751,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/misc/juce_EnumHelpers.h" "../../../../../modules/juce_core/misc/juce_EnumHelpers.h"
"../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp" "../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp"
"../../../../../modules/juce_core/misc/juce_Functional.h" "../../../../../modules/juce_core/misc/juce_Functional.h"
"../../../../../modules/juce_core/misc/juce_OptionsHelpers.h"
"../../../../../modules/juce_core/misc/juce_Result.cpp" "../../../../../modules/juce_core/misc/juce_Result.cpp"
"../../../../../modules/juce_core/misc/juce_Result.h" "../../../../../modules/juce_core/misc/juce_Result.h"
"../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp" "../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp"
@ -3556,6 +3561,7 @@ set_source_files_properties(
"../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/detail/juce_WebControlRelayEvents.h"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h"
"../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"
@ -3587,6 +3593,8 @@ set_source_files_properties(
"../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.h"
"../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp" "../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp" "../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm" "../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm"

View file

@ -2371,6 +2371,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -2961,6 +2964,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -3363,6 +3367,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -3382,6 +3387,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/>
@ -3414,5 +3420,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -572,6 +572,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -2956,6 +2959,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -4635,6 +4641,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -5841,6 +5850,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -5898,6 +5910,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -986,6 +986,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/misc/juce_EnumHelpers.h" "../../../../../modules/juce_core/misc/juce_EnumHelpers.h"
"../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp" "../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp"
"../../../../../modules/juce_core/misc/juce_Functional.h" "../../../../../modules/juce_core/misc/juce_Functional.h"
"../../../../../modules/juce_core/misc/juce_OptionsHelpers.h"
"../../../../../modules/juce_core/misc/juce_Result.cpp" "../../../../../modules/juce_core/misc/juce_Result.cpp"
"../../../../../modules/juce_core/misc/juce_Result.h" "../../../../../modules/juce_core/misc/juce_Result.h"
"../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp" "../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp"
@ -1892,6 +1893,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/detail/juce_WebControlRelayEvents.h"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h"
"../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"
@ -1923,6 +1925,8 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.h"
"../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp" "../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp" "../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm" "../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm"
@ -2933,6 +2937,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/misc/juce_EnumHelpers.h" "../../../../../modules/juce_core/misc/juce_EnumHelpers.h"
"../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp" "../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp"
"../../../../../modules/juce_core/misc/juce_Functional.h" "../../../../../modules/juce_core/misc/juce_Functional.h"
"../../../../../modules/juce_core/misc/juce_OptionsHelpers.h"
"../../../../../modules/juce_core/misc/juce_Result.cpp" "../../../../../modules/juce_core/misc/juce_Result.cpp"
"../../../../../modules/juce_core/misc/juce_Result.h" "../../../../../modules/juce_core/misc/juce_Result.h"
"../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp" "../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp"
@ -3839,6 +3844,7 @@ set_source_files_properties(
"../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/detail/juce_WebControlRelayEvents.h"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h"
"../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"
@ -3870,6 +3876,8 @@ set_source_files_properties(
"../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.h"
"../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp" "../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp" "../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm" "../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm"

View file

@ -2505,6 +2505,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -3141,6 +3144,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -3596,6 +3600,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -3615,6 +3620,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/>
@ -3681,5 +3687,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -614,6 +614,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -3163,6 +3166,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -4911,6 +4917,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -6276,6 +6285,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -6333,6 +6345,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -2505,6 +2505,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -3141,6 +3144,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -3596,6 +3600,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -3615,6 +3620,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/>
@ -3681,5 +3687,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -614,6 +614,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -3163,6 +3166,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -4911,6 +4917,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -6276,6 +6285,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -6333,6 +6345,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -2505,6 +2505,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -3141,6 +3144,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -3596,6 +3600,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -3615,6 +3620,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/>
@ -3681,5 +3687,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -614,6 +614,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -3163,6 +3166,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -4911,6 +4917,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -6276,6 +6285,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -6333,6 +6345,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -568,6 +568,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -668,5 +669,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -669,6 +669,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>

View file

@ -0,0 +1,92 @@
# ==============================================================================
#
# This file is part of the JUCE framework.
# Copyright (c) Raw Material Software Limited
#
# JUCE is an open source framework subject to commercial or open source
# licensing.
#
# By downloading, installing, or using the JUCE framework, or combining the
# JUCE framework with any other source code, object code, content or any other
# copyrightable work, you agree to the terms of the JUCE End User Licence
# Agreement, and all incorporated terms including the JUCE Privacy Policy and
# the JUCE Website Terms of Service, as applicable, which will bind you. If you
# do not agree to the terms of these agreements, we will not license the JUCE
# framework to you, and you must discontinue the installation or download
# process and cease use of the JUCE framework.
#
# JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
# JUCE Privacy Policy: https://juce.com/juce-privacy-policy
# JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
#
# Or:
#
# You may also use this code under the terms of the AGPLv3:
# https://www.gnu.org/licenses/agpl-3.0.en.html
#
# THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
# WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
#
# ==============================================================================
include(FindPackageHandleStandardArgs)
if(JUCE_WEBVIEW2_PACKAGE_LOCATION)
set(initial_search_dir ${JUCE_WEBVIEW2_PACKAGE_LOCATION})
else()
set(initial_search_dir "$ENV{USERPROFILE}/AppData/Local/PackageManagement/NuGet/Packages")
endif()
file(GLOB subdirs "${initial_search_dir}/*Microsoft.Web.WebView2*")
if(subdirs)
list(GET subdirs 0 search_dir)
list(LENGTH subdirs num_webview2_packages)
if(num_webview2_packages GREATER 1)
message(WARNING "Multiple WebView2 packages found in the local NuGet folder. Proceeding with ${search_dir}.")
endif()
find_path(WebView2_root_dir build/native/include/WebView2.h HINTS ${search_dir})
set(WebView2_include_dir "${WebView2_root_dir}/build/native/include")
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm64")
set(WebView2_arch arm64)
else()
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(WebView2_arch x64)
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(WebView2_arch x86)
endif()
endif()
set(WebView2_library "${WebView2_root_dir}/build/native/${WebView2_arch}/WebView2LoaderStatic.lib")
elseif(NOT WebView2_FIND_QUIETLY)
message(WARNING
"WebView2 wasn't found in the the local NuGet folder."
"\n"
"To install NuGet and the WebView2 package containing the statically linked library, "
"open a PowerShell and issue the following commands"
"\n"
"> Register-PackageSource -provider NuGet -name nugetRepository -location https://www.nuget.org/api/v2\n"
"> Install-Package NuGet.CommandLine -Scope CurrentUser\n"
"> Install-Package Microsoft.Web.WebView2 -Scope CurrentUser -RequiredVersion 1.0.1901.177\n")
endif()
find_package_handle_standard_args(WebView2 DEFAULT_MSG WebView2_include_dir WebView2_library)
if(WebView2_FOUND)
set(WebView2_INCLUDE_DIRS ${WebView2_include_dir})
set(WebView2_LIBRARIES ${WebView2_library} )
mark_as_advanced(WebView2_library WebView2_include_dir WebView2_root_dir)
if(NOT TARGET juce_webview2)
add_library(juce_webview2 INTERFACE)
add_library(juce::juce_webview2 ALIAS juce_webview2)
target_include_directories(juce_webview2 INTERFACE ${WebView2_INCLUDE_DIRS})
target_link_libraries(juce_webview2 INTERFACE ${WebView2_LIBRARIES})
endif()
endif()

View file

@ -275,6 +275,17 @@ function(_juce_link_optional_libraries target)
if(CMAKE_SYSTEM_NAME STREQUAL "iOS" AND needs_camera) if(CMAKE_SYSTEM_NAME STREQUAL "iOS" AND needs_camera)
_juce_link_frameworks("${target}" PRIVATE ImageIO) _juce_link_frameworks("${target}" PRIVATE ImageIO)
endif() endif()
elseif(WIN32)
get_target_property(needs_webview2 ${target} JUCE_NEEDS_WEBVIEW2)
if (needs_webview2)
if(NOT ("${JUCE_CMAKE_UTILS_DIR}" IN_LIST CMAKE_MODULE_PATH))
list(APPEND CMAKE_MODULE_PATH "${JUCE_CMAKE_UTILS_DIR}")
endif()
find_package(WebView2 REQUIRED)
target_link_libraries(${target} PRIVATE juce::juce_webview2)
endif()
endif() endif()
endfunction() endfunction()
@ -1864,6 +1875,7 @@ function(_juce_initialise_target target)
COMPANY_EMAIL COMPANY_EMAIL
NEEDS_CURL # Set this true if you want to link curl on Linux NEEDS_CURL # Set this true if you want to link curl on Linux
NEEDS_WEB_BROWSER # Set this true if you want to link webkit on Linux NEEDS_WEB_BROWSER # Set this true if you want to link webkit on Linux
NEEDS_WEBVIEW2 # Set this true if you want to link WebView2 statically on Windows
NEEDS_STORE_KIT # Set this true if you want in-app-purchases on Mac NEEDS_STORE_KIT # Set this true if you want in-app-purchases on Mac
PUSH_NOTIFICATIONS_ENABLED PUSH_NOTIFICATIONS_ENABLED
NETWORK_MULTICAST_ENABLED NETWORK_MULTICAST_ENABLED
@ -2130,6 +2142,10 @@ function(juce_add_pip header)
list(APPEND extra_target_args PLUGINHOST_AU TRUE) list(APPEND extra_target_args PLUGINHOST_AU TRUE)
endif() endif()
if("JUCE_USE_WIN_WEBVIEW2_WITH_STATIC_LINKING=1" IN_LIST pip_moduleflags)
list(APPEND extra_target_args NEEDS_WEBVIEW2 TRUE)
endif()
if(pip_kind STREQUAL "AudioProcessor") if(pip_kind STREQUAL "AudioProcessor")
_juce_get_metadata("${metadata_dict}" documentControllerClass JUCE_PIP_DOCUMENTCONTROLLER_CLASS) _juce_get_metadata("${metadata_dict}" documentControllerClass JUCE_PIP_DOCUMENTCONTROLLER_CLASS)

View file

@ -957,6 +957,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/misc/juce_EnumHelpers.h" "../../../../../modules/juce_core/misc/juce_EnumHelpers.h"
"../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp" "../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp"
"../../../../../modules/juce_core/misc/juce_Functional.h" "../../../../../modules/juce_core/misc/juce_Functional.h"
"../../../../../modules/juce_core/misc/juce_OptionsHelpers.h"
"../../../../../modules/juce_core/misc/juce_Result.cpp" "../../../../../modules/juce_core/misc/juce_Result.cpp"
"../../../../../modules/juce_core/misc/juce_Result.h" "../../../../../modules/juce_core/misc/juce_Result.h"
"../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp" "../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp"
@ -1781,6 +1782,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/detail/juce_WebControlRelayEvents.h"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h"
"../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"
@ -1812,6 +1814,8 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.h"
"../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp" "../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp" "../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm" "../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm"
@ -2831,6 +2835,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/misc/juce_EnumHelpers.h" "../../../../../modules/juce_core/misc/juce_EnumHelpers.h"
"../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp" "../../../../../modules/juce_core/misc/juce_EnumHelpers_test.cpp"
"../../../../../modules/juce_core/misc/juce_Functional.h" "../../../../../modules/juce_core/misc/juce_Functional.h"
"../../../../../modules/juce_core/misc/juce_OptionsHelpers.h"
"../../../../../modules/juce_core/misc/juce_Result.cpp" "../../../../../modules/juce_core/misc/juce_Result.cpp"
"../../../../../modules/juce_core/misc/juce_Result.h" "../../../../../modules/juce_core/misc/juce_Result.h"
"../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp" "../../../../../modules/juce_core/misc/juce_RuntimePermissions.cpp"
@ -3655,6 +3660,7 @@ set_source_files_properties(
"../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp"
"../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h" "../../../../../modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h"
"../../../../../modules/juce_gui_extra/detail/juce_WebControlRelayEvents.h"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"
"../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h" "../../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.h"
"../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h" "../../../../../modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"
@ -3686,6 +3692,8 @@ set_source_files_properties(
"../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h" "../../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.cpp"
"../../../../../modules/juce_gui_extra/misc/juce_WebControlRelays.h"
"../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp" "../../../../../modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp" "../../../../../modules/juce_gui_extra/native/juce_AndroidViewComponent.cpp"
"../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm" "../../../../../modules/juce_gui_extra/native/juce_AppleRemote_mac.mm"

View file

@ -2392,6 +2392,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -3052,6 +3055,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -3461,6 +3465,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -3480,6 +3485,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/>
@ -3548,5 +3554,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -581,6 +581,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -3010,6 +3013,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -4776,6 +4782,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -6003,6 +6012,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -6060,6 +6072,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -1574,6 +1574,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -1869,6 +1872,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -2278,6 +2282,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -2297,6 +2302,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/>
@ -2344,5 +2350,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -305,6 +305,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -1954,6 +1957,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -2754,6 +2760,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -3981,6 +3990,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -4038,6 +4050,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -1574,6 +1574,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -1869,6 +1872,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -2278,6 +2282,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -2297,6 +2302,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/>
@ -2344,5 +2350,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -305,6 +305,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -1954,6 +1957,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -2754,6 +2760,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -3981,6 +3990,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -4038,6 +4050,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -1574,6 +1574,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -1869,6 +1872,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -2278,6 +2282,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -2297,6 +2302,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/> <ClInclude Include="..\..\JuceLibraryCode\BinaryData.h"/>
@ -2344,5 +2350,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -305,6 +305,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -1954,6 +1957,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -2754,6 +2760,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -3981,6 +3990,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -4038,6 +4050,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -844,11 +844,11 @@ public:
} }
{ {
auto* importGroup = projectXml.createNewChildElement ("ImportGroup");
importGroup->setAttribute ("Label", "ExtensionTargets");
if (owner.shouldAddWebView2Package()) if (owner.shouldAddWebView2Package())
{ {
auto* importGroup = projectXml.createNewChildElement ("ImportGroup");
importGroup->setAttribute ("Label", "ExtensionTargets");
auto packageTargetsPath = "packages\\" + getWebView2PackageName() + "." + getWebView2PackageVersion() auto packageTargetsPath = "packages\\" + getWebView2PackageName() + "." + getWebView2PackageVersion()
+ "\\build\\native\\" + getWebView2PackageName() + ".targets"; + "\\build\\native\\" + getWebView2PackageName() + ".targets";
@ -856,6 +856,13 @@ public:
e->setAttribute ("Project", packageTargetsPath); e->setAttribute ("Project", packageTargetsPath);
e->setAttribute ("Condition", "Exists('" + packageTargetsPath + "')"); e->setAttribute ("Condition", "Exists('" + packageTargetsPath + "')");
} }
if (owner.shouldLinkWebView2Statically())
{
auto* propertyGroup = projectXml.createNewChildElement ("PropertyGroup");
auto* loaderPref = propertyGroup->createNewChildElement ("WebView2LoaderPreference");
loaderPref->addTextElement ("Static");
}
} }
} }
@ -1882,11 +1889,18 @@ protected:
bool shouldAddWebView2Package() const bool shouldAddWebView2Package() const
{ {
return project.getEnabledModules().isModuleEnabled ("juce_gui_extra") return project.getEnabledModules().isModuleEnabled ("juce_gui_extra")
&& project.isConfigFlagEnabled ("JUCE_USE_WIN_WEBVIEW2", false); && ( project.isConfigFlagEnabled ("JUCE_USE_WIN_WEBVIEW2", false)
|| project.isConfigFlagEnabled ("JUCE_USE_WIN_WEBVIEW2_WITH_STATIC_LINKING", false));
}
bool shouldLinkWebView2Statically() const
{
return project.getEnabledModules().isModuleEnabled ("juce_gui_extra")
&& project.isConfigFlagEnabled ("JUCE_USE_WIN_WEBVIEW2_WITH_STATIC_LINKING", false);
} }
static String getWebView2PackageName() { return "Microsoft.Web.WebView2"; } static String getWebView2PackageName() { return "Microsoft.Web.WebView2"; }
static String getWebView2PackageVersion() { return "1.0.902.49"; } static String getWebView2PackageVersion() { return "1.0.1901.177"; }
void createPackagesConfigFile() const void createPackagesConfigFile() const
{ {

View file

@ -2513,6 +2513,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -3237,6 +3240,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -3692,6 +3696,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -3711,6 +3716,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\..\..\modules\juce_midi_ci\ci\juce_CIChannelAddress.h"/> <ClInclude Include="..\..\..\..\modules\juce_midi_ci\ci\juce_CIChannelAddress.h"/>
@ -3815,5 +3821,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -614,6 +614,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -3184,6 +3187,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -5025,6 +5031,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -6390,6 +6399,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -6447,6 +6459,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -2513,6 +2513,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -3237,6 +3240,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -3692,6 +3696,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -3711,6 +3716,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\..\..\modules\juce_midi_ci\ci\juce_CIChannelAddress.h"/> <ClInclude Include="..\..\..\..\modules\juce_midi_ci\ci\juce_CIChannelAddress.h"/>
@ -3815,5 +3821,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -614,6 +614,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -3184,6 +3187,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -5025,6 +5031,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -6390,6 +6399,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -6447,6 +6459,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -2513,6 +2513,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -3237,6 +3240,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -3692,6 +3696,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -3711,6 +3716,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\..\..\modules\juce_midi_ci\ci\juce_CIChannelAddress.h"/> <ClInclude Include="..\..\..\..\modules\juce_midi_ci\ci\juce_CIChannelAddress.h"/>
@ -3815,5 +3821,4 @@
<ResourceCompile Include=".\resources.rc"/> <ResourceCompile Include=".\resources.rc"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -614,6 +614,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -3184,6 +3187,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -5025,6 +5031,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -6390,6 +6399,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -6447,6 +6459,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -2391,6 +2391,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -3028,6 +3031,7 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ConsoleApplication.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_EnumHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_RuntimePermissions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_ScopeGuard.h"/>
@ -3437,6 +3441,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_CPlusPlusCodeTokeniserFunctions.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_LuaCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_ActiveXControlComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\embedding\juce_AndroidViewComponent.h"/>
@ -3456,6 +3461,7 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SplashScreen.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_SystemTrayIconComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"/>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\juce_gui_extra.h"/>
<ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/> <ClInclude Include="..\..\..\..\modules\juce_opengl\geometry\juce_Draggable3DOrientation.h"/>
@ -3521,5 +3527,4 @@
<None Include="..\..\..\..\modules\juce_graphics\image_formats\pnglib\libpng_readme.txt"/> <None Include="..\..\..\..\modules\juce_graphics\image_formats\pnglib\libpng_readme.txt"/>
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
</Project> </Project>

View file

@ -575,6 +575,9 @@
<Filter Include="JUCE Modules\juce_gui_extra\code_editor"> <Filter Include="JUCE Modules\juce_gui_extra\code_editor">
<UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier> <UniqueIdentifier>{DF95D4BF-E18C-125A-5EBB-8993A06E232C}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="JUCE Modules\juce_gui_extra\detail">
<UniqueIdentifier>{E0FCBD5F-0B11-D78C-F786-52AB7FEE2383}</UniqueIdentifier>
</Filter>
<Filter Include="JUCE Modules\juce_gui_extra\documents"> <Filter Include="JUCE Modules\juce_gui_extra\documents">
<UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier> <UniqueIdentifier>{118946F2-AC24-0F09-62D5-753DF87A60CD}</UniqueIdentifier>
</Filter> </Filter>
@ -3007,6 +3010,9 @@
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.cpp">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp"> <ClCompile Include="..\..\..\..\modules\juce_gui_extra\native\juce_ActiveXComponent_windows.cpp">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClCompile> </ClCompile>
@ -4743,6 +4749,9 @@
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Functional.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_OptionsHelpers.h">
<Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h"> <ClInclude Include="..\..\..\..\modules\juce_core\misc\juce_Result.h">
<Filter>JUCE Modules\juce_core\misc</Filter> <Filter>JUCE Modules\juce_core\misc</Filter>
</ClInclude> </ClInclude>
@ -5970,6 +5979,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\code_editor\juce_XMLCodeTokeniser.h">
<Filter>JUCE Modules\juce_gui_extra\code_editor</Filter> <Filter>JUCE Modules\juce_gui_extra\code_editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\detail\juce_WebControlRelayEvents.h">
<Filter>JUCE Modules\juce_gui_extra\detail</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\documents\juce_FileBasedDocument.h">
<Filter>JUCE Modules\juce_gui_extra\documents</Filter> <Filter>JUCE Modules\juce_gui_extra\documents</Filter>
</ClInclude> </ClInclude>
@ -6027,6 +6039,9 @@
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebBrowserComponent.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter> <Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\misc\juce_WebControlRelays.h">
<Filter>JUCE Modules\juce_gui_extra\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h"> <ClInclude Include="..\..\..\..\modules\juce_gui_extra\native\juce_NSViewFrameWatcher_mac.h">
<Filter>JUCE Modules\juce_gui_extra\native</Filter> <Filter>JUCE Modules\juce_gui_extra\native</Filter>
</ClInclude> </ClInclude>

View file

@ -64,6 +64,7 @@
#define JUCE_AUDIO_PROCESSORS_H_INCLUDED #define JUCE_AUDIO_PROCESSORS_H_INCLUDED
#include <juce_gui_basics/juce_gui_basics.h> #include <juce_gui_basics/juce_gui_basics.h>
#include <juce_gui_extra/juce_gui_extra.h>
#include <juce_audio_basics/juce_audio_basics.h> #include <juce_audio_basics/juce_audio_basics.h>
//============================================================================== //==============================================================================

View file

@ -274,4 +274,160 @@ void ButtonParameterAttachment::buttonClicked (Button*)
attachment.setValueAsCompleteGesture (button.getToggleState() ? 1.0f : 0.0f); attachment.setValueAsCompleteGesture (button.getToggleState() ? 1.0f : 0.0f);
} }
//==============================================================================
#if JUCE_WEB_BROWSER
WebSliderParameterAttachment::WebSliderParameterAttachment (RangedAudioParameter& parameterIn,
WebSliderRelay& sliderStateIn,
UndoManager* undoManager)
: sliderState (sliderStateIn),
parameter (parameterIn),
attachment (parameter, [this] (float newValue) { setValue (newValue); }, undoManager)
{
sendInitialUpdate();
sliderState.addListener (this);
}
WebSliderParameterAttachment::~WebSliderParameterAttachment()
{
sliderState.removeListener (this);
}
void WebSliderParameterAttachment::sendInitialUpdate()
{
const auto range = parameter.getNormalisableRange();
DynamicObject::Ptr object { new DynamicObject };
object->setProperty (detail::WebSliderRelayEvents::Event::eventTypeKey, "propertiesChanged");
object->setProperty ("start", range.start);
object->setProperty ("end", range.end);
object->setProperty ("skew", range.skew);
object->setProperty ("name", parameter.getName (100));
object->setProperty ("label", parameter.getLabel());
object->setProperty ("numSteps", parameter.getNumSteps());
object->setProperty ("interval", range.interval);
sliderState.emitEvent (object.get());
attachment.sendInitialUpdate();
}
void WebSliderParameterAttachment::setValue (float newValue)
{
const ScopedValueSetter<bool> svs (ignoreCallbacks, true);
sliderState.setValue (newValue);
}
void WebSliderParameterAttachment::sliderValueChanged (WebSliderRelay* slider)
{
if (ignoreCallbacks)
{
jassertfalse;
return;
}
attachment.setValueAsPartOfGesture (slider->getValue());
}
//==============================================================================
WebToggleButtonParameterAttachment::WebToggleButtonParameterAttachment (RangedAudioParameter& parameterIn,
WebToggleButtonRelay& button,
UndoManager* undoManager)
: relay (button),
parameter (parameterIn),
attachment (parameter, [this] (float f) { setValue (f); }, undoManager)
{
sendInitialUpdate();
relay.addListener (this);
}
WebToggleButtonParameterAttachment::~WebToggleButtonParameterAttachment()
{
relay.removeListener (this);
}
void WebToggleButtonParameterAttachment::sendInitialUpdate()
{
DynamicObject::Ptr object { new DynamicObject };
object->setProperty (detail::WebSliderRelayEvents::Event::eventTypeKey, "propertiesChanged");
object->setProperty ("name", parameter.getName (100));
relay.emitEvent (object.get());
attachment.sendInitialUpdate();
}
void WebToggleButtonParameterAttachment::setValue (float newValue)
{
const ScopedValueSetter<bool> svs (ignoreCallbacks, true);
relay.setToggleState (newValue >= 0.5f);
}
void WebToggleButtonParameterAttachment::toggleStateChanged (bool newValue)
{
if (ignoreCallbacks)
{
jassertfalse;
return;
}
attachment.setValueAsCompleteGesture (newValue ? 1.0f : 0.0f);
}
void WebToggleButtonParameterAttachment::initialUpdateRequested()
{
sendInitialUpdate();
}
//==============================================================================
WebComboBoxParameterAttachment::WebComboBoxParameterAttachment (RangedAudioParameter& parameterIn,
WebComboBoxRelay& combo,
UndoManager* undoManager)
: relay (combo),
parameter (parameterIn),
attachment (parameter, [this] (float f) { setValue (f); }, undoManager)
{
sendInitialUpdate();
relay.addListener (this);
}
WebComboBoxParameterAttachment::~WebComboBoxParameterAttachment()
{
relay.removeListener (this);
}
void WebComboBoxParameterAttachment::sendInitialUpdate()
{
DynamicObject::Ptr object { new DynamicObject };
object->setProperty (detail::WebSliderRelayEvents::Event::eventTypeKey, "propertiesChanged");
object->setProperty ("name", parameter.getName (100));
if (auto* choiceParameter = dynamic_cast<AudioParameterChoice*> (&parameter))
object->setProperty ("choices", choiceParameter->choices);
else
object->setProperty ("choices", StringArray{});
relay.emitEvent (object.get());
attachment.sendInitialUpdate();
}
void WebComboBoxParameterAttachment::setValue (float newValue)
{
const auto normValue = parameter.convertTo0to1 (newValue);
const ScopedValueSetter<bool> svs (ignoreCallbacks, true);
relay.setValue (normValue);
}
void WebComboBoxParameterAttachment::valueChanged (float newValue)
{
if (ignoreCallbacks)
{
jassertfalse;
return;
}
attachment.setValueAsCompleteGesture (parameter.convertFrom0to1 (newValue));
}
void WebComboBoxParameterAttachment::initialUpdateRequested()
{
sendInitialUpdate();
}
#endif
} // namespace juce } // namespace juce

View file

@ -257,4 +257,144 @@ private:
bool ignoreCallbacks = false; bool ignoreCallbacks = false;
}; };
#if JUCE_WEB_BROWSER || DOXYGEN
//==============================================================================
/**
An object of this class maintains a connection between a WebSliderRelay and a
plug-in parameter.
During the lifetime of this object it keeps the two things in sync, making it
easy to connect a WebSliderRelay to a parameter. When this object is deleted,
the connection is broken. Make sure that your parameter and WebSliderRelay are
not deleted before this object!
@tags{Audio}
*/
class WebSliderParameterAttachment : private WebSliderRelay::Listener
{
public:
/** Creates a connection between a plug-in parameter and a WebSliderRelay.
@param parameter The parameter to use
@param sliderStateIn The WebSliderRelay to use
@param undoManager An optional UndoManager
*/
WebSliderParameterAttachment (RangedAudioParameter& parameterIn,
WebSliderRelay& sliderStateIn,
UndoManager* undoManager = nullptr);
/** Destructor. */
~WebSliderParameterAttachment() override;
/** Call this after setting up your slider in the case where you need to do
extra setup after constructing this attachment.
*/
void sendInitialUpdate();
private:
void setValue (float newValue);
void sliderValueChanged (WebSliderRelay*) override;
void sliderDragStarted (WebSliderRelay*) override { attachment.beginGesture(); }
void sliderDragEnded (WebSliderRelay*) override { attachment.endGesture(); }
void initialUpdateRequested (WebSliderRelay*) override { sendInitialUpdate(); }
WebSliderRelay& sliderState;
RangedAudioParameter& parameter;
ParameterAttachment attachment;
bool ignoreCallbacks = false;
};
//==============================================================================
/**
An object of this class maintains a connection between a WebToggleButtonRelay and a
plug-in parameter.
During the lifetime of this object it keeps the two things in sync, making it
easy to connect a WebToggleButtonRelay to a parameter. When this object is deleted,
the connection is broken. Make sure that your parameter and WebToggleButtonRelay are
not deleted before this object!
@tags{Audio}
*/
class WebToggleButtonParameterAttachment : private WebToggleButtonRelay::Listener
{
public:
/** Creates a connection between a plug-in parameter and a WebToggleButtonRelay.
@param parameter The parameter to use
@param button The WebToggleButtonRelay to use
@param undoManager An optional UndoManager
*/
WebToggleButtonParameterAttachment (RangedAudioParameter& parameterIn,
WebToggleButtonRelay& button,
UndoManager* undoManager = nullptr);
/** Destructor. */
~WebToggleButtonParameterAttachment() override;
/** Call this after setting up your button in the case where you need to do
extra setup after constructing this attachment.
*/
void sendInitialUpdate();
private:
void setValue (float newValue);
void toggleStateChanged (bool newValue) override;
void initialUpdateRequested() override;
WebToggleButtonRelay& relay;
RangedAudioParameter& parameter;
ParameterAttachment attachment;
bool ignoreCallbacks = false;
};
//==============================================================================
/**
An object of this class maintains a connection between a WebComboBoxRelay and a
plug-in parameter.
During the lifetime of this object it keeps the two things in sync, making it
easy to connect a WebComboBoxRelay to a parameter. When this object is deleted,
the connection is broken. Make sure that your parameter and WebComboBoxRelay are
not deleted before this object!
@tags{Audio}
*/
class WebComboBoxParameterAttachment : private WebComboBoxRelay::Listener
{
public:
/** Creates a connection between a plug-in parameter and a WebComboBoxRelay.
@param parameter The parameter to use
@param combo The WebComboBoxRelay to use
@param undoManager An optional UndoManager
*/
WebComboBoxParameterAttachment (RangedAudioParameter& parameterIn, WebComboBoxRelay& combo,
UndoManager* undoManager = nullptr);
/** Destructor. */
~WebComboBoxParameterAttachment() override;
/** Call this after setting up your combo box in the case where you need to do
extra setup after constructing this attachment.
*/
void sendInitialUpdate();
private:
void setValue (float newValue);
void valueChanged (float newValue) override;
void initialUpdateRequested() override;
WebComboBoxRelay& relay;
RangedAudioParameter& parameter;
ParameterAttachment attachment;
bool ignoreCallbacks = false;
};
#endif
} // namespace juce } // namespace juce

View file

@ -365,6 +365,7 @@ JUCE_END_IGNORE_WARNINGS_MSVC
#include "memory/juce_Reservoir.h" #include "memory/juce_Reservoir.h"
#include "files/juce_AndroidDocument.h" #include "files/juce_AndroidDocument.h"
#include "streams/juce_AndroidDocumentInputSource.h" #include "streams/juce_AndroidDocumentInputSource.h"
#include "misc/juce_OptionsHelpers.h"
#include "detail/juce_CallbackListenerList.h" #include "detail/juce_CallbackListenerList.h"

View file

@ -0,0 +1,44 @@
/*
==============================================================================
This file is part of the JUCE framework.
Copyright (c) Raw Material Software Limited
JUCE is an open source framework subject to commercial or open source
licensing.
By downloading, installing, or using the JUCE framework, or combining the
JUCE framework with any other source code, object code, content or any other
copyrightable work, you agree to the terms of the JUCE End User Licence
Agreement, and all incorporated terms including the JUCE Privacy Policy and
the JUCE Website Terms of Service, as applicable, which will bind you. If you
do not agree to the terms of these agreements, we will not license the JUCE
framework to you, and you must discontinue the installation or download
process and cease use of the JUCE framework.
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
Or:
You may also use this code under the terms of the AGPLv3:
https://www.gnu.org/licenses/agpl-3.0.en.html
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
template <typename OptionsType>
class OptionsBuilder
{
public:
virtual ~OptionsBuilder() = default;
virtual OptionsType buildOptions (const OptionsType& initialOptions) = 0;
OptionsType buildOptions() { return buildOptions (OptionsType{}); }
};

View file

@ -35,6 +35,51 @@
namespace juce namespace juce
{ {
/** A class for receiving callbacks from a Slider or WebSliderRelay.
To be told when a slider's value changes, you can register a Slider::Listener
object using Slider::addListener().
@see Slider::addListener, Slider::removeListener, WebSliderRelay::addListener,
WebSliderRelay::removeListener
*/
template <typename Emitter>
class JUCE_API SliderListener
{
public:
//==============================================================================
/** Destructor. */
virtual ~SliderListener() = default;
//==============================================================================
/** Called when the slider's value is changed.
This may be caused by dragging it, or by typing in its text entry box,
or by a call to Slider::setValue().
You can find out the new value using Slider::getValue().
@see Slider::valueChanged
*/
virtual void sliderValueChanged (Emitter*) = 0;
//==============================================================================
/** Called when the slider is about to be dragged.
This is called when a drag begins, then it's followed by multiple calls
to sliderValueChanged(), and then sliderDragEnded() is called after the
user lets go.
@see sliderDragEnded, Slider::startedDragging
*/
virtual void sliderDragStarted (Emitter*) {}
/** Called after a drag operation has finished.
@see sliderDragStarted, Slider::stoppedDragging
*/
virtual void sliderDragEnded (Emitter*) {}
};
//============================================================================== //==============================================================================
/** /**
A slider control for changing a value. A slider control for changing a value.
@ -557,48 +602,7 @@ public:
NotificationType notification = sendNotificationAsync); NotificationType notification = sendNotificationAsync);
//============================================================================== //==============================================================================
/** A class for receiving callbacks from a Slider. using Listener = SliderListener<Slider>;
To be told when a slider's value changes, you can register a Slider::Listener
object using Slider::addListener().
@see Slider::addListener, Slider::removeListener
*/
class JUCE_API Listener
{
public:
//==============================================================================
/** Destructor. */
virtual ~Listener() = default;
//==============================================================================
/** Called when the slider's value is changed.
This may be caused by dragging it, or by typing in its text entry box,
or by a call to Slider::setValue().
You can find out the new value using Slider::getValue().
@see Slider::valueChanged
*/
virtual void sliderValueChanged (Slider* slider) = 0;
//==============================================================================
/** Called when the slider is about to be dragged.
This is called when a drag begins, then it's followed by multiple calls
to sliderValueChanged(), and then sliderDragEnded() is called after the
user lets go.
@see sliderDragEnded, Slider::startedDragging
*/
virtual void sliderDragStarted (Slider*) {}
/** Called after a drag operation has finished.
@see sliderDragStarted, Slider::stoppedDragging
*/
virtual void sliderDragEnded (Slider*) {}
};
/** Adds a listener to be called when this slider's value changes. */ /** Adds a listener to be called when this slider's value changes. */
void addListener (Listener* listener); void addListener (Listener* listener);

View file

@ -0,0 +1,255 @@
/*
==============================================================================
This file is part of the JUCE framework.
Copyright (c) Raw Material Software Limited
JUCE is an open source framework subject to commercial or open source
licensing.
By downloading, installing, or using the JUCE framework, or combining the
JUCE framework with any other source code, object code, content or any other
copyrightable work, you agree to the terms of the JUCE End User Licence
Agreement, and all incorporated terms including the JUCE Privacy Policy and
the JUCE Website Terms of Service, as applicable, which will bind you. If you
do not agree to the terms of these agreements, we will not license the JUCE
framework to you, and you must discontinue the installation or download
process and cease use of the JUCE framework.
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
Or:
You may also use this code under the terms of the AGPLv3:
https://www.gnu.org/licenses/agpl-3.0.en.html
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
namespace juce::detail
{
#if JUCE_WEB_BROWSER || DOXYGEN
struct WebSliderRelayEvents
{
WebSliderRelayEvents() = delete;
struct Event
{
String eventType;
DynamicObject::Ptr object;
static std::optional<Event> extract (const var& v)
{
auto* dynObj = v.getDynamicObject();
if (dynObj == nullptr)
return std::nullopt;
const auto eventTypeProp = dynObj->getProperty (eventTypeKey);
if (! eventTypeProp.isString())
return std::nullopt;
return Event { eventTypeProp.toString(), dynObj };
}
static inline const Identifier eventTypeKey { "eventType" };
};
struct ValueChanged
{
float newValue;
static std::optional<ValueChanged> extract (const Event& event)
{
if (event.eventType != eventId.toString())
return std::nullopt;
const auto newValue = event.object->getProperty (newValueKey);
if (! (newValue.isInt() || newValue.isInt64() || newValue.isDouble()))
return std::nullopt;
return ValueChanged { (float) newValue };
}
static inline const Identifier eventId { "valueChanged" };
static inline const Identifier newValueKey { "value" };
};
struct SliderDragStarted
{
static std::optional<SliderDragStarted> extract (const Event& event)
{
if (event.eventType != eventId.toString())
return std::nullopt;
return SliderDragStarted{};
}
static inline const Identifier eventId { "sliderDragStarted" };
};
struct SliderDragEnded
{
static std::optional<SliderDragEnded> extract (const Event& event)
{
if (event.eventType != eventId.toString())
return std::nullopt;
return SliderDragEnded{};
}
static inline const Identifier eventId { "sliderDragEnded" };
};
struct InitialUpdateRequested
{
static std::optional<InitialUpdateRequested> extract (const Event& event)
{
if (event.eventType != eventId.toString())
return std::nullopt;
return InitialUpdateRequested{};
}
static inline const Identifier eventId { "requestInitialUpdate" };
};
};
//==============================================================================
struct WebToggleButtonRelayEvents
{
WebToggleButtonRelayEvents() = delete;
struct Event
{
String eventType;
DynamicObject::Ptr object;
static std::optional<Event> extract (const var& v)
{
auto* dynObj = v.getDynamicObject();
if (dynObj == nullptr)
return std::nullopt;
const auto eventTypeProp = dynObj->getProperty (eventTypeKey);
if (! eventTypeProp.isString())
return std::nullopt;
return Event { eventTypeProp.toString(), dynObj };
}
static inline const Identifier eventTypeKey { "eventType" };
};
struct ToggleStateChanged
{
bool value;
static std::optional<ToggleStateChanged> extract (const Event& event)
{
if (event.eventType != eventId.toString())
return std::nullopt;
const auto newState = event.object->getProperty (valueKey);
if (! newState.isBool())
return std::nullopt;
return ToggleStateChanged { newState };
}
static inline const Identifier eventId { "valueChanged" };
static inline const Identifier valueKey { "value" };
};
struct InitialUpdateRequested
{
static std::optional<InitialUpdateRequested> extract (const Event& event)
{
if (event.eventType != eventId.toString())
return std::nullopt;
return InitialUpdateRequested{};
}
static inline const Identifier eventId { "requestInitialUpdate" };
};
};
//==============================================================================
struct WebComboBoxRelayEvents
{
WebComboBoxRelayEvents() = delete;
struct Event
{
String eventType;
DynamicObject::Ptr object;
static std::optional<Event> extract (const var& v)
{
auto* dynObj = v.getDynamicObject();
if (dynObj == nullptr)
return std::nullopt;
const auto eventTypeProp = dynObj->getProperty (eventTypeKey);
if (! eventTypeProp.isString())
return std::nullopt;
return Event { eventTypeProp.toString(), dynObj };
}
static inline const Identifier eventTypeKey { "eventType" };
};
struct ValueChanged
{
float value;
static std::optional<ValueChanged> extract (const Event& event)
{
if (event.eventType != eventId.toString())
return std::nullopt;
const auto newValue = event.object->getProperty (valueKey);
if (! (newValue.isInt() || newValue.isInt64() || newValue.isDouble()))
return std::nullopt;
return ValueChanged { (float) newValue };
}
static inline const Identifier eventId { "valueChanged" };
static inline const Identifier valueKey { "value" };
};
struct InitialUpdateRequested
{
static std::optional<InitialUpdateRequested> extract (const Event& event)
{
if (event.eventType != eventId.toString())
return std::nullopt;
return InitialUpdateRequested{};
}
static inline const Identifier eventId { "requestInitialUpdate" };
};
};
#endif
}

View file

@ -128,6 +128,8 @@
#include <gtk/gtkx.h> #include <gtk/gtkx.h>
#include <glib-unix.h> #include <glib-unix.h>
#include <webkit2/webkit2.h> #include <webkit2/webkit2.h>
#include <jsc/jsc.h>
#include <libsoup/soup.h>
JUCE_END_IGNORE_WARNINGS_GCC_LIKE JUCE_END_IGNORE_WARNINGS_GCC_LIKE
#endif #endif
@ -150,6 +152,7 @@
#include "misc/juce_LiveConstantEditor.cpp" #include "misc/juce_LiveConstantEditor.cpp"
#include "misc/juce_AnimatedAppComponent.cpp" #include "misc/juce_AnimatedAppComponent.cpp"
#include "misc/juce_WebBrowserComponent.cpp" #include "misc/juce_WebBrowserComponent.cpp"
#include "misc/juce_WebControlRelays.cpp"
//============================================================================== //==============================================================================
#if JUCE_MAC || JUCE_IOS #if JUCE_MAC || JUCE_IOS

View file

@ -76,17 +76,43 @@
#define JUCE_WEB_BROWSER 1 #define JUCE_WEB_BROWSER 1
#endif #endif
/** Config: JUCE_USE_WIN_WEBVIEW2_WITH_STATIC_LINKING
Enables the use of the Microsoft Edge (Chromium) WebView2 browser on Windows.
If using the Projucer, the Microsoft.Web.WebView2 package will be added to the
project solution if this flag is enabled. If you are building using CMake you
will need to manually add the package via the NuGet package manager.
Using this flag requires statically linking against WebView2LoaderStatic.lib,
which at this time is only available through the NuGet package, but is missing
in VCPKG.
In addition to enabling this macro, you will need to use the
WebBrowserComponent::Options::Backend::webview2 option when instantiating the
WebBrowserComponent.
*/
#ifndef JUCE_USE_WIN_WEBVIEW2_WITH_STATIC_LINKING
#define JUCE_USE_WIN_WEBVIEW2_WITH_STATIC_LINKING 0
#else
#define JUCE_USE_WIN_WEBVIEW2 1
#endif
/** Config: JUCE_USE_WIN_WEBVIEW2 /** Config: JUCE_USE_WIN_WEBVIEW2
Enables the use of the Microsoft Edge (Chromium) WebView2 browser on Windows, Enables the use of the Microsoft Edge (Chromium) WebView2 browser on Windows.
currently in developer preview.
If using the Projucer, the Microsoft.Web.WebView2 package will be added to the If using the Projucer, the Microsoft.Web.WebView2 package will be added to the
project solution if this flag is enabled. If you are building using CMake you project solution if this flag is enabled. If you are building using CMake you
will need to manually add the package via the Visual Studio package manager. will need to manually add the package via the Visual Studio package manager.
If the WITH_STATIC_LINKING variant of this flag is also set, you must statically
link against WebView2LoaderStatic.lib, otherwise dynamic loading will be used.
See more about dynamic linking in the documentation of
WebBrowserComponent::Options::WinWebView2::withDLLLocation().
In addition to enabling this macro, you will need to use the In addition to enabling this macro, you will need to use the
WindowsWebView2WebBrowserComponent wrapper - see the documentation of that WebBrowserComponent::Options::Backend::webview2 option when instantiating the
class for more details. WebBrowserComponent.
*/ */
#ifndef JUCE_USE_WIN_WEBVIEW2 #ifndef JUCE_USE_WIN_WEBVIEW2
#define JUCE_USE_WIN_WEBVIEW2 0 #define JUCE_USE_WIN_WEBVIEW2 0
@ -130,3 +156,5 @@
#include "misc/juce_WebBrowserComponent.h" #include "misc/juce_WebBrowserComponent.h"
#include "misc/juce_LiveConstantEditor.h" #include "misc/juce_LiveConstantEditor.h"
#include "misc/juce_AnimatedAppComponent.h" #include "misc/juce_AnimatedAppComponent.h"
#include "detail/juce_WebControlRelayEvents.h"
#include "misc/juce_WebControlRelays.h"

View file

@ -43,6 +43,669 @@ bool WebBrowserComponent::pageLoadHadNetworkError ([[maybe_unused]] const String
void WebBrowserComponent::windowCloseRequest() {} void WebBrowserComponent::windowCloseRequest() {}
void WebBrowserComponent::newWindowAttemptingToLoad ([[maybe_unused]] const String& newURL) {} void WebBrowserComponent::newWindowAttemptingToLoad ([[maybe_unused]] const String& newURL) {}
// At least this much code has to be injected as user script, since the native backend functions
// rely on the presence of the `window.__JUCE__.backend.emitByBackend()` function. The rest can be
// optionally imported as JS.
static constexpr const char* lowLevelIntegrationsScript = R"(
if (
typeof window.__JUCE__ !== "undefined" &&
typeof window.__JUCE__.getAndroidUserScripts !== "undefined" &&
typeof window.inAndroidUserScriptEval === "undefined"
) {
window.inAndroidUserScriptEval = true;
eval(window.__JUCE__.getAndroidUserScripts());
delete window.inAndroidUserScriptEval;
}
{
if (typeof window.__JUCE__ === "undefined") {
console.warn(
"The 'window.__JUCE__' object is undefined." +
" Native integration features will not work." +
" Defining a placeholder 'window.__JUCE__' object."
);
window.__JUCE__ = {
postMessage: function () {},
};
}
if (typeof window.__JUCE__.initialisationData === "undefined") {
window.__JUCE__.initialisationData = {
__juce__platform: [],
__juce__functions: [],
__juce__registeredGlobalEventIds: [],
__juce__sliders: [],
__juce__toggles: [],
__juce__comboBoxes: [],
};
}
class ListenerList {
constructor() {
this.listeners = new Map();
this.listenerId = 0;
}
addListener(fn) {
const newListenerId = this.listenerId++;
this.listeners.set(newListenerId, fn);
return newListenerId;
}
removeListener(id) {
if (this.listeners.has(id)) {
this.listeners.delete(id);
}
}
callListeners(payload) {
for (const [, value] of this.listeners) {
value(payload);
}
}
}
class EventListenerList {
constructor() {
this.eventListeners = new Map();
}
addEventListener(eventId, fn) {
if (!this.eventListeners.has(eventId))
this.eventListeners.set(eventId, new ListenerList());
const id = this.eventListeners.get(eventId).addListener(fn);
return [eventId, id];
}
removeEventListener([eventId, id]) {
if (this.eventListeners.has(eventId)) {
this.eventListeners.get(eventId).removeListener(id);
}
}
emitEvent(eventId, object) {
if (this.eventListeners.has(eventId))
this.eventListeners.get(eventId).callListeners(object);
}
}
class Backend {
constructor() {
this.listeners = new EventListenerList();
}
addEventListener(eventId, fn) {
return this.listeners.addEventListener(eventId, fn);
}
removeEventListener([eventId, id]) {
this.listeners.removeEventListener(eventId, id);
}
emitEvent(eventId, object) {
window.__JUCE__.postMessage(
JSON.stringify({ eventId: eventId, payload: object })
);
}
emitByBackend(eventId, object) {
this.listeners.emitEvent(eventId, JSON.parse(object));
}
}
if (typeof window.__JUCE__.backend === "undefined")
window.__JUCE__.backend = new Backend();
}
)";
static void evaluationHandler (WebBrowserComponent::EvaluationResult r)
{
if (r.getResult() == nullptr)
{
// The unsupported return type means a successful Javascript evaluation that yielded a
// result that cannot be translated and returned to native code such as a Promise.
jassert (r.getError()->type == WebBrowserComponent::EvaluationResult::Error::Type::unsupportedReturnType);
DBG (r.getError()->message);
return;
}
}
static StringArray getUserScriptsForInitialisationData (const std::vector<std::pair<String, var>>& data)
{
std::map<String, StringArray> sortedData;
for (const auto& [key, value] : data)
sortedData[key].add (JSON::toString (value));
StringArray result;
for (const auto& [key, values] : sortedData)
result.add ("window.__JUCE__.initialisationData." + key + " = ["
+ values.joinIntoString (",") + "];");
return result;
}
template <typename T>
static auto getCommaSeparatedList (const T& mapOfStringable)
{
StringArray keys;
for (auto it : mapOfStringable)
keys.add (it.first.toString().quoted());
return keys.joinIntoString (",");
}
struct NativeEvents
{
NativeEvents() = delete;
struct NativeEvent
{
String eventId;
var payload;
static constexpr std::optional<int> marshallingVersion = std::nullopt;
template <typename Archive, typename Item>
static void serialise (Archive& archive, Item& item)
{
archive (named ("eventId", item.eventId),
named ("payload", item.payload));
}
};
struct Invoke
{
String name;
var params;
int64 resultId;
static constexpr std::optional<int> marshallingVersion = std::nullopt;
template <typename Archive, typename Item>
static void serialise (Archive& archive, Item& item)
{
archive (named ("name", item.name),
named ("params", item.params),
named ("resultId", item.resultId));
}
static inline const Identifier eventId { "__juce__invoke" };
static inline const Identifier completeId { "__juce__complete" };
};
};
class NativeFunctionsProvider : public OptionsBuilder<WebBrowserComponent::Options>,
private AsyncUpdater
{
public:
explicit NativeFunctionsProvider (WebBrowserComponent& ownerIn)
: owner (ownerIn)
{
}
WebBrowserComponent::Options buildOptions (const WebBrowserComponent::Options& initialOptions) override
{
nativeFunctions = initialOptions.getNativeFunctions();
if (nativeFunctions.empty())
return initialOptions;
auto options = initialOptions.withNativeIntegrationEnabled()
.withEventListener (NativeEvents::Invoke::eventId,
[this] (const auto& object)
{
handleNativeFunctionCall (object);
});
for (auto it : nativeFunctions)
options = options.withInitialisationData ("__juce__functions", it.first.toString());
return options;
}
private:
void handleAsyncUpdate() override
{
const auto popFront = [&] (auto&& callback)
{
functionCompletionsMutex.lock();
ErasedScopeGuard unlocker { [&] { functionCompletionsMutex.unlock(); } };
if (! functionCompletions.empty())
{
auto completion = functionCompletions.front();
functionCompletions.pop_front();
unlocker.reset();
callback (completion);
return true;
}
else
{
return false;
}
};
while (popFront ([&] (const auto& c) { emitCompletionEvent (c.first, c.second); }))
;
}
void handleNativeFunctionCall (const var& object)
{
const auto invocation = FromVar::convert<NativeEvents::Invoke> (object);
if (! invocation.has_value())
{
jassertfalse;
return;
}
auto it = nativeFunctions.find (invocation->name);
if (it == nativeFunctions.end())
{
jassertfalse;
return;
}
jassert (invocation->params.isArray());
it->second (*invocation->params.getArray(),
[this, resultId = invocation->resultId] (auto result)
{
completeNativeFunctionCall (resultId, result);
});
}
void completeNativeFunctionCall (int64 resultId, const var& object)
{
if (MessageManager::getInstance()->isThisTheMessageThread())
{
emitCompletionEvent (resultId, object);
}
else
{
const std::lock_guard lock { functionCompletionsMutex };
functionCompletions.push_back (std::make_pair (resultId, object));
triggerAsyncUpdate();
}
}
void emitCompletionEvent (int64 resultId, const var& object)
{
DynamicObject::Ptr eventObject { new DynamicObject() };
eventObject->setProperty ("promiseId", resultId);
eventObject->setProperty ("result", object);
jassert (owner.isVisible());
owner.emitEventIfBrowserIsVisible (NativeEvents::Invoke::completeId, eventObject.get());
}
WebBrowserComponent& owner;
std::map<Identifier, WebBrowserComponent::NativeFunction> nativeFunctions;
std::deque<std::pair<int64, var>> functionCompletions;
std::mutex functionCompletionsMutex;
JUCE_DECLARE_NON_COPYABLE (NativeFunctionsProvider)
JUCE_DECLARE_NON_MOVEABLE (NativeFunctionsProvider)
};
class NativeEventListeners
{
public:
void addListener (const Identifier& eventId, std::function<void (const var&)> handler)
{
listeners.push_back (std::move (handler));
listenerMap[eventId].add (&listeners.back());
}
void emit (const Identifier& eventId, const var& object)
{
if (const auto& it = listenerMap.find (eventId); it != listenerMap.end())
it->second.call ([&object] (auto& l) { l (object); });
}
private:
std::list<WebBrowserComponent::NativeEventListener> listeners;
std::map<Identifier, ListenerList<WebBrowserComponent::NativeEventListener>> listenerMap;
};
class WebBrowserComponent::Impl
{
public:
Impl (WebBrowserComponent& ownerIn, const Options& optionsIn)
: owner (ownerIn),
options ([&]
{
makeFunctionsProviderIfNecessary (nativeFunctionsProvider, *this, optionsIn);
if (nativeFunctionsProvider.has_value())
return getOptions (optionsIn).withOptionsFrom (*nativeFunctionsProvider);
return getOptions (optionsIn);
}())
{
auto userScripts = options.getUserScripts();
// Adding user scripts in reverse order of depending on each other. The most depended on
// comes last.
for (const auto& eventListener : options.getEventListeners())
{
userScripts.insert (0,
"window.__JUCE__.initialisationData.__juce__registeredGlobalEventIds = ["
+ getCommaSeparatedList (options.getEventListeners()) + "];");
addPermanentEventListener (eventListener.first, eventListener.second);
}
for (const auto& script : getUserScriptsForInitialisationData (options.getInitialisationData()))
userScripts.insert (0, script);
userScripts.insert (0, lowLevelIntegrationsScript);
platform = createAndInitPlatformDependentPart (*this, options, userScripts);
}
void emitEvent (const Identifier& eventId, const var& object)
{
evaluateJavascript ("window.__JUCE__.backend.emitByBackend(" + eventId.toString().quoted() + ", "
+ JSON::toString (object, true).quoted ('\'') + ");", evaluationHandler);
}
void goToURL (const String& url, const StringArray* headers, const MemoryBlock* postData)
{
platform->goToURL (url, headers, postData);
}
void stop()
{
platform->stop();
}
void goBack()
{
platform->goBack();
owner.lastURL.clear();
owner.blankPageShown = false;
}
void goForward()
{
owner.lastURL.clear();
platform->goForward();
}
void refresh()
{
platform->refresh();
}
void evaluateJavascript (const String& script, EvaluationCallback callback)
{
platform->evaluateJavascript (script, std::move (callback));
}
void setSize (int width, int height)
{
platform->setWebViewSize (width, height);
}
void checkWindowAssociation()
{
platform->checkWindowAssociation();
}
void fallbackPaint (Graphics& webBrowserComponentContext)
{
platform->fallbackPaint (webBrowserComponentContext);
}
void focusGainedWithDirection (FocusChangeType type, FocusChangeDirection dir)
{
platform->focusGainedWithDirection (type, dir);
}
struct Platform;
private:
class PlatformInterface
{
public:
PlatformInterface() = default;
virtual ~PlatformInterface() = default;
virtual void goToURL (const String&, const StringArray*, const MemoryBlock*) = 0;
virtual void goBack() = 0;
virtual void goForward() = 0;
virtual void stop() = 0;
virtual void refresh() = 0;
virtual void evaluateJavascript (const String&, WebBrowserComponent::EvaluationCallback) = 0;
virtual void setWebViewSize (int, int) = 0;
virtual void checkWindowAssociation() = 0;
virtual void focusGainedWithDirection (FocusChangeType, FocusChangeDirection) {}
virtual void fallbackPaint (Graphics&) {}
};
static void makeFunctionsProviderIfNecessary (std::optional<NativeFunctionsProvider>& provider,
WebBrowserComponent::Impl& impl,
const WebBrowserComponent::Options& options)
{
if (! options.getNativeFunctions().empty())
provider.emplace (impl.owner);
}
static Options getOptions (const Options& optionsIn)
{
const auto os = SystemStats::getOperatingSystemType();
const auto platformString = [&]
{
using OsType = SystemStats::OperatingSystemType;
if ((os & OsType::MacOSX) != 0)
return "macos";
if ((os & OsType::iOS) != 0)
return "ios";
if ((os & OsType::Windows) != 0)
return "windows";
if ((os & OsType::Android) != 0)
return "android";
if ((os & OsType::Linux) != 0)
return "linux";
return "";
}();
return optionsIn.withInitialisationData ("__juce__platform", platformString);
}
void addPermanentEventListener (const Identifier& eventId, NativeEventListener listener)
{
nativeEventListeners.addListener (eventId, std::move (listener));
}
std::optional<Resource> handleResourceRequest (const String& url)
{
if (resourceProvider != nullptr)
return resourceProvider (url);
return std::nullopt;
}
void handleNativeEvent (const var& message)
{
const auto event = FromVar::convert<NativeEvents::NativeEvent> (message);
if (! event.has_value())
{
jassertfalse;
return;
}
nativeEventListeners.emit (event->eventId, event->payload);
}
static std::unique_ptr<PlatformInterface> createAndInitPlatformDependentPart (WebBrowserComponent::Impl&,
const Options&,
const StringArray&);
WebBrowserComponent& owner;
std::optional<NativeFunctionsProvider> nativeFunctionsProvider;
Options options;
ResourceProvider resourceProvider { options.getResourceProvider() };
NativeEventListeners nativeEventListeners;
std::unique_ptr<PlatformInterface> platform;
};
//==============================================================================
WebBrowserComponent::WebBrowserComponent (const Options& options)
: impl (std::make_unique<Impl> (*this, options)),
unloadPageWhenHidden (! options.keepsPageLoadedWhenBrowserIsHidden())
{
setOpaque (true);
#if JUCE_LINUX
ignoreUnused (blankPageShown);
ignoreUnused (unloadPageWhenHidden);
#endif
}
WebBrowserComponent::~WebBrowserComponent() = default;
void WebBrowserComponent::emitEventIfBrowserIsVisible (const Identifier& eventId, const var& object)
{
if (isVisible())
impl->emitEvent (eventId, object);
}
const String& WebBrowserComponent::getResourceProviderRoot()
{
const auto os = SystemStats::getOperatingSystemType();
using OsType = SystemStats::OperatingSystemType;
if ( (os & OsType::MacOSX) != 0
|| (os & OsType::iOS) != 0
|| (os & OsType::Linux) != 0)
{
static String backendUrl { "juce://juce.backend/" };
return backendUrl;
}
if ( (os & OsType::Windows) != 0
|| (os & OsType::Android) != 0)
{
static String backendUrl { "https://juce.backend/" };
return backendUrl;
}
static String emptyUrl { "" };
return emptyUrl;
}
void WebBrowserComponent::goToURL (const String& url,
const StringArray* headers,
const MemoryBlock* postData)
{
lastURL = url;
if (headers != nullptr)
lastHeaders = *headers;
else
lastHeaders.clear();
if (postData != nullptr)
lastPostData = *postData;
else
lastPostData.reset();
blankPageShown = false;
impl->goToURL (url, headers, postData);
}
void WebBrowserComponent::stop()
{
impl->stop();
}
void WebBrowserComponent::goBack()
{
impl->goBack();
lastURL.clear();
blankPageShown = false;
}
void WebBrowserComponent::goForward()
{
lastURL.clear();
impl->goForward();
}
void WebBrowserComponent::refresh()
{
impl->refresh();
}
void WebBrowserComponent::paint (Graphics& g)
{
impl->fallbackPaint (g);
}
void WebBrowserComponent::parentHierarchyChanged()
{
impl->checkWindowAssociation();
}
void WebBrowserComponent::visibilityChanged()
{
impl->checkWindowAssociation();
}
void WebBrowserComponent::resized()
{
impl->setSize (getWidth(), getHeight());
}
void WebBrowserComponent::reloadLastURL()
{
const auto ptrOrNullIfEmpty = [] (auto& value)
{
return ! value.isEmpty() ? &value : nullptr;
};
if (lastURL.isNotEmpty())
{
goToURL (lastURL, ptrOrNullIfEmpty (lastHeaders), ptrOrNullIfEmpty (lastPostData));
lastURL.clear();
}
}
void WebBrowserComponent::evaluateJavascript (const String& script, EvaluationCallback callback)
{
impl->evaluateJavascript (script, std::move (callback));
}
void WebBrowserComponent::focusGainedWithDirection (FocusChangeType type,
FocusChangeDirection direction)
{
impl->focusGainedWithDirection (type, direction);
}
#endif #endif
} // namespace juce } // namespace juce

View file

@ -37,6 +37,16 @@ namespace juce
#if JUCE_WEB_BROWSER || DOXYGEN #if JUCE_WEB_BROWSER || DOXYGEN
#if (JUCE_MAC && (defined (MAC_OS_X_VERSION_10_13) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_13))) \
|| (JUCE_IOS && (defined (__IPHONE_11_0) && (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_11_0))) \
|| (JUCE_WINDOWS && JUCE_USE_WIN_WEBVIEW2) \
|| JUCE_ANDROID \
|| JUCE_LINUX
#define JUCE_WEB_BROWSER_RESOURCE_PROVIDER_AVAILABLE 1
#else
#define JUCE_WEB_BROWSER_RESOURCE_PROVIDER_AVAILABLE 0
#endif
//============================================================================== //==============================================================================
/** /**
A component that displays an embedded web browser. A component that displays an embedded web browser.
@ -54,6 +64,37 @@ namespace juce
class JUCE_API WebBrowserComponent : public Component class JUCE_API WebBrowserComponent : public Component
{ {
public: public:
//==============================================================================
/** Type for a listener registered with Options::withNativeEventListener. */
using NativeEventListener = std::function<void (var)>;
/** Type for the completion passed as the second parameter of NativeFunction. Can be called
from any thread.
*/
using NativeFunctionCompletion = std::function<void (var)>;
/** Type for functions registered with Options::withNativeFunction. The first parameter is an
Array object containing the arguments of the Javascript function invocation.
The second parameter is the result that completes the Promise returned by the Javascript
function call. It can be called from any thread.
*/
using NativeFunction = std::function<void (const Array<var>&, NativeFunctionCompletion)>;
/** A resource returned by a ResourceProvider.
@see Options::withResourceProvider
*/
struct Resource
{
std::vector<std::byte> data;
String mimeType;
};
/** The type used in Options::withResourceProvider.
*/
using ResourceProvider = std::function<std::optional<Resource> (const String&)>;
//============================================================================== //==============================================================================
/** /**
Options to configure WebBrowserComponent. Options to configure WebBrowserComponent.
@ -105,7 +146,7 @@ public:
handy to stop the browser using resources in the background when it's not handy to stop the browser using resources in the background when it's not
actually being used. actually being used.
*/ */
[[nodiscard]] Options withKeepPageLoadedWhenBrowserIsHidden() const { return withMember (*this, &Options::keepPageLoadedWhenBrowserIsHidden, true); } [[nodiscard]] Options withKeepPageLoadedWhenBrowserIsHidden() const { return withMember (*this, &Options::keepPageLoadedWhenBrowserIsHidden, true); }
/** /**
Use a specific user agent string when requesting web pages. Use a specific user agent string when requesting web pages.
@ -125,7 +166,13 @@ public:
*/ */
[[nodiscard]] WinWebView2 withDLLLocation (const File& location) const { return withMember (*this, &WinWebView2::dllLocation, location); } [[nodiscard]] WinWebView2 withDLLLocation (const File& location) const { return withMember (*this, &WinWebView2::dllLocation, location); }
/** Sets a non-default location for storing user data for the browser instance. */ /** Sets a non-default location for storing user data for the browser instance.
In plugin projects you may find it necessary to use this option and specify a
location such as File::SpecialLocationType::tempDirectory. Otherwise WebView2
may function incorrectly due to being denied access to the default user data
location.
*/
[[nodiscard]] WinWebView2 withUserDataFolder (const File& folder) const { return withMember (*this, &WinWebView2::userDataFolder, folder); } [[nodiscard]] WinWebView2 withUserDataFolder (const File& folder) const { return withMember (*this, &WinWebView2::userDataFolder, folder); }
/** If this is set, the status bar usually displayed in the lower-left of the webview /** If this is set, the status bar usually displayed in the lower-left of the webview
@ -165,23 +212,157 @@ public:
Colour backgroundColour; Colour backgroundColour;
}; };
/** Specifies options that apply to the Windows implementation when the WebView2 feature is
enabled.
@see withBackend
*/
[[nodiscard]] Options withWinWebView2Options (const WinWebView2& winWebView2Options) const [[nodiscard]] Options withWinWebView2Options (const WinWebView2& winWebView2Options) const
{ {
return withMember (*this, &Options::winWebView2, winWebView2Options); return withMember (*this, &Options::winWebView2, winWebView2Options);
} }
/** Enables native integration features for the code running inside the WebBrowserComponent.
This injects data and function objects under `window.__JUCE__.backend` through which
scripts running in the WebBrowserComponent can send events to the backend and call
registered native functions.
You should only enable native integrations if you have full control over the content
loaded into the component. Navigating to 3rd party websites with these integrations
enabled may expose the application and the computer to security risks.
@see withNativeFunction, withEventListener
*/
[[nodiscard]] Options withNativeIntegrationEnabled (bool enabled = true) const
{
return withMember (*this, &Options::enableNativeIntegration, enabled);
}
/** Registers a NativeFunction under the given name.
To call this function from the frontend, you can import the JUCE frontend helper module
or issue a call to the low-level frontend API.
@code
import { getNativeFunction } from "./juce";
function someJavascriptFunction() {
const myBackendFunction = getNativeFunction("myBackendFunction");
myBackendFunction (1, 2, "some string");
}
@endcode
*/
[[nodiscard]] Options withNativeFunction (const Identifier& name, NativeFunction callback) const
{
auto copy = *this;
jassert (copy.nativeFunctions.count (name) == 0);
copy.nativeFunctions[name] = std::move (callback);
return copy;
}
/** Registers a NativeEventListener that receives events sent to the specified eventId.
To send a message to this listener from the frontend, call for example
@code window.__JUCE__.backend.emitEvent(eventId, { x: 2, y: 6 }); @endcode
*/
[[nodiscard]] Options withEventListener (const Identifier& eventId, NativeEventListener listener) const
{
auto copy = *this;
copy.eventListeners.emplace_back (eventId, std::move (listener));
return copy;
}
/** Adds a Javascript code that will be evaluated before any other resource is loaded but
after the JUCE backend definitions become available, hence the specified script can
rely on the presence of `window.__JUCE__.backend`.
This script will be evaluated after all goToUrl() calls.
*/
[[nodiscard]] Options withUserScript (StringRef script) const
{
auto copy = *this;
copy.userScripts.add (script);
return copy;
}
/** Ensures that there will be a Javascript Array under
`window.__JUCE__.backend.initialisationData.name` and that it will contain the value
provided here.
The initialisation data is injected prior to loading any resource. Multiple values added
for the same name will all be available in the Array.
*/
[[nodiscard]] Options withInitialisationData (StringRef name, const var& value) const
{
auto copy = *this;
copy.initialisationData.push_back (std::make_pair (String { name }, value));
return copy;
}
#if JUCE_WEB_BROWSER_RESOURCE_PROVIDER_AVAILABLE || JUCE_DOXYGEN
/** Sets a ResourceProvider object that can complete WebView resource requests and return
data without having to issue a network operation.
Requests sent to WebBrowserComponent::getResourceProviderRoot() + "resource.path" will
invoke the provider with the path "/resource.path".
If you call WebBrowserComponent::goToURL with the value returned by
WebBrowserComponent::getResourceProviderRoot, your resource provider will receive a
request for the resource "/" for which you will typically want to return the contents of
your index.html.
You can also specify an optional allowedOriginIn parameter that will make your
ResourceProvider available to scripts loaded from that origin. E.g. if you specify
"http://localhost:3000", then a script loaded from such a local development server will
be able to access resources such as getResourceProviderRoot() + "live_data.bin".
Allowing external origins is handy for development, but is a potential security risk in
publicly released binaries.
*/
[[nodiscard]] Options withResourceProvider (ResourceProvider provider,
std::optional<String> allowedOriginIn = std::nullopt) const
{
return withMember (withMember (*this, &Options::resourceProvider, std::move (provider)),
&Options::allowedOrigin,
std::move (allowedOriginIn));
}
#endif
/** Adds all options provided by the builder to the returned Options object.
*/
template <typename OptionsType>
OptionsType withOptionsFrom (OptionsBuilder<OptionsType>& builder) const
{
return builder.buildOptions (static_cast<const OptionsType&> (*this));
}
//============================================================================== //==============================================================================
Backend getBackend() const noexcept { return browserBackend; } auto getBackend() const noexcept { return browserBackend; }
bool keepsPageLoadedWhenBrowserIsHidden() const noexcept { return keepPageLoadedWhenBrowserIsHidden; } auto keepsPageLoadedWhenBrowserIsHidden() const noexcept { return keepPageLoadedWhenBrowserIsHidden; }
String getUserAgent() const { return userAgent; } auto getUserAgent() const { return userAgent; }
WinWebView2 getWinWebView2BackendOptions() const { return winWebView2; } auto getWinWebView2BackendOptions() const { return winWebView2; }
auto getNativeIntegrationsEnabled() const { return enableNativeIntegration; }
const auto& getNativeFunctions() const { return nativeFunctions; }
const auto& getEventListeners() const { return eventListeners; }
const auto& getUserScripts() const { return userScripts; }
const auto& getInitialisationData() const { return initialisationData; }
auto getResourceProvider() const { return resourceProvider; }
const auto& getAllowedOrigin() const { return allowedOrigin; }
private: private:
//============================================================================== //==============================================================================
Backend browserBackend = Backend::defaultBackend; Backend browserBackend = Backend::defaultBackend;
bool keepPageLoadedWhenBrowserIsHidden = false; bool keepPageLoadedWhenBrowserIsHidden = false;
bool enableNativeIntegration = false;
String userAgent; String userAgent;
WinWebView2 winWebView2; WinWebView2 winWebView2;
std::map<Identifier, NativeFunction> nativeFunctions;
std::vector<std::pair<Identifier, NativeEventListener>> eventListeners;
StringArray userScripts;
std::vector<std::pair<String, var>> initialisationData;
ResourceProvider resourceProvider;
std::optional<String> allowedOrigin;
}; };
//============================================================================== //==============================================================================
@ -230,6 +411,101 @@ public:
/** Clear cookies that the OS has stored for the WebComponents of this application */ /** Clear cookies that the OS has stored for the WebComponents of this application */
static void clearCookies(); static void clearCookies();
/** Returns a platform specific string that represents the root address for resources served
by the ResourceProvider.
If you pass this value to goToURL the ResourceProvider will receive a request with the "/"
path parameter. In response to this request the provider may typically want to return the
contents of the "index.html" file.
@see ResourceProvider, Options::withResourceProvider, goToURL
*/
static const String& getResourceProviderRoot();
//==============================================================================
/** On MacOS, iOS and Linux getResult will return a nullptr if the evaluation failed. In this
case getError will return a non-null Error result, which contains more information about
why the evaluation failed. It could be e.g. a syntax error or referencing an undefined
object.
On Windows and Android getResult will always return a valid pointer to a variant, and
getError will always return a nullptr. In case there was an evaluation failure, getResult
returns a void variant, which is indistinguishable from a successful evaluation that yielded
a null result. Unfortunately these platforms don't offer a way to detect evaluation errors.
*/
class EvaluationResult
{
public:
struct Error
{
enum class Type
{
/** Error occurring for a reason unknown to us. */
unknown,
/** Error occurring because of a Javascript exception being thrown. */
javascriptException,
/** Error occurring because the returned result cannot be serialised into a native
type e.g. Promise.
*/
unsupportedReturnType
};
Type type;
String message;
};
EvaluationResult (const var& result) : value { result }
{
}
EvaluationResult (const Error& error) : value { error }
{
}
const var* getResult() const
{
return std::get_if<var> (&value);
}
const Error* getError() const
{
return std::get_if<Error> (&value);
}
private:
std::variant<var, Error> value;
};
/** Callback type that can be passed optionally to evaluateJavascript. */
using EvaluationCallback = std::function<void (EvaluationResult)>;
/** Evaluates the specified script in the context of the current state of the
WebBrowserComponent.
If the optional callback is provided it will be called with the result of the evaluation.
The callback will be called on the message thread.
*/
void evaluateJavascript (const String& script, EvaluationCallback callback = nullptr);
/** Emits an object on the frontend under the specified eventId.
Ids beginning with `__juce` are reserved for the framework implementation.
Example for listening to such events on the frontend:
@code
// Subscribing
const removalToken = window.__JUCE__.backend.addEventListener(eventId, (objectFromBackend) => {
console.log(objectFromBackend.message);
});
// Unsubscribing
window.__JUCE__.backend.removeEventListener(removalToken);
@endcode
*/
void emitEventIfBrowserIsVisible (const Identifier& eventId, const var& object);
//============================================================================== //==============================================================================
/** This callback is called when the browser is about to navigate /** This callback is called when the browser is about to navigate
to a new location. to a new location.
@ -279,7 +555,7 @@ public:
void focusGainedWithDirection (FocusChangeType, FocusChangeDirection) override; void focusGainedWithDirection (FocusChangeType, FocusChangeDirection) override;
/** @internal */ /** @internal */
class Pimpl; class Impl;
private: private:
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override
@ -287,15 +563,13 @@ private:
return std::make_unique<AccessibilityHandler> (*this, AccessibilityRole::group); return std::make_unique<AccessibilityHandler> (*this, AccessibilityRole::group);
} }
//============================================================================== std::unique_ptr<Impl> impl;
std::unique_ptr<Pimpl> browser;
bool blankPageShown = false, unloadPageWhenHidden; bool blankPageShown = false, unloadPageWhenHidden;
String lastURL; String lastURL;
StringArray lastHeaders; StringArray lastHeaders;
MemoryBlock lastPostData; MemoryBlock lastPostData;
void reloadLastURL(); void reloadLastURL();
void checkWindowAssociation();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebBrowserComponent) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebBrowserComponent)
}; };

View file

@ -0,0 +1,256 @@
/*
==============================================================================
This file is part of the JUCE framework.
Copyright (c) Raw Material Software Limited
JUCE is an open source framework subject to commercial or open source
licensing.
By downloading, installing, or using the JUCE framework, or combining the
JUCE framework with any other source code, object code, content or any other
copyrightable work, you agree to the terms of the JUCE End User Licence
Agreement, and all incorporated terms including the JUCE Privacy Policy and
the JUCE Website Terms of Service, as applicable, which will bind you. If you
do not agree to the terms of these agreements, we will not license the JUCE
framework to you, and you must discontinue the installation or download
process and cease use of the JUCE framework.
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
Or:
You may also use this code under the terms of the AGPLv3:
https://www.gnu.org/licenses/agpl-3.0.en.html
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
namespace juce
{
#if JUCE_WEB_BROWSER
WebSliderRelay::WebSliderRelay (WebBrowserComponent& browserIn, StringRef nameIn)
: browser (browserIn),
name (nameIn)
{
}
void WebSliderRelay::setValue (float newValue)
{
using namespace detail;
DynamicObject::Ptr object { new DynamicObject };
object->setProperty (WebSliderRelayEvents::Event::eventTypeKey,
WebSliderRelayEvents::ValueChanged::eventId.toString());
object->setProperty (WebSliderRelayEvents::ValueChanged::newValueKey, newValue);
value = newValue;
emitEvent (object.get());
}
float WebSliderRelay::getValue() const
{
return value;
}
void WebSliderRelay::addListener (Listener* l)
{
listeners.add (l);
}
void WebSliderRelay::removeListener (Listener* l)
{
listeners.remove (l);
}
WebBrowserComponent::Options WebSliderRelay::buildOptions (const WebBrowserComponent::Options& initialOptions)
{
return initialOptions
.withEventListener (eventId, [this] (auto object) { handleEvent (object); })
.withInitialisationData ("__juce__sliders", name);
}
void WebSliderRelay::emitEvent (const var& payload)
{
browser.emitEventIfBrowserIsVisible (eventId, payload);
}
void WebSliderRelay::handleEvent (const var& event)
{
using namespace detail;
if (const auto sliderEvent = WebSliderRelayEvents::Event::extract (event))
{
if (const auto valueChanged = WebSliderRelayEvents::ValueChanged::extract (*sliderEvent))
{
if (! approximatelyEqual (std::exchange (value, valueChanged->newValue), valueChanged->newValue))
listeners.call ([this] (Listener& l) { l.sliderValueChanged (this); });
return;
}
if (const auto dragStarted = WebSliderRelayEvents::SliderDragStarted::extract (*sliderEvent))
{
listeners.call ([this] (Listener& l) { l.sliderDragStarted (this); });
return;
}
if (const auto dragEnded = WebSliderRelayEvents::SliderDragEnded::extract (*sliderEvent))
{
listeners.call ([this] (Listener& l) { l.sliderDragEnded (this); });
return;
}
if (const auto initialUpdate =
WebSliderRelayEvents::InitialUpdateRequested::extract (*sliderEvent))
{
listeners.call ([this] (Listener& l) { l.initialUpdateRequested (this); });
return;
}
}
const auto s = JSON::toString (event);
jassertfalse;
}
//==============================================================================
WebToggleButtonRelay::WebToggleButtonRelay ([[maybe_unused]] WebBrowserComponent& browserIn, StringRef nameIn)
: browser (browserIn),
name (nameIn)
{
}
void WebToggleButtonRelay::setToggleState (bool newState)
{
using namespace detail;
DynamicObject::Ptr object { new DynamicObject };
object->setProperty (WebToggleButtonRelayEvents::Event::eventTypeKey,
WebToggleButtonRelayEvents::ToggleStateChanged::eventId.toString());
object->setProperty (WebToggleButtonRelayEvents::ToggleStateChanged::valueKey, newState);
emitEvent (object.get());
}
void WebToggleButtonRelay::addListener (Listener* l)
{
listeners.add (l);
}
void WebToggleButtonRelay::removeListener (Listener* l)
{
listeners.remove (l);
}
WebBrowserComponent::Options WebToggleButtonRelay::buildOptions (const WebBrowserComponent::Options& initialOptions)
{
return initialOptions
.withEventListener (eventId, [this] (auto object) { handleEvent (object); })
.withInitialisationData ("__juce__toggles", name);
}
void WebToggleButtonRelay::emitEvent (const var& payload)
{
browser.emitEventIfBrowserIsVisible (eventId, payload);
}
void WebToggleButtonRelay::handleEvent (const var& event)
{
using namespace detail;
if (const auto buttonEvent = WebToggleButtonRelayEvents::Event::extract (event))
{
if (const auto toggleStateChanged = WebToggleButtonRelayEvents::ToggleStateChanged::extract (*buttonEvent))
{
listeners.call ([&toggleStateChanged] (Listener& l)
{ l.toggleStateChanged (toggleStateChanged->value); });
return;
}
if (const auto initialUpdate = WebToggleButtonRelayEvents::InitialUpdateRequested::extract (*buttonEvent))
{
listeners.call ([] (Listener& l) { l.initialUpdateRequested(); });
return;
}
}
const auto s = JSON::toString (event);
jassertfalse;
}
//==============================================================================
WebComboBoxRelay::WebComboBoxRelay ([[maybe_unused]] WebBrowserComponent& browserIn, StringRef nameIn)
: browser (browserIn),
name (nameIn)
{
}
void WebComboBoxRelay::setValue (float newValue)
{
using namespace detail;
DynamicObject::Ptr object { new DynamicObject };
object->setProperty (WebComboBoxRelayEvents::Event::eventTypeKey,
WebComboBoxRelayEvents::ValueChanged::eventId.toString());
object->setProperty (WebComboBoxRelayEvents::ValueChanged::valueKey, newValue);
emitEvent (object.get());
}
void WebComboBoxRelay::addListener (Listener* l)
{
listeners.add (l);
}
void WebComboBoxRelay::removeListener (Listener* l)
{
listeners.remove (l);
}
WebBrowserComponent::Options WebComboBoxRelay::buildOptions (const WebBrowserComponent::Options& initialOptions)
{
return initialOptions
.withEventListener (eventId, [this] (auto object) { handleEvent (object); })
.withInitialisationData ("__juce__comboBoxes", name);
}
void WebComboBoxRelay::emitEvent (const var& payload)
{
browser.emitEventIfBrowserIsVisible (eventId, payload);
}
void WebComboBoxRelay::handleEvent (const var& event)
{
using namespace detail;
if (const auto buttonEvent = WebComboBoxRelayEvents::Event::extract (event))
{
if (const auto valueChanged = WebComboBoxRelayEvents::ValueChanged::extract (*buttonEvent))
{
listeners.call ([&valueChanged] (Listener& l)
{ l.valueChanged (valueChanged->value); });
return;
}
if (const auto initialUpdate = WebComboBoxRelayEvents::InitialUpdateRequested::extract (*buttonEvent))
{
listeners.call ([] (Listener& l) { l.initialUpdateRequested(); });
return;
}
}
const auto s = JSON::toString (event);
jassertfalse;
}
#endif
} // namespace juce

View file

@ -0,0 +1,248 @@
/*
==============================================================================
This file is part of the JUCE framework.
Copyright (c) Raw Material Software Limited
JUCE is an open source framework subject to commercial or open source
licensing.
By downloading, installing, or using the JUCE framework, or combining the
JUCE framework with any other source code, object code, content or any other
copyrightable work, you agree to the terms of the JUCE End User Licence
Agreement, and all incorporated terms including the JUCE Privacy Policy and
the JUCE Website Terms of Service, as applicable, which will bind you. If you
do not agree to the terms of these agreements, we will not license the JUCE
framework to you, and you must discontinue the installation or download
process and cease use of the JUCE framework.
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
Or:
You may also use this code under the terms of the AGPLv3:
https://www.gnu.org/licenses/agpl-3.0.en.html
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
namespace juce
{
#if JUCE_WEB_BROWSER || DOXYGEN
/** Helper class that relays audio parameter information to an object inside a WebBrowserComponent.
In order to create a relay you need to specify a WebBrowserComponent object and an identifier
for the relayed state. This will result in a Javascript object becoming available inside the
WebBrowserComponent under the provided identifier.
You can then use a WebSliderParameterAttachment as you would a SliderAttachment, to attach the
relay to a RangedAudioParameter. This will synchronise the state and events of the Javascript
object with the audio parameter at all times.
@code
// Add a relay to your AudioProcessorEditor members
WebSliderRelay cutoffSliderRelay { webComponent, "cutoffSlider" };
@endcode
@code
// In your Javascript GUI code you obtain an object from the framework
import * as Juce from "juce-framework-frontend";
const sliderState = Juce.getSliderState("cutoffSlider");
@endcode
@see WebSliderParameterAttachment
*/
class JUCE_API WebSliderRelay : public OptionsBuilder<WebBrowserComponent::Options>
{
public:
/** Creating a relay will ensure that a Javascript object under the provided name will be
available in the specified WebBrowserComponent's context. Use the frontend framework's
getSliderState function with the same name to get a hold of this object.
*/
WebSliderRelay (WebBrowserComponent& browserIn, StringRef nameIn);
//==============================================================================
/** @internal */
struct Listener : public SliderListener<WebSliderRelay>
{
virtual void initialUpdateRequested (WebSliderRelay*) = 0;
};
/** @internal */
void setValue (float newValue);
/** @internal */
float getValue() const;
/** @internal */
void addListener (Listener* l);
/** @internal */
void removeListener (Listener* l);
/** @internal */
WebBrowserComponent::Options buildOptions (const WebBrowserComponent::Options& initialOptions) override;
/** @internal */
void emitEvent (const var& payload);
private:
void handleEvent (const var& event);
WebBrowserComponent& browser;
String name;
float value{};
Identifier eventId { "__juce__slider" + name };
ListenerList<Listener> listeners;
JUCE_DECLARE_NON_COPYABLE (WebSliderRelay)
JUCE_DECLARE_NON_MOVEABLE (WebSliderRelay)
};
/** Helper class that relays audio parameter information to an object inside a WebBrowserComponent.
In order to create a relay you need to specify a WebBrowserComponent object and an identifier
for the relayed state. This will result in a Javascript object becoming available inside the
WebBrowserComponent under the provided identifier.
You can then use a WebToggleButtonParameterAttachment as you would a ButtonParameterAttachment,
to attach the relay to a RangedAudioParameter. This will synchronise the state and events of
the Javascript object with the audio parameter at all times.
@code
// Add a relay to your AudioProcessorEditor members
WebToggleButtonRelay muteToggleRelay { webComponent, "muteToggle" };
@endcode
@code
// In your Javascript GUI code you obtain an object from the framework
import * as Juce from "juce-framework-frontend";
const checkboxState = Juce.getToggleState("muteToggle");
@endcode
@see WebToggleButtonParameterAttachment
*/
class JUCE_API WebToggleButtonRelay : public OptionsBuilder<WebBrowserComponent::Options>
{
public:
/** Creating a relay will ensure that a Javascript object under the provided name will be
available in the specified WebBrowserComponent's context. Use the frontend framework's
getToggleState function with the same name to get a hold of this object.
*/
WebToggleButtonRelay (WebBrowserComponent& browserIn, StringRef nameIn);
//==============================================================================
/** @internal */
struct Listener
{
virtual ~Listener() = default;
virtual void toggleStateChanged (bool) = 0;
virtual void initialUpdateRequested() = 0;
};
/** @internal */
void setToggleState (bool newState);
/** @internal */
void addListener (Listener* l);
/** @internal */
void removeListener (Listener* l);
/** @internal */
WebBrowserComponent::Options buildOptions (const WebBrowserComponent::Options& initialOptions) override;
/** @internal */
void emitEvent (const var& payload);
private:
void handleEvent (const var& event);
WebBrowserComponent& browser;
String name;
Identifier eventId { "__juce__toggle" + name };
ListenerList<Listener> listeners;
JUCE_DECLARE_NON_COPYABLE (WebToggleButtonRelay)
JUCE_DECLARE_NON_MOVEABLE (WebToggleButtonRelay)
};
/** Helper class that relays audio parameter information to an object inside a WebBrowserComponent.
In order to create a relay you need to specify a WebBrowserComponent object and an identifier
for the relayed state. This will result in a Javascript object becoming available inside the
WebBrowserComponent under the provided identifier.
You can then use a WebComboBoxParameterAttachment as you would a ComboBoxParameterAttachment,
to attach the relay to a RangedAudioParameter. This will synchronise the state and events of
the Javascript object with the audio parameter at all times.
@code
// Add a relay to your AudioProcessorEditor members
WebComboBoxRelay filterTypeComboRelay { webComponent, "filterTypeCombo" };
@endcode
@code
// In your Javascript GUI code you obtain an object from the framework
import * as Juce from "juce-framework-frontend";
const comboBoxState = Juce.getComboBoxState("filterTypeCombo");
@endcode
@see WebComboBoxParameterAttachment
*/
class JUCE_API WebComboBoxRelay : public OptionsBuilder<WebBrowserComponent::Options>
{
public:
/** Creating a relay will ensure that a Javascript object under the provided name will be
available in the specified WebBrowserComponent's context. Use the frontend framework's
getComboBoxState function with the same name to get a hold of this object.
*/
WebComboBoxRelay (WebBrowserComponent& browserIn, StringRef nameIn);
//==============================================================================
/** @internal */
struct Listener
{
virtual ~Listener() = default;
virtual void valueChanged (float) = 0;
virtual void initialUpdateRequested() = 0;
};
/** @internal */
void setValue (float newValue);
/** @internal */
void addListener (Listener* l);
/** @internal */
void removeListener (Listener* l);
/** @internal */
WebBrowserComponent::Options buildOptions (const WebBrowserComponent::Options& initialOptions) override;
/** @internal */
void emitEvent (const var& payload);
private:
void handleEvent (const var& event);
WebBrowserComponent& browser;
String name;
Identifier eventId { "__juce__comboBox" + name };
ListenerList<Listener> listeners;
JUCE_DECLARE_NON_COPYABLE (WebComboBoxRelay)
JUCE_DECLARE_NON_MOVEABLE (WebComboBoxRelay)
};
#endif
}

View file

@ -1,141 +0,0 @@
/*
==============================================================================
This file is part of the JUCE framework.
Copyright (c) Raw Material Software Limited
JUCE is an open source framework subject to commercial or open source
licensing.
By downloading, installing, or using the JUCE framework, or combining the
JUCE framework with any other source code, object code, content or any other
copyrightable work, you agree to the terms of the JUCE End User Licence
Agreement, and all incorporated terms including the JUCE Privacy Policy and
the JUCE Website Terms of Service, as applicable, which will bind you. If you
do not agree to the terms of these agreements, we will not license the JUCE
framework to you, and you must discontinue the installation or download
process and cease use of the JUCE framework.
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
Or:
You may also use this code under the terms of the AGPLv3:
https://www.gnu.org/licenses/agpl-3.0.en.html
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
package com.rmsl.juce;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Message;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
//==============================================================================
public class JuceWebView
{
static public class Client extends WebViewClient
{
public Client (long hostToUse)
{
host = hostToUse;
}
public void hostDeleted ()
{
synchronized (hostLock)
{
host = 0;
}
}
public void onPageFinished (WebView view, String url)
{
if (host == 0)
return;
webViewPageLoadFinished (host, view, url);
}
public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error)
{
if (host == 0)
return;
webViewReceivedSslError (host, view, handler, error);
}
public void onPageStarted (WebView view, String url, Bitmap favicon)
{
if (host != 0)
webViewPageLoadStarted (host, view, url);
}
public WebResourceResponse shouldInterceptRequest (WebView view, String url)
{
synchronized (hostLock)
{
if (host != 0)
{
boolean shouldLoad = webViewPageLoadStarted (host, view, url);
if (shouldLoad)
return null;
}
}
return new WebResourceResponse ("text/html", null, null);
}
private native boolean webViewPageLoadStarted (long host, WebView view, String url);
private native void webViewPageLoadFinished (long host, WebView view, String url);
private native void webViewReceivedSslError (long host, WebView view, SslErrorHandler handler, SslError error);
private long host;
private final Object hostLock = new Object ();
}
static public class ChromeClient extends WebChromeClient
{
public ChromeClient (long hostToUse)
{
host = hostToUse;
}
@Override
public void onCloseWindow (WebView window)
{
webViewCloseWindowRequest (host, window);
}
@Override
public boolean onCreateWindow (WebView view, boolean isDialog,
boolean isUserGesture, Message resultMsg)
{
webViewCreateWindowRequest (host, view);
return false;
}
private native void webViewCloseWindowRequest (long host, WebView view);
private native void webViewCreateWindowRequest (long host, WebView view);
private long host;
private final Object hostLock = new Object ();
}
}

View file

@ -1,141 +0,0 @@
/*
==============================================================================
This file is part of the JUCE framework.
Copyright (c) Raw Material Software Limited
JUCE is an open source framework subject to commercial or open source
licensing.
By downloading, installing, or using the JUCE framework, or combining the
JUCE framework with any other source code, object code, content or any other
copyrightable work, you agree to the terms of the JUCE End User Licence
Agreement, and all incorporated terms including the JUCE Privacy Policy and
the JUCE Website Terms of Service, as applicable, which will bind you. If you
do not agree to the terms of these agreements, we will not license the JUCE
framework to you, and you must discontinue the installation or download
process and cease use of the JUCE framework.
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
Or:
You may also use this code under the terms of the AGPLv3:
https://www.gnu.org/licenses/agpl-3.0.en.html
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
package com.rmsl.juce;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Message;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
//==============================================================================
public class JuceWebView21
{
static public class Client extends WebViewClient
{
public Client (long hostToUse)
{
host = hostToUse;
}
public void hostDeleted ()
{
synchronized (hostLock)
{
host = 0;
}
}
public void onPageFinished (WebView view, String url)
{
if (host == 0)
return;
webViewPageLoadFinished (host, view, url);
}
public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error)
{
if (host == 0)
return;
webViewReceivedSslError (host, view, handler, error);
}
public void onPageStarted (WebView view, String url, Bitmap favicon)
{
if (host != 0)
webViewPageLoadStarted (host, view, url);
}
public WebResourceResponse shouldInterceptRequest (WebView view, String url)
{
synchronized (hostLock)
{
if (host != 0)
{
boolean shouldLoad = webViewPageLoadStarted (host, view, url);
if (shouldLoad)
return null;
}
}
return new WebResourceResponse ("text/html", null, null);
}
private native boolean webViewPageLoadStarted (long host, WebView view, String url);
private native void webViewPageLoadFinished (long host, WebView view, String url);
private native void webViewReceivedSslError (long host, WebView view, SslErrorHandler handler, SslError error);
private long host;
private final Object hostLock = new Object ();
}
static public class ChromeClient extends WebChromeClient
{
public ChromeClient (long hostToUse)
{
host = hostToUse;
}
@Override
public void onCloseWindow (WebView window)
{
webViewCloseWindowRequest (host, window);
}
@Override
public boolean onCreateWindow (WebView view, boolean isDialog,
boolean isUserGesture, Message resultMsg)
{
webViewCreateWindowRequest (host, view);
return false;
}
private native void webViewCloseWindowRequest (long host, WebView view);
private native void webViewCreateWindowRequest (long host, WebView view);
private long host;
private final Object hostLock = new Object ();
}
}

View file

@ -0,0 +1,356 @@
/*
==============================================================================
This file is part of the JUCE framework.
Copyright (c) Raw Material Software Limited
JUCE is an open source framework subject to commercial or open source
licensing.
By downloading, installing, or using the JUCE framework, or combining the
JUCE framework with any other source code, object code, content or any other
copyrightable work, you agree to the terms of the JUCE End User Licence
Agreement, and all incorporated terms including the JUCE Privacy Policy and
the JUCE Website Terms of Service, as applicable, which will bind you. If you
do not agree to the terms of these agreements, we will not license the JUCE
framework to you, and you must discontinue the installation or download
process and cease use of the JUCE framework.
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
Or:
You may also use this code under the terms of the AGPLv3:
https://www.gnu.org/licenses/agpl-3.0.en.html
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
package com.rmsl.juce;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Build;
import android.os.Message;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebResourceResponse;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import java.lang.annotation.Native;
import java.util.ArrayList;
//==============================================================================
public class JuceWebViewClasses
{
static public class NativeInterface
{
private long host;
private final Object hostLock = new Object ();
//==============================================================================
public NativeInterface (long hostToUse)
{
host = hostToUse;
}
public void hostDeleted ()
{
synchronized (hostLock)
{
host = 0;
}
}
//==============================================================================
public void onPageStarted (WebView view, String url)
{
if (host == 0)
return;
handleResourceRequest (host, view, url);
}
public WebResourceResponse shouldInterceptRequest (WebView view, WebResourceRequest request)
{
synchronized (hostLock)
{
if (host != 0)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
return handleResourceRequest (host, view, request.getUrl().toString());
}
}
return null;
}
public void onPageFinished (WebView view, String url)
{
if (host == 0)
return;
webViewPageLoadFinished (host, view, url);
}
public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error)
{
if (host == 0)
return;
webViewReceivedSslError (host, view, handler, error);
}
public void onReceivedHttpError (WebView view, WebResourceRequest request, WebResourceResponse errorResponse)
{
if (host == 0)
return;
webViewReceivedHttpError (host, view, request, errorResponse);
}
public void onCloseWindow (WebView window)
{
if (host == 0)
return;
webViewCloseWindowRequest (host, window);
}
public boolean onCreateWindow (WebView view, boolean isDialog,
boolean isUserGesture, Message resultMsg)
{
if (host == 0)
return false;
webViewCreateWindowRequest (host, view);
return false;
}
public String postMessageHandler (String message)
{
synchronized (hostLock)
{
if (host != 0)
{
String result = postMessage (host, message);
if (result == null)
return "";
return result;
}
}
return "";
}
public void handleJavascriptEvaluationResult (long evalId, String result)
{
if (host == 0)
return;
evaluationResultHandler (host, evalId, result);
}
public boolean shouldOverrideUrlLoading (String url)
{
if (host == 0)
return false;
return ! pageAboutToLoad (host, url);
}
//==============================================================================
private native WebResourceResponse handleResourceRequest (long host, WebView view, String url);
private native void webViewPageLoadFinished (long host, WebView view, String url);
private native void webViewReceivedSslError (long host, WebView view, SslErrorHandler handler, SslError error);
private native void webViewReceivedHttpError (long host, WebView view, WebResourceRequest request, WebResourceResponse errorResponse);
private native void webViewCloseWindowRequest (long host, WebView view);
private native void webViewCreateWindowRequest (long host, WebView view);
private native void evaluationResultHandler (long host, long evalId, String result);
private native String postMessage (long host, String message);
private native boolean pageAboutToLoad (long host, String url);
}
static public class Client extends WebViewClient
{
private NativeInterface nativeInterface;
//==============================================================================
public Client (NativeInterface nativeInterfaceIn)
{
nativeInterface = nativeInterfaceIn;
}
//==============================================================================
@Override
public void onPageFinished (WebView view, String url)
{
nativeInterface.onPageFinished (view, url);
}
@Override
public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error)
{
nativeInterface.onReceivedSslError (view, handler, error);
}
@Override
public void onReceivedHttpError (WebView view, WebResourceRequest request, WebResourceResponse errorResponse)
{
nativeInterface.onReceivedHttpError (view, request, errorResponse);
}
@Override
public void onPageStarted (WebView view, String url, Bitmap favicon)
{
nativeInterface.onPageStarted (view, url);
}
@Override
public WebResourceResponse shouldInterceptRequest (WebView view, WebResourceRequest request)
{
return nativeInterface.shouldInterceptRequest (view, request);
}
@Override
public boolean shouldOverrideUrlLoading (WebView view, WebResourceRequest request)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
return nativeInterface.shouldOverrideUrlLoading (request.getUrl().toString());
return false;
}
@Override
public boolean shouldOverrideUrlLoading (WebView view, String url)
{
return nativeInterface.shouldOverrideUrlLoading (url);
}
}
static public class ChromeClient extends WebChromeClient
{
private NativeInterface nativeInterface;
//==============================================================================
public ChromeClient (NativeInterface nativeInterfaceIn)
{
nativeInterface = nativeInterfaceIn;
}
//==============================================================================
@Override
public void onCloseWindow (WebView window)
{
nativeInterface.onCloseWindow (window);
}
@Override
public boolean onCreateWindow (WebView view, boolean isDialog,
boolean isUserGesture, Message resultMsg)
{
return nativeInterface.onCreateWindow (view, isDialog, isUserGesture, resultMsg);
}
}
static public class WebAppInterface
{
private NativeInterface nativeInterface;
String userScripts;
//==============================================================================
public WebAppInterface (NativeInterface nativeInterfaceIn, String userScriptsIn)
{
nativeInterface = nativeInterfaceIn;
userScripts = userScriptsIn;
}
//==============================================================================
@JavascriptInterface
public String postMessage (String message)
{
return nativeInterface.postMessageHandler (message);
}
@JavascriptInterface
public String getAndroidUserScripts()
{
return userScripts;
}
}
static public class JuceWebView extends WebView
{
private NativeInterface nativeInterface;
private long evaluationId = 0;
public JuceWebView (Context context, long host, String userAgent, String initScripts)
{
super (context);
nativeInterface = new NativeInterface (host);
WebSettings settings = getSettings();
settings.setJavaScriptEnabled (true);
settings.setBuiltInZoomControls (true);
settings.setDisplayZoomControls (false);
settings.setSupportMultipleWindows (true);
settings.setUserAgentString (userAgent);
setWebChromeClient (new ChromeClient (nativeInterface));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
setWebContentsDebuggingEnabled (true);
}
setWebViewClient (new Client (nativeInterface));
addJavascriptInterface (new WebAppInterface (nativeInterface, initScripts), "__JUCE__");
}
public void disconnectNative()
{
nativeInterface.hostDeleted();
}
public long evaluateJavascript (String script)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
final long currentEvaluationId = evaluationId++;
final NativeInterface accessibleNativeInterface = nativeInterface;
super.evaluateJavascript (script, new ValueCallback<String>()
{
@Override
public void onReceiveValue(String result)
{
accessibleNativeInterface.handleJavascriptEvaluationResult (currentEvaluationId,
result);
}
});
return currentEvaluationId;
}
return -1;
}
}
}

View file

@ -90,9 +90,6 @@ public:
auto peerView = (NSView*) peer->getNativeHandle(); auto peerView = (NSView*) peer->getNativeHandle();
[peerView addSubview: view]; [peerView addSubview: view];
if (@available (macOS 10.10, *))
[view setAccessibilityParent:static_cast<id> (owner.getAccessibilityHandler()->getNativeImplementation())];
componentMovedOrResized (false, false); componentMovedOrResized (false, false);
} }
else else

View file

@ -115,13 +115,98 @@ static NSMutableURLRequest* getRequestForURL (const String& url, const StringArr
return nullptr; return nullptr;
} }
static var fromObject (id object)
{
// An undefined var serialises to 'undefined' i.e. an expression not returning a value
if (object == nil)
return var::undefined();
if ([object isKindOfClass:[NSNumber class]])
{
// The object returned by evaluateJavaScript is a __NSCFBoolean*, which is a private class
// to the framework, but a handle to this class can be obtained through @YES. When cast to
// an NSNumber this object would have the wrong type encoding, so [number objCType]; would
// return 'c' instead of 'B', hence that approach wouldn't work.
if ([object isKindOfClass: [@YES class]])
return static_cast<NSNumber*> (object).boolValue == YES ? true : false;
return static_cast<NSNumber*> (object).doubleValue;
}
if ([object isKindOfClass:[NSString class]])
return nsStringToJuce (object);
if ([object isKindOfClass:[NSArray class]])
{
Array<var> result;
auto* array = static_cast<NSArray*> (object);
for (id elem in array)
result.add (fromObject (elem));
return result;
}
if ([object isKindOfClass:[NSDictionary class]])
{
const auto* dict = static_cast<NSDictionary*> (object);
DynamicObject::Ptr result (new DynamicObject());
for (id key in dict)
result->setProperty (nsStringToJuce (key), fromObject ([dict objectForKey:key]));
return result.get();
}
if ([object isKindOfClass:[NSDate class]])
{
JUCE_AUTORELEASEPOOL
{
auto* date = static_cast<NSDate*> (object);
auto* formatter = [[NSDateFormatter alloc] init];
const auto javascriptDateFormatString = @"yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSS'Z'";
[formatter setDateFormat: javascriptDateFormatString];
[formatter setTimeZone: [NSTimeZone timeZoneWithName: @"UTC"]];
NSString* dateString = [formatter stringFromDate: date];
return nsStringToJuce (dateString);
}
}
// Returning a Void var, which serialises to 'null'
if ([object isKindOfClass:[NSNull class]])
return {};
jassertfalse;
return {};
}
using LastFocusChange = std::optional<Component::FocusChangeDirection>;
static const char* lastFocusChangeMemberName = "lastFocusChangeHandle";
[[maybe_unused]] static void setLastFocusChangeHandle (id instance, LastFocusChange* object)
{
object_setInstanceVariable (instance, lastFocusChangeMemberName, object);
}
[[maybe_unused]] static LastFocusChange* getLastFocusChangeHandle (id instance)
{
return getIvar<LastFocusChange*> (instance, lastFocusChangeMemberName);
}
#if JUCE_MAC #if JUCE_MAC
template <class WebViewClass> template <class WebViewClass>
struct WebViewKeyEquivalentResponder final : public ObjCClass<WebViewClass> struct WebViewKeyEquivalentResponder final : public ObjCClass<WebViewClass>
{ {
using Base = ObjCClass<WebViewClass>;
WebViewKeyEquivalentResponder() WebViewKeyEquivalentResponder()
: ObjCClass<WebViewClass> ("WebViewKeyEquivalentResponder_") : Base ("WebViewKeyEquivalentResponder_")
{ {
this->template addIvar<LastFocusChange*> (lastFocusChangeMemberName);
this->addMethod (@selector (performKeyEquivalent:), this->addMethod (@selector (performKeyEquivalent:),
[] (id self, SEL selector, NSEvent* event) [] (id self, SEL selector, NSEvent* event)
{ {
@ -156,8 +241,48 @@ struct WebViewKeyEquivalentResponder final : public ObjCClass<WebViewClass>
return sendAction (@selector (selectAll:)); return sendAction (@selector (selectAll:));
} }
return ObjCClass<WebViewClass>::template sendSuperclassMessage<BOOL> (self, selector, event); return Base::template sendSuperclassMessage<BOOL> (self, selector, event);
}); });
this->addMethod (@selector (resignFirstResponder),
[] (id self, SEL selector)
{
const auto result = Base::template sendSuperclassMessage<BOOL> (self, selector);
auto* focusChangeTypeHandle = getLastFocusChangeHandle (self);
jassert (focusChangeTypeHandle != nullptr); // Forgot to call setLastFocusChangeHandle?
focusChangeTypeHandle->emplace (Component::FocusChangeDirection::unknown);
auto* currentEvent = [NSApp currentEvent];
if (currentEvent == nullptr)
return result;
const auto eventType = [currentEvent type];
if ( eventType != NSEventTypeKeyUp
&& eventType != NSEventTypeKeyDown
&& eventType != NSEventTypeFlagsChanged)
{
return result;
}
// Device independent key numbers should be compared with Carbon
// constants, but we define the one we need here to avoid importing
// Carbon.h
static constexpr unsigned short carbonTabKeycode = 0x30;
if ([currentEvent keyCode] != carbonTabKeycode)
return result;
const auto shiftKeyDown = ([currentEvent modifierFlags] & NSEventModifierFlagShift) != 0;
focusChangeTypeHandle->emplace (shiftKeyDown ? Component::FocusChangeDirection::backward
: Component::FocusChangeDirection::forward);
return result;
});
this->registerClass(); this->registerClass();
} }
}; };
@ -267,16 +392,56 @@ private:
JUCE_END_IGNORE_WARNINGS_GCC_LIKE JUCE_END_IGNORE_WARNINGS_GCC_LIKE
#endif #endif
// Connects the delegate to the rest of the implementation without making WebViewDelegateClass
// a nested class as well.
class DelegateConnector
{
public:
DelegateConnector (WebBrowserComponent& browserIn,
std::function<void (const var&)> handleNativeEventFnIn,
std::function<std::optional<WebBrowserComponent::Resource> (const String&)> handleResourceRequestFnIn,
const WebBrowserComponent::Options& optionsIn)
: browser (browserIn),
handleNativeEventFn (std::move (handleNativeEventFnIn)),
handleResourceRequestFn (std::move (handleResourceRequestFnIn)),
options (optionsIn)
{
}
auto& getBrowser() { return browser; }
void handleNativeEvent (const var& message)
{
handleNativeEventFn (message);
}
auto handleResourceRequest (const String& url)
{
return handleResourceRequestFn (url);
}
[[nodiscard]] const auto& getOptions() const
{
return options;
}
private:
WebBrowserComponent& browser;
std::function<void (const var&)> handleNativeEventFn;
std::function<std::optional<WebBrowserComponent::Resource> (const String&)> handleResourceRequestFn;
WebBrowserComponent::Options options;
};
struct API_AVAILABLE (macos (10.10)) WebViewDelegateClass final : public ObjCClass<NSObject> struct API_AVAILABLE (macos (10.10)) WebViewDelegateClass final : public ObjCClass<NSObject>
{ {
WebViewDelegateClass() : ObjCClass ("JUCEWebViewDelegate_") WebViewDelegateClass() : ObjCClass ("JUCEWebViewDelegate_")
{ {
addIvar<WebBrowserComponent*> ("owner"); addIvar<DelegateConnector*> ("connector");
addMethod (@selector (webView:decidePolicyForNavigationAction:decisionHandler:), addMethod (@selector (webView:decidePolicyForNavigationAction:decisionHandler:),
[] (id self, SEL, WKWebView*, WKNavigationAction* navigationAction, void (^decisionHandler) (WKNavigationActionPolicy)) [] (id self, SEL, WKWebView*, WKNavigationAction* navigationAction, void (^decisionHandler) (WKNavigationActionPolicy))
{ {
if (getOwner (self)->pageAboutToLoad (nsStringToJuce ([[[navigationAction request] URL] absoluteString]))) if (getConnector (self)->getBrowser().pageAboutToLoad (nsStringToJuce ([[[navigationAction request] URL] absoluteString])))
decisionHandler (WKNavigationActionPolicyAllow); decisionHandler (WKNavigationActionPolicyAllow);
else else
decisionHandler (WKNavigationActionPolicyCancel); decisionHandler (WKNavigationActionPolicyCancel);
@ -285,34 +450,112 @@ struct API_AVAILABLE (macos (10.10)) WebViewDelegateClass final : public ObjCCla
addMethod (@selector (webView:didFinishNavigation:), addMethod (@selector (webView:didFinishNavigation:),
[] (id self, SEL, WKWebView* webview, WKNavigation*) [] (id self, SEL, WKWebView* webview, WKNavigation*)
{ {
getOwner (self)->pageFinishedLoading (nsStringToJuce ([[webview URL] absoluteString])); getConnector (self)->getBrowser().pageFinishedLoading (nsStringToJuce ([[webview URL] absoluteString]));
}); });
addMethod (@selector (webView:didFailNavigation:withError:), addMethod (@selector (webView:didFailNavigation:withError:),
[] (id self, SEL, WKWebView*, WKNavigation*, NSError* error) [] (id self, SEL, WKWebView*, WKNavigation*, NSError* error)
{ {
displayError (getOwner (self), error); displayError (&getConnector (self)->getBrowser(), error);
}); });
addMethod (@selector (webView:didFailProvisionalNavigation:withError:), addMethod (@selector (webView:didFailProvisionalNavigation:withError:),
[] (id self, SEL, WKWebView*, WKNavigation*, NSError* error) [] (id self, SEL, WKWebView*, WKNavigation*, NSError* error)
{ {
displayError (getOwner (self), error); displayError (&getConnector (self)->getBrowser(), error);
}); });
addMethod (@selector (webViewDidClose:), addMethod (@selector (webViewDidClose:),
[] (id self, SEL, WKWebView*) [] (id self, SEL, WKWebView*)
{ {
getOwner (self)->windowCloseRequest(); getConnector (self)->getBrowser().windowCloseRequest();
}); });
addMethod (@selector (webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:), addMethod (@selector (webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:),
[] (id self, SEL, WKWebView*, WKWebViewConfiguration*, WKNavigationAction* navigationAction, WKWindowFeatures*) [] (id self, SEL, WKWebView*, WKWebViewConfiguration*, WKNavigationAction* navigationAction, WKWindowFeatures*)
{ {
getOwner (self)->newWindowAttemptingToLoad (nsStringToJuce ([[[navigationAction request] URL] absoluteString])); getConnector (self)->getBrowser().newWindowAttemptingToLoad (nsStringToJuce ([[[navigationAction request] URL] absoluteString]));
return nil; return nil;
}); });
addMethod (@selector (userContentController:didReceiveScriptMessage:),
[] (id self, SEL, id, id message)
{
const auto object = fromObject ([message body]);
if (! object.isString())
{
jassertfalse;
return;
}
getConnector (self)->handleNativeEvent (JSON::fromString (object.toString()));
});
addMethod (@selector (webView:startURLSchemeTask:),
[] (id self, SEL, id, id urlSchemeTask)
{
const auto request = [urlSchemeTask request];
auto* url = [&]
{
auto r = [request URL];
return r == nil ? [NSURL URLWithString:@""] : (NSURL* _Nonnull) r;
}();
const auto path = nsStringToJuce ([url path]);
const auto resource = getConnector (self)->handleResourceRequest (path);
JUCE_AUTORELEASEPOOL
{
const auto makeResponse = [&url] (auto responseCode, id headers=nil)
{
auto response = [[NSHTTPURLResponse alloc] initWithURL:url
statusCode:responseCode
HTTPVersion:@"HTTP/1.1"
headerFields:headers];
if (response == nil)
return [[NSHTTPURLResponse alloc] autorelease];
return (NSHTTPURLResponse* _Nonnull) [response autorelease];
};
if (resource.has_value())
{
NSMutableDictionary* headers = [@ {
@"Content-Length" : juceStringToNS (String { resource->data.size() }),
@"Content-Type" : juceStringToNS (resource->mimeType),
} mutableCopy];
if (auto allowedOrigin = getConnector (self)->getOptions().getAllowedOrigin())
{
[headers setObject:juceStringToNS (*allowedOrigin)
forKey:@"Access-Control-Allow-Origin"];
}
auto response = makeResponse (200, headers);
[urlSchemeTask didReceiveResponse:response];
[urlSchemeTask didReceiveData:[NSData dataWithBytes:resource->data.data()
length:resource->data.size()]];
}
else
{
[urlSchemeTask didReceiveResponse:makeResponse (404)];
}
[urlSchemeTask didFinish];
}
});
addMethod (@selector (webView:stopURLSchemeTask:),
[] (id, SEL, id, id)
{
});
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
if (@available (macOS 10.12, *)) if (@available (macOS 10.12, *))
{ {
@ -384,8 +627,15 @@ struct API_AVAILABLE (macos (10.10)) WebViewDelegateClass final : public ObjCCla
registerClass(); registerClass();
} }
static void setOwner (id self, WebBrowserComponent* owner) { object_setInstanceVariable (self, "owner", owner); } static void setConnector (id self, DelegateConnector* connector)
static WebBrowserComponent* getOwner (id self) { return getIvar<WebBrowserComponent*> (self, "owner"); } {
object_setInstanceVariable (self, "connector", connector);
}
static DelegateConnector* getConnector (id self)
{
return getIvar<DelegateConnector*> (self, "connector");
}
private: private:
static void displayError (WebBrowserComponent* owner, NSError* error) static void displayError (WebBrowserComponent* owner, NSError* error)
@ -403,25 +653,32 @@ private:
}; };
//============================================================================== //==============================================================================
struct WebViewBase struct WebBrowserComponent::Impl::Platform
{ {
virtual ~WebViewBase() = default; class WKWebViewImpl;
class WebViewImpl;
virtual void goToURL (const String&, const StringArray*, const MemoryBlock*) = 0;
virtual void goBack() = 0;
virtual void goForward() = 0;
virtual void stop() = 0;
virtual void refresh() = 0;
virtual id getWebView() = 0;
}; };
static constexpr const char* platformSpecificIntegrationScript = R"(
window.__JUCE__ = {
postMessage: function (object) {
window.webkit.messageHandlers.__JUCE__.postMessage(object);
},
};
)";
//==============================================================================
#if JUCE_MAC #if JUCE_MAC
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations") JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations")
class WebViewImpl : public WebViewBase class WebBrowserComponent::Impl::Platform::WebViewImpl : public WebBrowserComponent::Impl::PlatformInterface,
#if JUCE_MAC
public NSViewComponent
#else
public UIViewComponent
#endif
{ {
public: public:
WebViewImpl (WebBrowserComponent* owner, const String& userAgent) WebViewImpl (WebBrowserComponent::Impl& implIn, const String& userAgent) : browser (implIn.owner)
{ {
static WebViewKeyEquivalentResponder<WebView> webviewClass; static WebViewKeyEquivalentResponder<WebView> webviewClass;
@ -429,24 +686,59 @@ public:
frameName: nsEmptyString() frameName: nsEmptyString()
groupName: nsEmptyString()]); groupName: nsEmptyString()]);
setLastFocusChangeHandle (webView.get(), &lastFocusChange);
webView.get().customUserAgent = juceStringToNS (userAgent); webView.get().customUserAgent = juceStringToNS (userAgent);
static DownloadClickDetectorClass cls; static DownloadClickDetectorClass cls;
clickListener.reset ([cls.createInstance() init]); clickListener.reset ([cls.createInstance() init]);
DownloadClickDetectorClass::setOwner (clickListener.get(), owner); DownloadClickDetectorClass::setOwner (clickListener.get(), &browser);
[webView.get() setPolicyDelegate: clickListener.get()]; [webView.get() setPolicyDelegate: clickListener.get()];
[webView.get() setFrameLoadDelegate: clickListener.get()]; [webView.get() setFrameLoadDelegate: clickListener.get()];
[webView.get() setUIDelegate: clickListener.get()]; [webView.get() setUIDelegate: clickListener.get()];
setView (webView.get());
browser.addAndMakeVisible (this);
} }
~WebViewImpl() override ~WebViewImpl() override
{ {
setView (nil);
[webView.get() setPolicyDelegate: nil]; [webView.get() setPolicyDelegate: nil];
[webView.get() setFrameLoadDelegate: nil]; [webView.get() setFrameLoadDelegate: nil];
[webView.get() setUIDelegate: nil]; [webView.get() setUIDelegate: nil];
} }
void setWebViewSize (int width, int height) override
{
setSize (width, height);
}
void checkWindowAssociation() override
{
if (browser.isShowing())
{
browser.reloadLastURL();
if (browser.blankPageShown)
browser.goBack();
}
else
{
if (browser.unloadPageWhenHidden && ! browser.blankPageShown)
{
// when the component becomes invisible, some stuff like flash
// carries on playing audio, so we need to force it onto a blank
// page to avoid this, (and send it back when it's made visible again).
browser.blankPageShown = true;
goToURL ("about:blank", nullptr, nullptr);
}
}
}
void goToURL (const String& url, void goToURL (const String& url,
const StringArray* headers, const StringArray* headers,
const MemoryBlock* postData) override const MemoryBlock* postData) override
@ -486,9 +778,7 @@ public:
void stop() override { [webView.get() stopLoading: nil]; } void stop() override { [webView.get() stopLoading: nil]; }
void refresh() override { [webView.get() reload: nil]; } void refresh() override { [webView.get() reload: nil]; }
id getWebView() override { return webView.get(); } void mouseMove (const MouseEvent&) override
void mouseMove (const MouseEvent&)
{ {
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector") JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
// WebKit doesn't capture mouse-moves itself, so it seems the only way to make // WebKit doesn't capture mouse-moves itself, so it seems the only way to make
@ -498,47 +788,185 @@ public:
JUCE_END_IGNORE_WARNINGS_GCC_LIKE JUCE_END_IGNORE_WARNINGS_GCC_LIKE
} }
void evaluateJavascript (const String&, WebBrowserComponent::EvaluationCallback) override
{
// This feature is only available on MacOS 10.11 and above
jassertfalse;
}
private: private:
WebBrowserComponent& browser;
LastFocusChange lastFocusChange;
ObjCObjectHandle<WebView*> webView; ObjCObjectHandle<WebView*> webView;
ObjCObjectHandle<id> clickListener; ObjCObjectHandle<id> clickListener;
}; };
JUCE_END_IGNORE_WARNINGS_GCC_LIKE JUCE_END_IGNORE_WARNINGS_GCC_LIKE
#endif #endif
class API_AVAILABLE (macos (10.11)) WKWebViewImpl : public WebViewBase class API_AVAILABLE (macos (10.11)) WebBrowserComponent::Impl::Platform::WKWebViewImpl : public WebBrowserComponent::Impl::PlatformInterface,
#if JUCE_MAC
public NSViewComponent
#else
public UIViewComponent
#endif
{ {
public: public:
WKWebViewImpl (WebBrowserComponent* owner, const String& userAgent) WKWebViewImpl (WebBrowserComponent::Impl& implIn,
const WebBrowserComponent::Options& browserOptions,
const StringArray& userScripts)
: owner (implIn),
delegateConnector (implIn.owner,
[this] (const auto& m) { owner.handleNativeEvent (m); },
[this] (const auto& r) { return owner.handleResourceRequest (r); },
browserOptions)
{ {
#if JUCE_MAC ObjCObjectHandle<WKWebViewConfiguration*> config { [WKWebViewConfiguration new] };
static WebViewKeyEquivalentResponder<WKWebView> webviewClass; id preferences = [config.get() preferences];
webView.reset ([webviewClass.createInstance() initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)]); [preferences setValue:@(true) forKey:@"fullScreenEnabled"];
#else [preferences setValue:@(true) forKey:@"DOMPasteAllowed"];
webView.reset ([[WKWebView alloc] initWithFrame: CGRectMake (0, 0, 100.0f, 100.0f)]); [preferences setValue:@(true) forKey:@"javaScriptCanAccessClipboard"];
#endif
if (userAgent.isNotEmpty())
webView.get().customUserAgent = juceStringToNS (userAgent);
static WebViewDelegateClass cls; static WebViewDelegateClass cls;
webViewDelegate.reset ([cls.createInstance() init]); webViewDelegate.reset ([cls.createInstance() init]);
WebViewDelegateClass::setOwner (webViewDelegate.get(), owner); WebViewDelegateClass::setConnector (webViewDelegate.get(), &delegateConnector);
if (browserOptions.getNativeIntegrationsEnabled())
{
[[config.get() userContentController] addScriptMessageHandler:webViewDelegate.get()
name:@"__JUCE__"];
}
// It isn't necessary to concatenate all scripts and add them as one. They will still work
// when added separately. But in the latter case sometimes only the first one is visible in
// the WebView developer console, so concatenating them helps with debugging.
auto allUserScripts = userScripts;
allUserScripts.insert (0, platformSpecificIntegrationScript);
NSUniquePtr<WKUserScript> script { [[WKUserScript alloc]
initWithSource:juceStringToNS (allUserScripts.joinIntoString ("\n"))
injectionTime:WKUserScriptInjectionTimeAtDocumentStart
forMainFrameOnly:YES] };
[[config.get() userContentController] addUserScript:script.get()];
if (@available (macOS 10.13, iOS 11.0, *))
{
if (browserOptions.getResourceProvider() != nullptr)
[config.get() setURLSchemeHandler:webViewDelegate.get() forURLScheme:@"juce"];
}
#if JUCE_DEBUG
[preferences setValue: @(true) forKey: @"developerExtrasEnabled"];
#endif
#if JUCE_MAC
static WebViewKeyEquivalentResponder<WKWebView> webviewClass;
webView.reset ([webviewClass.createInstance() initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
configuration: config.get()]);
setLastFocusChangeHandle (webView.get(), &lastFocusChange);
#else
webView.reset ([[WKWebView alloc] initWithFrame: CGRectMake (0, 0, 100.0f, 100.0f)
configuration: config.get()]);
#endif
if (const auto userAgent = browserOptions.getUserAgent(); userAgent.isNotEmpty())
webView.get().customUserAgent = juceStringToNS (userAgent);
[webView.get() setNavigationDelegate: webViewDelegate.get()]; [webView.get() setNavigationDelegate: webViewDelegate.get()];
[webView.get() setUIDelegate: webViewDelegate.get()]; [webView.get() setUIDelegate: webViewDelegate.get()];
#if JUCE_DEBUG setView (webView.get());
[[[webView.get() configuration] preferences] setValue: @(true) forKey: @"developerExtrasEnabled"]; owner.owner.addAndMakeVisible (this);
#endif
} }
~WKWebViewImpl() override ~WKWebViewImpl() override
{ {
setView (nil);
[webView.get() setNavigationDelegate: nil]; [webView.get() setNavigationDelegate: nil];
[webView.get() setUIDelegate: nil]; [webView.get() setUIDelegate: nil];
} }
void setWebViewSize (int width, int height) override
{
setSize (width, height);
}
void checkWindowAssociation() override
{
auto& browser = owner.owner;
if (browser.isShowing())
{
browser.reloadLastURL();
if (browser.blankPageShown)
browser.goBack();
}
else
{
if (browser.unloadPageWhenHidden && ! browser.blankPageShown)
{
// when the component becomes invisible, some stuff like flash
// carries on playing audio, so we need to force it onto a blank
// page to avoid this, (and send it back when it's made visible again).
browser.blankPageShown = true;
goToURL ("about:blank", nullptr, nullptr);
}
}
}
void focusGainedWithDirection (FocusChangeType, FocusChangeDirection) override
{
const auto webViewFocusLossDirection = std::exchange (lastFocusChange, std::nullopt);
// We didn't receive the focus from the WebView, so we need to pass it onto it
if (! webViewFocusLossDirection.has_value())
{
#if JUCE_MAC
[[webView.get() window] makeFirstResponder: webView.get()];
#endif
return;
}
auto* comp = [&]() -> Component*
{
auto* c = owner.owner.getParentComponent();
if (c == nullptr)
return nullptr;
const auto traverser = c->createFocusTraverser();
if (*webViewFocusLossDirection == FocusChangeDirection::forward)
{
if (auto* next = traverser->getNextComponent (this); next != nullptr)
return next;
return traverser->getDefaultComponent (c);
}
if (*webViewFocusLossDirection == FocusChangeDirection::backward)
{
if (auto* previous = traverser->getPreviousComponent (&owner.owner); previous != nullptr)
return previous;
if (auto all = traverser->getAllComponents (c); ! all.empty())
return all.back();
}
return nullptr;
}();
if (comp != nullptr)
comp->getAccessibilityHandler()->grabFocus();
else
giveAwayKeyboardFocus();
}
void goToURL (const String& url, void goToURL (const String& url,
const StringArray* headers, const StringArray* headers,
const MemoryBlock* postData) override const MemoryBlock* postData) override
@ -574,169 +1002,87 @@ public:
void stop() override { [webView.get() stopLoading]; } void stop() override { [webView.get() stopLoading]; }
void refresh() override { [webView.get() reload]; } void refresh() override { [webView.get() reload]; }
id getWebView() override { return webView.get(); } void evaluateJavascript (const String& script, WebBrowserComponent::EvaluationCallback callback) override
{
[webView.get() evaluateJavaScript: juceStringToNS (script)
completionHandler: ^(id obj, NSError* error)
{
if (callback == nullptr)
return;
if (error != nil)
{
const auto resultError = [&]() -> WebBrowserComponent::EvaluationResult::Error
{
const auto errorCode = [error code];
if (errorCode == 4)
{
String errorMsgTemplate { "JAVASCRIPT_ERROR at (EVALUATION_SOURCE:LINE_NUMBER:COLUMN_NUMBER)" };
if (id m = [error.userInfo objectForKey:@"WKJavaScriptExceptionMessage"]; m != nil)
errorMsgTemplate = errorMsgTemplate.replace ("JAVASCRIPT_ERROR", nsStringToJuce (m));
if (id m = [error.userInfo objectForKey:@"WKJavaScriptExceptionSourceURL"]; m != nil)
errorMsgTemplate = errorMsgTemplate.replace ("EVALUATION_SOURCE", nsStringToJuce ([m absoluteString]));
if (id m = [error.userInfo objectForKey:@"WKJavaScriptExceptionLineNumber"]; m != nil)
errorMsgTemplate = errorMsgTemplate.replace ("LINE_NUMBER", String { [m intValue] });
if (id m = [error.userInfo objectForKey:@"WKJavaScriptExceptionColumnNumber"]; m != nil)
errorMsgTemplate = errorMsgTemplate.replace ("COLUMN_NUMBER", String { [m intValue] });
return { WebBrowserComponent::EvaluationResult::Error::Type::javascriptException,
errorMsgTemplate };
}
else if (errorCode == 5)
{
String errorMessage;
if (id m = [[error userInfo] objectForKey:@"NSLocalizedDescription"]; m != nil)
errorMessage = nsStringToJuce (m);
return { WebBrowserComponent::EvaluationResult::Error::Type::unsupportedReturnType,
errorMessage };
}
return { WebBrowserComponent::EvaluationResult::Error::Type::unknown, "Unknown error" };
}();
callback (EvaluationResult { resultError });
}
else
{
callback (EvaluationResult { fromObject (obj) });
}
}];
}
private: private:
WebBrowserComponent::Impl& owner;
DelegateConnector delegateConnector;
LastFocusChange lastFocusChange;
ObjCObjectHandle<WKWebView*> webView; ObjCObjectHandle<WKWebView*> webView;
ObjCObjectHandle<id> webViewDelegate; ObjCObjectHandle<id> webViewDelegate;
}; };
//============================================================================== //==============================================================================
class WebBrowserComponent::Pimpl auto WebBrowserComponent::Impl::createAndInitPlatformDependentPart (WebBrowserComponent::Impl& impl,
#if JUCE_MAC const WebBrowserComponent::Options& options,
: public NSViewComponent const StringArray& userScripts)
#else -> std::unique_ptr<PlatformInterface>
: public UIViewComponent
#endif
{ {
public: if (@available (macOS 10.11, *))
Pimpl (WebBrowserComponent* owner, const String& userAgent) return std::make_unique<Platform::WKWebViewImpl> (impl, options, userScripts);
{
if (@available (macOS 10.11, *))
webView = std::make_unique<WKWebViewImpl> (owner, userAgent);
#if JUCE_MAC
else
webView = std::make_unique<WebViewImpl> (owner, userAgent);
#endif
setView (webView->getWebView()); #if JUCE_MAC
} return std::make_unique<Platform::WebViewImpl> (impl, options.getUserAgent());
#endif
~Pimpl() override return {};
{
webView = nullptr;
setView (nil);
}
void goToURL (const String& url,
const StringArray* headers,
const MemoryBlock* postData)
{
webView->goToURL (url, headers, postData);
}
void goBack() { webView->goBack(); }
void goForward() { webView->goForward(); }
void stop() { webView->stop(); }
void refresh() { webView->refresh(); }
private:
std::unique_ptr<WebViewBase> webView;
};
//==============================================================================
WebBrowserComponent::WebBrowserComponent (const Options& options)
: unloadPageWhenHidden (! options.keepsPageLoadedWhenBrowserIsHidden())
{
setOpaque (true);
browser.reset (new Pimpl (this, options.getUserAgent()));
addAndMakeVisible (browser.get());
}
WebBrowserComponent::~WebBrowserComponent() = default;
//==============================================================================
void WebBrowserComponent::goToURL (const String& url,
const StringArray* headers,
const MemoryBlock* postData)
{
lastURL = url;
if (headers != nullptr)
lastHeaders = *headers;
else
lastHeaders.clear();
if (postData != nullptr)
lastPostData = *postData;
else
lastPostData.reset();
blankPageShown = false;
browser->goToURL (url, headers, postData);
}
void WebBrowserComponent::stop()
{
browser->stop();
}
void WebBrowserComponent::goBack()
{
lastURL.clear();
blankPageShown = false;
browser->goBack();
}
void WebBrowserComponent::goForward()
{
lastURL.clear();
browser->goForward();
}
void WebBrowserComponent::refresh()
{
browser->refresh();
} }
//============================================================================== //==============================================================================
void WebBrowserComponent::paint (Graphics&)
{
}
void WebBrowserComponent::checkWindowAssociation()
{
if (isShowing())
{
reloadLastURL();
if (blankPageShown)
goBack();
}
else
{
if (unloadPageWhenHidden && ! blankPageShown)
{
// when the component becomes invisible, some stuff like flash
// carries on playing audio, so we need to force it onto a blank
// page to avoid this, (and send it back when it's made visible again).
blankPageShown = true;
browser->goToURL ("about:blank", nullptr, nullptr);
}
}
}
void WebBrowserComponent::reloadLastURL()
{
if (lastURL.isNotEmpty())
{
goToURL (lastURL, &lastHeaders, &lastPostData);
lastURL.clear();
}
}
void WebBrowserComponent::parentHierarchyChanged()
{
checkWindowAssociation();
}
void WebBrowserComponent::resized()
{
browser->setSize (getWidth(), getHeight());
}
void WebBrowserComponent::visibilityChanged()
{
checkWindowAssociation();
}
void WebBrowserComponent::focusGainedWithDirection (FocusChangeType, FocusChangeDirection)
{
}
void WebBrowserComponent::clearCookies() void WebBrowserComponent::clearCookies()
{ {
NSHTTPCookieStorage* storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; NSHTTPCookieStorage* storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];

View file

@ -35,30 +35,15 @@
namespace juce namespace juce
{ {
struct InternalWebViewType struct WebBrowserComponent::Impl::Platform : public PlatformInterface
{ {
InternalWebViewType() = default; class Win32WebView;
virtual ~InternalWebViewType() = default; class WebView2;
virtual void createBrowser() = 0;
virtual bool hasBrowserBeenCreated() = 0;
virtual void goToURL (const String&, const StringArray*, const MemoryBlock*) = 0;
virtual void stop() = 0;
virtual void goBack() = 0;
virtual void goForward() = 0;
virtual void refresh() = 0;
virtual void focusGained() {}
virtual void setWebViewSize (int, int) = 0;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InternalWebViewType)
}; };
//============================================================================== //==============================================================================
class Win32WebView final : public InternalWebViewType, class WebBrowserComponent::Impl::Platform::Win32WebView final : public WebBrowserComponent::Impl::PlatformInterface,
public ActiveXControlComponent public ActiveXControlComponent
{ {
public: public:
Win32WebView (WebBrowserComponent& parent, const String& userAgentToUse) Win32WebView (WebBrowserComponent& parent, const String& userAgentToUse)
@ -68,6 +53,35 @@ public:
owner.addAndMakeVisible (this); owner.addAndMakeVisible (this);
} }
void checkWindowAssociation() override
{
if (owner.isShowing())
{
if (! hasBrowserBeenCreated() && owner.getPeer() != nullptr)
{
createBrowser();
owner.reloadLastURL();
}
else
{
if (owner.blankPageShown)
goBack();
}
}
else
{
if (owner.unloadPageWhenHidden && ! owner.blankPageShown)
{
// when the component becomes invisible, some stuff like flash
// carries on playing audio, so we need to force it onto a blank
// page to avoid this..
owner.blankPageShown = true;
goToURL ("about:blank", nullptr, nullptr);
}
}
}
~Win32WebView() override ~Win32WebView() override
{ {
if (connectionPoint != nullptr) if (connectionPoint != nullptr)
@ -80,7 +94,7 @@ public:
browser->Release(); browser->Release();
} }
void createBrowser() override void createBrowser()
{ {
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token") JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token")
@ -117,13 +131,24 @@ public:
JUCE_END_IGNORE_WARNINGS_GCC_LIKE JUCE_END_IGNORE_WARNINGS_GCC_LIKE
} }
bool hasBrowserBeenCreated() override bool hasBrowserBeenCreated()
{ {
return browser != nullptr; return browser != nullptr;
} }
void fallbackPaint (Graphics& webBrowserComponentContext) override
{
if (! hasBrowserBeenCreated())
{
webBrowserComponentContext.fillAll (Colours::white);
checkWindowAssociation();
}
}
void goToURL (const String& url, const StringArray* requestedHeaders, const MemoryBlock* postData) override void goToURL (const String& url, const StringArray* requestedHeaders, const MemoryBlock* postData) override
{ {
checkWindowAssociation();
if (browser != nullptr) if (browser != nullptr)
{ {
VARIANT headerFlags, frame, postDataVar, headersVar; // (_variant_t isn't available in all compilers) VARIANT headerFlags, frame, postDataVar, headersVar; // (_variant_t isn't available in all compilers)
@ -211,7 +236,7 @@ public:
browser->Refresh(); browser->Refresh();
} }
void focusGained() override void focusGainedWithDirection (FocusChangeType, FocusChangeDirection) override
{ {
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token") JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token")
@ -241,13 +266,17 @@ public:
JUCE_END_IGNORE_WARNINGS_GCC_LIKE JUCE_END_IGNORE_WARNINGS_GCC_LIKE
} }
using ActiveXControlComponent::focusGained;
void setWebViewSize (int width, int height) override void setWebViewSize (int width, int height) override
{ {
setSize (width, height); setSize (width, height);
} }
void evaluateJavascript (const String&, WebBrowserComponent::EvaluationCallback) override
{
// This feature is only supported when using WebView2
jassertfalse;
}
private: private:
WebBrowserComponent& owner; WebBrowserComponent& owner;
IWebBrowser2* browser = nullptr; IWebBrowser2* browser = nullptr;
@ -404,24 +433,69 @@ static bool anyChildWindow (HWND hwnd, std::function<bool (HWND)> predicate)
return result; return result;
} }
class WebView2 final : public InternalWebViewType, static constexpr const char* platformSpecificIntegrationScript = R"(
public Component, window.__JUCE__ = {
public ComponentMovementWatcher, postMessage: function(object) {
private AsyncUpdater window.chrome.webview.postMessage(object);
},
};
)";
class WebBrowserComponent::Impl::Platform::WebView2 final : public WebBrowserComponent::Impl::PlatformInterface,
public Component,
public ComponentMovementWatcher,
private AsyncUpdater
{ {
public: public:
WebView2 (WebBrowserComponent& o, const WebBrowserComponent::Options& prefs) static std::unique_ptr<WebView2> tryConstruct (WebBrowserComponent& o,
: ComponentMovementWatcher (&o), const WebBrowserComponent::Options& prefs,
owner (o), const StringArray& userScriptsIn)
preferences (prefs.getWinWebView2BackendOptions()),
userAgent (prefs.getUserAgent())
{ {
if (auto handle = createWebViewHandle (preferences)) if (auto handle = createWebViewHandle (prefs))
webViewHandle = std::move (*handle); return rawToUniquePtr (new WebView2 (o, prefs, userScriptsIn, std::move (*handle)));
else
throw std::runtime_error ("Failed to create the CoreWebView2Environment");
owner.addAndMakeVisible (this); return nullptr;
}
void checkWindowAssociation() override
{
if (owner.isShowing())
{
if (! hasBrowserBeenCreated() && owner.getPeer() != nullptr)
{
createBrowser();
owner.reloadLastURL();
}
else
{
if (owner.blankPageShown)
goBack();
}
}
else
{
if (owner.unloadPageWhenHidden && ! owner.blankPageShown)
{
// when the component becomes invisible, some stuff like flash
// carries on playing audio, so we need to force it onto a blank
// page to avoid this..
owner.blankPageShown = true;
goToURL ("about:blank", nullptr, nullptr);
}
}
if (! hasBrowserBeenCreated())
createBrowser();
}
void fallbackPaint (Graphics& webBrowserComponentContext) override
{
if (! hasBrowserBeenCreated())
{
webBrowserComponentContext.fillAll (Colours::white);
checkWindowAssociation();
}
} }
void focusGainedWithDirection (FocusChangeType, FocusChangeDirection direction) override void focusGainedWithDirection (FocusChangeType, FocusChangeDirection direction) override
@ -450,7 +524,7 @@ public:
closeWebView(); closeWebView();
} }
void createBrowser() override void createBrowser()
{ {
if (webView == nullptr) if (webView == nullptr)
{ {
@ -459,7 +533,7 @@ public:
} }
} }
bool hasBrowserBeenCreated() override bool hasBrowserBeenCreated()
{ {
return webView != nullptr return webView != nullptr
|| webView2ConstructionHelper.webView2BeingCreated == this || webView2ConstructionHelper.webView2BeingCreated == this
@ -468,6 +542,8 @@ public:
void goToURL (const String& url, const StringArray* headers, const MemoryBlock* postData) override void goToURL (const String& url, const StringArray* headers, const MemoryBlock* postData) override
{ {
checkWindowAssociation();
urlRequest = { url, urlRequest = { url,
headers != nullptr ? *headers : StringArray(), headers != nullptr ? *headers : StringArray(),
postData != nullptr && postData->getSize() > 0 ? *postData : MemoryBlock() }; postData != nullptr && postData->getSize() > 0 ? *postData : MemoryBlock() };
@ -517,7 +593,7 @@ public:
setSize (width, height); setSize (width, height);
} }
void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/) override void componentMovedOrResized (bool, bool) override
{ {
if (auto* peer = owner.getTopLevelComponent()->getPeer()) if (auto* peer = owner.getTopLevelComponent()->getPeer())
setControlBounds (peer->getAreaCoveredBy (owner)); setControlBounds (peer->getAreaCoveredBy (owner));
@ -549,36 +625,42 @@ public:
ComSmartPtr<ICoreWebView2Environment> environment; ComSmartPtr<ICoreWebView2Environment> environment;
}; };
static std::optional<WebViewHandle> createWebViewHandle (const WebBrowserComponent::Options::WinWebView2& options) static std::optional<WebViewHandle> createWebViewHandle (const WebBrowserComponent::Options& options)
{ {
using CreateWebViewEnvironmentWithOptionsFunc = HRESULT (*) (PCWSTR, PCWSTR, using CreateWebViewEnvironmentWithOptionsFunc = HRESULT (__stdcall *) (PCWSTR, PCWSTR,
ICoreWebView2EnvironmentOptions*, ICoreWebView2EnvironmentOptions*,
ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler*); ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler*);
auto dllPath = options.getDLLLocation().getFullPathName(); auto dllPath = options.getWinWebView2BackendOptions().getDLLLocation().getFullPathName();
if (dllPath.isEmpty()) if (dllPath.isEmpty())
dllPath = "WebView2Loader.dll"; dllPath = "WebView2Loader.dll";
WebViewHandle result; WebViewHandle result;
result.loaderHandle = WebViewHandle::LibraryRef (LoadLibraryA (dllPath.toUTF8()), &::FreeLibrary); auto* createWebViewEnvironmentWithOptions = [&]() -> CreateWebViewEnvironmentWithOptionsFunc
{
#if JUCE_USE_WIN_WEBVIEW2_WITH_STATIC_LINKING
return &CreateCoreWebView2EnvironmentWithOptions;
#else
result.loaderHandle = WebViewHandle::LibraryRef (LoadLibraryA (dllPath.toUTF8()), &::FreeLibrary);
if (result.loaderHandle == nullptr) if (result.loaderHandle == nullptr)
return {}; return nullptr;
auto* createWebViewEnvironmentWithOptions = (CreateWebViewEnvironmentWithOptionsFunc) GetProcAddress (result.loaderHandle.get(), return (CreateWebViewEnvironmentWithOptionsFunc) GetProcAddress (result.loaderHandle.get(),
"CreateCoreWebView2EnvironmentWithOptions"); "CreateCoreWebView2EnvironmentWithOptions");
if (createWebViewEnvironmentWithOptions == nullptr) #endif
return {}; }();
auto webViewOptions = Microsoft::WRL::Make<CoreWebView2EnvironmentOptions>(); auto webViewOptions = Microsoft::WRL::Make<CoreWebView2EnvironmentOptions>();
const auto userDataFolder = options.getUserDataFolder().getFullPathName();
const auto userDataFolder = options.getWinWebView2BackendOptions().getUserDataFolder().getFullPathName();
auto hr = createWebViewEnvironmentWithOptions (nullptr, auto hr = createWebViewEnvironmentWithOptions (nullptr,
userDataFolder.isNotEmpty() ? userDataFolder.toWideCharPointer() : nullptr, userDataFolder.isNotEmpty() ? userDataFolder.toWideCharPointer() : nullptr,
webViewOptions.Get(), webViewOptions.Get(),
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>( Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler> (
[&result] (HRESULT, ICoreWebView2Environment* env) -> HRESULT [&result] (HRESULT, ICoreWebView2Environment* env) -> HRESULT
{ {
result.environment = env; result.environment = env;
@ -591,7 +673,54 @@ public:
return result; return result;
} }
void evaluateJavascript (const String& script, EvaluationCallback callbackIn) override
{
if (webView == nullptr)
{
scriptsWaitingForExecution.push_back ({ script, std::move (callbackIn) });
triggerAsyncUpdate();
return;
}
webView->ExecuteScript (script.toUTF16(),
Callback<ICoreWebView2ExecuteScriptCompletedHandler> (
[callback = std::move (callbackIn)] (HRESULT error, PCWSTR result) -> HRESULT
{
if (callback == nullptr)
return S_OK;
const auto callbackArg = [&]
{
using Error = WebBrowserComponent::EvaluationResult::Error;
if (error != S_OK)
return EvaluationResult { Error { Error::Type::unknown, "Error code: " + String { error } } };
return EvaluationResult { JSON::fromString (StringRef { CharPointer_UTF16 { result } }) };
}();
callback (callbackArg);
return S_OK;
}).Get());
}
private: private:
//==============================================================================
WebView2 (WebBrowserComponent& o,
const WebBrowserComponent::Options& prefs,
const StringArray& userScriptsIn,
WebViewHandle handle)
: ComponentMovementWatcher (&o),
owner (o),
preferences (prefs),
userAgent (prefs.getUserAgent()),
userScripts (userScriptsIn),
webViewHandle (std::move (handle))
{
owner.addAndMakeVisible (this);
}
//============================================================================== //==============================================================================
template <class ArgType> template <class ArgType>
static String getUriStringFromArgs (ArgType* args) static String getUriStringFromArgs (ArgType* args)
@ -600,8 +729,10 @@ private:
{ {
LPWSTR uri; LPWSTR uri;
args->get_Uri (&uri); args->get_Uri (&uri);
String result { CharPointer_UTF16 { uri } };
CoTaskMemFree (uri);
return uri; return result;
} }
return {}; return {};
@ -677,20 +808,17 @@ private:
return S_OK; return S_OK;
}).Get(), &navigationCompletedToken); }).Get(), &navigationCompletedToken);
webView->AddWebResourceRequestedFilter (L"*", COREWEBVIEW2_WEB_RESOURCE_CONTEXT_DOCUMENT); webView->AddWebResourceRequestedFilter (L"*", COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL);
webView->add_WebResourceRequested (Callback<ICoreWebView2WebResourceRequestedEventHandler> ( webView->add_WebResourceRequested (Callback<ICoreWebView2WebResourceRequestedEventHandler> (
[this] (ICoreWebView2*, ICoreWebView2WebResourceRequestedEventArgs* args) -> HRESULT [this] (ICoreWebView2*, ICoreWebView2WebResourceRequestedEventArgs* args) -> HRESULT
{ {
if (urlRequest.url.isEmpty())
return S_OK;
ComSmartPtr<ICoreWebView2WebResourceRequest> request; ComSmartPtr<ICoreWebView2WebResourceRequest> request;
args->get_Request (request.resetAndGetPointerAddress()); args->get_Request (request.resetAndGetPointerAddress());
auto uriString = getUriStringFromArgs<ICoreWebView2WebResourceRequest> (request); auto uriString = getUriStringFromArgs<ICoreWebView2WebResourceRequest> (request);
if (uriString == urlRequest.url if (! urlRequest.url.isEmpty() && uriString == urlRequest.url
|| (uriString.endsWith ("/") && uriString.upToLastOccurrenceOf ("/", false, false) == urlRequest.url)) || (uriString.endsWith ("/") && uriString.upToLastOccurrenceOf ("/", false, false) == urlRequest.url))
{ {
String method ("GET"); String method ("GET");
@ -721,8 +849,49 @@ private:
urlRequest = {}; urlRequest = {};
} }
if (const auto resourceRequestUri = uriString.fromFirstOccurrenceOf ("https://juce.backend", false, false);
resourceRequestUri.isNotEmpty())
{
if (auto responseData = owner.impl->handleResourceRequest (resourceRequestUri))
{
ComSmartPtr<IStream> stream (SHCreateMemStream ((BYTE*) responseData->data.data(),
(UINT) responseData->data.size()));
StringArray headers { "Content-Type: " + responseData->mimeType };
if (const auto allowedOrigin = owner.impl->options.getAllowedOrigin())
headers.add ("Access-Control-Allow-Origin: " + *allowedOrigin);
ComSmartPtr<ICoreWebView2WebResourceResponse> response;
if (webViewHandle.environment->CreateWebResourceResponse (stream,
200,
L"OK",
headers.joinIntoString ("\n").toUTF16(),
response.resetAndGetPointerAddress())
!= S_OK)
{
return E_FAIL;
}
args->put_Response (response);
}
}
return S_OK; return S_OK;
}).Get(), &webResourceRequestedToken); }).Get(), &webResourceRequestedToken);
webView->add_WebMessageReceived (Callback<ICoreWebView2WebMessageReceivedEventHandler> (
[this] (ICoreWebView2*, ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT
{
if (LPWSTR message = {};
args->TryGetWebMessageAsString (std::addressof (message)) == S_OK)
{
owner.impl->handleNativeEvent (JSON::fromString (StringRef { CharPointer_UTF16 (message) }));
}
return S_OK;
}).Get(), &webMessageReceivedToken);
} }
if (webViewController != nullptr) if (webViewController != nullptr)
@ -786,6 +955,9 @@ private:
webView->RemoveWebResourceRequestedFilter (L"*", COREWEBVIEW2_WEB_RESOURCE_CONTEXT_DOCUMENT); webView->RemoveWebResourceRequestedFilter (L"*", COREWEBVIEW2_WEB_RESOURCE_CONTEXT_DOCUMENT);
webView->remove_WebResourceRequested (webResourceRequestedToken); webView->remove_WebResourceRequested (webResourceRequestedToken);
} }
if (webMessageReceivedToken.value != 0)
webView->remove_WebMessageReceived (webMessageReceivedToken);
} }
if (webViewController != nullptr) if (webViewController != nullptr)
@ -802,7 +974,7 @@ private:
if (controller2 != nullptr) if (controller2 != nullptr)
{ {
const auto bgColour = preferences.getBackgroundColour(); const auto bgColour = preferences.getWinWebView2BackendOptions().getBackgroundColour();
controller2->put_DefaultBackgroundColor ({ (BYTE) bgColour.getAlpha(), controller2->put_DefaultBackgroundColor ({ (BYTE) bgColour.getAlpha(),
(BYTE) bgColour.getRed(), (BYTE) bgColour.getRed(),
@ -815,8 +987,12 @@ private:
if (settings != nullptr) if (settings != nullptr)
{ {
settings->put_IsStatusBarEnabled (! preferences.getIsStatusBarDisabled()); #if ! JUCE_DEBUG
settings->put_IsBuiltInErrorPageEnabled (! preferences.getIsBuiltInErrorPageDisabled()); settings->put_AreDevToolsEnabled (false);
#endif
settings->put_IsStatusBarEnabled (! preferences.getWinWebView2BackendOptions().getIsStatusBarDisabled());
settings->put_IsBuiltInErrorPageEnabled (! preferences.getWinWebView2BackendOptions().getIsBuiltInErrorPageDisabled());
if (userAgent.isNotEmpty()) if (userAgent.isNotEmpty())
{ {
@ -862,6 +1038,22 @@ private:
weakThis->webViewController = controller; weakThis->webViewController = controller;
controller->get_CoreWebView2 (weakThis->webView.resetAndGetPointerAddress()); controller->get_CoreWebView2 (weakThis->webView.resetAndGetPointerAddress());
auto allUserScripts = weakThis->userScripts;
allUserScripts.insert (0, platformSpecificIntegrationScript);
for (const auto& script : allUserScripts)
{
weakThis->webView->AddScriptToExecuteOnDocumentCreated (script.toUTF16(),
Callback<ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler> (
[] (HRESULT error, PCWSTR) -> HRESULT
{
if (error != S_OK)
jassertfalse;
return S_OK;
}).Get());
}
if (weakThis->webView != nullptr) if (weakThis->webView != nullptr)
{ {
if (UINT32 browserProcessId; if (UINT32 browserProcessId;
@ -936,7 +1128,24 @@ private:
//============================================================================== //==============================================================================
void handleAsyncUpdate() override void handleAsyncUpdate() override
{ {
createWebView(); if (webView == nullptr && ! webViewBeingCreated)
{
webViewBeingCreated = true;
createWebView();
}
if (webView == nullptr && ! scriptsWaitingForExecution.empty())
{
triggerAsyncUpdate();
return;
}
while (! scriptsWaitingForExecution.empty())
{
auto [script, callback] = scriptsWaitingForExecution.front();
scriptsWaitingForExecution.pop_front();
evaluateJavascript (script, std::move (callback));
}
} }
//============================================================================== //==============================================================================
@ -962,19 +1171,22 @@ private:
//============================================================================== //==============================================================================
WebBrowserComponent& owner; WebBrowserComponent& owner;
WebBrowserComponent::Options::WinWebView2 preferences; WebBrowserComponent::Options preferences;
String userAgent; String userAgent;
StringArray userScripts;
WebViewHandle webViewHandle; WebViewHandle webViewHandle;
ComSmartPtr<ICoreWebView2Controller> webViewController; ComSmartPtr<ICoreWebView2Controller> webViewController;
ComSmartPtr<ICoreWebView2> webView; ComSmartPtr<ICoreWebView2> webView;
bool webViewBeingCreated = false;
EventRegistrationToken navigationStartingToken { 0 }, EventRegistrationToken navigationStartingToken { 0 },
newWindowRequestedToken { 0 }, newWindowRequestedToken { 0 },
windowCloseRequestedToken { 0 }, windowCloseRequestedToken { 0 },
navigationCompletedToken { 0 }, navigationCompletedToken { 0 },
webResourceRequestedToken { 0 }, webResourceRequestedToken { 0 },
moveFocusRequestedToken { 0 }; moveFocusRequestedToken { 0 },
webMessageReceivedToken { 0 };
bool inMoveFocusRequested = false; bool inMoveFocusRequested = false;
@ -995,6 +1207,7 @@ private:
}; };
inline static WebView2ConstructionHelper webView2ConstructionHelper; inline static WebView2ConstructionHelper webView2ConstructionHelper;
std::deque<std::pair<String, EvaluationCallback>> scriptsWaitingForExecution;
NativeScaleFactorNotifier scaleFactorNotifier { this, NativeScaleFactorNotifier scaleFactorNotifier { this,
[this] (auto) [this] (auto)
@ -1010,176 +1223,6 @@ private:
#endif #endif
//============================================================================== //==============================================================================
class WebBrowserComponent::Pimpl
{
public:
Pimpl (WebBrowserComponent& owner,
[[maybe_unused]] const Options& preferences,
bool useWebView2,
const String& userAgent)
{
if (useWebView2)
{
#if JUCE_USE_WIN_WEBVIEW2
try
{
internal.reset (new WebView2 (owner, preferences));
}
catch (const std::runtime_error&) {}
#endif
}
if (internal == nullptr)
internal.reset (new Win32WebView (owner, userAgent));
}
InternalWebViewType& getInternalWebView()
{
return *internal;
}
private:
std::unique_ptr<InternalWebViewType> internal;
};
//==============================================================================
WebBrowserComponent::WebBrowserComponent (const Options& options)
: browser (new Pimpl (*this, options,
options.getBackend() == Options::Backend::webview2, options.getUserAgent())),
unloadPageWhenHidden (! options.keepsPageLoadedWhenBrowserIsHidden())
{
setOpaque (true);
}
WebBrowserComponent::~WebBrowserComponent()
{
}
//==============================================================================
void WebBrowserComponent::goToURL (const String& url,
const StringArray* headers,
const MemoryBlock* postData)
{
lastURL = url;
if (headers != nullptr)
lastHeaders = *headers;
else
lastHeaders.clear();
if (postData != nullptr)
lastPostData = *postData;
else
lastPostData.reset();
blankPageShown = false;
if (! browser->getInternalWebView().hasBrowserBeenCreated())
checkWindowAssociation();
browser->getInternalWebView().goToURL (url, headers, postData);
}
void WebBrowserComponent::stop()
{
browser->getInternalWebView().stop();
}
void WebBrowserComponent::goBack()
{
lastURL.clear();
blankPageShown = false;
browser->getInternalWebView().goBack();
}
void WebBrowserComponent::goForward()
{
lastURL.clear();
browser->getInternalWebView().goForward();
}
void WebBrowserComponent::refresh()
{
browser->getInternalWebView().refresh();
}
//==============================================================================
void WebBrowserComponent::paint (Graphics& g)
{
if (! browser->getInternalWebView().hasBrowserBeenCreated())
{
g.fillAll (Colours::white);
checkWindowAssociation();
}
}
void WebBrowserComponent::checkWindowAssociation()
{
if (isShowing())
{
if (! browser->getInternalWebView().hasBrowserBeenCreated() && getPeer() != nullptr)
{
browser->getInternalWebView().createBrowser();
reloadLastURL();
}
else
{
if (blankPageShown)
goBack();
}
}
else
{
if (browser != nullptr && unloadPageWhenHidden && ! blankPageShown)
{
// when the component becomes invisible, some stuff like flash
// carries on playing audio, so we need to force it onto a blank
// page to avoid this..
blankPageShown = true;
browser->getInternalWebView().goToURL ("about:blank", nullptr, nullptr);
}
}
}
void WebBrowserComponent::reloadLastURL()
{
if (lastURL.isNotEmpty())
{
goToURL (lastURL, &lastHeaders, &lastPostData);
lastURL.clear();
}
}
void WebBrowserComponent::parentHierarchyChanged()
{
checkWindowAssociation();
}
void WebBrowserComponent::resized()
{
browser->getInternalWebView().setWebViewSize (getWidth(), getHeight());
}
void WebBrowserComponent::visibilityChanged()
{
checkWindowAssociation();
}
void WebBrowserComponent::focusGainedWithDirection (FocusChangeType type, FocusChangeDirection dir)
{
ignoreUnused (type, dir);
#if JUCE_USE_WIN_WEBVIEW2
if (auto* webView2 = dynamic_cast<WebView2*> (&browser->getInternalWebView()))
webView2->focusGainedWithDirection (type, dir);
else
#endif
browser->getInternalWebView().focusGained();
}
void WebBrowserComponent::clearCookies() void WebBrowserComponent::clearCookies()
{ {
HeapBlock<::INTERNET_CACHE_ENTRY_INFOA> entry; HeapBlock<::INTERNET_CACHE_ENTRY_INFOA> entry;
@ -1226,11 +1269,27 @@ bool WebBrowserComponent::areOptionsSupported (const Options& options)
if (options.getBackend() != Options::Backend::webview2) if (options.getBackend() != Options::Backend::webview2)
return false; return false;
if (auto webView = WebView2::createWebViewHandle (options.getWinWebView2BackendOptions())) if (auto webView = WebBrowserComponent::Impl::Platform::WebView2::createWebViewHandle (options))
return true; return true;
#endif #endif
return false; return false;
} }
auto WebBrowserComponent::Impl::createAndInitPlatformDependentPart (WebBrowserComponent::Impl& impl,
const WebBrowserComponent::Options& options,
[[maybe_unused]] const StringArray& userScripts)
-> std::unique_ptr<PlatformInterface>
{
if (options.getBackend() == WebBrowserComponent::Options::Backend::webview2)
{
#if JUCE_USE_WIN_WEBVIEW2
if (auto constructed = Platform::WebView2::tryConstruct (impl.owner, options, userScripts))
return constructed;
#endif
}
return std::make_unique<Platform::Win32WebView> (impl.owner, options.getUserAgent());
}
} // namespace juce } // namespace juce