删除所有popup

This commit is contained in:
Poker 2023-06-29 21:42:34 +08:00
parent e010984313
commit 79da476545
No known key found for this signature in database
GPG Key ID: C65A6AD457D5C8F8
20 changed files with 256 additions and 790 deletions

View File

@ -20,7 +20,6 @@
using System;
using System.Threading.Tasks;
using Windows.Graphics;
using LiteDB;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@ -38,9 +37,9 @@ using Pixeval.Util.Threading;
using Pixeval.Util.UI;
using WinUI3Utilities;
using AppContext = Pixeval.AppManagement.AppContext;
using ApplicationTheme = Pixeval.Options.ApplicationTheme;
using IllustrationViewModel = Pixeval.UserControls.IllustrationView.IllustrationViewModel;
using AppTheme = Pixeval.Options.ApplicationTheme;
using Microsoft.UI;
using Pixeval.UserControls.IllustrationView;
namespace Pixeval;
@ -102,27 +101,19 @@ public class AppViewModel : AutoActivateObservableRecipient,
.AddSingleton(provider => new BrowseHistoryPersistentManager(provider.GetRequiredService<LiteDatabase>(), App.AppViewModel.AppSetting.MaximumBrowseHistoryRecords)));
}
public void SwitchTheme(ApplicationTheme theme)
public void SwitchTheme(AppTheme theme)
{
var selectedTheme = theme switch
{
ApplicationTheme.Dark => ElementTheme.Dark,
ApplicationTheme.Light => ElementTheme.Light,
ApplicationTheme.SystemDefault => ElementTheme.Default,
AppTheme.Dark => ElementTheme.Dark,
AppTheme.Light => ElementTheme.Light,
AppTheme.SystemDefault => ElementTheme.Default,
_ => throw new ArgumentOutOfRangeException(nameof(theme), theme, null)
};
if (CurrentContext.Window.Content is FrameworkElement rootElement)
rootElement.RequestedTheme = selectedTheme;
// TODO: 没反应
Application.Current.Resources["WindowCaptionForeground"] =
selectedTheme switch
{
ElementTheme.Dark => Colors.White,
ElementTheme.Light => Colors.Black,
_ => Application.Current.RequestedTheme is Microsoft.UI.Xaml.ApplicationTheme.Dark ? Colors.White : Colors.Black
};
}
public async Task ShowExceptionDialogAsync(Exception e)
@ -146,12 +137,12 @@ public class AppViewModel : AutoActivateObservableRecipient,
public void PrepareForActivation()
{
((MainWindow) CurrentContext.Window).ShowProgressRing();
((MainWindow)CurrentContext.Window).ShowProgressRing();
}
public void ActivationProcessed()
{
((MainWindow) CurrentContext.Window).HideProgressRing();
((MainWindow)CurrentContext.Window).HideProgressRing();
}
/// <summary>

View File

@ -7,37 +7,34 @@
Closed="MainWindow_OnClosed"
mc:Ignorable="d">
<Grid>
<Grid>
<Frame
x:Name="PixevalAppRootFrame"
x:FieldModifier="public"
Loaded="PixevalAppRootFrame_OnLoaded"
Navigated="PixevalAppRootFrame_OnNavigated"
Navigating="PixevalAppRootFrame_OnNavigating"
NavigationFailed="PixevalAppRootFrame_OnNavigationFailed">
<Frame.ContentTransitions>
<TransitionCollection>
<NavigationThemeTransition DefaultNavigationTransitionInfo="{x:Bind DefaultNavigationTransitionInfo}" />
</TransitionCollection>
</Frame.ContentTransitions>
</Frame>
<Grid
x:Name="Processing"
Width="100"
Height="100"
<Frame
x:Name="PixevalAppRootFrame"
x:FieldModifier="public"
Loaded="PixevalAppRootFrame_OnLoaded"
Navigated="PixevalAppRootFrame_OnNavigated"
Navigating="PixevalAppRootFrame_OnNavigating"
NavigationFailed="PixevalAppRootFrame_OnNavigationFailed">
<Frame.ContentTransitions>
<TransitionCollection>
<NavigationThemeTransition DefaultNavigationTransitionInfo="{x:Bind DefaultNavigationTransitionInfo}" />
</TransitionCollection>
</Frame.ContentTransitions>
</Frame>
<Grid
x:Name="Processing"
Width="100"
Height="100"
HorizontalAlignment="Center"
VerticalAlignment="Center"
CornerRadius="15"
Visibility="Collapsed">
<Rectangle Fill="{ThemeResource PixevalAppAcrylicBrush}" />
<ProgressRing
Width="40"
Height="40"
HorizontalAlignment="Center"
VerticalAlignment="Center"
CornerRadius="15"
Visibility="Collapsed">
<Rectangle Fill="{ThemeResource PixevalAppAcrylicBrush}" />
<ProgressRing
Width="40"
Height="40"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsIndeterminate="True" />
</Grid>
<TeachingTip x:Name="PixevalAppSnackBar" x:FieldModifier="public" />
IsIndeterminate="True" />
</Grid>
</Grid>
</Window>

View File

