From 895424ecc0d28ee9c43149485e290bb694b3d000 Mon Sep 17 00:00:00 2001 From: Hertatijanto Hartono Date: Sat, 13 Jun 2020 22:50:55 +0700 Subject: [PATCH] Add wxWebView::SetZoomFactor(float) and GetZoomFactor() The new method allows to set the zoom level more precisely than the existing SetZoom(wxWebViewZoom). Also improve the webview sample by using radio menu items instead of check items and manually resetting them. Closes https://github.com/wxWidgets/wxWidgets/pull/1894 Closes #18769. --- include/wx/gtk/webview_webkit.h | 2 + include/wx/msw/webview_edge.h | 2 + include/wx/msw/webview_ie.h | 4 + include/wx/osx/webview_webkit.h | 2 + include/wx/webview.h | 2 + interface/wx/webview.h | 25 +++++- samples/webview/webview.cpp | 72 +++++++++-------- src/gtk/webview_webkit.cpp | 11 +++ src/gtk/webview_webkit2.cpp | 9 +++ src/msw/webview_edge.cpp | 14 +++- src/msw/webview_ie.cpp | 133 ++++++++++++++++++++++++++------ src/osx/webview_webkit.mm | 10 +++ 12 files changed, 227 insertions(+), 59 deletions(-) diff --git a/include/wx/gtk/webview_webkit.h b/include/wx/gtk/webview_webkit.h index fa61f06ca5..f71bc72d82 100644 --- a/include/wx/gtk/webview_webkit.h +++ b/include/wx/gtk/webview_webkit.h @@ -83,7 +83,9 @@ public: wxWebViewZoomType GetZoomType() const wxOVERRIDE; bool CanSetZoomType(wxWebViewZoomType) const wxOVERRIDE; virtual wxWebViewZoom GetZoom() const wxOVERRIDE; + virtual float GetZoomFactor() const wxOVERRIDE; virtual void SetZoom(wxWebViewZoom) wxOVERRIDE; + virtual void SetZoomFactor(float) wxOVERRIDE; //Clipboard functions virtual bool CanCut() const wxOVERRIDE; diff --git a/include/wx/msw/webview_edge.h b/include/wx/msw/webview_edge.h index e1ccdcefab..f969566b33 100644 --- a/include/wx/msw/webview_edge.h +++ b/include/wx/msw/webview_edge.h @@ -74,7 +74,9 @@ public: virtual void Print() wxOVERRIDE; virtual wxWebViewZoom GetZoom() const wxOVERRIDE; + virtual float GetZoomFactor() const wxOVERRIDE; virtual void SetZoom(wxWebViewZoom zoom) wxOVERRIDE; + virtual void SetZoomFactor(float zoom) wxOVERRIDE; //Clipboard functions virtual bool CanCut() const wxOVERRIDE; diff --git a/include/wx/msw/webview_ie.h b/include/wx/msw/webview_ie.h index f892cc1c65..eb843f68a3 100644 --- a/include/wx/msw/webview_ie.h +++ b/include/wx/msw/webview_ie.h @@ -98,7 +98,9 @@ public: virtual void Print() wxOVERRIDE; virtual wxWebViewZoom GetZoom() const wxOVERRIDE; + virtual float GetZoomFactor() const wxOVERRIDE; virtual void SetZoom(wxWebViewZoom zoom) wxOVERRIDE; + virtual void SetZoomFactor(float zoom) wxOVERRIDE; //Clipboard functions virtual bool CanCut() const wxOVERRIDE; @@ -146,7 +148,9 @@ public: void SetIETextZoom(wxWebViewZoom level); wxWebViewZoom GetIEOpticalZoom() const; + int GetIEOpticalZoomFactor() const; void SetIEOpticalZoom(wxWebViewZoom level); + void SetIEOpticalZoomFactor(int zoom); void onActiveXEvent(wxActiveXEvent& evt); void onEraseBg(wxEraseEvent&) {} diff --git a/include/wx/osx/webview_webkit.h b/include/wx/osx/webview_webkit.h index 7e43bc37fa..96a57a1708 100644 --- a/include/wx/osx/webview_webkit.h +++ b/include/wx/osx/webview_webkit.h @@ -63,7 +63,9 @@ public: virtual wxString GetCurrentURL() const wxOVERRIDE; virtual wxString GetCurrentTitle() const wxOVERRIDE; virtual wxWebViewZoom GetZoom() const wxOVERRIDE; + virtual float GetZoomFactor() const wxOVERRIDE; virtual void SetZoom(wxWebViewZoom zoom) wxOVERRIDE; + virtual void SetZoomFactor(float zoom) wxOVERRIDE; virtual void SetZoomType(wxWebViewZoomType zoomType) wxOVERRIDE; virtual wxWebViewZoomType GetZoomType() const wxOVERRIDE; diff --git a/include/wx/webview.h b/include/wx/webview.h index 9573ac99bf..da045589b4 100644 --- a/include/wx/webview.h +++ b/include/wx/webview.h @@ -201,8 +201,10 @@ public: //Zoom virtual bool CanSetZoomType(wxWebViewZoomType type) const = 0; virtual wxWebViewZoom GetZoom() const = 0; + virtual float GetZoomFactor() const = 0; virtual wxWebViewZoomType GetZoomType() const = 0; virtual void SetZoom(wxWebViewZoom zoom) = 0; + virtual void SetZoomFactor(float zoom) = 0; virtual void SetZoomType(wxWebViewZoomType zoomType) = 0; //Selection diff --git a/interface/wx/webview.h b/interface/wx/webview.h index 9503697e3b..bae8d6c498 100644 --- a/interface/wx/webview.h +++ b/interface/wx/webview.h @@ -882,11 +882,20 @@ public: virtual bool CanSetZoomType(wxWebViewZoomType type) const = 0; /** - Get the zoom factor of the page. + Get the zoom level of the page. + See GetZoomFactor() to get more precise zoom scale value other than + as provided by @c wxWebViewZoom. @return The current level of zoom. */ virtual wxWebViewZoom GetZoom() const = 0; + /** + Get the zoom factor of the page. + @return The current factor of zoom. + @since 3.1.4 + */ + virtual float GetZoomFactor() const = 0; + /** Get how the zoom factor is currently interpreted. @return How the zoom factor is currently interpreted by the HTML engine. @@ -894,12 +903,24 @@ public: virtual wxWebViewZoomType GetZoomType() const = 0; /** - Set the zoom factor of the page. + Set the zoom level of the page. + See SetZoomFactor() for more precise scaling other than the measured + steps provided by @c wxWebViewZoom. @param zoom How much to zoom (scale) the HTML document. */ virtual void SetZoom(wxWebViewZoom zoom) = 0; /** + Set the zoom factor of the page. + @param zoom How much to zoom (scale) the HTML document in arbitrary + number. + @note zoom scale in IE will be converted into @c wxWebViewZoom levels + for @c wxWebViewZoomType of @c wxWEBVIEW_ZOOM_TYPE_TEXT. + @since 3.1.4 + */ + virtual void SetZoomFactor(float zoom) = 0; + + /** Set how to interpret the zoom factor. @param zoomType How the zoom factor should be interpreted by the HTML engine. diff --git a/samples/webview/webview.cpp b/samples/webview/webview.cpp index aae3218750..224f14efa2 100644 --- a/samples/webview/webview.cpp +++ b/samples/webview/webview.cpp @@ -35,6 +35,7 @@ #endif #include "wx/webviewarchivehandler.h" #include "wx/webviewfshandler.h" +#include "wx/numdlg.h" #include "wx/infobar.h" #include "wx/filesys.h" #include "wx/fs_arc.h" @@ -132,6 +133,7 @@ public: void OnRedo(wxCommandEvent& evt); void OnMode(wxCommandEvent& evt); void OnZoomLayout(wxCommandEvent& evt); + void OnZoomCustom(wxCommandEvent& evt); void OnHistory(wxCommandEvent& evt); void OnScrollLineUp(wxCommandEvent&) { m_browser->LineUp(); } void OnScrollLineDown(wxCommandEvent&) { m_browser->LineDown(); } @@ -194,6 +196,7 @@ private: wxMenuItem* m_tools_medium; wxMenuItem* m_tools_large; wxMenuItem* m_tools_largest; + wxMenuItem* m_tools_custom; wxMenuItem* m_tools_handle_navigation; wxMenuItem* m_tools_handle_new_window; wxMenuItem* m_tools_enable_history; @@ -237,6 +240,7 @@ private: wxMenuHistoryMap m_histMenuItems; wxString m_findText; int m_findFlags, m_findCount; + long m_zoomFactor; // Last executed JavaScript snippet, for convenience. wxString m_javascript; @@ -402,12 +406,13 @@ WebFrame::WebFrame(const wxString& url) : wxMenuItem* viewSource = m_tools_menu->Append(wxID_ANY , _("View Source")); wxMenuItem* viewText = m_tools_menu->Append(wxID_ANY, _("View Text")); m_tools_menu->AppendSeparator(); - m_tools_layout = m_tools_menu->AppendCheckItem(wxID_ANY, _("Use Layout Zoom")); - m_tools_tiny = m_tools_menu->AppendCheckItem(wxID_ANY, _("Tiny")); - m_tools_small = m_tools_menu->AppendCheckItem(wxID_ANY, _("Small")); - m_tools_medium = m_tools_menu->AppendCheckItem(wxID_ANY, _("Medium")); - m_tools_large = m_tools_menu->AppendCheckItem(wxID_ANY, _("Large")); - m_tools_largest = m_tools_menu->AppendCheckItem(wxID_ANY, _("Largest")); + m_tools_layout = m_tools_menu->AppendRadioItem(wxID_ANY, _("Use Layout Zoom")); + m_tools_tiny = m_tools_menu->AppendRadioItem(wxID_ANY, _("Tiny")); + m_tools_small = m_tools_menu->AppendRadioItem(wxID_ANY, _("Small")); + m_tools_medium = m_tools_menu->AppendRadioItem(wxID_ANY, _("Medium")); + m_tools_large = m_tools_menu->AppendRadioItem(wxID_ANY, _("Large")); + m_tools_largest = m_tools_menu->AppendRadioItem(wxID_ANY, _("Largest")); + m_tools_custom = m_tools_menu->AppendRadioItem(wxID_ANY, _("Custom Size")); m_tools_menu->AppendSeparator(); m_tools_handle_navigation = m_tools_menu->AppendCheckItem(wxID_ANY, _("Handle Navigation")); m_tools_handle_new_window = m_tools_menu->AppendCheckItem(wxID_ANY, _("Handle New Windows")); @@ -486,10 +491,14 @@ WebFrame::WebFrame(const wxString& url) : m_tools_handle_navigation->Check(); m_tools_handle_new_window->Check(); m_tools_enable_history->Check(); + + //Zoom + m_zoomFactor = 100; + m_tools_medium->Check(); + if(!m_browser->CanSetZoomType(wxWEBVIEW_ZOOM_TYPE_LAYOUT)) m_tools_layout->Enable(false); - // Connect the toolbar events Bind(wxEVT_TOOL, &WebFrame::OnBack, this, m_toolbar_back->GetId()); Bind(wxEVT_TOOL, &WebFrame::OnForward, this, m_toolbar_forward->GetId()); @@ -527,6 +536,7 @@ WebFrame::WebFrame(const wxString& url) : Bind(wxEVT_MENU, &WebFrame::OnSetZoom, this, m_tools_medium->GetId()); Bind(wxEVT_MENU, &WebFrame::OnSetZoom, this, m_tools_large->GetId()); Bind(wxEVT_MENU, &WebFrame::OnSetZoom, this, m_tools_largest->GetId()); + Bind(wxEVT_MENU, &WebFrame::OnSetZoom, this, m_tools_custom->GetId()); Bind(wxEVT_MENU, &WebFrame::OnClearHistory, this, clearhist->GetId()); Bind(wxEVT_MENU, &WebFrame::OnEnableHistory, this, m_tools_enable_history->GetId()); Bind(wxEVT_MENU, &WebFrame::OnCut, this, m_edit_cut->GetId()); @@ -928,32 +938,6 @@ void WebFrame::OnToolsClicked(wxCommandEvent& WXUNUSED(evt)) if(m_browser->GetCurrentURL() == "") return; - m_tools_tiny->Check(false); - m_tools_small->Check(false); - m_tools_medium->Check(false); - m_tools_large->Check(false); - m_tools_largest->Check(false); - - wxWebViewZoom zoom = m_browser->GetZoom(); - switch (zoom) - { - case wxWEBVIEW_ZOOM_TINY: - m_tools_tiny->Check(); - break; - case wxWEBVIEW_ZOOM_SMALL: - m_tools_small->Check(); - break; - case wxWEBVIEW_ZOOM_MEDIUM: - m_tools_medium->Check(); - break; - case wxWEBVIEW_ZOOM_LARGE: - m_tools_large->Check(); - break; - case wxWEBVIEW_ZOOM_LARGEST: - m_tools_largest->Check(); - break; - } - m_edit_cut->Enable(m_browser->CanCut()); m_edit_copy->Enable(m_browser->CanCopy()); m_edit_paste->Enable(m_browser->CanPaste()); @@ -1033,6 +1017,10 @@ void WebFrame::OnSetZoom(wxCommandEvent& evt) { m_browser->SetZoom(wxWEBVIEW_ZOOM_LARGEST); } + else if (evt.GetId() == m_tools_custom->GetId()) + { + OnZoomCustom(evt); + } else { wxFAIL; @@ -1047,6 +1035,24 @@ void WebFrame::OnZoomLayout(wxCommandEvent& WXUNUSED(evt)) m_browser->SetZoomType(wxWEBVIEW_ZOOM_TYPE_TEXT); } +void WebFrame::OnZoomCustom(wxCommandEvent& WXUNUSED(evt)) +{ + wxNumberEntryDialog dialog + ( + this, + "Enter zoom factor as a percentage (10-10000)%", + "Zoom Factor:", + "Change Zoom Factor", + m_zoomFactor, + 10, 10000 + ); + if( dialog.ShowModal() != wxID_OK ) + return; + + m_zoomFactor = dialog.GetValue(); + m_browser->SetZoomFactor((float)m_zoomFactor/100); +} + void WebFrame::OnHistory(wxCommandEvent& evt) { m_browser->LoadHistoryItem(m_histMenuItems[evt.GetId()]); diff --git a/src/gtk/webview_webkit.cpp b/src/gtk/webview_webkit.cpp index 0a740099fc..69cefa2111 100644 --- a/src/gtk/webview_webkit.cpp +++ b/src/gtk/webview_webkit.cpp @@ -775,6 +775,12 @@ wxWebViewZoom wxWebViewWebKit::GetZoom() const } +float wxWebViewWebKit::GetZoomFactor() const +{ + return GetWebkitZoom(); +} + + void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom) { // arbitrary way to map our common zoom enum to float zoom @@ -805,6 +811,11 @@ void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom) } } +void wxWebViewWebKit::SetZoomFactor(float zoom) +{ + SetWebkitZoom(zoom); +} + void wxWebViewWebKit::SetZoomType(wxWebViewZoomType type) { webkit_web_view_set_full_content_zoom(m_web_view, diff --git a/src/gtk/webview_webkit2.cpp b/src/gtk/webview_webkit2.cpp index 656a10f778..69583a546a 100644 --- a/src/gtk/webview_webkit2.cpp +++ b/src/gtk/webview_webkit2.cpp @@ -913,6 +913,10 @@ wxWebViewZoom wxWebViewWebKit::GetZoom() const return wxWEBVIEW_ZOOM_LARGEST; } +float wxWebViewWebKit::GetZoomFactor() const +{ + return GetWebkitZoom(); +} void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom) { @@ -944,6 +948,11 @@ void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom) } } +void wxWebViewWebKit::SetZoomFactor(float zoom) +{ + SetWebkitZoom(zoom); +} + void wxWebViewWebKit::SetZoomType(wxWebViewZoomType type) { WebKitSettings* settings = webkit_web_view_get_settings(m_web_view); diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index a907b50d26..2d902f474e 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -560,6 +560,13 @@ wxWebViewZoom wxWebViewEdge::GetZoom() const return wxWEBVIEW_ZOOM_TINY; } +float wxWebViewEdge::GetZoomFactor() const +{ + double old_zoom_factor = 0.0; + m_impl->m_webViewController->get_ZoomFactor(&old_zoom_factor); + return old_zoom_factor; +} + void wxWebViewEdge::SetZoom(wxWebViewZoom zoom) { double old_zoom_factor = 0.0; @@ -585,7 +592,12 @@ void wxWebViewEdge::SetZoom(wxWebViewZoom zoom) default: break; } - m_impl->m_webViewController->put_ZoomFactor(zoom_factor); + SetZoomFactor(zoom_factor); +} + +void wxWebViewEdge::SetZoomFactor(float zoom) +{ + m_impl->m_webViewController->put_ZoomFactor(zoom); } bool wxWebViewEdge::CanCut() const diff --git a/src/msw/webview_ie.cpp b/src/msw/webview_ie.cpp index daf3e3b729..9c5028bd62 100644 --- a/src/msw/webview_ie.cpp +++ b/src/msw/webview_ie.cpp @@ -284,6 +284,44 @@ wxWebViewZoom wxWebViewIE::GetZoom() const } +float wxWebViewIE::GetZoomFactor() const +{ + wxWebViewZoom level = wxWEBVIEW_ZOOM_MEDIUM; + float zoomFactor = 1.0; + + if (m_impl->m_zoomType == wxWEBVIEW_ZOOM_TYPE_LAYOUT) + { + zoomFactor = (float)GetIEOpticalZoomFactor(); + zoomFactor /= 100; + } + else if (m_impl->m_zoomType == wxWEBVIEW_ZOOM_TYPE_TEXT) + { + level = GetIETextZoom(); + switch(level) + { + case wxWEBVIEW_ZOOM_TINY: + zoomFactor = 0.6; + break; + case wxWEBVIEW_ZOOM_SMALL: + zoomFactor = 0.8; + break; + case wxWEBVIEW_ZOOM_MEDIUM: + zoomFactor = 1.0; + break; + case wxWEBVIEW_ZOOM_LARGE: + zoomFactor = 1.3; + break; + case wxWEBVIEW_ZOOM_LARGEST: + zoomFactor = 1.6; + break; + default: + wxFAIL; + } + } + + return zoomFactor; +} + void wxWebViewIE::SetZoom(wxWebViewZoom zoom) { switch( m_impl->m_zoomType ) @@ -299,6 +337,41 @@ void wxWebViewIE::SetZoom(wxWebViewZoom zoom) } } +void wxWebViewIE::SetZoomFactor(float zoom) +{ + wxWebViewZoom level = wxWEBVIEW_ZOOM_MEDIUM; + + if (m_impl->m_zoomType == wxWEBVIEW_ZOOM_TYPE_LAYOUT) + { + SetIEOpticalZoomFactor(zoom * 100); + } + else if (m_impl->m_zoomType == wxWEBVIEW_ZOOM_TYPE_TEXT) + { + //We make a somewhat arbitray map here, taken from values used by webkit + if (zoom <= 65) + { + level = wxWEBVIEW_ZOOM_TINY; + } + else if (zoom > 65 && zoom <= 90) + { + level = wxWEBVIEW_ZOOM_SMALL; + } + else if (zoom > 90 && zoom <= 115) + { + level = wxWEBVIEW_ZOOM_MEDIUM; + } + else if (zoom > 115 && zoom <= 145) + { + level = wxWEBVIEW_ZOOM_LARGE; + } + else + { + level = wxWEBVIEW_ZOOM_LARGEST; + } + SetIETextZoom(level); + } +} + void wxWebViewIE::SetIETextZoom(wxWebViewZoom level) { //We do not use OLECMDID_OPTICAL_GETZOOMRANGE as the docs say the range @@ -338,33 +411,40 @@ wxWebViewZoom wxWebViewIE::GetIETextZoom() const void wxWebViewIE::SetIEOpticalZoom(wxWebViewZoom level) { - //We do not use OLECMDID_OPTICAL_GETZOOMRANGE as the docs say the range - //is 10 to 1000 so the check is unnecessary - VARIANT zoomVariant; - VariantInit (&zoomVariant); - V_VT(&zoomVariant) = VT_I4; + int zoom = 100; //We make a somewhat arbitray map here, taken from values used by webkit switch(level) { case wxWEBVIEW_ZOOM_TINY: - V_I4(&zoomVariant) = 60; + zoom = 60; break; case wxWEBVIEW_ZOOM_SMALL: - V_I4(&zoomVariant) = 80; + zoom = 80; break; case wxWEBVIEW_ZOOM_MEDIUM: - V_I4(&zoomVariant) = 100; + zoom = 100; break; case wxWEBVIEW_ZOOM_LARGE: - V_I4(&zoomVariant) = 130; + zoom = 130; break; case wxWEBVIEW_ZOOM_LARGEST: - V_I4(&zoomVariant) = 160; + zoom = 160; break; default: wxFAIL; } + SetIEOpticalZoomFactor(zoom); +} + +void wxWebViewIE::SetIEOpticalZoomFactor(int zoom) +{ + //We do not use OLECMDID_OPTICAL_GETZOOMRANGE as the docs say the range + //is 10 to 1000 so the check is unnecessary + VARIANT zoomVariant; + VariantInit (&zoomVariant); + V_VT(&zoomVariant) = VT_I4; + V_I4(&zoomVariant) = zoom; #if wxDEBUG_LEVEL HRESULT result = @@ -378,19 +458,7 @@ void wxWebViewIE::SetIEOpticalZoom(wxWebViewZoom level) wxWebViewZoom wxWebViewIE::GetIEOpticalZoom() const { - VARIANT zoomVariant; - VariantInit (&zoomVariant); - V_VT(&zoomVariant) = VT_I4; - -#if wxDEBUG_LEVEL - HRESULT result = -#endif - m_impl->m_webBrowser->ExecWB((OLECMDID)63 /*OLECMDID_OPTICAL_ZOOM*/, - OLECMDEXECOPT_DODEFAULT, NULL, - &zoomVariant); - wxASSERT(result == S_OK); - - const int zoom = V_I4(&zoomVariant); + const int zoom = GetIEOpticalZoomFactor(); //We make a somewhat arbitray map here, taken from values used by webkit if (zoom <= 65) @@ -415,6 +483,25 @@ wxWebViewZoom wxWebViewIE::GetIEOpticalZoom() const } } +int wxWebViewIE::GetIEOpticalZoomFactor() const +{ + VARIANT zoomVariant; + VariantInit (&zoomVariant); + V_VT(&zoomVariant) = VT_I4; + +#if wxDEBUG_LEVEL + HRESULT result = +#endif + m_impl->m_webBrowser->ExecWB((OLECMDID)63 /*OLECMDID_OPTICAL_ZOOM*/, + OLECMDEXECOPT_DODEFAULT, NULL, + &zoomVariant); + wxASSERT(result == S_OK); + + const int zoom = V_I4(&zoomVariant); + + return zoom; +} + void wxWebViewIE::SetZoomType(wxWebViewZoomType type) { m_impl->m_zoomType = type; diff --git a/src/osx/webview_webkit.mm b/src/osx/webview_webkit.mm index 381d0f3330..382572b31f 100644 --- a/src/osx/webview_webkit.mm +++ b/src/osx/webview_webkit.mm @@ -520,6 +520,11 @@ wxWebViewZoom wxWebViewWebKit::GetZoom() const return wxWEBVIEW_ZOOM_MEDIUM; } +float wxWebViewWebKit::GetZoomFactor() const +{ + return GetWebkitZoom(); +} + void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom) { // arbitrary way to map our common zoom enum to float zoom @@ -551,6 +556,11 @@ void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom) } +void wxWebViewWebKit::SetZoomFactor(float zoom) +{ + SetWebkitZoom(zoom); +} + void wxWebViewWebKit::DoSetPage(const wxString& src, const wxString& baseUrl) { if ( !m_webView )