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
|
@ -190,4 +190,7 @@ temp/
|
|||
# New .cxx temp folder
|
||||
**/.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")
|
||||
# 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
@ -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:
|
||||
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)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#define __cocos2d_tests__UIWebViewTest__
|
||||
|
||||
#include "../UIScene.h"
|
||||
#include "ui/UIWebView/UIWebView.h"
|
||||
|
||||
DEFINE_TEST_SUITE(WebViewTests);
|
||||
|
||||
|
|
Loading…
Reference in New Issue