@ -1,26 +1,31 @@
<controls:EnhancedPage x:Class="Pixeval.Pages.Login.LoginPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Pixeval.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:login="using:Pixeval.Pages.Login"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:misc="using:Pixeval.Misc"
xmlns:misc1="using:Pixeval.Pages.Misc"
xmlns:attributes="using:Pixeval.Attributes"
d:DataContext="{d:DesignInstance login:LoginPageViewModel}"
Loaded="LoginPage_OnLoaded"
mc:Ignorable="d">
<controls:EnhancedPage
x:Class="Pixeval.Pages.Login.LoginPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:attributes="using:Pixeval.Attributes"
xmlns:controls="using:Pixeval.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:login="using:Pixeval.Pages.Login"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DataContext="{d:DesignInstance login:LoginPageViewModel}"
Loaded="LoginPage_OnLoaded"
mc:Ignorable="d">
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Width="150"
Height="150"
Source="../../Assets/Images/logo.png" />
<Image
Width="150"
Height="150"
Source="../../Assets/Images/logo.png" />
<ProgressRing Width="30" Height="30" />
<TextBlock Margin="0,15,0,0"
HorizontalAlignment="Center"
FontSize="10"
Text="{x:Bind attributes:LocalizedResourceAttributeHelper.GetLocalizedResourceContent(_viewModel.LoginPhase), Mode=OneWay}" />
<TextBlock
Margin="0,15,0,0"
HorizontalAlignment="Center"
FontSize="10"
Text="{x:Bind attributes:LocalizedResourceAttributeHelper.GetLocalizedResourceContent(_viewModel.LoginPhase), Mode=OneWay}" />
</StackPanel>
<Border
Margin="100"
Child="{x:Bind _viewModel.WebView, Mode=OneWay}"
CornerRadius="4" />
</Grid>
</controls:EnhancedPage>
</controls:EnhancedPage>

View File

