mirror of https://github.com/axmolengine/axmol.git
Merge pull request #514 from rh101/windows-webview
Implement Windows WebView using WebView2 Edge Chromium
This commit is contained in:
commit
3345d2f145
|
@ -191,3 +191,6 @@ temp/
|
||||||
**/.cxx
|
**/.cxx
|
||||||
|
|
||||||
**/SharedLoader.java
|
**/SharedLoader.java
|
||||||
|
|
||||||
|
# ignore downloaded tools
|
||||||
|
tools/external/
|
|
@ -159,6 +159,18 @@ if(WINDOWS)
|
||||||
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/precheader.cpp" PROPERTIES COMPILE_FLAGS "/Ycprecheader.h")
|
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/precheader.cpp" PROPERTIES COMPILE_FLAGS "/Ycprecheader.h")
|
||||||
# compile c as c++. needed for precompiled header
|
# compile c as c++. needed for precompiled header
|
||||||
set_source_files_properties(${COCOS_SPINE_SRC} base/ccFPSImages.c PROPERTIES LANGUAGE CXX)
|
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()
|
endif()
|
||||||
|
|
||||||
# engine extensions
|
# engine extensions
|
||||||
|
|
|
@ -353,6 +353,80 @@ namespace utils
|
||||||
{
|
{
|
||||||
return ((number > 0) && (number & (number - 1)) == 0);
|
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
|
NS_CC_END
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
if(WINDOWS)
|
if(WINDOWS)
|
||||||
set(COCOS_UI_SPECIFIC_HEADER
|
set(COCOS_UI_SPECIFIC_HEADER
|
||||||
ui/UIEditBox/UIEditBoxImpl-win32.h
|
ui/UIEditBox/UIEditBoxImpl-win32.h
|
||||||
|
ui/UIWebView/UIWebViewImpl-win32.h
|
||||||
|
ui/UIWebView/UIWebView.h
|
||||||
)
|
)
|
||||||
set(COCOS_UI_SPECIFIC_SRC
|
set(COCOS_UI_SPECIFIC_SRC
|
||||||
ui/UIEditBox/UIEditBoxImpl-win32.cpp
|
ui/UIEditBox/UIEditBoxImpl-win32.cpp
|
||||||
|
ui/UIWebView/UIWebViewImpl-win32.cpp
|
||||||
|
ui/UIWebView/UIWebView.cpp
|
||||||
)
|
)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
if(MACOSX)
|
if(MACOSX)
|
||||||
|
|
|
@ -22,5 +22,16 @@
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
#include "platform/CCPlatformConfig.h"
|
||||||
|
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||||
|
|
||||||
#include "ui/UIWebView/UIWebViewImpl-android.h"
|
#include "ui/UIWebView/UIWebViewImpl-android.h"
|
||||||
#include "ui/UIWebView/UIWebView-inl.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
|
@ -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
102
setup.py
|
@ -59,6 +59,9 @@ try:
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
from time import time
|
||||||
|
from time import sleep
|
||||||
|
from os.path import dirname
|
||||||
|
|
||||||
ADXE_ROOT = 'ADXE_ROOT'
|
ADXE_ROOT = 'ADXE_ROOT'
|
||||||
ADXE_CONSOLE_ROOT = 'ADXE_CONSOLE_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' %
|
print('\nPlease execute command: "source %s" to make added system variables take effect\n' %
|
||||||
self.file_used_for_setup)
|
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 __name__ == '__main__':
|
||||||
if not _check_python_version():
|
if not _check_python_version():
|
||||||
exit()
|
exit()
|
||||||
|
@ -700,3 +790,15 @@ if __name__ == '__main__':
|
||||||
SendMessageTimeoutW = ctypes.windll.user32.SendMessageTimeoutW
|
SendMessageTimeoutW = ctypes.windll.user32.SendMessageTimeoutW
|
||||||
SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
|
SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
|
||||||
u'Environment', SMTO_ABORTIFHUNG, 5000, ctypes.byref(result))
|
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)
|
||||||
|
|
|
@ -361,6 +361,15 @@ if(WINDOWS OR MACOSX OR LINUX)
|
||||||
)
|
)
|
||||||
endif()
|
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
|
list(APPEND GAME_HEADER
|
||||||
Classes/Box2DTest/Box2dTest.h
|
Classes/Box2DTest/Box2dTest.h
|
||||||
)
|
)
|
||||||
|
|
|
@ -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)
|
#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"
|
#include "UIEditBoxTest.h"
|
||||||
#endif
|
#endif
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
||||||
|
#include "UIWebViewTest/UIWebViewTest.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
GUIDynamicCreateTests::GUIDynamicCreateTests()
|
GUIDynamicCreateTests::GUIDynamicCreateTests()
|
||||||
{
|
{
|
||||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS)
|
#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; });
|
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; });
|
addTest("WebView Test", [](){ return new (std::nothrow) WebViewTests; });
|
||||||
#endif
|
#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)
|
#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)
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#define __cocos2d_tests__UIWebViewTest__
|
#define __cocos2d_tests__UIWebViewTest__
|
||||||
|
|
||||||
#include "../UIScene.h"
|
#include "../UIScene.h"
|
||||||
|
#include "ui/UIWebView/UIWebView.h"
|
||||||
|
|
||||||
DEFINE_TEST_SUITE(WebViewTests);
|
DEFINE_TEST_SUITE(WebViewTests);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue