Merge pull request #514 from rh101/windows-webview

Implement Windows WebView using WebView2 Edge Chromium
This commit is contained in:
halx99 2021-10-05 15:40:14 +08:00 committed by GitHub
commit 3345d2f145
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1550 additions and 1 deletions

5
.gitignore vendored
View File

@ -190,4 +190,7 @@ temp/
# New .cxx temp folder
**/.cxx
**/SharedLoader.java
**/SharedLoader.java
# ignore downloaded tools
tools/external/

View File

@ -159,6 +159,18 @@ if(WINDOWS)
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/precheader.cpp" PROPERTIES COMPILE_FLAGS "/Ycprecheader.h")
# compile c as c++. needed for precompiled header
set_source_files_properties(${COCOS_SPINE_SRC} base/ccFPSImages.c PROPERTIES LANGUAGE CXX)
find_program(NUGET_EXE NAMES nuget
PATHS ${ADXE_ROOT_PATH}/tools/external/nuget)
if(NOT NUGET_EXE)
message("NUGET.EXE not found.")
message(FATAL_ERROR "Please run setup.py again to download NUGET.EXE, and run CMake again.")
endif()
exec_program(${NUGET_EXE}
ARGS install "Microsoft.Web.WebView2" -Version 1.0.992.28 -ExcludeVersion -OutputDirectory ${CMAKE_BINARY_DIR}/packages)
target_link_libraries(${ADXE_CORE_LIB} ${CMAKE_BINARY_DIR}/packages/Microsoft.Web.WebView2/build/native/Microsoft.Web.WebView2.targets)
endif()
# engine extensions

View File

@ -353,6 +353,80 @@ namespace utils
{
return ((number > 0) && (number & (number - 1)) == 0);
}
// Convert ASCII hex digit to a nibble (four bits, 0 - 15).
//
// Use unsigned to avoid signed overflow UB.
inline unsigned char hex2nibble(unsigned char c)
{
if (c >= '0' && c <= '9')
{
return c - '0';
}
else if (c >= 'a' && c <= 'f')
{
return 10 + (c - 'a');
}
else if (c >= 'A' && c <= 'F')
{
return 10 + (c - 'A');
}
return 0;
}
// Convert ASCII hex string (two characters) to byte.
//
// E.g., "0B" => 0x0B, "af" => 0xAF.
inline char hex2char(const char* p)
{
return hex2nibble(p[0]) * 16 + hex2nibble(p[1]);
}
inline std::string urlEncode(const std::string& s)
{
std::string encoded;
for (const char c : s)
{
if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~')
{
encoded = encoded + c;
}
else
{
char hex[4];
snprintf(hex, sizeof(hex), "%%%02x", c);
encoded = encoded + hex;
}
}
return encoded;
}
inline std::string urlDecode(const std::string& st)
{
std::string decoded;
const char* s = st.c_str();
const size_t length = st.length();
for (unsigned int i = 0; i < length; ++i)
{
if (!s[i])
break;
if (s[i] == '%')
{
decoded.push_back(hex2char(s + i + 1));
i = i + 2;
}
else if (s[i] == '+')
{
decoded.push_back(' ');
}
else
{
decoded.push_back(s[i]);
}
}
return decoded;
}
}
NS_CC_END

View File

@ -1,9 +1,13 @@
if(WINDOWS)
set(COCOS_UI_SPECIFIC_HEADER
ui/UIEditBox/UIEditBoxImpl-win32.h
ui/UIWebView/UIWebViewImpl-win32.h
ui/UIWebView/UIWebView.h
)
set(COCOS_UI_SPECIFIC_SRC
ui/UIEditBox/UIEditBoxImpl-win32.cpp
ui/UIWebView/UIWebViewImpl-win32.cpp
ui/UIWebView/UIWebView.cpp
)
elseif(APPLE)
if(MACOSX)

View File