@ -77,6 +77,12 @@ public partial class LoginPageViewModel : AutoActivateObservableRecipient
[ObservableProperty]
private LoginPhaseEnum _loginPhase;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(IsWebViewVisible))]
private LoginWebViewPopup? _webView;
public Visibility IsWebViewVisible => WebView is null ? Visibility.Collapsed : Visibility.Visible;
public void AdvancePhase(LoginPhaseEnum newPhase)
{
LoginPhase = newPhase;
@ -176,24 +182,22 @@ public partial class LoginPageViewModel : AutoActivateObservableRecipient
using var proxyServer = PixivAuthenticationProxyServer.Create(IPAddress.Loopback, port, await AppContext.GetFakeServerCertificateAsync());
Environment.SetEnvironmentVariable("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", $"--proxy-server=127.0.0.1:{port} --ignore-certificate-errors");
var content = new LoginWebViewPopup();
var webViewPopup = PopupManager.CreatePopup(content, widthMargin: 150, heightMargin: 100, minHeight: 400, minWidth: 600);
WebView = new();
AdvancePhase(LoginPhaseEnum.ExecutingWebView2);
PopupManager.ShowPopup(webViewPopup);
await content.LoginWebView.EnsureCoreWebView2Async();
content.LoginWebView.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
content.LoginWebView.CoreWebView2.WebResourceRequested += (_, args) =>
await WebView.LoginWebView.EnsureCoreWebView2Async();
WebView.LoginWebView.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
WebView.LoginWebView.CoreWebView2.WebResourceRequested += (_, args) =>
{
args.Request.Headers.SetHeader("Accept-Language", args.Request.Uri.Contains("recaptcha") ? "zh-cn" : CultureInfo.CurrentUICulture.Name);
};
var verifier = PixivAuthSignature.GetCodeVerify();
content.LoginWebView.Source = new Uri(PixivAuthSignature.GenerateWebPageUrl(verifier));
WebView.LoginWebView.Source = new Uri(PixivAuthSignature.GenerateWebPageUrl(verifier));
var (url, cookie) = await content.CookieCompletion.Task;
PopupManager.ClosePopup(webViewPopup);
var (url, cookie) = await WebView.CookieCompletion.Task;
WebView = null;
var code = HttpUtility.ParseQueryString(new Uri(url).Query)["code"]!;

View File

@ -1,264 +0,0 @@
#region Copyright (c) Pixeval/Pixeval
// GPL v3 License
//
// Pixeval/Pixeval
// Copyright (c) 2022 Pixeval/AppPopup.cs
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Collections.Generic;
using System.Numerics;
using Windows.Foundation;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Animation;
using Pixeval.Util.UI;
using WinUI3Utilities;
namespace Pixeval.Popups;
public static class PopupManager
{
private static readonly Dictionary<Guid, AppPopup> OpenPopupsInternal = new();
public static IReadOnlyDictionary<Guid, AppPopup> OpenPopups => OpenPopupsInternal;
public static AppPopup CreatePopup(
IAppPopupContent content,
double width = double.NaN,
double height = double.NaN,
double widthMargin = double.NaN,
double heightMargin = double.NaN,
double minWidth = 0,
double maxWidth = double.MaxValue,
double minHeight = 0,
double maxHeight = double.MaxValue,
bool lightDismiss = false,
bool useAnimation = true,
Action<IAppPopupContent>? opening = null,
Action<IAppPopupContent, object?>? closing = null)
{
return new AppPopup(content, width, height, widthMargin, heightMargin, minWidth, maxWidth, minHeight, maxHeight, lightDismiss, useAnimation, opening, closing);
}
public static void ShowPopup(AppPopup popup)
{
popup.Show();
OpenPopupsInternal[popup.UniqueId] = popup;
}
public static void ClosePopup(AppPopup popup)
{
popup.Close();
OpenPopupsInternal.Remove(popup.UniqueId);
}
public static void ClosePopup(Guid guid)
{
if (OpenPopupsInternal.TryGetValue(guid, out var popup))
{
popup.Close();
OpenPopupsInternal.Remove(guid);
}
}
}
public class AppPopup
{
private readonly Action<IAppPopupContent, object?>? _closing;
private readonly IAppPopupContent _content;
private readonly double _height;
private readonly double _heightMargin;
private readonly double _maxHeight;
private readonly double _maxWidth;
private readonly double _minHeight;
private readonly double _minWidth;
private readonly Action<IAppPopupContent>? _opening;
private readonly bool _useAnimation;
private readonly double _width;
private readonly double _widthMargin;
public AppPopup(
IAppPopupContent content,
double width = double.NaN,
double height = double.NaN,
double widthMargin = double.NaN,
double heightMargin = double.NaN,
double minWidth = 0,
double maxWidth = double.MaxValue,
double minHeight = 0,
double maxHeight = double.MaxValue,
bool lightDismiss = false,
bool useAnimation = true,
Action<IAppPopupContent>? opening = null,
Action<IAppPopupContent, object?>? closing = null)
{
_content = content;
_width = width;
_height = height;
_opening = opening;
_closing = closing;
_maxWidth = maxWidth;
_widthMargin = widthMargin;
_heightMargin = heightMargin;
_minWidth = minWidth;
_maxWidth = maxWidth;
_minHeight = minHeight;
_maxHeight = maxHeight;
_useAnimation = useAnimation;
var (windowWidth, windowHeight) = UIHelper.GetAppWindowSizeTuple();
UniqueId = content.UniqueId;
content.UIContent.HorizontalAlignment = HorizontalAlignment.Stretch;
content.UIContent.VerticalAlignment = VerticalAlignment.Stretch;
var themeShadow = new ThemeShadow();
var shadowReceiver = new Grid
{
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch,
Background = (Brush)Application.Current.Resources["ApplicationPageBackgroundThemeBrush"],
Opacity = 0.4
};
var popupContentPresenter = new ContentPresenter
{
Shadow = themeShadow,
Translation = new Vector3(0, 0, 40),
BorderBrush = (Brush)Application.Current.Resources["PixevalBorderBrush"],
Background = (Brush)Application.Current.Resources["PixevalPanelBackgroundThemeBrush"],
CornerRadius = new CornerRadius(10),
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Content = content
};
themeShadow.Receivers.Add(shadowReceiver);
if (lightDismiss)
{
shadowReceiver.Tapped += OnShadowReceiverOnTapped;
}
else
{
shadowReceiver.Tapped -= OnShadowReceiverOnTapped;
}
void OnShadowReceiverOnTapped(object sender, TappedRoutedEventArgs a)
{
PopupManager.ClosePopup(PopupManager.OpenPopups[UniqueId]);
}
Popup = new Popup
{
RequestedTheme = App.AppViewModel.AppRootFrameTheme,
Transitions = new TransitionCollection
{
new PopupThemeTransition()
},
XamlRoot = App.AppViewModel.AppWindowRootFrame.XamlRoot,
Width = windowWidth,
Height = windowHeight,
Child = new Grid
{
Children =
{
shadowReceiver, popupContentPresenter
}
}
};
CurrentContext.Window.SizeChanged += WindowOnSizeChanged;
}
public Popup Popup { get; }
public Guid UniqueId { get; }
private void WindowOnSizeChanged(object sender, WindowSizeChangedEventArgs args)
{
RearrangePopup(args.Size);
}
private void RearrangePopup(Size desiredSize)
{
var (windowWidth, windowHeight) = (desiredSize.Width, desiredSize.Height);
var child = (Grid)Popup.Child;
var container = (ContentPresenter)((Grid)Popup.Child).Children[1];
Popup.Width = windowWidth;
Popup.Height = windowHeight;
child.Width = windowWidth;
child.Height = windowHeight;
if (!double.IsNaN(_width))
{
container.Width = _width;
}
else if (!double.IsNaN(_widthMargin))
{
container.Width = Math.Clamp(windowWidth - _widthMargin * 2, _minWidth, _maxWidth);
}
if (!double.IsNaN(_height))
{
container.Height = _height;
}
else if (!double.IsNaN(_heightMargin))
{
container.Height = Math.Clamp(windowHeight - _heightMargin * 2, _minHeight, _maxHeight);
}
}
public void Show()
{
if (_useAnimation)
{
var inAnimation = new PopInThemeAnimation();
var storyboard = UIHelper.CreateStoryboard(inAnimation);
Storyboard.SetTarget(inAnimation, Popup);
storyboard.Begin();
}
Popup.IsOpen = true;
_opening?.Invoke(_content);
RearrangePopup(UIHelper.GetDpiAwareAppWindowSize());
}
public void Close()
{
if (_useAnimation)
{
var inAnimation = new PopOutThemeAnimation();
var storyboard = UIHelper.CreateStoryboard(inAnimation);
Storyboard.SetTarget(inAnimation, Popup);
storyboard.Completed += (_, _) =>
{
Popup.IsOpen = false;
_closing?.Invoke(_content, _content is ICompletableAppPopupContent completable ? completable.GetCompletionResult() : null);
};
storyboard.Begin();
}
else
{
Popup.IsOpen = false;
_closing?.Invoke(_content, _content is ICompletableAppPopupContent completable ? completable.GetCompletionResult() : null);
}
}
~AppPopup()
{
CurrentContext.Window.SizeChanged -= WindowOnSizeChanged;
}
}

View File

@ -4,9 +4,7 @@
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"
xmlns:ui="using:Pixeval.Util.UI"
xmlns:userControls="using:Pixeval.UserControls"
ui:NavigationHelper.ClosePopupHotKey="Escape"
mc:Ignorable="d">
<StackPanel>
<Grid>

View File

@ -1,31 +0,0 @@
#region Copyright (c) Pixeval/Pixeval
// GPL v3 License
//
// Pixeval/Pixeval
// Copyright (c) 2022 Pixeval/IAppPopupContent.cs
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using Microsoft.UI.Xaml;
namespace Pixeval.Popups;
public interface IAppPopupContent
{
Guid UniqueId { get; }
FrameworkElement UIContent { get; }
}

View File

@ -1,26 +0,0 @@
#region Copyright (c) Pixeval/Pixeval
// GPL v3 License
//
// Pixeval/Pixeval
// Copyright (c) 2022 Pixeval/ICompletableAppPopupContent.cs
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
namespace Pixeval.Popups;
public interface ICompletableAppPopupContent : IAppPopupContent
{
object GetCompletionResult();
}

View File

@ -1,132 +1,87 @@
<UserControl x:Class="Pixeval.Popups.IllustrationResultFilter.IllustrationResultFilterPopupContent"
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:illustrationResultFilter="using:Pixeval.Popups.IllustrationResultFilter"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:tokenInput="using:Pixeval.UserControls.TokenInput"
xmlns:tokenInputTextBox="using:Pixeval.Controls.TokenInputTextBox"
xmlns:ui="using:Pixeval.Util.UI"
ui:NavigationHelper.ClosePopupHotKey="Escape"
Loaded="IllustrationResultFilterPopupContent_OnLoaded"
mc:Ignorable="d">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<TextBlock x:Uid="/IllustrationResultFilterPopupContent/TitleTextBlock"
Margin="0,0,0,10"
Style="{StaticResource TitleTextBlockStyle}" />
<Button x:Name="CloseButton"
Width="38"
Height="38"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Content="{ui:FontIcon Glyph=ChromeCloseE8BB,
FontSize={StaticResource PixevalButtonIconSize}}"
CornerRadius="90"
Tapped="CloseButton_OnTapped" />
</Grid>
<ScrollViewer Grid.Row="1">
<StackPanel HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Spacing="5">
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
x:Uid="/IllustrationResultFilterPopupContent/LeastBookmarkCountEntry">
<NumberBox x:Uid="/IllustrationResultFilterPopupContent/LeastBookmarkCountNumberBox"
Width="400"
HorizontalAlignment="Left"
Minimum="0"
Style="{StaticResource SettingsNumberBoxStyle}"
Value="{x:Bind _viewModel.LeastBookmark, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
x:Uid="/IllustrationResultFilterPopupContent/MaximumBookmarkCountEntry">
<NumberBox x:Uid="/IllustrationResultFilterPopupContent/MaximumBookmarkCountNumberBox"
Width="400"
HorizontalAlignment="Left"
Minimum="0"
Style="{StaticResource SettingsNumberBoxStyle}"
Value="{x:Bind _viewModel.MaximumBookmark, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
x:Uid="/IllustrationResultFilterPopupContent/IncludeTagsEntry">
<tokenInput:TokenInput x:Uid="/IllustrationResultFilterPopupContent/IncludeTagTokenInput"
TokenSource="{x:Bind _viewModel.IncludeTags, Mode=OneWay}" />
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
x:Uid="/IllustrationResultFilterPopupContent/ExcludeTagsEntry">
<tokenInput:TokenInput x:Uid="/IllustrationResultFilterPopupContent/ExcludeTagTokenInput"
TokenSource="{x:Bind _viewModel.ExcludeTags, Mode=OneWay}" />
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
x:Uid="/IllustrationResultFilterPopupContent/UserGroupNameEntry">
<tokenInput:TokenInput x:Uid="/IllustrationResultFilterPopupContent/UserGroupNameInput"
TokenSource="{x:Bind _viewModel.UserGroupName, Mode=OneWay}" />
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
x:Uid="/IllustrationResultFilterPopupContent/IllustratorNameEntry">
<tokenInputTextBox:TokenInputTextBox
x:Uid="/IllustrationResultFilterPopupContent/IllustratorNameInput"
Token="{x:Bind _viewModel.IllustratorName, Mode=OneWay}" />
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
x:Uid="/IllustrationResultFilterPopupContent/IllustrationNameEntry">
<tokenInputTextBox:TokenInputTextBox
x:Uid="/IllustrationResultFilterPopupContent/IllustrationNameInput"
Token="{x:Bind _viewModel.IllustrationName, Mode=OneWay}" />
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
x:Uid="/IllustrationResultFilterPopupContent/IllustratorIdEntry">
<NumberBox x:Uid="/IllustrationResultFilterPopupContent/IllustratorIdInput"
Width="400"
HorizontalAlignment="Left"
SpinButtonPlacementMode="Hidden"
Style="{StaticResource SettingsNumberBoxStyle}"
Text="{x:Bind _viewModel.IllustratorId, Mode=TwoWay}" />
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
x:Uid="/IllustrationResultFilterPopupContent/IllustrationIdEntry">
<NumberBox x:Uid="/IllustrationResultFilterPopupContent/IllustrationIdInput"
Width="400"
HorizontalAlignment="Left"
SpinButtonPlacementMode="Hidden"
Style="{StaticResource SettingsNumberBoxStyle}"
Text="{x:Bind _viewModel.IllustrationId, Mode=TwoWay}" />
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
x:Uid="/IllustrationResultFilterPopupContent/PublishDateStartEntry">
<CalendarDatePicker x:Uid="/IllustrationResultFilterPopupContent/PublishDateStartPicker"
Width="400"
Date="{x:Bind _viewModel.PublishDateStart, Mode=TwoWay}" />
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
<illustrationResultFilter:IllustrationResultFilterFunctionEntry
x:Uid="/IllustrationResultFilterPopupContent/PublishDateEndEntry">
<CalendarDatePicker x:Uid="/IllustrationResultFilterPopupContent/PublishDateEndPicker"
Width="400"
Date="{x:Bind _viewModel.PublishDateEnd, Mode=TwoWay}" />
</illustrationResultFilter:IllustrationResultFilterFunctionEntry>
</StackPanel>
</ScrollViewer>
<Button x:Uid="/IllustrationResultFilterPopupContent/ResetButton"
Grid.Row="2"
Margin="0,15,0,0"
<UserControl
x:Class="Pixeval.Popups.IllustrationResultFilter.IllustrationResultFilterPopupContent"
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:filter="using:Pixeval.Popups.IllustrationResultFilter"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:tokenInput="using:Pixeval.UserControls.TokenInput"
xmlns:tokenInputTextBox="using:Pixeval.Controls.TokenInputTextBox"
mc:Ignorable="d">
<StackPanel Spacing="5">
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/LeastBookmarkCountEntry">
<NumberBox
x:Uid="/IllustrationResultFilterPopupContent/LeastBookmarkCountNumberBox"
Width="400"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Tapped="ResetButton_OnTapped" />
</Grid>
</UserControl>
Minimum="0"
Style="{StaticResource SettingsNumberBoxStyle}"
Value="{x:Bind ViewModel.LeastBookmark, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</filter:IllustrationResultFilterFunctionEntry>
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/MaximumBookmarkCountEntry">
<NumberBox
x:Uid="/IllustrationResultFilterPopupContent/MaximumBookmarkCountNumberBox"
Width="400"
HorizontalAlignment="Left"
Minimum="0"
Style="{StaticResource SettingsNumberBoxStyle}"
Value="{x:Bind ViewModel.MaximumBookmark, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</filter:IllustrationResultFilterFunctionEntry>
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/IncludeTagsEntry">
<tokenInput:TokenInput x:Uid="/IllustrationResultFilterPopupContent/IncludeTagTokenInput" TokenSource="{x:Bind ViewModel.IncludeTags, Mode=OneWay}" />
</filter:IllustrationResultFilterFunctionEntry>
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/ExcludeTagsEntry">
<tokenInput:TokenInput x:Uid="/IllustrationResultFilterPopupContent/ExcludeTagTokenInput" TokenSource="{x:Bind ViewModel.ExcludeTags, Mode=OneWay}" />
</filter:IllustrationResultFilterFunctionEntry>
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/UserGroupNameEntry">
<tokenInput:TokenInput x:Uid="/IllustrationResultFilterPopupContent/UserGroupNameInput" TokenSource="{x:Bind ViewModel.UserGroupName, Mode=OneWay}" />
</filter:IllustrationResultFilterFunctionEntry>
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/IllustratorNameEntry">
<tokenInputTextBox:TokenInputTextBox x:Uid="/IllustrationResultFilterPopupContent/IllustratorNameInput" Token="{x:Bind ViewModel.IllustratorName, Mode=OneWay}" />
</filter:IllustrationResultFilterFunctionEntry>
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/IllustrationNameEntry">
<tokenInputTextBox:TokenInputTextBox x:Uid="/IllustrationResultFilterPopupContent/IllustrationNameInput" Token="{x:Bind ViewModel.IllustrationName, Mode=OneWay}" />
</filter:IllustrationResultFilterFunctionEntry>
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/IllustratorIdEntry">
<NumberBox
x:Uid="/IllustrationResultFilterPopupContent/IllustratorIdInput"
Width="400"
HorizontalAlignment="Left"
SpinButtonPlacementMode="Hidden"
Style="{StaticResource SettingsNumberBoxStyle}"
Text="{x:Bind ViewModel.IllustratorId, Mode=TwoWay}" />
</filter:IllustrationResultFilterFunctionEntry>
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/IllustrationIdEntry">
<NumberBox
x:Uid="/IllustrationResultFilterPopupContent/IllustrationIdInput"
Width="400"
HorizontalAlignment="Left"
SpinButtonPlacementMode="Hidden"
Style="{StaticResource SettingsNumberBoxStyle}"
Text="{x:Bind ViewModel.IllustrationId, Mode=TwoWay}" />
</filter:IllustrationResultFilterFunctionEntry>
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/PublishDateStartEntry">
<CalendarDatePicker
x:Uid="/IllustrationResultFilterPopupContent/PublishDateStartPicker"
Width="400"
Date="{x:Bind ViewModel.PublishDateStart, Mode=TwoWay}" />
</filter:IllustrationResultFilterFunctionEntry>
<filter:IllustrationResultFilterFunctionEntry x:Uid="/IllustrationResultFilterPopupContent/PublishDateEndEntry">
<CalendarDatePicker
x:Uid="/IllustrationResultFilterPopupContent/PublishDateEndPicker"
Width="400"
Date="{x:Bind ViewModel.PublishDateEnd, Mode=TwoWay}" />
</filter:IllustrationResultFilterFunctionEntry>
</StackPanel>
</UserControl>

