From ea20a66bc24a0289967a71b354a0ec520c2004f6 Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 4 Apr 2025 22:52:42 +0200 Subject: [PATCH] Integrate webview directly in Window class alike with file dialog Signed-off-by: falkTX --- dgl/WebView.hpp | 32 ++++++++++++++++ dgl/Window.hpp | 27 ++++++++++++- dgl/src/Window.cpp | 16 +++++++- dgl/src/WindowPrivateData.cpp | 71 +++++++++++++++++++++++++++++++++-- dgl/src/WindowPrivateData.hpp | 15 +++++++- dgl/src/pugl.cpp | 13 ++++++- 6 files changed, 164 insertions(+), 10 deletions(-) create mode 100644 dgl/WebView.hpp diff --git a/dgl/WebView.hpp b/dgl/WebView.hpp new file mode 100644 index 00000000..3fb04cce --- /dev/null +++ b/dgl/WebView.hpp @@ -0,0 +1,32 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2025 Filipe Coelho + * + * Permission to use, copy, modify, and/or distribute this software for any purpose with + * or without fee is hereby granted, provided that the above copyright notice and this + * permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef DGL_WEB_VIEW_HPP_INCLUDED +#define DGL_WEB_VIEW_HPP_INCLUDED + +#include "Base.hpp" + +START_NAMESPACE_DGL + +#include "../distrho/extra/WebViewImpl.hpp" + +#if defined(HAVE_X11) && defined(DISTRHO_OS_LINUX) +int dpf_webview_start(int argc, char* argv[]); +#endif + +END_NAMESPACE_DGL + +#endif // DGL_WEB_VIEW_HPP_INCLUDED diff --git a/dgl/Window.hpp b/dgl/Window.hpp index ac6b89cd..64d0f561 100644 --- a/dgl/Window.hpp +++ b/dgl/Window.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2024 Filipe Coelho + * Copyright (C) 2012-2025 Filipe Coelho * * Permission to use, copy, modify, and/or distribute this software for any purpose with * or without fee is hereby granted, provided that the above copyright notice and this @@ -23,6 +23,10 @@ # include "FileBrowserDialog.hpp" #endif +#ifdef DGL_USE_WEB_VIEW +# include "WebView.hpp" +#endif + #include #ifdef DISTRHO_NAMESPACE @@ -407,6 +411,27 @@ public: bool openFileBrowser(const DGL_NAMESPACE::FileBrowserOptions& options = FileBrowserOptions()); #endif + #ifdef DGL_USE_WEB_VIEW + /** + Create a new web view. + + The web view will be added on top of this window. + This means it will draw on top of whatever is below it, + something to take into consideration if mixing regular widgets with web views. + + Provided metrics in @p options must have scale factor pre-applied. + + @p url: The URL to open, assumed to be in encoded form (e.g spaces converted to %20) + @p options: Extra options, optional + */ + bool createWebView(const char* url, const DGL_NAMESPACE::WebViewOptions& options = WebViewOptions()); + + /** + Evaluate/run JavaScript on the web view. + */ + void evaluateJS(const char* js); + #endif + /** Request repaint of this window, for the entire area. */ diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp index b21e5c4c..57ae2570 100644 --- a/dgl/src/Window.cpp +++ b/dgl/src/Window.cpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2024 Filipe Coelho + * Copyright (C) 2012-2025 Filipe Coelho * * Permission to use, copy, modify, and/or distribute this software for any purpose with * or without fee is hereby granted, provided that the above copyright notice and this @@ -421,6 +421,20 @@ bool Window::openFileBrowser(const FileBrowserOptions& options) } #endif +#ifdef DGL_USE_WEB_VIEW +bool Window::createWebView(const char* const url, const DGL_NAMESPACE::WebViewOptions& options) +{ + return pData->createWebView(url, options); +} + +void Window::evaluateJS(const char* const js) +{ + DISTRHO_SAFE_ASSERT_RETURN(pData->webViewHandle != nullptr,); + + webViewEvaluateJS(pData->webViewHandle, js); +} +#endif + void Window::repaint() noexcept { if (pData->view == nullptr) diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp index 71ea9f9c..be1a51df 100644 --- a/dgl/src/WindowPrivateData.cpp +++ b/dgl/src/WindowPrivateData.cpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2024 Filipe Coelho + * Copyright (C) 2012-2025 Filipe Coelho * * Permission to use, copy, modify, and/or distribute this software for any purpose with * or without fee is hereby granted, provided that the above copyright notice and this @@ -128,6 +128,9 @@ Window::PrivateData::PrivateData(Application& a, Window* const s) filenameToRenderInto(nullptr), #ifdef DGL_USE_FILE_BROWSER fileBrowserHandle(nullptr), + #endif + #ifdef DGL_USE_WEB_VIEW + webViewHandle(nullptr), #endif modal() { @@ -158,6 +161,9 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c filenameToRenderInto(nullptr), #ifdef DGL_USE_FILE_BROWSER fileBrowserHandle(nullptr), + #endif + #ifdef DGL_USE_WEB_VIEW + webViewHandle(nullptr), #endif modal(ppData) { @@ -190,6 +196,9 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, filenameToRenderInto(nullptr), #ifdef DGL_USE_FILE_BROWSER fileBrowserHandle(nullptr), + #endif + #ifdef DGL_USE_WEB_VIEW + webViewHandle(nullptr), #endif modal() { @@ -225,6 +234,9 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, filenameToRenderInto(nullptr), #ifdef DGL_USE_FILE_BROWSER fileBrowserHandle(nullptr), + #endif + #ifdef DGL_USE_WEB_VIEW + webViewHandle(nullptr), #endif modal() { @@ -245,6 +257,10 @@ Window::PrivateData::~PrivateData() #ifdef DGL_USE_FILE_BROWSER if (fileBrowserHandle != nullptr) fileBrowserClose(fileBrowserHandle); + #endif + #ifdef DGL_USE_WEB_VIEW + if (webViewHandle != nullptr) + webViewDestroy(webViewHandle); #endif puglHide(view); appData->oneWindowClosed(); @@ -392,13 +408,21 @@ void Window::PrivateData::hide() if (modal.enabled) stopModal(); -#ifdef DGL_USE_FILE_BROWSER + #ifdef DGL_USE_FILE_BROWSER if (fileBrowserHandle != nullptr) { fileBrowserClose(fileBrowserHandle); fileBrowserHandle = nullptr; } -#endif + #endif + + #ifdef DGL_USE_WEB_VIEW + if (webViewHandle != nullptr) + { + webViewDestroy(webViewHandle); + webViewHandle = nullptr; + } + #endif puglHide(view); @@ -441,6 +465,11 @@ void Window::PrivateData::idleCallback() fileBrowserHandle = nullptr; } #endif + +#ifdef DGL_USE_WEB_VIEW + if (webViewHandle != nullptr) + webViewIdle(webViewHandle); +#endif } // ----------------------------------------------------------------------- @@ -477,7 +506,7 @@ bool Window::PrivateData::removeIdleCallback(IdleCallback* const callback) #ifdef DGL_USE_FILE_BROWSER // ----------------------------------------------------------------------- -// file handling +// file browser dialog bool Window::PrivateData::openFileBrowser(const FileBrowserOptions& options) { @@ -500,6 +529,32 @@ bool Window::PrivateData::openFileBrowser(const FileBrowserOptions& options) } #endif // DGL_USE_FILE_BROWSER +#ifdef DGL_USE_WEB_VIEW +// ----------------------------------------------------------------------- +// file browser dialog + +bool Window::PrivateData::createWebView(const char* const url, const DGL_NAMESPACE::WebViewOptions& options) +{ + if (webViewHandle != nullptr) + webViewDestroy(webViewHandle); + + const PuglRect rect = puglGetFrame(view); + uint initialWidth = static_cast(rect.width) - options.offset.x; + uint initialHeight = static_cast(rect.height) - options.offset.y; + + webViewOffset = Point(options.offset.x, options.offset.y); + + webViewHandle = webViewCreate(url, + puglGetNativeView(view), + initialWidth, + initialHeight, + autoScaling ? autoScaleFactor : scaleFactor, + options); + + return webViewHandle != nullptr; +} +#endif // DGL_USE_WEB_VIEW + // ----------------------------------------------------------------------- // modal handling @@ -599,6 +654,14 @@ void Window::PrivateData::onPuglConfigure(const uint width, const uint height) const uint uwidth = d_roundToUnsignedInt(width / autoScaleFactor); const uint uheight = d_roundToUnsignedInt(height / autoScaleFactor); + #ifdef DGL_USE_WEB_VIEW + if (webViewHandle != nullptr) + webViewResize(webViewHandle, + uwidth - webViewOffset.getX(), + uheight - webViewOffset.getY(), + autoScaling ? autoScaleFactor : scaleFactor); + #endif + self->onReshape(uwidth, uheight); #ifndef DPF_TEST_WINDOW_CPP diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp index ed7b971f..31b1481a 100644 --- a/dgl/src/WindowPrivateData.hpp +++ b/dgl/src/WindowPrivateData.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2024 Filipe Coelho + * Copyright (C) 2012-2025 Filipe Coelho * * Permission to use, copy, modify, and/or distribute this software for any purpose with * or without fee is hereby granted, provided that the above copyright notice and this @@ -95,6 +95,12 @@ struct Window::PrivateData : IdleCallback { DGL_NAMESPACE::FileBrowserHandle fileBrowserHandle; #endif + #ifdef DGL_USE_WEB_VIEW + /** Handle for web view operations. */ + DGL_NAMESPACE::WebViewHandle webViewHandle; + DGL_NAMESPACE::Point webViewOffset; + #endif + /** Modal window setup. */ struct Modal { PrivateData* parent; // parent of this window (so we can become modal) @@ -169,10 +175,15 @@ struct Window::PrivateData : IdleCallback { bool removeIdleCallback(IdleCallback* callback); #ifdef DGL_USE_FILE_BROWSER - // file handling + // file browser dialog bool openFileBrowser(const DGL_NAMESPACE::FileBrowserOptions& options); #endif + #ifdef DGL_USE_WEB_VIEW + // web view + bool createWebView(const char* url, const DGL_NAMESPACE::WebViewOptions& options); + #endif + static void renderToPicture(const char* filename, const GraphicsContext& context, uint width, uint height); // modal handling diff --git a/dgl/src/pugl.cpp b/dgl/src/pugl.cpp index e67563af..6ccd2aa6 100644 --- a/dgl/src/pugl.cpp +++ b/dgl/src/pugl.cpp @@ -110,16 +110,25 @@ # endif #endif -#ifndef DGL_FILE_BROWSER_DISABLED +#ifdef DGL_USE_FILE_BROWSER +# define DGL_FILE_BROWSER_DIALOG_HPP_INCLUDED # define FILE_BROWSER_DIALOG_DGL_NAMESPACE # define FILE_BROWSER_DIALOG_NAMESPACE DGL_NAMESPACE -# define DGL_FILE_BROWSER_DIALOG_HPP_INCLUDED START_NAMESPACE_DGL # include "../../distrho/extra/FileBrowserDialogImpl.hpp" END_NAMESPACE_DGL # include "../../distrho/extra/FileBrowserDialogImpl.cpp" #endif +#ifdef DGL_USE_WEB_VIEW +# define DGL_WEB_VIEW_HPP_INCLUDED +# define WEB_VIEW_DGL_NAMESPACE +START_NAMESPACE_DGL +# include "../../distrho/extra/WebViewImpl.hpp" +END_NAMESPACE_DGL +# include "../../distrho/extra/WebViewImpl.cpp" +#endif + #if defined(DGL_USING_X11) && defined(DGL_X11_WINDOW_ICON_NAME) extern const ulong* DGL_X11_WINDOW_ICON_NAME; #endif