Files
Better-Seewo/Installer/MainWindow.xaml.cs

355 lines
12 KiB
C#
Raw Permalink Normal View History

/*
* MainWindow.xaml.cs - Better-Seewo
* Welcome -> Install -> Complete
*
*/
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace Better_Seewo.Installer
{
/// <summary>
/// MainWindow 的交互逻辑 - Fluent Design 风格安装向导主窗口
/// </summary>
public partial class MainWindow : Window
{
/// <summary>
/// 页面切换动画时长(毫秒)
/// </summary>
private const int PageTransitionDuration = 300;
/// <summary>
/// 进度指示器动画时长(毫秒)
/// </summary>
private const int DotAnimationDuration = 300;
/// <summary>
/// 当前安装步骤索引0=欢迎页, 1=安装页, 2=完成页)
/// </summary>
private int _currentStep = 0;
/// <summary>
/// 构造函数,初始化窗口组件
/// </summary>
public MainWindow()
{
InitializeComponent();
// 为所有按钮初始化 RenderTransform用于悬停缩放动画
BtnNext.RenderTransform = new ScaleTransform(1.0, 1.0);
BtnInstall.RenderTransform = new ScaleTransform(1.0, 1.0);
BtnFinish.RenderTransform = new ScaleTransform(1.0, 1.0);
BtnBack.RenderTransform = new ScaleTransform(1.0, 1.0);
}
/// <summary>
/// 窗口加载完成事件处理 - 导航到默认欢迎页
/// </summary>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// 导航到欢迎页
NavigateToPage(new Pages.WelcomePage());
// 设置按钮状态
UpdateButtonStates();
}
#region ===== =====
/// <summary>
/// 标题栏鼠标左键按下 - 实现窗口拖动
/// </summary>
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// 如果点击的是按钮区域则不触发拖动
if (e.Source is Button) return;
// 调用 DragMove 实现窗口拖动
if (e.LeftButton == MouseButtonState.Pressed)
{
DragMove();
}
}
#endregion
#region ===== =====
/// <summary>
/// 关闭按钮点击 - 安装进行中不允许关闭
/// </summary>
private void BtnClose_Click(object sender, RoutedEventArgs e)
{
// 安装进行中时禁止关闭
if (App.IsInstalling)
{
MessageBox.Show(
"安装正在进行中,请等待安装完成后再关闭。",
"Better-Seewo 安装程序",
MessageBoxButton.OK,
MessageBoxImage.Information
);
return;
}
// 安装已完成或未开始时,确认关闭
if (App.IsInstallCompleted)
{
Application.Current.Shutdown();
return;
}
// 未完成安装时二次确认
var result = MessageBox.Show(
"安装尚未完成,确定要退出安装程序吗?",
"Better-Seewo 安装程序",
MessageBoxButton.YesNo,
MessageBoxImage.Question
);
if (result == MessageBoxResult.Yes)
{
Application.Current.Shutdown();
}
}
#endregion
#region ===== =====
/// <summary>
/// 下一步按钮点击 - 从欢迎页跳转到安装页
/// </summary>
private void BtnNext_Click(object sender, RoutedEventArgs e)
{
if (_currentStep == 0)
{
// 从欢迎页进入安装页
_currentStep = 1;
NavigateToPage(new Pages.InstallPage());
UpdateButtonStates();
UpdateProgressDots();
}
}
/// <summary>
/// 安装按钮点击 - 开始执行安装
/// </summary>
private void BtnInstall_Click(object sender, RoutedEventArgs e)
{
if (ContentFrame.Content is Pages.InstallPage installPage)
{
// 标记安装开始
App.IsInstalling = true;
App.InstallStartTime = DateTime.Now;
// 禁用安装按钮,显示返回按钮不可用
BtnInstall.IsEnabled = false;
BtnInstall.Content = "正在安装...";
BtnBack.IsEnabled = false;
// 启动安装过程
installPage.StartInstallation();
}
}
/// <summary>
/// 返回按钮点击 - 返回上一步
/// </summary>
private void BtnBack_Click(object sender, RoutedEventArgs e)
{
if (_currentStep == 1)
{
// 从安装页返回欢迎页
_currentStep = 0;
NavigateToPage(new Pages.WelcomePage());
UpdateButtonStates();
UpdateProgressDots();
}
}
/// <summary>
/// 完成按钮点击 - 关闭安装程序
/// </summary>
private void BtnFinish_Click(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
#endregion
#region ===== =====
/// <summary>
/// 导航到指定页面,带淡出旧页面 -> 新页面从右侧滑入的动画效果
/// </summary>
/// <param name="page">要导航到的 Page 实例</param>
private void NavigateToPage(Page page)
{
// 步骤1淡出当前页面
var fadeOutAnimation = new DoubleAnimation
{
From = 1.0,
To = 0.0,
Duration = TimeSpan.FromMilliseconds(PageTransitionDuration / 2),
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
};
fadeOutAnimation.Completed += (s, e) =>
{
// 步骤2切换到新页面
ContentFrame.Navigate(page);
// 步骤3新页面从右侧滑入 + 淡入
var translateAnimation = new DoubleAnimation
{
From = 30.0,
To = 0.0,
Duration = TimeSpan.FromMilliseconds(PageTransitionDuration / 2),
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
};
var fadeInAnimation = new DoubleAnimation
{
From = 0.0,
To = 1.0,
Duration = TimeSpan.FromMilliseconds(PageTransitionDuration / 2),
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
};
// 应用水平偏移动画
ContentFrame.BeginAnimation(
FrameworkElement.RenderTransformOriginProperty, null);
var translateTransform = new TranslateTransform(30, 0);
ContentFrame.RenderTransform = translateTransform;
translateTransform.BeginAnimation(TranslateTransform.XProperty, translateAnimation);
// 应用淡入动画
ContentFrame.BeginAnimation(OpacityProperty, fadeInAnimation);
};
// 应用淡出动画到 Frame
ContentFrame.BeginAnimation(OpacityProperty, fadeOutAnimation);
}
/// <summary>
/// 根据当前步骤更新按钮的可见性和状态
/// </summary>
private void UpdateButtonStates()
{
switch (_currentStep)
{
case 0: // 欢迎页
BtnBack.Visibility = Visibility.Collapsed;
BtnNext.Visibility = Visibility.Visible;
BtnInstall.Visibility = Visibility.Collapsed;
BtnFinish.Visibility = Visibility.Collapsed;
BtnNext.IsEnabled = true;
BtnNext.Content = "下一步 \uE74E;";
break;
case 1: // 安装页
BtnBack.Visibility = Visibility.Visible;
BtnBack.IsEnabled = true;
BtnNext.Visibility = Visibility.Collapsed;
BtnInstall.Visibility = Visibility.Visible;
BtnInstall.IsEnabled = true;
BtnInstall.Content = "开始安装 \uE74E;";
BtnFinish.Visibility = Visibility.Collapsed;
break;
case 2: // 完成页
BtnBack.Visibility = Visibility.Collapsed;
BtnNext.Visibility = Visibility.Collapsed;
BtnInstall.Visibility = Visibility.Collapsed;
BtnFinish.Visibility = Visibility.Visible;
break;
}
}
/// <summary>
/// 更新底部进度指示器圆点的颜色,高亮当前步骤
/// </summary>
private void UpdateProgressDots()
{
// 获取主题中的画刷资源
var accentBrush = (Brush)FindResource("AccentBrush");
var borderBrush = (Brush)FindResource("BorderBrush");
// 更新三个圆点的颜色
Dot1.Fill = _currentStep >= 0 ? accentBrush : borderBrush;
Dot2.Fill = _currentStep >= 1 ? accentBrush : borderBrush;
Dot3.Fill = _currentStep >= 2 ? accentBrush : borderBrush;
// 为当前圆点播放缩放动画(突出当前步骤)
var currentDot = _currentStep switch
{
0 => Dot1,
1 => Dot2,
2 => Dot3,
_ => Dot1
};
AnimateDotScale(currentDot);
}
/// <summary>
/// 为进度指示器圆点播放缩放脉冲动画
/// </summary>
private void AnimateDotScale(FrameworkElement dot)
{
// 放大到 1.5 倍再缩回 1.0 倍
var scaleUpAnimation = new DoubleAnimation
{
From = 1.0,
To = 1.5,
Duration = TimeSpan.FromMilliseconds(DotAnimationDuration),
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
};
var scaleDownAnimation = new DoubleAnimation
{
From = 1.5,
To = 1.0,
Duration = TimeSpan.FromMilliseconds(DotAnimationDuration),
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn },
BeginTime = TimeSpan.FromMilliseconds(DotAnimationDuration)
};
// 设置缩放变换中心点
dot.RenderTransform = new ScaleTransform(1.0, 1.0, 4, 4);
// 应用缩放动画
dot.RenderTransform.BeginAnimation(ScaleTransform.ScaleXProperty, scaleUpAnimation);
dot.RenderTransform.BeginAnimation(ScaleTransform.ScaleXProperty, scaleDownAnimation);
dot.RenderTransform.BeginAnimation(ScaleTransform.ScaleYProperty, scaleUpAnimation);
dot.RenderTransform.BeginAnimation(ScaleTransform.ScaleYProperty, scaleDownAnimation);
}
/// <summary>
/// 安装完成后由 InstallPage 调用,切换到完成页
/// </summary>
public void OnInstallCompleted()
{
// 标记安装完成
App.IsInstalling = false;
App.IsInstallCompleted = true;
// 切换到完成页
Dispatcher.Invoke(() =>
{
_currentStep = 2;
NavigateToPage(new Pages.CompletePage());
UpdateButtonStates();
UpdateProgressDots();
});
}
#endregion
}
}