View File

@ -1,4 +1,4 @@
#region Copyright (c) Pixeval/Pixeval
#region Copyright (c) Pixeval/Pixeval
// GPL v3 License
//
// Pixeval/Pixeval
@ -18,91 +18,39 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Reflection;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Input;
using Pixeval.Attributes;
namespace Pixeval.Popups.IllustrationResultFilter;
public sealed partial class IllustrationResultFilterPopupContent : ICompletableAppPopupContent
public sealed partial class IllustrationResultFilterPopupContent
{
private readonly IllustrationResultFilterPopupViewModel _viewModel;
public IllustrationResultFilterPopupViewModel ViewModel { get; set; } = new();
private EventHandler<TappedRoutedEventArgs>? _closeButtonTapped;
private EventHandler<TappedRoutedEventArgs>? _resetButtonTapped;
public IllustrationResultFilterPopupContent(IllustrationResultFilterPopupViewModel viewModel)
public IllustrationResultFilterPopupContent()
{
_viewModel = viewModel;
UniqueId = Guid.NewGuid();
InitializeComponent();
}
public bool IsReset { get; private set; }
public FilterSettings GetFilterSettings =>
new(ViewModel.IncludeTags,
ViewModel.ExcludeTags,
ViewModel.LeastBookmark,
ViewModel.MaximumBookmark,
ViewModel.UserGroupName,
ViewModel.IllustratorName,
ViewModel.IllustratorId,
ViewModel.IllustrationName,
ViewModel.IllustrationId,
ViewModel.PublishDateStart,
ViewModel.PublishDateEnd);
public Guid UniqueId { get; }
public FrameworkElement UIContent => this;
public object GetCompletionResult()
public void Reset()
{
return new FilterSettings(
_viewModel.IncludeTags,
_viewModel.ExcludeTags,
_viewModel.LeastBookmark,
_viewModel.MaximumBookmark,
_viewModel.UserGroupName,
_viewModel.IllustratorName,
_viewModel.IllustratorId,
_viewModel.IllustrationName,
_viewModel.IllustrationId,
_viewModel.PublishDateStart,
_viewModel.PublishDateEnd);
}
public event EventHandler<TappedRoutedEventArgs> ResetButtonTapped
{
add => _resetButtonTapped += value;
remove => _resetButtonTapped -= value;
}
public event EventHandler<TappedRoutedEventArgs> CloseButtonTapped
{
add => _closeButtonTapped += value;
remove => _closeButtonTapped -= value;
}
private void CloseButton_OnTapped(object sender, TappedRoutedEventArgs e)
{
_closeButtonTapped?.Invoke(this, e);
}
/// <summary>
/// Flush the bindings
/// </summary>
public void Cleanup()
{
Focus(FocusState.Programmatic);
}
private void ResetButton_OnTapped(object sender, TappedRoutedEventArgs e)
{
IsReset = true;
foreach (var propertyInfo in typeof(IllustrationResultFilterPopupViewModel).GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
propertyInfo.SetValue(_viewModel, propertyInfo.GetDefaultValue());
propertyInfo.SetValue(ViewModel, propertyInfo.GetDefaultValue());
}
_resetButtonTapped?.Invoke(this, e);
}
private void IllustrationResultFilterPopupContent_OnLoaded(object sender, RoutedEventArgs e)
{
// Focus the popup content so that the hot key for closing can work properly
CloseButton.Focus(FocusState.Programmatic);
}
}
}