@ -22,5 +22,16 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "platform/CCPlatformConfig.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "ui/UIWebView/UIWebViewImpl-android.h"
#include "ui/UIWebView/UIWebView-inl.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "ui/UIWebView/UIWebViewImpl-win32.h"
#include "ui/UIWebView/UIWebView-inl.h"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,89 @@
/****************************************************************************
Copyright (c) 2014 cocos2d-x.org
Author: Jeff Wang <wohaaitinciu@gmail.com>
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __COCOS2D__UI__WEBVIEWIMPL_WIN32_H_
#define __COCOS2D__UI__WEBVIEWIMPL_WIN32_H_
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#include <string>
#include "CCStdC.h"
namespace cocos2d {
class Data;
class Renderer;
class Mat4;
namespace ui {
class WebView;
}
}
class Win32WebControl;
namespace cocos2d {
namespace ui {
class WebViewImpl
{
public:
WebViewImpl(cocos2d::ui::WebView *webView);
virtual ~WebViewImpl();
void setJavascriptInterfaceScheme(const std::string &scheme);
void loadData(const cocos2d::Data &data, const std::string &MIMEType, const std::string &encoding, const std::string &baseURL);
void loadHTMLString(const std::string &string, const std::string &baseURL);
void loadURL(const std::string &url, bool cleanCachedData);
void loadFile(const std::string &fileName);
void stopLoading();
void reload();
bool canGoBack();
bool canGoForward();
void goBack();
void goForward();
void evaluateJS(const std::string &js);
void setScalesPageToFit(const bool scalesPageToFit);
virtual void draw(cocos2d::Renderer *renderer, cocos2d::Mat4 const &transform, uint32_t flags);
virtual void setVisible(bool visible);
void setBounces(bool bounces);
void setOpacityWebView(float opacity);
float getOpacityWebView() const;
void setBackgroundTransparent();
private:
bool _createSucceeded;
Win32WebControl *_systemWebControl;
WebView *_webView;
};
} // namespace ui
} //cocos2d
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#endif // __COCOS2D__UI__WEBVIEWIMPL_WIN32_H_

102
setup.py
View File

@ -59,6 +59,9 @@ try:
except Exception:
pass
from optparse import OptionParser
from time import time
from time import sleep
from os.path import dirname
ADXE_ROOT = 'ADXE_ROOT'
ADXE_CONSOLE_ROOT = 'ADXE_CONSOLE_ROOT'
@ -667,6 +670,93 @@ class SetEnvVar(object):
print('\nPlease execute command: "source %s" to make added system variables take effect\n' %
self.file_used_for_setup)
class FileDownloader(object):
def __init__(self):
self.current_absolute_path = os.path.dirname(os.path.realpath(__file__))
def download_file(self, url, filename):
# remove file for retry
try:
os.remove(filename)
except OSError:
pass
print("==> Ready to download '%s' from '%s'" % (filename, url))
import urllib2
try:
u = urllib2.urlopen(url)
except urllib2.HTTPError as e:
if e.code == 404:
print("==> Error: Could not find the file from url: '%s'" % (url))
print("==> Http request failed, error code: " + str(e.code) + ", reason: " + e.read())
sys.exit(1)
f = open(filename, 'wb')
meta = u.info()
content_len = meta.getheaders("Content-Length")
file_size = 0
if content_len and len(content_len) > 0:
file_size = int(content_len[0])
else:
print("==> WARNING: Couldn't grab the file size from remote")
return
print("==> Start to download, please wait ...")
file_size_dl = 0
block_sz = 8192
block_size_per_second = 0
old_time = time()
status = ""
while True:
buffer = u.read(block_sz)
if not buffer:
print("%s%s" % (" " * len(status), "\r")),
break
file_size_dl += len(buffer)
block_size_per_second += len(buffer)
f.write(buffer)
new_time = time()
if (new_time - old_time) > 1:
speed = block_size_per_second / (new_time - old_time) / 1000.0
if file_size != 0:
percent = file_size_dl * 100. / file_size
status = r"Downloaded: %6dK / Total: %dK, Percent: %3.2f%%, Speed: %6.2f KB/S " % (file_size_dl / 1000, file_size / 1000, percent, speed)
else:
status = r"Downloaded: %6dK, Speed: %6.2f KB/S " % (file_size_dl / 1000, speed)
print(status),
sys.stdout.flush()
print("\r"),
block_size_per_second = 0
old_time = new_time
print("==> Downloading finished!")
f.close()
def ensure_directory(self, target):
if not os.path.exists(target):
os.mkdir(target)
def download_file_with_retry(self, url, filename, times, delay):
import urllib2
output_path = dirname(filename)
downloader.ensure_directory(output_path)
times_count = 0
while(times_count < times):
times_count += 1
try:
if(times_count > 1):
print("==> Download file retry " + str(times_count))
self.download_file(url, filename)
return
except Exception as err:
if(times_count >= times):
raise err
sleep(delay)
if __name__ == '__main__':
if not _check_python_version():
exit()
@ -700,3 +790,15 @@ if __name__ == '__main__':
SendMessageTimeoutW = ctypes.windll.user32.SendMessageTimeoutW
SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
u'Environment', SMTO_ABORTIFHUNG, 5000, ctypes.byref(result))
current_absolute_path = os.path.dirname(os.path.realpath(__file__))
external_tools_path = os.path.join(current_absolute_path, 'tools', 'external')
if not os.path.exists(external_tools_path):
os.mkdir(external_tools_path)
downloader = FileDownloader()
if env._isWindows():
file_path = os.path.join(external_tools_path, 'nuget', 'nuget.exe')
if not os.path.isfile(file_path):
downloader.download_file_with_retry('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', file_path, 5, 3)

View File

@ -361,6 +361,15 @@ if(WINDOWS OR MACOSX OR LINUX)
)
endif()
if(WINDOWS)
list(APPEND GAME_HEADER
Classes/UITest/CocoStudioGUITest/UIWebViewTest/UIWebViewTest.h
)
list(APPEND GAME_SOURCE
Classes/UITest/CocoStudioGUITest/UIWebViewTest/UIWebViewTest.cpp
)
endif()
list(APPEND GAME_HEADER
Classes/Box2DTest/Box2dTest.h
)

View File

@ -51,11 +51,17 @@
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "UIEditBoxTest.h"
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "UIWebViewTest/UIWebViewTest.h"
#endif
GUIDynamicCreateTests::GUIDynamicCreateTests()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
addTest("VideoPlayer Test", [](){ return new (std::nothrow) VideoPlayerTests; });
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
addTest("WebView Test", [](){ return new (std::nothrow) WebViewTests; });
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)

View File

@ -27,6 +27,7 @@
#define __cocos2d_tests__UIWebViewTest__
#include "../UIScene.h"
#include "ui/UIWebView/UIWebView.h"
DEFINE_TEST_SUITE(WebViewTests);