feat: Better-Seewo v2.0.0 - 希沃白板功能增强插件
- Fluent Design 风格 UI,深色/浅色主题切换 - 平滑过渡动画(页面切换、按钮交互、状态变化) - 五大核心功能:安装管理、墨迹管理、格式转换、触摸设置、激活管理 - 基于 dotnetCampus.EasiPlugin.Sdk v2.1.1-alpha.3 插件框架 - WPF 安装向导(欢迎页 -> 安装页 -> 完成页)
This commit is contained in:
422
Installer/Pages/CompletePage.xaml
Normal file
422
Installer/Pages/CompletePage.xaml
Normal file
@@ -0,0 +1,422 @@
|
||||
<!--
|
||||
CompletePage.xaml - Better-Seewo 安装向导完成页面
|
||||
显示安装成功图标、安装摘要和操作按钮
|
||||
带成功图标弹出动画和元素交错淡入
|
||||
作者:雾启工作室
|
||||
-->
|
||||
|
||||
<Page x:Class="Better_Seewo.Installer.Pages.CompletePage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Background="Transparent">
|
||||
|
||||
<!-- ===== 页面入场动画 ===== -->
|
||||
<Page.Triggers>
|
||||
<EventTrigger RoutedEvent="Page.Loaded">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<!-- 成功图标弹出动画:Scale 0 -> 1.2 -> 1.0 -->
|
||||
<DoubleAnimation Storyboard.TargetName="SuccessIconPanel"
|
||||
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
|
||||
From="0" To="1.2"
|
||||
Duration="0:0:0.400">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
<DoubleAnimation Storyboard.TargetName="SuccessIconPanel"
|
||||
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
|
||||
From="0" To="1.2"
|
||||
Duration="0:0:0.400">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
<!-- 弹出后回弹到 1.0 -->
|
||||
<DoubleAnimation Storyboard.TargetName="SuccessIconPanel"
|
||||
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
|
||||
From="1.2" To="1.0"
|
||||
Duration="0:0:0.200"
|
||||
BeginTime="0:0:0.400">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseInOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
<DoubleAnimation Storyboard.TargetName="SuccessIconPanel"
|
||||
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
|
||||
From="1.2" To="1.0"
|
||||
Duration="0:0:0.200"
|
||||
BeginTime="0:0:0.400">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseInOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
|
||||
<!-- 标题文字:淡入(延迟 300ms) -->
|
||||
<DoubleAnimation Storyboard.TargetName="TitlePanel"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0" To="1"
|
||||
Duration="0:0:0.400"
|
||||
BeginTime="0:0:0.300">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
|
||||
<!-- 安装摘要:淡入(延迟 450ms) -->
|
||||
<DoubleAnimation Storyboard.TargetName="SummaryPanel"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0" To="1"
|
||||
Duration="0:0:0.400"
|
||||
BeginTime="0:0:0.450">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
|
||||
<!-- 按钮区域:淡入(延迟 600ms) -->
|
||||
<DoubleAnimation Storyboard.TargetName="ButtonsPanel"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0" To="1"
|
||||
Duration="0:0:0.400"
|
||||
BeginTime="0:0:0.600">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
</Page.Triggers>
|
||||
|
||||
<!-- ===== 页面内容 ===== -->
|
||||
<Grid Margin="40,24,40,16">
|
||||
<StackPanel HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
MaxWidth="420">
|
||||
|
||||
<!-- ============================== -->
|
||||
<!-- ===== 成功图标 ===== -->
|
||||
<!-- ============================== -->
|
||||
<Grid x:Name="SuccessIconPanel"
|
||||
Width="72" Height="72"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,20">
|
||||
<Grid.RenderTransform>
|
||||
<ScaleTransform ScaleX="0" ScaleY="0" />
|
||||
</Grid.RenderTransform>
|
||||
|
||||
<!-- 外层发光效果 -->
|
||||
<Ellipse Fill="{DynamicResource SuccessBrush}"
|
||||
Opacity="0.12"
|
||||
Width="80" Height="80" />
|
||||
|
||||
<!-- 绿色圆形背景 -->
|
||||
<Ellipse Fill="{DynamicResource SuccessBrush}"
|
||||
Opacity="0.2"
|
||||
Width="72" Height="72" />
|
||||
|
||||
<!-- 绿色圆圈 -->
|
||||
<Path Data="M36,4C17.9,4 4,17.9 4,36C4,54.1 17.9,68 36,68C54.1,68 68,54.1 68,36C68,17.9 54.1,4 36,4Z"
|
||||
Fill="None"
|
||||
Stroke="{DynamicResource SuccessBrush}"
|
||||
StrokeThickness="2.5"
|
||||
Stretch="Uniform"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
|
||||
<!-- 勾号 -->
|
||||
<Path Data="M22,36L32,46L50,26"
|
||||
Fill="None"
|
||||
Stroke="{DynamicResource SuccessBrush}"
|
||||
StrokeThickness="3"
|
||||
StrokeLineCap="Round"
|
||||
StrokeLineJoin="Round"
|
||||
Stretch="Uniform"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Margin="2,2,2,-2" />
|
||||
</Grid>
|
||||
|
||||
<!-- ============================== -->
|
||||
<!-- ===== 标题和描述 ===== -->
|
||||
<!-- ============================== -->
|
||||
<StackPanel x:Name="TitlePanel"
|
||||
HorizontalAlignment="Center"
|
||||
Opacity="0"
|
||||
Margin="0,0,0,20">
|
||||
|
||||
<!-- 标题 -->
|
||||
<TextBlock Text="安装完成!"
|
||||
FontSize="24"
|
||||
FontWeight="Bold"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,4" />
|
||||
|
||||
<!-- 描述 -->
|
||||
<TextBlock Text="Better-Seewo 已成功安装到您的计算机"
|
||||
FontSize="13"
|
||||
Foreground="{DynamicResource TextSecondaryBrush}"
|
||||
HorizontalAlignment="Center" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- ============================== -->
|
||||
<!-- ===== 安装摘要 ===== -->
|
||||
<!-- ============================== -->
|
||||
<Border x:Name="SummaryPanel"
|
||||
Background="{DynamicResource CardBackgroundBrush}"
|
||||
BorderBrush="{DynamicResource BorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8"
|
||||
Padding="16"
|
||||
Opacity="0"
|
||||
Margin="0,0,0,24">
|
||||
|
||||
<StackPanel>
|
||||
<!-- 摘要标题 -->
|
||||
<TextBlock Text="安装摘要"
|
||||
FontSize="13"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
Margin="0,0,0,12" />
|
||||
|
||||
<!-- 版本号 -->
|
||||
<Grid Margin="0,0,0,8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="版本号"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextSecondaryBrush}"
|
||||
Margin="0,0,16,0" />
|
||||
<TextBlock x:Name="TxtVersion"
|
||||
Grid.Column="1"
|
||||
Text="v2.0.0"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}" />
|
||||
</Grid>
|
||||
|
||||
<!-- 安装路径 -->
|
||||
<Grid Margin="0,0,0,8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="安装路径"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextSecondaryBrush}"
|
||||
Margin="0,0,16,0" />
|
||||
<TextBlock x:Name="TxtInstallPath"
|
||||
Grid.Column="1"
|
||||
Text="C:\Program Files (x86)\Seewo\EasiNote5\Plugins\Better-EN5"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
</Grid>
|
||||
|
||||
<!-- 安装时间 -->
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="安装时间"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextSecondaryBrush}"
|
||||
Margin="0,0,16,0" />
|
||||
<TextBlock x:Name="TxtInstallTime"
|
||||
Grid.Column="1"
|
||||
Text="--"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- ============================== -->
|
||||
<!-- ===== 操作按钮 ===== -->
|
||||
<!-- ============================== -->
|
||||
<StackPanel x:Name="ButtonsPanel"
|
||||
Opacity="0"
|
||||
HorizontalAlignment="Center">
|
||||
|
||||
<Grid HorizontalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 启动管理器按钮 -->
|
||||
<Button Grid.Column="0"
|
||||
Content="启动管理器"
|
||||
FontSize="13"
|
||||
FontWeight="SemiBold"
|
||||
Height="36"
|
||||
Padding="24,0"
|
||||
Margin="0,0,12,0"
|
||||
Background="{DynamicResource AccentBrush}"
|
||||
Foreground="White"
|
||||
BorderThickness="0"
|
||||
Cursor="Hand"
|
||||
Click="BtnLaunchManager_Click"
|
||||
Style="{DynamicResource PrimaryButtonStyle}" />
|
||||
|
||||
<!-- 关闭安装程序按钮 -->
|
||||
<Button Grid.Column="1"
|
||||
Content="关闭"
|
||||
FontSize="13"
|
||||
Height="36"
|
||||
Padding="24,0"
|
||||
Background="Transparent"
|
||||
Foreground="{DynamicResource TextSecondaryBrush}"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource BorderBrush}"
|
||||
Cursor="Hand"
|
||||
Click="BtnClose_Click"
|
||||
Style="{DynamicResource ActionButtonStyle}" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- ===== 页面级样式资源(按钮样式引用主窗口的样式) ===== -->
|
||||
<Page.Resources>
|
||||
|
||||
<!-- 主要按钮样式(复制主窗口的样式,用于独立展示) -->
|
||||
<Style x:Key="PrimaryButtonStyle" TargetType="Button">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border x:Name="BtnBg"
|
||||
Background="{TemplateBinding Background}"
|
||||
CornerRadius="6"
|
||||
Padding="{TemplateBinding Padding}">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="BtnBg" Property="Background" Value="{DynamicResource AccentHoverBrush}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="BtnBg" Property="Background" Value="{DynamicResource AccentPressedBrush}" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<EventTrigger RoutedEvent="MouseEnter">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
|
||||
To="1.05" Duration="0:0:0.200">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
|
||||
To="1.05" Duration="0:0:0.200">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
<EventTrigger RoutedEvent="MouseLeave">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
|
||||
To="1.0" Duration="0:0:0.200">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
|
||||
To="1.0" Duration="0:0:0.200">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- 次要按钮样式 -->
|
||||
<Style x:Key="ActionButtonStyle" TargetType="Button">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border x:Name="BtnBg"
|
||||
Background="Transparent"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="6"
|
||||
Padding="{TemplateBinding Padding}">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="BtnBg" Property="Background" Value="{DynamicResource WindowButtonHoverBrush}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="BtnBg" Property="Background" Value="{DynamicResource WindowButtonPressedBrush}" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<EventTrigger RoutedEvent="MouseEnter">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
|
||||
To="1.05" Duration="0:0:0.200">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
|
||||
To="1.05" Duration="0:0:0.200">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
<EventTrigger RoutedEvent="MouseLeave">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
|
||||
To="1.0" Duration="0:0:0.200">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
|
||||
To="1.0" Duration="0:0:0.200">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Page.Resources>
|
||||
|
||||
</Page>
|
||||
109
Installer/Pages/CompletePage.xaml.cs
Normal file
109
Installer/Pages/CompletePage.xaml.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* CompletePage.xaml.cs - Better-Seewo 安装向导完成页面逻辑
|
||||
* 显示安装摘要信息,提供启动管理器和关闭安装程序的入口
|
||||
* 作者:雾启工作室
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Better_Seewo.Installer.Pages
|
||||
{
|
||||
/// <summary>
|
||||
/// CompletePage 的交互逻辑 - 安装向导完成页面
|
||||
/// </summary>
|
||||
public partial class CompletePage : Page
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数,初始化页面组件并填充安装摘要
|
||||
/// </summary>
|
||||
public CompletePage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// 填充安装摘要信息
|
||||
LoadInstallSummary();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载安装摘要信息到界面
|
||||
/// </summary>
|
||||
private void LoadInstallSummary()
|
||||
{
|
||||
// 版本号
|
||||
TxtVersion.Text = $"v{App.AppVersion}";
|
||||
|
||||
// 安装路径
|
||||
TxtInstallPath.Text = App.InstallPath;
|
||||
|
||||
// 安装时间
|
||||
if (App.InstallStartTime != DateTime.MinValue)
|
||||
{
|
||||
var duration = DateTime.Now - App.InstallStartTime;
|
||||
TxtInstallTime.Text = $"{App.InstallStartTime:yyyy-MM-dd HH:mm:ss} (耗时 {duration.TotalSeconds:F1} 秒)";
|
||||
}
|
||||
else
|
||||
{
|
||||
TxtInstallTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动管理器按钮点击 - 尝试启动 Better-Seewo Manager
|
||||
/// </summary>
|
||||
private void BtnLaunchManager_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 尝试查找并启动管理器可执行文件
|
||||
string managerPath = Path.Combine(
|
||||
Path.GetDirectoryName(App.InstallPath),
|
||||
"Better-Seewo.Manager.exe"
|
||||
);
|
||||
|
||||
if (File.Exists(managerPath))
|
||||
{
|
||||
// 启动管理器
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = managerPath,
|
||||
UseShellExecute = true
|
||||
});
|
||||
|
||||
// 关闭安装程序
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 管理器文件不存在,提示用户
|
||||
MessageBox.Show(
|
||||
"未找到管理器程序。您可以稍后手动启动 Better-Seewo 管理器。",
|
||||
"Better-Seewo 安装程序",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Information
|
||||
);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(
|
||||
$"启动管理器失败:{ex.Message}",
|
||||
"Better-Seewo 安装程序",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Warning
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭按钮点击 - 关闭安装程序
|
||||
/// </summary>
|
||||
private void BtnClose_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
305
Installer/Pages/InstallPage.xaml
Normal file
305
Installer/Pages/InstallPage.xaml
Normal file
@@ -0,0 +1,305 @@
|
||||
<!--
|
||||
InstallPage.xaml - Better-Seewo 安装向导安装页面
|
||||
显示安装路径、进度条、安装日志和安装步骤状态
|
||||
作者:雾启工作室
|
||||
-->
|
||||
|
||||
<Page x:Class="Better_Seewo.Installer.Pages.InstallPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Background="Transparent">
|
||||
|
||||
<!-- ===== 页面入场动画 ===== -->
|
||||
<Page.Triggers>
|
||||
<EventTrigger RoutedEvent="Page.Loaded">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<!-- 路径区域:淡入 -->
|
||||
<DoubleAnimation Storyboard.TargetName="PathPanel"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0" To="1"
|
||||
Duration="0:0:0.400">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
|
||||
<!-- 进度区域:淡入(延迟 100ms) -->
|
||||
<DoubleAnimation Storyboard.TargetName="ProgressPanel"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0" To="1"
|
||||
Duration="0:0:0.400"
|
||||
BeginTime="0:0:0.100">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
|
||||
<!-- 步骤区域:淡入(延迟 200ms) -->
|
||||
<DoubleAnimation Storyboard.TargetName="StepsPanel"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0" To="1"
|
||||
Duration="0:0:0.400"
|
||||
BeginTime="0:0:0.200">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
|
||||
<!-- 日志区域:淡入(延迟 300ms) -->
|
||||
<DoubleAnimation Storyboard.TargetName="LogPanel"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0" To="1"
|
||||
Duration="0:0:0.400"
|
||||
BeginTime="0:0:0.300">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
</Page.Triggers>
|
||||
|
||||
<!-- ===== 页面内容 ===== -->
|
||||
<Grid Margin="40,24,40,16">
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<!-- 标题 -->
|
||||
<RowDefinition Height="Auto" />
|
||||
<!-- 下方内容区 -->
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 标题 -->
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="正在安装..."
|
||||
FontSize="20"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
Margin="0,0,0,16" />
|
||||
|
||||
<!-- 下方内容区 -->
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.RowDefinitions>
|
||||
<!-- 安装路径 -->
|
||||
<RowDefinition Height="Auto" />
|
||||
<!-- 进度条 -->
|
||||
<RowDefinition Height="Auto" />
|
||||
<!-- 安装步骤 -->
|
||||
<RowDefinition Height="Auto" />
|
||||
<!-- 安装日志(填充剩余空间) -->
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- ============================== -->
|
||||
<!-- ===== 安装路径 ===== -->
|
||||
<!-- ============================== -->
|
||||
<StackPanel x:Name="PathPanel"
|
||||
Opacity="0"
|
||||
Margin="0,0,0,16">
|
||||
|
||||
<!-- 路径标签 -->
|
||||
<TextBlock Text="安装路径"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextSecondaryBrush}"
|
||||
Margin="0,0,0,4" />
|
||||
|
||||
<!-- 路径输入行 -->
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- 路径输入框 -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<!-- 浏览按钮 -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 路径 TextBox -->
|
||||
<TextBox x:Name="TxtInstallPath"
|
||||
Grid.Column="0"
|
||||
Text="C:\Program Files (x86)\Seewo\EasiNote5\Plugins\Better-EN5"
|
||||
FontSize="12"
|
||||
FontFamily="Microsoft YaHei UI"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
Background="{DynamicResource InputBackgroundBrush}"
|
||||
BorderBrush="{DynamicResource BorderBrush}"
|
||||
BorderThickness="1"
|
||||
Padding="8,6"
|
||||
VerticalContentAlignment="Center"
|
||||
IsReadOnly="True" />
|
||||
|
||||
<!-- 浏览按钮 -->
|
||||
<Button Grid.Column="1"
|
||||
Content="浏览..."
|
||||
FontSize="12"
|
||||
Height="32"
|
||||
Padding="12,0"
|
||||
Margin="6,0,0,0"
|
||||
Background="{DynamicResource CardBackgroundBrush}"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
BorderBrush="{DynamicResource BorderBrush}"
|
||||
BorderThickness="1"
|
||||
Cursor="Hand"
|
||||
Click="BtnBrowse_Click" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ============================== -->
|
||||
<!-- ===== 进度条 ===== -->
|
||||
<!-- ============================== -->
|
||||
<StackPanel x:Name="ProgressPanel"
|
||||
Opacity="0"
|
||||
Margin="0,0,0,16">
|
||||
|
||||
<!-- 进度条轨道背景 -->
|
||||
<Border Background="{DynamicResource ProgressTrackBrush}"
|
||||
CornerRadius="4"
|
||||
Height="6"
|
||||
Margin="0,0,0,4"
|
||||
ClipToBounds="True">
|
||||
|
||||
<!-- 进度条前景(实际进度) -->
|
||||
<Grid>
|
||||
<!-- 百分比文字背景(覆盖在进度条上) -->
|
||||
<Rectangle x:Name="ProgressFill"
|
||||
Fill="{DynamicResource AccentBrush}"
|
||||
Width="0"
|
||||
HorizontalAlignment="Left" />
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 百分比文字 -->
|
||||
<TextBlock x:Name="TxtProgress"
|
||||
Text="0%"
|
||||
FontSize="11"
|
||||
Foreground="{DynamicResource TextSecondaryBrush}"
|
||||
HorizontalAlignment="Right" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- ============================== -->
|
||||
<!-- ===== 安装步骤状态 ===== -->
|
||||
<!-- ============================== -->
|
||||
<StackPanel x:Name="StepsPanel"
|
||||
Opacity="0"
|
||||
Margin="0,0,0,16">
|
||||
|
||||
<!-- 步骤标签 -->
|
||||
<TextBlock Text="安装步骤"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextSecondaryBrush}"
|
||||
Margin="0,0,0,8" />
|
||||
|
||||
<!-- 步骤 1:检测 EN5 安装状态 -->
|
||||
<Grid Margin="0,0,0,6">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 状态图标 -->
|
||||
<TextBlock x:Name="Step1Icon"
|
||||
Grid.Column="0"
|
||||
Text="⏳"
|
||||
FontSize="14"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,10,0" />
|
||||
|
||||
<!-- 步骤描述 -->
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="检测 EN5 安装状态"
|
||||
FontSize="13"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
|
||||
<!-- 步骤 2:复制插件文件 -->
|
||||
<Grid Margin="0,0,0,6">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 状态图标 -->
|
||||
<TextBlock x:Name="Step2Icon"
|
||||
Grid.Column="0"
|
||||
Text="⏳"
|
||||
FontSize="14"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,10,0" />
|
||||
|
||||
<!-- 步骤描述 -->
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="复制插件文件"
|
||||
FontSize="13"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
|
||||
<!-- 步骤 3:注册插件 -->
|
||||
<Grid Margin="0,0,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 状态图标 -->
|
||||
<TextBlock x:Name="Step3Icon"
|
||||
Grid.Column="0"
|
||||
Text="⏳"
|
||||
FontSize="14"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,10,0" />
|
||||
|
||||
<!-- 步骤描述 -->
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="注册插件"
|
||||
FontSize="13"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ============================== -->
|
||||
<!-- ===== 安装日志 ===== -->
|
||||
<!-- ============================== -->
|
||||
<Grid x:Name="LogPanel"
|
||||
Opacity="0">
|
||||
|
||||
<!-- 日志标签 -->
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="安装日志"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextSecondaryBrush}"
|
||||
Margin="0,0,0,4" />
|
||||
|
||||
<!-- 日志输出区域 -->
|
||||
<Border Grid.Row="1"
|
||||
Background="{DynamicResource InputBackgroundBrush}"
|
||||
BorderBrush="{DynamicResource BorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="4"
|
||||
Padding="4">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto"
|
||||
x:Name="LogScrollViewer">
|
||||
<TextBox x:Name="TxtLog"
|
||||
IsReadOnly="True"
|
||||
TextWrapping="Wrap"
|
||||
FontFamily="Cascadia Code, Microsoft YaHei UI"
|
||||
FontSize="11"
|
||||
Foreground="{DynamicResource TextSecondaryBrush}"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
Text="" />
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
</Page>
|
||||
345
Installer/Pages/InstallPage.xaml.cs
Normal file
345
Installer/Pages/InstallPage.xaml.cs
Normal file
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* InstallPage.xaml.cs - Better-Seewo 安装向导安装页面逻辑
|
||||
* 负责模拟安装过程、更新进度条和日志、管理安装步骤状态
|
||||
* 作者:雾启工作室
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media.Animation;
|
||||
|
||||
namespace Better_Seewo.Installer.Pages
|
||||
{
|
||||
/// <summary>
|
||||
/// InstallPage 的交互逻辑 - 安装向导安装页面
|
||||
/// </summary>
|
||||
public partial class InstallPage : Page
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前安装进度(0-100)
|
||||
/// </summary>
|
||||
private int _currentProgress;
|
||||
|
||||
/// <summary>
|
||||
/// 标记安装是否已启动
|
||||
/// </summary>
|
||||
private bool _isStarted;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,初始化页面组件
|
||||
/// </summary>
|
||||
public InstallPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// 设置默认安装路径
|
||||
TxtInstallPath.Text = App.InstallPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 浏览按钮点击 - 选择安装路径
|
||||
/// </summary>
|
||||
private void BtnBrowse_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// 如果安装已开始则不允许更改路径
|
||||
if (_isStarted) return;
|
||||
|
||||
// 使用文件夹浏览对话框选择安装路径
|
||||
var dialog = new System.Windows.Forms.FolderBrowserDialog
|
||||
{
|
||||
Description = "选择 Better-Seewo 安装路径",
|
||||
ShowNewFolderButton = true,
|
||||
SelectedPath = TxtInstallPath.Text
|
||||
};
|
||||
|
||||
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||
{
|
||||
TxtInstallPath.Text = dialog.SelectedPath;
|
||||
App.InstallPath = dialog.SelectedPath;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始安装过程(由主窗口调用)
|
||||
/// 模拟三个安装步骤:检测EN5 -> 复制文件 -> 注册插件
|
||||
/// </summary>
|
||||
public async void StartInstallation()
|
||||
{
|
||||
if (_isStarted) return;
|
||||
_isStarted = true;
|
||||
|
||||
try
|
||||
{
|
||||
// 禁用路径输入和浏览按钮
|
||||
TxtInstallPath.IsReadOnly = true;
|
||||
|
||||
// 更新安装路径
|
||||
App.InstallPath = TxtInstallPath.Text;
|
||||
|
||||
// ===== 步骤 1:检测 EN5 安装状态 =====
|
||||
SetStepStatus(1, "running");
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 正在检测 EasiNote5 安装状态...");
|
||||
await Task.Delay(800);
|
||||
|
||||
// 检查 EN5 安装目录是否存在
|
||||
string en5Path = GetEn5InstallPath();
|
||||
bool en5Exists = !string.IsNullOrEmpty(en5Path) && Directory.Exists(en5Path);
|
||||
|
||||
if (en5Exists)
|
||||
{
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 已检测到 EasiNote5 安装路径: {en5Path}");
|
||||
SetStepStatus(1, "success");
|
||||
}
|
||||
else
|
||||
{
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 未检测到 EasiNote5 安装,将继续安装到指定路径");
|
||||
SetStepStatus(1, "warning");
|
||||
}
|
||||
|
||||
UpdateProgress(25);
|
||||
await Task.Delay(300);
|
||||
|
||||
// ===== 步骤 2:复制插件文件 =====
|
||||
SetStepStatus(2, "running");
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 正在复制插件文件...");
|
||||
await Task.Delay(600);
|
||||
|
||||
// 创建目标目录
|
||||
string installDir = App.InstallPath;
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(installDir))
|
||||
{
|
||||
Directory.CreateDirectory(installDir);
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 已创建安装目录: {installDir}");
|
||||
}
|
||||
|
||||
// TODO: 实际安装时,将插件文件从安装包复制到目标目录
|
||||
// 以下为模拟文件复制过程
|
||||
string[] mockFiles = {
|
||||
"Better-EN5.dll",
|
||||
"Better-EN5.pdb",
|
||||
"Newtonsoft.Json.dll",
|
||||
"config.json"
|
||||
};
|
||||
|
||||
foreach (var file in mockFiles)
|
||||
{
|
||||
await Task.Delay(200);
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 正在复制: {file}");
|
||||
UpdateProgress(25 + (Array.IndexOf(mockFiles, file) + 1) * 10);
|
||||
}
|
||||
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 插件文件复制完成");
|
||||
SetStepStatus(2, "success");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 复制文件失败: {ex.Message}");
|
||||
SetStepStatus(2, "error");
|
||||
throw;
|
||||
}
|
||||
|
||||
await Task.Delay(300);
|
||||
|
||||
// ===== 步骤 3:注册插件 =====
|
||||
SetStepStatus(3, "running");
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 正在注册插件...");
|
||||
await Task.Delay(500);
|
||||
|
||||
try
|
||||
{
|
||||
// TODO: 实际安装时,写入注册表或配置文件完成插件注册
|
||||
await Task.Delay(400);
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 正在写入插件配置...");
|
||||
UpdateProgress(80);
|
||||
|
||||
await Task.Delay(300);
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 正在注册 EasiNote5 插件组件...");
|
||||
UpdateProgress(90);
|
||||
|
||||
await Task.Delay(300);
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 插件注册完成");
|
||||
SetStepStatus(3, "success");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 注册插件失败: {ex.Message}");
|
||||
SetStepStatus(3, "error");
|
||||
throw;
|
||||
}
|
||||
|
||||
// ===== 安装完成 =====
|
||||
UpdateProgress(100);
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] ========================================");
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 安装完成!Better-Seewo v{App.AppVersion} 已成功安装");
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 安装路径: {App.InstallPath}");
|
||||
|
||||
// 延迟后自动切换到完成页
|
||||
await Task.Delay(1000);
|
||||
|
||||
// 通知主窗口安装完成
|
||||
if (Window.GetWindow(this) is MainWindow mainWindow)
|
||||
{
|
||||
mainWindow.OnInstallCompleted();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppendLog($"[{DateTime.Now:HH:mm:ss}] 安装过程中发生错误: {ex.Message}");
|
||||
MessageBox.Show(
|
||||
$"安装失败:{ex.Message}",
|
||||
"Better-Seewo 安装程序",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Error
|
||||
);
|
||||
|
||||
// 恢复按钮状态,允许重试
|
||||
if (Window.GetWindow(this) is MainWindow mainWindow)
|
||||
{
|
||||
mainWindow.BtnInstall.IsEnabled = true;
|
||||
mainWindow.BtnInstall.Content = "重试安装 \uE74E;";
|
||||
mainWindow.BtnBack.IsEnabled = true;
|
||||
}
|
||||
|
||||
App.IsInstalling = false;
|
||||
_isStarted = false;
|
||||
}
|
||||
}
|
||||
|
||||
#region ===== 辅助方法 =====
|
||||
|
||||
/// <summary>
|
||||
/// 获取 EasiNote5 的安装路径
|
||||
/// 检查常见的 EN5 安装目录
|
||||
/// </summary>
|
||||
private static string GetEn5InstallPath()
|
||||
{
|
||||
// 常见的 EasiNote5 安装路径
|
||||
string[] possiblePaths = {
|
||||
@"C:\Program Files (x86)\Seewo\EasiNote5",
|
||||
@"C:\Program Files\Seewo\EasiNote5",
|
||||
@"D:\Program Files (x86)\Seewo\EasiNote5",
|
||||
@"D:\Program Files\Seewo\EasiNote5"
|
||||
};
|
||||
|
||||
foreach (var path in possiblePaths)
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置安装步骤的状态图标
|
||||
/// </summary>
|
||||
/// <param name="step">步骤编号(1-3)</param>
|
||||
/// <param name="status">状态:running/success/warning/error</param>
|
||||
private void SetStepStatus(int step, string status)
|
||||
{
|
||||
// 确保在 UI 线程执行
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
var icon = step switch
|
||||
{
|
||||
1 => Step1Icon,
|
||||
2 => Step2Icon,
|
||||
3 => Step3Icon,
|
||||
_ => Step1Icon
|
||||
};
|
||||
|
||||
if (icon == null) return;
|
||||
|
||||
// 根据状态设置图标和颜色
|
||||
icon.Text = status switch
|
||||
{
|
||||
"running" => "⏳",
|
||||
"success" => "✓",
|
||||
"warning" => "⚠",
|
||||
"error" => "✗",
|
||||
_ => "⏳"
|
||||
};
|
||||
|
||||
icon.Foreground = status switch
|
||||
{
|
||||
"running" => (System.Windows.Media.Brush)FindResource("WarningBrush"),
|
||||
"success" => (System.Windows.Media.Brush)FindResource("SuccessBrush"),
|
||||
"warning" => (System.Windows.Media.Brush)FindResource("WarningBrush"),
|
||||
"error" => (System.Windows.Media.Brush)FindResource("ErrorBrush"),
|
||||
_ => (System.Windows.Media.Brush)FindResource("TextSecondaryBrush")
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新进度条和百分比文字
|
||||
/// </summary>
|
||||
/// <param name="progress">进度值(0-100)</param>
|
||||
private void UpdateProgress(int progress)
|
||||
{
|
||||
_currentProgress = Math.Clamp(progress, 0, 100);
|
||||
|
||||
// 确保在 UI 线程执行
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
// 更新百分比文字
|
||||
TxtProgress.Text = $"{_currentProgress}%";
|
||||
|
||||
// 更新进度条宽度(使用动画)
|
||||
var widthAnimation = new DoubleAnimation
|
||||
{
|
||||
From = (ProgressFill.ActualWidth > 0 ? ProgressFill.ActualWidth : 0),
|
||||
To = (_currentProgress / 100.0) * ProgressFill.Parent.ActualWidth,
|
||||
Duration = TimeSpan.FromMilliseconds(300),
|
||||
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
|
||||
};
|
||||
|
||||
// 如果父容器尚未布局完成,直接设置宽度
|
||||
if (ProgressFill.Parent.ActualWidth == 0)
|
||||
{
|
||||
// 等待布局完成后设置
|
||||
ProgressFill.Loaded += (s, e) =>
|
||||
{
|
||||
var loadedAnimation = new DoubleAnimation
|
||||
{
|
||||
From = 0,
|
||||
To = (_currentProgress / 100.0) * ProgressFill.Parent.ActualWidth,
|
||||
Duration = TimeSpan.FromMilliseconds(300),
|
||||
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
|
||||
};
|
||||
ProgressFill.BeginAnimation(WidthProperty, loadedAnimation);
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
ProgressFill.BeginAnimation(WidthProperty, widthAnimation);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向日志文本框追加一行日志
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息</param>
|
||||
private void AppendLog(string message)
|
||||
{
|
||||
// 确保在 UI 线程执行
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
TxtLog.Text += message + Environment.NewLine;
|
||||
|
||||
// 自动滚动到底部
|
||||
LogScrollViewer.ScrollToEnd();
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
278
Installer/Pages/WelcomePage.xaml
Normal file
278
Installer/Pages/WelcomePage.xaml
Normal file
@@ -0,0 +1,278 @@
|
||||
<!--
|
||||
WelcomePage.xaml - Better-Seewo 安装向导欢迎页面
|
||||
居中布局,显示 Logo、标题、副标题、功能列表和许可协议
|
||||
带入场交错动画效果
|
||||
作者:雾启工作室
|
||||
-->
|
||||
|
||||
<Page x:Class="Better_Seewo.Installer.Pages.WelcomePage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Background="Transparent">
|
||||
|
||||
<!-- ===== 页面入场动画 ===== -->
|
||||
<Page.Triggers>
|
||||
<EventTrigger RoutedEvent="Page.Loaded">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<!-- 标题区域:从上方滑入(延迟 0ms) -->
|
||||
<DoubleAnimation Storyboard.TargetName="TitlePanel"
|
||||
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)"
|
||||
From="-30" To="0"
|
||||
Duration="0:0:0.500">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
<DoubleAnimation Storyboard.TargetName="TitlePanel"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0" To="1"
|
||||
Duration="0:0:0.500">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
|
||||
<!-- 副标题区域:淡入(延迟 100ms) -->
|
||||
<DoubleAnimation Storyboard.TargetName="SubtitlePanel"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0" To="1"
|
||||
Duration="0:0:0.400"
|
||||
BeginTime="0:0:0.100">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
|
||||
<!-- 功能列表:淡入(延迟 200ms) -->
|
||||
<DoubleAnimation Storyboard.TargetName="FeaturesPanel"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0" To="1"
|
||||
Duration="0:0:0.400"
|
||||
BeginTime="0:0:0.200">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
|
||||
<!-- 许可协议区域:淡入(延迟 350ms) -->
|
||||
<DoubleAnimation Storyboard.TargetName="LicensePanel"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0" To="1"
|
||||
Duration="0:0:0.400"
|
||||
BeginTime="0:0:0.350">
|
||||
<DoubleAnimation.EasingFunction>
|
||||
<CubicEase EasingMode="EaseOut" />
|
||||
</DoubleAnimation.EasingFunction>
|
||||
</DoubleAnimation>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
</Page.Triggers>
|
||||
|
||||
<!-- ===== 页面内容 ===== -->
|
||||
<Grid Margin="40,24,40,16">
|
||||
<!-- 滚动支持 -->
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
|
||||
<StackPanel HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
MaxWidth="480">
|
||||
|
||||
<!-- ============================== -->
|
||||
<!-- ===== 标题区域(Logo + 标题) ===== -->
|
||||
<!-- ============================== -->
|
||||
<!-- Logo + 标题(从上方滑入) -->
|
||||
<StackPanel x:Name="TitlePanel"
|
||||
HorizontalAlignment="Center"
|
||||
Opacity="0"
|
||||
Margin="0,0,0,20">
|
||||
<StackPanel.RenderTransform>
|
||||
<TranslateTransform Y="-30" />
|
||||
</StackPanel.RenderTransform>
|
||||
|
||||
<!-- 六边形 Logo 图标 -->
|
||||
<Grid Width="64" Height="64"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,12">
|
||||
<!-- 外层发光效果 -->
|
||||
<Ellipse Fill="{DynamicResource AccentBrush}"
|
||||
Opacity="0.15"
|
||||
Width="72" Height="72" />
|
||||
<!-- 六边形主体 -->
|
||||
<Path Data="M32 4L56 18V46L32 60L8 46V18L32 4Z"
|
||||
Fill="{DynamicResource AccentBrush}"
|
||||
Stretch="Uniform"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleX="0.9" ScaleY="0.9" />
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
<!-- 内部钻石图形 -->
|
||||
<Path Data="M32 16L44 28V40L32 48L20 40V28L32 16Z"
|
||||
Fill="{DynamicResource BackgroundBrush}"
|
||||
Stretch="Uniform"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center">
|
||||
<Path.RenderTransform>
|
||||
<ScaleTransform ScaleX="0.5" ScaleY="0.5" />
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Grid>
|
||||
|
||||
<!-- 标题文字 -->
|
||||
<TextBlock Text="Better-Seewo"
|
||||
FontSize="28"
|
||||
FontWeight="Bold"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
HorizontalAlignment="Center" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- 副标题 + 版本描述(淡入,延迟 100ms) -->
|
||||
<StackPanel x:Name="SubtitlePanel"
|
||||
HorizontalAlignment="Center"
|
||||
Opacity="0"
|
||||
Margin="0,0,0,20">
|
||||
|
||||
<!-- 副标题 -->
|
||||
<TextBlock Text="雾生万象,启以为光"
|
||||
FontSize="14"
|
||||
Foreground="{DynamicResource AccentBrush}"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,4" />
|
||||
|
||||
<!-- 版本描述 -->
|
||||
<TextBlock Text="希沃白板功能增强插件 v2.0.0"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextSecondaryBrush}"
|
||||
HorizontalAlignment="Center" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- ============================== -->
|
||||
<!-- ===== 功能列表 ===== -->
|
||||
<!-- ============================== -->
|
||||
<StackPanel x:Name="FeaturesPanel"
|
||||
Opacity="0"
|
||||
Margin="0,0,0,16">
|
||||
|
||||
<!-- 功能列表标题 -->
|
||||
<TextBlock Text="核心功能"
|
||||
FontSize="13"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource TextSecondaryBrush}"
|
||||
Margin="0,0,0,8" />
|
||||
|
||||
<!-- 功能 1:增强白板功能 -->
|
||||
<Border Background="{DynamicResource CardBackgroundBrush}"
|
||||
BorderBrush="{DynamicResource BorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="6"
|
||||
Padding="12,10"
|
||||
Margin="0,0,0,6">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<!-- 图标:画笔 -->
|
||||
<Path Data="M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.28,5.05L19.03,8.79L20.71,7.04Z"
|
||||
Fill="{DynamicResource AccentBrush}"
|
||||
Stretch="Uniform"
|
||||
Width="16" Height="16"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,12,0" />
|
||||
<TextBlock Text="增强白板功能"
|
||||
FontSize="13"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 功能 2:墨迹导入导出 -->
|
||||
<Border Background="{DynamicResource CardBackgroundBrush}"
|
||||
BorderBrush="{DynamicResource BorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="6"
|
||||
Padding="12,10"
|
||||
Margin="0,0,0,6">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<!-- 图标:文件导入导出 -->
|
||||
<Path Data="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"
|
||||
Fill="{DynamicResource AccentBrush}"
|
||||
Stretch="Uniform"
|
||||
Width="16" Height="16"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,12,0" />
|
||||
<TextBlock Text="墨迹导入导出"
|
||||
FontSize="13"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 功能 3:格式转换工具 -->
|
||||
<Border Background="{DynamicResource CardBackgroundBrush}"
|
||||
BorderBrush="{DynamicResource BorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="6"
|
||||
Padding="12,10"
|
||||
Margin="0,0,0,0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<!-- 图标:格式转换箭头 -->
|
||||
<Path Data="M16,6L18.29,8.29L13.41,13.17L14.83,14.59L19.71,9.71L22,12V6M16,18H8V6H10V4H8A2,2 0 0,0 6,6V18A2,2 0 0,0 8,20H16A2,2 0 0,0 18,18V16H16V18Z"
|
||||
Fill="{DynamicResource AccentBrush}"
|
||||
Stretch="Uniform"
|
||||
Width="16" Height="16"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,12,0" />
|
||||
<TextBlock Text="格式转换工具"
|
||||
FontSize="13"
|
||||
Foreground="{DynamicResource TextPrimaryBrush}"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ============================== -->
|
||||
<!-- ===== 许可协议区域 ===== -->
|
||||
<!-- ============================== -->
|
||||
<StackPanel x:Name="LicensePanel"
|
||||
Opacity="0">
|
||||
|
||||
<!-- 分隔线 -->
|
||||
<Border Height="1"
|
||||
Background="{DynamicResource BorderBrush}"
|
||||
Margin="0,0,0,12" />
|
||||
|
||||
<!-- 协议文本框(ScrollViewer 包裹) -->
|
||||
<Border Background="{DynamicResource InputBackgroundBrush}"
|
||||
BorderBrush="{DynamicResource BorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="4"
|
||||
MaxHeight="80"
|
||||
Margin="0,0,0,8">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto"
|
||||
Padding="8">
|
||||
<TextBlock TextWrapping="Wrap"
|
||||
FontSize="11"
|
||||
Foreground="{DynamicResource TextTertiaryBrush}"
|
||||
LineHeight="16">
|
||||
<Run Text="MIT License" FontWeight="SemiBold" />
|
||||
<Run Text="

Copyright (c) 2024 雾启工作室

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software." />
|
||||
</TextBlock>
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
|
||||
<!-- 接受协议 CheckBox -->
|
||||
<CheckBox x:Name="ChkAcceptLicense"
|
||||
Content="我已阅读并同意上述许可协议"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource TextSecondaryBrush}"
|
||||
Margin="0,0,0,4"
|
||||
Checked="ChkAcceptLicense_CheckedChanged"
|
||||
Unchecked="ChkAcceptLicense_CheckedChanged" />
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
|
||||
</Page>
|
||||
51
Installer/Pages/WelcomePage.xaml.cs
Normal file
51
Installer/Pages/WelcomePage.xaml.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* WelcomePage.xaml.cs - Better-Seewo 安装向导欢迎页面逻辑
|
||||
* 负责许可协议复选框状态管理,控制下一步按钮的启用/禁用
|
||||
* 作者:雾启工作室
|
||||
*/
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Better_Seewo.Installer.Pages
|
||||
{
|
||||
/// <summary>
|
||||
/// WelcomePage 的交互逻辑 - 安装向导欢迎页面
|
||||
/// </summary>
|
||||
public partial class WelcomePage : Page
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数,初始化页面组件
|
||||
/// </summary>
|
||||
public WelcomePage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户是否已接受许可协议
|
||||
/// </summary>
|
||||
public bool IsLicenseAccepted => ChkAcceptLicense.IsChecked == true;
|
||||
|
||||
/// <summary>
|
||||
/// 许可协议复选框状态变更事件处理
|
||||
/// 更新主窗口中下一步按钮的启用状态
|
||||
/// </summary>
|
||||
private void ChkAcceptLicense_CheckedChanged(object sender, RoutedEventArgs e)
|
||||
{
|
||||
UpdateNextButtonState();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据协议接受状态更新主窗口下一步按钮的可用性
|
||||
/// </summary>
|
||||
private void UpdateNextButtonState()
|
||||
{
|
||||
// 获取主窗口实例并更新按钮状态
|
||||
if (Window.GetWindow(this) is MainWindow mainWindow)
|
||||
{
|
||||
mainWindow.BtnNext.IsEnabled = IsLicenseAccepted;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user