View File

@ -1,14 +1,15 @@
<UserControl x:Class="Pixeval.Popups.LoginWebViewPopup"
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"
mc:Ignorable="d">
<WebView2 x:Name="LoginWebView"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
x:FieldModifier="public"
CoreWebView2Initialized="LoginWebView_OnCoreWebView2Initialized"
NavigationStarting="LoginWebView_OnNavigationStarting" />
<UserControl
x:Class="Pixeval.Popups.LoginWebViewPopup"
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"
mc:Ignorable="d">
<WebView2
x:Name="LoginWebView"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
x:FieldModifier="public"
CoreWebView2Initialized="LoginWebView_OnCoreWebView2Initialized"
NavigationStarting="LoginWebView_OnNavigationStarting" />
</UserControl>

View File

@ -1,4 +1,4 @@
#region Copyright (c) Pixeval/Pixeval
#region Copyright (c) Pixeval/Pixeval
// GPL v3 License
//
// Pixeval/Pixeval
@ -25,35 +25,26 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.Core;
namespace Pixeval.Popups
namespace Pixeval.Popups;
public sealed partial class LoginWebViewPopup
{
public sealed partial class LoginWebViewPopup : IAppPopupContent
public LoginWebViewPopup() => InitializeComponent();
public readonly TaskCompletionSource<(string, string)> CookieCompletion = new();
private async void LoginWebView_OnNavigationStarting(WebView2 sender, CoreWebView2NavigationStartingEventArgs args)
{
public LoginWebViewPopup()
if (args.Uri.StartsWith("pixiv://"))
{
InitializeComponent();
UniqueId = Guid.NewGuid();
}
public readonly TaskCompletionSource<(string, string)> CookieCompletion = new();
public Guid UniqueId { get; }
public FrameworkElement UIContent => this;
private async void LoginWebView_OnNavigationStarting(WebView2 sender, CoreWebView2NavigationStartingEventArgs args)
{
if (args.Uri.StartsWith("pixiv://"))
{
var cookies = await LoginWebView.CoreWebView2.CookieManager.GetCookiesAsync("https://pixiv.net");
var cookieString = string.Join(';', cookies.Select(c => $"{c.Name}={c.Value}"));
CookieCompletion.SetResult((args.Uri, cookieString));
}
}
private async void LoginWebView_OnCoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
{
await LoginWebView.CoreWebView2.CallDevToolsProtocolMethodAsync("Security.setIgnoreCertificateErrors", "{ \"ignore\": true }");
var cookies = await LoginWebView.CoreWebView2.CookieManager.GetCookiesAsync("https://pixiv.net");
var cookieString = string.Join(';', cookies.Select(c => $"{c.Name}={c.Value}"));
CookieCompletion.SetResult((args.Uri, cookieString));
}
}
private async void LoginWebView_OnCoreWebView2Initialized(WebView2 sender, CoreWebView2InitializedEventArgs args)
{
await LoginWebView.CoreWebView2.CallDevToolsProtocolMethodAsync("Security.setIgnoreCertificateErrors", "{ \"ignore\": true }");
}
}

