Compare commits

...

4 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
2a8b71a89c Add theme toggle support to all WebView2-based image panels
Co-authored-by: emako <24737061+emako@users.noreply.github.com>
2025-11-17 09:23:28 +00:00
copilot-swe-agent[bot]
0844c7fe14 Fix compiler warning about unnecessary new keyword
Co-authored-by: emako <24737061+emako@users.noreply.github.com>
2025-11-17 09:21:19 +00:00
copilot-swe-agent[bot]
c4ee8937bc Add theme toggle button to SVG preview
Co-authored-by: emako <24737061+emako@users.noreply.github.com>
2025-11-17 09:19:39 +00:00
copilot-swe-agent[bot]
9af3fe7f4e Initial plan 2025-11-17 09:12:48 +00:00
6 changed files with 143 additions and 9 deletions

View File

@@ -35,6 +35,10 @@ public class LottieImagePanel : SvgImagePanel
ObjectForScripting ??= new ScriptHandler(path);
_homePage = _resources["/lottie2html.html"];
// Update WebView2 background color based on current theme
UpdateWebViewBackgroundColor();
NavigateToUri(new Uri("file://quicklook/"));
}

View File

@@ -18,6 +18,7 @@
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
using QuickLook.Common.Helpers;
using QuickLook.Common.Plugin;
using QuickLook.Plugin.HtmlViewer;
using System;
using System.Collections.Generic;
@@ -29,17 +30,36 @@ using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace QuickLook.Plugin.ImageViewer.Webview.Svg;
public class SvgImagePanel : WebpagePanel, IWebImagePanel
public partial class SvgImagePanel : UserControl, IWebImagePanel
{
protected const string _resourcePrefix = "QuickLook.Plugin.ImageViewer.Resources.";
protected internal static readonly Dictionary<string, byte[]> _resources = [];
protected byte[] _homePage;
protected WebView2 _webView;
protected Uri _currentUri;
protected string _primaryPath;
protected string _fallbackPath;
private ContextObject _contextObject;
private object _objectForScripting;
public string FallbackPath
{
get => _fallbackPath;
set => _fallbackPath = value;
}
public ContextObject ContextObject
{
get => _contextObject;
set => _contextObject = value;
}
public object ObjectForScripting
{
get => _objectForScripting;
@@ -60,7 +80,21 @@ public class SvgImagePanel : WebpagePanel, IWebImagePanel
InitializeResources();
}
protected override void InitializeComponent()
public SvgImagePanel()
{
InitializeComponent();
// Clear merged dictionaries from design time
Resources.MergedDictionaries.Clear();
// Initialize WebView2
InitializeWebView();
// Wire up the theme toggle button
buttonBackgroundColour.Click += OnBackgroundColourOnClick;
}
protected void InitializeWebView()
{
_webView = new WebView2()
{
@@ -71,7 +105,53 @@ public class SvgImagePanel : WebpagePanel, IWebImagePanel
DefaultBackgroundColor = Color.Transparent,
};
_webView.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted;
Content = _webView;
// Add WebView2 to the Grid at the first position (behind the button)
var grid = (Grid)Content;
grid.Children.Insert(0, _webView);
}
private void OnBackgroundColourOnClick(object sender, RoutedEventArgs e)
{
if (ContextObject == null) return;
// Toggle the theme
var newTheme = ContextObject.Theme == Themes.Dark ? Themes.Light : Themes.Dark;
ContextObject.Theme = newTheme;
// Save the theme preference
SettingHelper.Set("LastTheme", (int)newTheme, "QuickLook.Plugin.ImageViewer");
// Update WebView2 background color
UpdateWebViewBackgroundColor();
}
protected void UpdateWebViewBackgroundColor()
{
if (_webView == null) return;
var isDark = ContextObject?.Theme == Themes.Dark;
_webView.DefaultBackgroundColor = isDark
? Color.FromArgb(255, 32, 32, 32)
: Color.White;
}
public void NavigateToUri(Uri uri)
{
if (_webView == null)
return;
_webView.Source = uri;
_currentUri = _webView.Source;
}
protected virtual void WebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
{
if (e.IsSuccess)
{
_webView.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
_webView.CoreWebView2.WebResourceRequested += WebView_WebResourceRequested;
}
}
protected static void InitializeResources()
@@ -102,10 +182,14 @@ public class SvgImagePanel : WebpagePanel, IWebImagePanel
ObjectForScripting ??= new ScriptHandler(path);
_homePage = _resources["/svg2html.html"];
// Update WebView2 background color based on current theme
UpdateWebViewBackgroundColor();
NavigateToUri(new Uri("file://quicklook/"));
}
protected override void WebView_WebResourceRequested(object sender, CoreWebView2WebResourceRequestedEventArgs args)
protected virtual void WebView_WebResourceRequested(object sender, CoreWebView2WebResourceRequestedEventArgs args)
{
Debug.WriteLine($"[{args.Request.Method}] {args.Request.Uri}");
@@ -186,7 +270,13 @@ public class SvgImagePanel : WebpagePanel, IWebImagePanel
return reader.ReadToEnd();
}
public new static class MimeTypes
public void Dispose()
{
_webView?.Dispose();
_webView = null;
}
public static class MimeTypes
{
public static string GetContentTypeHeader(string extension = null)
=> $"Content-Type: {WebpagePanel.MimeTypes.GetMimeType(extension)}";

View File

@@ -0,0 +1,32 @@
<UserControl x:Class="QuickLook.Plugin.ImageViewer.Webview.Svg.SvgImagePanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="svgImagePanel"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- only for design -->
<ResourceDictionary Source="/QuickLook.Common;component/Styles/MainWindowStyles.xaml" />
<ResourceDictionary Source="/QuickLook.Common;component/Styles/MainWindowStyles.Dark.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<!-- WebView2 will be added here programmatically -->
<StackPanel Margin="0,8,8,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Orientation="Horizontal">
<Button x:Name="buttonBackgroundColour"
Width="24"
Height="24"
Content="&#xEF1F;"
Style="{StaticResource CaptionButtonStyle}" />
</StackPanel>
</Grid>
</UserControl>

View File

@@ -34,6 +34,10 @@ public class SvgaImagePanel(IWebMetaProvider metaWeb) : SvgImagePanel()
ObjectForScripting ??= new ScriptHandler(path, _metaWeb);
_homePage = _resources["/svga2html.html"];
// Update WebView2 background color based on current theme
UpdateWebViewBackgroundColor();
NavigateToUri(new Uri("file://quicklook/"));
}
}

View File

@@ -35,6 +35,10 @@ public class TgsImagePanel : SvgImagePanel
ObjectForScripting ??= new TgsScriptHandler(path);
_homePage = _resources["/lottie2html.html"];
// Update WebView2 background color based on current theme
UpdateWebViewBackgroundColor();
NavigateToUri(new Uri("file://quicklook/"));
}

View File

@@ -102,10 +102,10 @@ internal static class WebHandler
ipWeb = ext switch
{
".svg" => new SvgImagePanel(),
".svga" => new SvgaImagePanel(metaWeb),
".lottie" or ".json" => new LottieImagePanel(),
".tgs" => new TgsImagePanel(),
".svg" => new SvgImagePanel() { ContextObject = context },
".svga" => new SvgaImagePanel(metaWeb) { ContextObject = context },
".lottie" or ".json" => new LottieImagePanel() { ContextObject = context },
".tgs" => new TgsImagePanel() { ContextObject = context },
_ => throw new NotSupportedException($"Unsupported file type: {ext}")
};