/* * MainWindow.xaml.cs - Better-Seewo 管理器主窗口逻辑 * 负责自定义标题栏拖动、窗口控制、页面导航、主题切换和动画效果 * 作者:雾启工作室 */ 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.Manager { /// /// MainWindow 的交互逻辑 - Fluent Design 风格主窗口 /// public partial class MainWindow : Window { /// /// 导航指示条动画时长(毫秒) /// private const int IndicatorAnimationDuration = 200; /// /// 页面淡入淡出动画时长(毫秒) /// private const int PageTransitionDuration = 300; /// /// 指示条目标宽度 /// private const double IndicatorTargetWidth = 3; /// /// 当前选中的导航按钮名称 /// private string _currentNavTag = "Install"; /// /// 构造函数,初始化窗口组件 /// public MainWindow() { InitializeComponent(); // 默认选中安装页面 SetActiveNavigation("BtnInstall", "IndicatorInstall"); } /// /// 窗口加载完成事件处理 - 触发入场动画和初始页面加载 /// private void Window_Loaded(object sender, RoutedEventArgs e) { // 入场动画已通过 XAML Trigger 触发 // 导航到默认页面 NavigateToPage("Install"); } #region ===== 自定义标题栏拖动 ===== /// /// 标题栏鼠标左键按下 - 实现窗口拖动 /// private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // 如果点击的是按钮区域则不触发拖动 if (e.Source is Button) return; // 调用 DragMove 实现窗口拖动 if (e.LeftButton == MouseButtonState.Pressed) { DragMove(); } } /// /// 标题栏鼠标双击 - 切换最大化/还原 /// protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); // 双击标题栏区域切换窗口状态 if (e.ClickCount == 2) { ToggleMaximize(); } } #endregion #region ===== 窗口控制按钮 ===== /// /// 最小化按钮点击 /// private void BtnMinimize_Click(object sender, RoutedEventArgs e) { // 将窗口最小化到任务栏 WindowState = WindowState.Minimized; } /// /// 最大化/还原按钮点击 /// private void BtnMaximize_Click(object sender, RoutedEventArgs e) { ToggleMaximize(); } /// /// 关闭按钮点击 - 关闭应用程序 /// private void BtnClose_Click(object sender, RoutedEventArgs e) { Application.Current.Shutdown(); } /// /// 切换窗口最大化/还原状态 /// private void ToggleMaximize() { if (WindowState == WindowState.Maximized) { WindowState = WindowState.Normal; // 更新按钮图标为最大化图标 BtnMaximize.Content = "\uE922"; } else { WindowState = WindowState.Maximized; // 更新按钮图标为还原图标 BtnMaximize.Content = "\uE923"; } } #endregion #region ===== 导航按钮切换 ===== /// /// 导航按钮点击事件 - 切换Frame页面内容 /// private void NavButton_Click(object sender, RoutedEventArgs e) { if (sender is Button btn && btn.Tag is string tag) { // 如果点击的是当前已选中项,则忽略 if (tag == _currentNavTag) return; // 更新当前选中项 _currentNavTag = tag; // 根据按钮名称设置选中状态和指示条动画 SetActiveNavigation(btn.Name, GetIndicatorName(btn.Name)); // 导航到对应页面 NavigateToPage(tag); } } /// /// 根据按钮名称获取对应的指示条名称 /// /// 按钮名称 /// 指示条名称 private string GetIndicatorName(string buttonName) { return buttonName switch { "BtnInstall" => "IndicatorInstall", "BtnInk" => "IndicatorInk", "BtnConvert" => "IndicatorConvert", "BtnTouch" => "IndicatorTouch", "BtnActivate" => "IndicatorActivate", _ => "IndicatorInstall" }; } /// /// 设置当前选中的导航按钮,并触发指示条动画 /// /// 选中的按钮名称 /// 对应的指示条名称 private void SetActiveNavigation(string activeButtonName, string activeIndicatorName) { // 所有导航按钮列表 string[] buttonNames = { "BtnInstall", "BtnInk", "BtnConvert", "BtnTouch", "BtnActivate" }; // 所有指示条列表 string[] indicatorNames = { "IndicatorInstall", "IndicatorInk", "IndicatorConvert", "IndicatorTouch", "IndicatorActivate" }; for (int i = 0; i < buttonNames.Length; i++) { // 查找按钮 var btn = FindName(buttonNames[i]) as Button; // 查找指示条 var indicator = FindName(indicatorNames[i]) as Border; if (btn == null || indicator == null) continue; if (buttonNames[i] == activeButtonName) { // 选中状态:高亮前景色,显示指示条 btn.Foreground = (Brush)FindResource("AccentBrush"); // 播放指示条展开动画(宽度从0到3px) AnimateIndicatorWidth(indicator, IndicatorTargetWidth); } else { // 非选中状态:恢复默认前景色,隐藏指示条 btn.Foreground = (Brush)FindResource("TextSecondaryBrush"); // 播放指示条收缩动画(宽度从当前值到0) AnimateIndicatorWidth(indicator, 0); } } } /// /// 为导航指示条播放宽度动画 /// /// 指示条控件 /// 目标宽度 private void AnimateIndicatorWidth(Border indicator, double targetWidth) { if (indicator == null) return; // 创建宽度动画 var widthAnimation = new DoubleAnimation { From = indicator.Width, To = targetWidth, Duration = TimeSpan.FromMilliseconds(IndicatorAnimationDuration), EasingFunction = new CubicEase { EasingMode = EasingMode.EaseInOut } }; // 应用动画到指示条的Width属性 indicator.BeginAnimation(WidthProperty, widthAnimation); } #endregion #region ===== 页面导航 ===== /// /// 导航到指定页面,带淡入淡出动画效果 /// /// 页面标识(Install/Ink/Convert/Touch/Activate) private void NavigateToPage(string pageTag) { // 创建淡出动画(当前页面) 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) => { // 根据页面标识加载对应页面 // TODO: 创建各个功能页面后取消注释 // switch (pageTag) // { // case "Install": // ContentFrame.Navigate(new Pages.InstallPage()); // break; // case "Ink": // ContentFrame.Navigate(new Pages.InkPage()); // break; // case "Convert": // ContentFrame.Navigate(new Pages.ConvertPage()); // break; // case "Touch": // ContentFrame.Navigate(new Pages.TouchPage()); // break; // case "Activate": // ContentFrame.Navigate(new Pages.ActivatePage()); // break; // } // 创建淡入动画(新页面) var fadeInAnimation = new DoubleAnimation { From = 0.0, To = 1.0, Duration = TimeSpan.FromMilliseconds(PageTransitionDuration / 2), EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut } }; // 应用淡入动画到Frame ContentFrame.BeginAnimation(OpacityProperty, fadeInAnimation); }; // 应用淡出动画到Frame ContentFrame.BeginAnimation(OpacityProperty, fadeOutAnimation); } #endregion #region ===== 主题切换 ===== /// /// 主题切换按钮点击事件 /// private void BtnThemeToggle_Click(object sender, RoutedEventArgs e) { // 切换到相反主题 bool newIsDark = !App.IsDarkTheme; // 调用 App.SwitchTheme 切换主题资源 App.SwitchTheme(newIsDark); // 更新主题图标 UpdateThemeIcon(newIsDark); } /// /// 根据当前主题更新切换按钮的图标 /// /// 当前是否为深色主题 private void UpdateThemeIcon(bool isDark) { if (ThemeIcon == null) return; if (isDark) { // 深色主题时显示太阳图标(提示可以切换到浅色) ThemeIcon.Data = Geometry.Parse( "M12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,2L14.39,5.42C13.73,5.14 13,5 12,5C11,5 10.27,5.14 9.61,5.42L12,2M3.34,7L7.5,6.35C7,7 6.63,7.73 6.43,8.5L3.34,7M3.36,17L6.44,15.5C6.64,16.28 7,17 7.5,17.65L3.36,17M20.64,7L17.55,8.5C17.36,7.72 17,7 16.5,6.35L20.64,7M20.65,17L16.5,17.65C17,17 17.37,16.27 17.57,15.5L20.65,17M12,22L9.61,18.58C10.27,18.86 11,19 12,19C13,19 13.73,18.86 14.39,18.58L12,22Z" ); } else { // 浅色主题时显示月亮图标(提示可以切换到深色) ThemeIcon.Data = Geometry.Parse( "M17.75,4.09L15.22,6.03L16.13,9.09L13.5,7.28L10.87,9.09L11.78,6.03L9.25,4.09L12.44,4L13.5,1L14.56,4L17.75,4.09M21.25,11L19.61,12.25L20.2,14.23L18.5,13.06L16.8,14.23L17.39,12.25L15.75,11L17.81,10.95L18.5,9L19.19,10.95L21.25,11M18.97,15.95C19.8,15.87 20.69,17.05 20.16,17.8C19.84,18.25 19.38,18.57 18.97,18.95C16.73,21.04 14.04,22.5 11,22.5C7.96,22.5 5.27,21.04 3.03,18.95C2.62,18.57 2.16,18.25 1.84,17.8C1.31,17.05 2.2,15.87 3.03,15.95C7.33,16.37 10.17,12.37 11,9.42C11.83,12.37 14.67,16.37 18.97,15.95Z" ); } } #endregion } }