View File

@ -177,12 +177,6 @@
<data name="PublishDateStartPicker.PlaceholderText" xml:space="preserve">
<value>只会包含该日期后发布的作品</value>
</data>
<data name="ResetButton.Content" xml:space="preserve">
<value>清空过滤器</value>
</data>
<data name="TitleTextBlock.Text" xml:space="preserve">
<value>过滤器设置</value>
</data>
<data name="UserGroupNameEntry.Header" xml:space="preserve">
<value>自定义收藏夹的名称</value>
</data>

View File

@ -168,4 +168,13 @@
<data name="FastFilterAutoSuggestBox.PlaceholderText" xml:space="preserve">
<value>输入ID/标签/作品名进行快速过滤</value>
</data>
<data name="FilterTeachingTip.ActionButtonContent" xml:space="preserve">
<value>清空过滤器</value>
</data>
<data name="FilterTeachingTip.CloseButtonContent" xml:space="preserve">
<value>应用</value>
</data>
<data name="FilterTeachingTip.Title" xml:space="preserve">
<value>过滤器设置</value>
</data>
</root>

View File

@ -123,7 +123,8 @@ public sealed partial class IllustrationView
{
TitleBarType = TitleBarHelper.TitleBarType.AppWindow,
Size = new SizeInt32(width, height)
});
})
.Activate();
}
private static unsafe (int windowWidth, int windowHeight) DetermineWindowSize(int illustWidth, double illustRatio)

