diff --git a/.gitignore b/.gitignore index cc6e753c..3552a738 100644 --- a/.gitignore +++ b/.gitignore @@ -21,7 +21,7 @@ Thumbs.db *.wav build/ - +plugins/libs/webview2 plugins/builds plugins/build temp/ diff --git a/LunaTranslator/LunaTranslator/gui/usefulwidget.py b/LunaTranslator/LunaTranslator/gui/usefulwidget.py index 3a7e8c63..f2c91d68 100644 --- a/LunaTranslator/LunaTranslator/gui/usefulwidget.py +++ b/LunaTranslator/LunaTranslator/gui/usefulwidget.py @@ -1,7 +1,7 @@ from qtsymbols import * import os, platform, functools, threading, time, inspect from traceback import print_exc -import windows, qtawesome +import windows, qtawesome, winsharedutils from webviewpy import ( webview_native_handle_kind_t, Webview, @@ -629,8 +629,12 @@ def getscaledrect(size: QSize): class WebivewWidget(QWidget): on_load = pyqtSignal(str) + on_ZoomFactorChanged = pyqtSignal(float) html_limit = 2 * 1024 * 1024 # 2mb + def __del__(self): + winsharedutils.remove_ZoomFactorChanged(self.__token) + def __init__(self, parent=None, debug=False) -> None: super().__init__(parent) declare_library_path( @@ -644,14 +648,50 @@ class WebivewWidget(QWidget): ) self.webview = None self.webview = Webview(debug=debug, window=int(self.winId())) - + # 直接写在这里了 + self._putzoom() + self.on_ZoomFactorChanged.connect(self._zoomchanged) + # + zoomfunc = winsharedutils.add_ZoomFactorChanged_CALLBACK(self.ZoomFactorChanged) + self.__token = winsharedutils.add_ZoomFactorChanged( + self.webview.get_native_handle( + webview_native_handle_kind_t.WEBVIEW_NATIVE_HANDLE_KIND_BROWSER_CONTROLLER + ), + zoomfunc, + ) + self.keepref = [zoomfunc] self.webview.bind("__on_load", self._on_load) self.webview.init("""window.__on_load(window.location.href)""") + def _putzoom(self): + self.put_ZoomFactor(globalconfig["webview2"]["ZoomFactor"]) + + def _zoomchanged(self, zoom): + globalconfig["webview2"]["ZoomFactor"] = zoom + + def ZoomFactorChanged(self, zoom): + self.on_ZoomFactorChanged.emit(zoom) + + def put_ZoomFactor(self, zoom): + winsharedutils.put_ZoomFactor( + self.webview.get_native_handle( + webview_native_handle_kind_t.WEBVIEW_NATIVE_HANDLE_KIND_BROWSER_CONTROLLER + ), + zoom, + ) + + def get_ZoomFactor(self, zoom): + return winsharedutils.get_ZoomFactor( + self.webview.get_native_handle( + webview_native_handle_kind_t.WEBVIEW_NATIVE_HANDLE_KIND_BROWSER_CONTROLLER + ) + ) + def _on_load(self, href): self.on_load.emit(href) def navigate(self, url): + self._putzoom() self.webview.navigate(url) def resizeEvent(self, a0: QResizeEvent) -> None: @@ -663,6 +703,7 @@ class WebivewWidget(QWidget): windows.MoveWindow(hwnd, 0, 0, size[0], size[1], True) def setHtml(self, html): + self._putzoom() self.webview.set_html(html) def parsehtml(self, html): @@ -753,6 +794,15 @@ class QWebWrap(QWidget): lambda qurl: self.on_load.emit(qurl.url()) ) + self.internal.setZoomFactor(globalconfig["QWebEngineView"]["ZoomFactor"]) + t = QTimer(self) + t.setInterval(1000) + t.timeout.connect(self.__getzoomfactor) + t.start(0) + + def __getzoomfactor(self): + globalconfig["QWebEngineView"]["ZoomFactor"] = self.internal.zoomFactor() + def navigate(self, url: str): from PyQt5.QtCore import QUrl @@ -1088,7 +1138,7 @@ class listediterline(QLineEdit): super().mousePressEvent(e) -def openfiledirectory(directory,multi, edit, isdir, filter1="*.*", callback=None): +def openfiledirectory(directory, multi, edit, isdir, filter1="*.*", callback=None): if isdir: f = QFileDialog.getExistingDirectory(directory=directory) res = f @@ -1101,7 +1151,7 @@ def openfiledirectory(directory,multi, edit, isdir, filter1="*.*", callback=None if len(res) == 0: return - edit.setText('|'.join(res) if multi else res) + edit.setText("|".join(res) if multi else res) if callback: callback(res) @@ -1116,9 +1166,9 @@ def getsimplepatheditor( ): lay = QHBoxLayout() lay.setContentsMargins(0, 0, 0, 0) - - director=(text[0] if len(text) else '') if multi else text - e = QLineEdit('|'.join(text) if multi else text) + + director = (text[0] if len(text) else "") if multi else text + e = QLineEdit("|".join(text) if multi else text) e.setReadOnly(True) if useiconbutton: bu = getcolorbutton("", "", None, icon="fa.gear", constcolor="#FF69B4") @@ -1126,7 +1176,13 @@ def getsimplepatheditor( bu = QPushButton(_TR("选择" + ("文件夹" if isdir else "文件"))) bu.clicked.connect( functools.partial( - openfiledirectory,director, multi, e, isdir, "" if isdir else filter1, callback + openfiledirectory, + director, + multi, + e, + isdir, + "" if isdir else filter1, + callback, ) ) lay.addWidget(e) diff --git a/LunaTranslator/LunaTranslator/winsharedutils.py b/LunaTranslator/LunaTranslator/winsharedutils.py index 4c7a5032..1938ed17 100644 --- a/LunaTranslator/LunaTranslator/winsharedutils.py +++ b/LunaTranslator/LunaTranslator/winsharedutils.py @@ -19,6 +19,7 @@ from ctypes import ( c_float, c_double, c_char, + CFUNCTYPE, ) from ctypes.wintypes import WORD, HANDLE, HWND, LONG, DWORD, RECT, BYTE from windows import WINDOWPLACEMENT @@ -399,3 +400,15 @@ setAcrylicEffect = utilsdll.setAcrylicEffect setAcrylicEffect.argtypes = (HWND,) clearEffect = utilsdll.clearEffect clearEffect.argtypes = (HWND,) + +add_ZoomFactorChanged_CALLBACK = CFUNCTYPE(None, c_double) +add_ZoomFactorChanged = utilsdll.add_ZoomFactorChanged +add_ZoomFactorChanged.argtypes = (c_void_p, c_void_p) +add_ZoomFactorChanged.restype = c_void_p +remove_ZoomFactorChanged = utilsdll.remove_ZoomFactorChanged +remove_ZoomFactorChanged.argtypes = c_void_p, c_void_p +get_ZoomFactor = utilsdll.get_ZoomFactor +get_ZoomFactor.argtypes = (c_void_p,) +get_ZoomFactor.restype = c_double +put_ZoomFactor = utilsdll.put_ZoomFactor +put_ZoomFactor.argtypes = c_void_p, c_double diff --git a/LunaTranslator/files/defaultconfig/config.json b/LunaTranslator/files/defaultconfig/config.json index 092715e1..b06ca20c 100644 --- a/LunaTranslator/files/defaultconfig/config.json +++ b/LunaTranslator/files/defaultconfig/config.json @@ -1638,6 +1638,12 @@ "name": "实时编辑" } }, + "webview2":{ + "ZoomFactor": 1 + }, + "QWebEngineView":{ + "ZoomFactor": 1 + }, "realtime_edit_target": "realtime_edit", "magpiepath": "", "minifollow": false, diff --git a/plugins/libs/libs.cmake b/plugins/libs/libs.cmake index 9ce4c0d0..5d77995e 100644 --- a/plugins/libs/libs.cmake +++ b/plugins/libs/libs.cmake @@ -11,6 +11,7 @@ include_directories(${CMAKE_CURRENT_LIST_DIR}/wil/include) include_directories(${CMAKE_CURRENT_LIST_DIR}/miniaudio) include_directories(${CMAKE_CURRENT_LIST_DIR}/tinymp3) +include_directories(${CMAKE_CURRENT_LIST_DIR}/webview2/Microsoft.Web.WebView2.1.0.1150.38/build/native/include) if(${CMAKE_SIZEOF_VOID_P} EQUAL 4) set(LTLPlatform "Win32") diff --git a/plugins/scripts/build32.bat b/plugins/scripts/build32.bat index 17accb67..ac36340f 100644 --- a/plugins/scripts/build32.bat +++ b/plugins/scripts/build32.bat @@ -1,3 +1,4 @@ +python fetchwebview2.py cmake ../CMakeLists.txt -G "Visual Studio 17 2022" -A win32 -T host=x86 -B ../build/x86 cmake --build ../build/x86 --config Release --target ALL_BUILD -j 14 python copytarget.py 1 \ No newline at end of file diff --git a/plugins/scripts/build64.bat b/plugins/scripts/build64.bat index b0698abe..fff3305c 100644 --- a/plugins/scripts/build64.bat +++ b/plugins/scripts/build64.bat @@ -1,3 +1,4 @@ +python fetchwebview2.py cmake ../CMakeLists.txt -G "Visual Studio 17 2022" -A x64 -T host=x64 -B ../build/x64 cmake --build ../build/x64 --config Release --target ALL_BUILD -j 14 python copytarget.py 0 \ No newline at end of file diff --git a/plugins/scripts/fetchwebview2.py b/plugins/scripts/fetchwebview2.py new file mode 100644 index 00000000..0dc56b02 --- /dev/null +++ b/plugins/scripts/fetchwebview2.py @@ -0,0 +1,22 @@ +mswebview2_version = "1.0.1150.38" + +import os, subprocess + +target = os.path.normpath(os.path.join(os.path.dirname(__file__), r"..\libs\webview2")) +os.makedirs(target, exist_ok=True) +nuget_exe = os.path.join(target, "nuget.exe") +print(nuget_exe) +if os.path.exists(nuget_exe) == False: + os.system( + rf'curl -sSLo "{nuget_exe}" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' + ) + +mswebview2_dir = os.path.join(target, f"Microsoft.Web.WebView2.{mswebview2_version}") +if os.path.exists(mswebview2_dir) == False: + os.mkdir(mswebview2_dir) + print( + rf""""{nuget_exe}" install Microsoft.Web.Webview2 -Verbosity quiet -Version "{mswebview2_version}" -OutputDirectory {target}""" + ) + subprocess.run( + rf'"{nuget_exe}" install Microsoft.Web.Webview2 -Verbosity quiet -Version "{mswebview2_version}" -OutputDirectory {target}' + ) diff --git a/plugins/winsharedutils/CMakeLists.txt b/plugins/winsharedutils/CMakeLists.txt index 6ef747bf..4039bdc7 100644 --- a/plugins/winsharedutils/CMakeLists.txt +++ b/plugins/winsharedutils/CMakeLists.txt @@ -11,7 +11,7 @@ generate_product_version( VERSION_PATCH ${VERSION_PATCH} ) -add_library(winsharedutils MODULE AreoAcrylic.cpp screenshot.cpp audio.cpp ../implsapi.cpp hwnd.cpp darklistener.cpp theme.cpp version.cpp otsu.cpp cinterface.cpp clipboard.cpp lnk.cpp dllmain.cpp levenshtein.cpp muteprocess.cpp sapi_dll.cpp simplemecab.cpp SimpleBrowser.cpp MWebBrowser.cpp icon.cpp maglistener.cpp ${versioninfo}) +add_library(winsharedutils MODULE webview2_extra.cpp AreoAcrylic.cpp screenshot.cpp audio.cpp ../implsapi.cpp hwnd.cpp darklistener.cpp theme.cpp version.cpp otsu.cpp cinterface.cpp clipboard.cpp lnk.cpp dllmain.cpp levenshtein.cpp muteprocess.cpp sapi_dll.cpp simplemecab.cpp SimpleBrowser.cpp MWebBrowser.cpp icon.cpp maglistener.cpp ${versioninfo}) target_precompile_headers(winsharedutils REUSE_FROM pch) if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) set_target_properties(winsharedutils PROPERTIES OUTPUT_NAME "winsharedutils64") diff --git a/plugins/winsharedutils/webview2_extra.cpp b/plugins/winsharedutils/webview2_extra.cpp new file mode 100644 index 00000000..4c9dc758 --- /dev/null +++ b/plugins/winsharedutils/webview2_extra.cpp @@ -0,0 +1,48 @@ +#include "define.h" + +#include +#include +#include +#include +#include +using namespace Microsoft::WRL; +#include + +DECLARE void *add_ZoomFactorChanged(void *m_host, void (*signal)(double)) +{ + + EventRegistrationToken *m_zoomFactorChangedToken = new EventRegistrationToken; + // Register a handler for the ZoomFactorChanged event. + // This handler just announces the new level of zoom on the window's title bar. + reinterpret_cast(m_host)->add_ZoomFactorChanged( + Callback( + [signal](ICoreWebView2Controller *sender, IUnknown *args) -> HRESULT + { + double zoomFactor; + sender->get_ZoomFactor(&zoomFactor); + signal(zoomFactor); + // std::wstring message = L"WebView2APISample (Zoom: " + + // std::to_wstring(int(zoomFactor * 100)) + L"%)"; + // SetWindowText(m_appWindow->GetMainWindow(), message.c_str()); + return S_OK; + }) + .Get(), + m_zoomFactorChangedToken); + return m_zoomFactorChangedToken; +} +DECLARE void remove_ZoomFactorChanged(void *m_host, void *m_zoomFactorChangedToken) +{ + + reinterpret_cast(m_host)->remove_ZoomFactorChanged(*reinterpret_cast(m_zoomFactorChangedToken)); + delete m_zoomFactorChangedToken; +} +DECLARE double get_ZoomFactor(void *m_host) +{ + double zoomFactor; + reinterpret_cast(m_host)->get_ZoomFactor(&zoomFactor); + return zoomFactor; +} +DECLARE void put_ZoomFactor(void *m_host, double zoomFactor) +{ + reinterpret_cast(m_host)->put_ZoomFactor(zoomFactor); +} \ No newline at end of file