View File

@ -4,6 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:illustrationResultFilter="using:Pixeval.Popups.IllustrationResultFilter"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:Pixeval.Util.UI"
mc:Ignorable="d">
@ -38,11 +39,11 @@
Icon="{ui:FontIcon Glyph=CancelE711}"
Label="{x:Bind ViewModel.SelectionLabel, Mode=OneWay}"
Tapped="CancelSelectionButton_OnTapped" />
<AppBarToggleButton
<AppBarButton
x:Name="OpenConditionDialogButton"
x:Uid="/IllustrationViewCommandBar/OpenConditionDialogButton"
Checked="OpenConditionDialogButton_OnChecked"
Icon="{ui:FontIcon Glyph=FilterE71C}" />
Icon="{ui:FontIcon Glyph=FilterE71C}"
Tapped="OpenConditionDialogButton_OnTapped" />
<AppBarButton
x:Name="SelectAllButton"
x:Uid="/IllustrationViewCommandBar/SelectAllButton"
@ -66,6 +67,16 @@
Icon="{ui:FontIcon Glyph=ShareE72D}"
Tapped="ShareButton_OnTapped" />
</CommandBar>
<TeachingTip
x:Name="FilterTeachingTip"
x:Uid="/IllustrationViewCommandBar/FilterTeachingTip"
Grid.Column="0"
ActionButtonClick="FilterTeachingTip_OnActionButtonClick"
CloseButtonClick="FilterTeachingTip_OnCloseButtonClick"
IsLightDismissEnabled="True"
Target="{x:Bind OpenConditionDialogButton}">
<illustrationResultFilter:IllustrationResultFilterPopupContent x:Name="FilterContent" />
</TeachingTip>
<TeachingTip
x:Name="CommandBarTeachingTip"
Grid.Column="0"

View File

@ -55,8 +55,6 @@ public sealed partial class IllustrationViewCommandBar
private FilterSettings _lastFilterSettings = FilterSettings.Default;
private readonly IllustrationResultFilterPopupViewModel _filterPopupViewModel = new();
public IllustrationViewCommandBar()
{
InitializeComponent();
@ -219,27 +217,19 @@ public sealed partial class IllustrationViewCommandBar
ViewModel.DataProvider.IllustrationsSource.WhereNotNull().ForEach(i => i.IsSelected = false);
}
private void OpenConditionDialogButton_OnChecked(object sender, RoutedEventArgs e)
private void OpenConditionDialogButton_OnTapped(object sender, TappedRoutedEventArgs e)
{
var content = new IllustrationResultFilterPopupContent(_filterPopupViewModel);
var popup = PopupManager.CreatePopup(content, 550, heightMargin: 100, lightDismiss: false, closing: ConditionPopupClosing);
content.ResetButtonTapped += (_, _) =>
{
content.Cleanup();
PopupManager.ClosePopup(popup);
};
content.CloseButtonTapped += (_, _) =>
{
content.Cleanup();
PopupManager.ClosePopup(popup);
};
PopupManager.ShowPopup(popup);
FilterTeachingTip.IsOpen = true;
}
private void ConditionPopupClosing(IAppPopupContent popup, object? arg)
private void FilterTeachingTip_OnActionButtonClick(TeachingTip sender, object args)
{
OpenConditionDialogButton.IsChecked = false;
if (arg is FilterSettings(
FilterContent.Reset();
}
private void FilterTeachingTip_OnCloseButtonClick(TeachingTip sender, object args)
{
if (FilterContent.GetFilterSettings is (
var includeTags,
var excludeTags,
var leastBookmark,
@ -258,11 +248,6 @@ public sealed partial class IllustrationViewCommandBar
}
_lastFilterSettings = filterSettings;
if (popup is IllustrationResultFilterPopupContent { IsReset: true })
{
ViewModel.DataProvider.Filter = null;
return;
}
ViewModel.DataProvider.Filter = null;
ViewModel.DataProvider.Filter = o =>

View File

@ -1,4 +1,4 @@
#region Copyright (c) Pixeval/Pixeval
#region Copyright (c) Pixeval/Pixeval
// GPL v3 License
//
// Pixeval/Pixeval
@ -52,7 +52,7 @@ public static class ThreadingHelper
public static void CompareExchange(ref int location1, int value, int comparand)
{
do { } while (Interlocked.CompareExchange(ref location1, value, comparand) != comparand);
while (Interlocked.CompareExchange(ref location1, value, comparand) != comparand);
}
// fork a task from current context.
@ -117,4 +117,4 @@ public static class ThreadingHelper
}).Discard();
return tcs.Task;
}
}
}

View File

@ -1,108 +0,0 @@
#region Copyright (c) Pixeval/Pixeval
// GPL v3 License
//
// Pixeval/Pixeval
// Copyright (c) 2022 Pixeval/NavigationHelper.cs
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
using Windows.System;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Pixeval.Popups;
namespace Pixeval.Util.UI;
public static class NavigationHelper
{
public static readonly DependencyProperty BackHotKeyProperty = DependencyProperty.RegisterAttached(
"BackHotKey",
typeof(VirtualKey),
typeof(NavigationHelper),
new PropertyMetadata(DependencyProperty.UnsetValue, BackHotKeyChanged));
public static readonly DependencyProperty ClosePopupHotKeyProperty = DependencyProperty.RegisterAttached(
"ClosePopupHotKey",
typeof(VirtualKey),
typeof(NavigationHelper),
new PropertyMetadata(DependencyProperty.UnsetValue, ClosePopupHotKey));
public static void SetBackHotKey(DependencyObject element, VirtualKey value)
{
element.SetValue(BackHotKeyProperty, value);
}
public static VirtualKey GetBackHotKey(DependencyObject element)
{
return (VirtualKey)element.GetValue(BackHotKeyProperty);
}
private static void BackHotKeyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Page and IGoBack)
{
if (e.NewValue is VirtualKey)
{
((Page)d).KeyDown += OnKeyDown;
}
else
{
((Page)d).KeyDown -= OnKeyDown;
}
void OnKeyDown(object _, KeyRoutedEventArgs args)
{
if (args.Key == (VirtualKey)e.NewValue)
{
((IGoBack)d).GoBack();
}
}
}
}
public static void SetClosePopupHotKey(DependencyObject element, VirtualKey value)
{
element.SetValue(ClosePopupHotKeyProperty, value);
}
public static VirtualKey GetClosePopupHotKey(DependencyObject element)
{
return (VirtualKey)element.GetValue(ClosePopupHotKeyProperty);
}
private static void ClosePopupHotKey(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is IAppPopupContent content)
{
if (e.NewValue is VirtualKey)
{
content.UIContent.KeyDown += UIContentOnKeyDown;
}
else
{
content.UIContent.KeyDown -= UIContentOnKeyDown;
}
void UIContentOnKeyDown(object sender, KeyRoutedEventArgs args)
{
if (args.Key == (VirtualKey)e.NewValue)
{
PopupManager.ClosePopup(content.UniqueId);
}
}
}
}
}

View File

@ -33,7 +33,11 @@ public static class WindowFactory
public static CustomizableWindow Fork(this Window owner, out CustomizableWindow window)
{
var w = window = new(owner);
window.Closed += (_, _) => ForkedWindowsInternal.Remove(w);
window.Closed += (_, _) =>
{
w.Close();
ForkedWindowsInternal.Remove(w);
};
ForkedWindowsInternal.Add(window);
return window;
}
@ -44,8 +48,9 @@ public static class WindowFactory
return window;
}
public static void Initialize(this CustomizableWindow window, AppHelper.InitializeInfo provider)
public static CustomizableWindow Initialize(this CustomizableWindow window, WindowHelper.InitializeInfo provider)
{
AppHelper.Initialize(provider, window);
WindowHelper.Initialize(window, provider);
return window;
}
}