improve:计时器UI

This commit is contained in:
2025-10-06 19:43:04 +08:00
parent aa3be4ab0d
commit 3ef047fb41
4 changed files with 394 additions and 0 deletions
@@ -0,0 +1,125 @@
<Window x:Class="Ink_Canvas.MinimizedTimerWindow"
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"
xmlns:local="clr-namespace:Ink_Canvas"
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
Topmost="True" Background="Transparent"
mc:Ignorable="d" WindowStyle="None" AllowsTransparency="True"
WindowStartupLocation="Manual" Title="计时器" Height="120" Width="300"
MouseLeftButtonDown="Window_MouseLeftButtonDown" MouseEnter="Window_MouseEnter" MouseLeave="Window_MouseLeave"
ResizeMode="NoResize">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="DigitResources.xaml" />
<ResourceDictionary Source="../Resources/Styles/Light.xaml" />
<ResourceDictionary Source="../Resources/Styles/Dark.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Border Background="{DynamicResource SeewoTimerWindowBackground}"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{DynamicResource SeewoTimerWindowBorderBrush}"
Margin="5">
<Grid>
<!-- 时间显示 -->
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<!-- 小时 -->
<Path x:Name="MinHour1Display" Data="{StaticResource Digit0}"
Fill="{DynamicResource SeewoTimerWindowDigitForeground}"
Width="24" Height="24"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform"
Margin="0,0,2,0"/>
<Path x:Name="MinHour2Display" Data="{StaticResource Digit0}"
Fill="{DynamicResource SeewoTimerWindowDigitForeground}"
Width="24" Height="24"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform"
Margin="0,0,2,0"/>
<!-- 冒号 -->
<TextBlock Text=":" FontSize="20" FontWeight="Bold"
Foreground="{DynamicResource SeewoTimerWindowDigitForeground}"
HorizontalAlignment="Center" VerticalAlignment="Center"
Margin="0,0,2,0"/>
<!-- 分钟 -->
<Path x:Name="MinMinute1Display" Data="{StaticResource Digit0}"
Fill="{DynamicResource SeewoTimerWindowDigitForeground}"
Width="24" Height="24"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform"
Margin="0,0,2,0"/>
<Path x:Name="MinMinute2Display" Data="{StaticResource Digit0}"
Fill="{DynamicResource SeewoTimerWindowDigitForeground}"
Width="24" Height="24"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform"
Margin="0,0,2,0"/>
<!-- 冒号 -->
<TextBlock Text=":" FontSize="20" FontWeight="Bold"
Foreground="{DynamicResource SeewoTimerWindowDigitForeground}"
HorizontalAlignment="Center" VerticalAlignment="Center"
Margin="0,0,2,0"/>
<!-- 秒 -->
<Path x:Name="MinSecond1Display" Data="{StaticResource Digit0}"
Fill="{DynamicResource SeewoTimerWindowDigitForeground}"
Width="24" Height="24"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform"
Margin="0,0,2,0"/>
<Path x:Name="MinSecond2Display" Data="{StaticResource Digit0}"
Fill="{DynamicResource SeewoTimerWindowDigitForeground}"
Width="24" Height="24"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform"
Margin="0,0,0,0"/>
</StackPanel>
</Grid>
<!-- 关闭按钮 -->
<Button x:Name="CloseButton"
Width="20" Height="20"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Margin="0,5,5,0"
Background="Transparent"
BorderThickness="0"
Click="CloseButton_Click"
Cursor="Hand"
Opacity="0.7">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}" CornerRadius="10">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#E81123"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
<TextBlock Text="✕" FontSize="12" FontWeight="Bold"
Foreground="{DynamicResource SeewoTimerWindowButtonForeground}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Button>
</Grid>
</Border>
</Window>
@@ -0,0 +1,193 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
namespace Ink_Canvas
{
/// <summary>
/// 最小化计时器窗口
/// </summary>
public partial class MinimizedTimerWindow : Window
{
private SeewoStyleTimerWindow parentWindow;
private System.Timers.Timer updateTimer;
private bool isMouseOver = false;
public MinimizedTimerWindow(SeewoStyleTimerWindow parent)
{
InitializeComponent();
parentWindow = parent;
// 设置窗口位置(在父窗口右下角)
this.Left = parent.Left + parent.Width - this.Width - 20;
this.Top = parent.Top + parent.Height - this.Height - 20;
// 启动更新定时器
updateTimer = new System.Timers.Timer(100); // 100ms更新一次
updateTimer.Elapsed += UpdateTimer_Elapsed;
updateTimer.Start();
// 应用主题
ApplyTheme();
}
private void UpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (parentWindow != null && parentWindow.IsTimerRunning)
{
Application.Current.Dispatcher.Invoke(() =>
{
UpdateTimeDisplay();
});
}
}
private void UpdateTimeDisplay()
{
if (parentWindow == null) return;
// 获取剩余时间
var remainingTime = parentWindow.GetRemainingTime();
if (remainingTime.HasValue)
{
var timeSpan = remainingTime.Value;
int hours = (int)timeSpan.TotalHours;
int minutes = timeSpan.Minutes;
int seconds = timeSpan.Seconds;
// 更新小时显示
SetDigitDisplay("MinHour1Display", hours / 10);
SetDigitDisplay("MinHour2Display", hours % 10);
// 更新分钟显示
SetDigitDisplay("MinMinute1Display", minutes / 10);
SetDigitDisplay("MinMinute2Display", minutes % 10);
// 更新秒显示
SetDigitDisplay("MinSecond1Display", seconds / 10);
SetDigitDisplay("MinSecond2Display", seconds % 10);
}
}
private void SetDigitDisplay(string pathName, int digit)
{
var path = this.FindName(pathName) as Path;
if (path != null)
{
string resourceKey = $"Digit{digit}";
var geometry = this.FindResource(resourceKey) as Geometry;
if (geometry != null)
{
path.Data = geometry;
}
}
}
private void ApplyTheme()
{
try
{
// 应用主题设置
var mainWindow = Application.Current.MainWindow as MainWindow;
if (mainWindow != null)
{
bool isLightTheme = IsLightTheme();
if (isLightTheme)
{
// 应用浅色主题
this.Background = new SolidColorBrush(Color.FromRgb(255, 255, 255));
}
else
{
// 应用深色主题
this.Background = new SolidColorBrush(Color.FromRgb(30, 30, 30));
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"应用主题时出错: {ex.Message}");
}
}
private bool IsLightTheme()
{
try
{
var mainWindow = Application.Current.MainWindow as MainWindow;
if (mainWindow != null)
{
var currentModeField = mainWindow.GetType().GetField("currentMode",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (currentModeField != null)
{
var currentMode = currentModeField.GetValue(mainWindow);
return currentMode?.ToString() == "Light";
}
}
}
catch
{
// 如果获取主题失败,默认使用浅色主题
}
return true;
}
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// 恢复主窗口
if (parentWindow != null)
{
parentWindow.Show();
parentWindow.Activate();
parentWindow.WindowState = WindowState.Normal;
this.Close();
}
}
private void Window_MouseEnter(object sender, MouseEventArgs e)
{
isMouseOver = true;
// 鼠标进入时显示关闭按钮
if (CloseButton != null)
{
CloseButton.Opacity = 1.0;
}
}
private void Window_MouseLeave(object sender, MouseEventArgs e)
{
isMouseOver = false;
// 鼠标离开时隐藏关闭按钮
if (CloseButton != null)
{
CloseButton.Opacity = 0.7;
}
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
// 停止计时器并关闭窗口
if (parentWindow != null)
{
parentWindow.StopTimer();
}
this.Close();
}
protected override void OnClosed(EventArgs e)
{
// 清理资源
if (updateTimer != null)
{
updateTimer.Stop();
updateTimer.Dispose();
}
base.OnClosed(e);
}
}
}
@@ -9,6 +9,7 @@
Topmost="True" Background="Transparent"
mc:Ignorable="d" WindowStyle="None" AllowsTransparency="True"
Loaded="Window_Loaded" Closing="Window_Closing" WindowStartupLocation="CenterScreen"
MouseMove="Window_MouseMove" MouseEnter="Window_MouseEnter"
Title="Ink Canvas 画板 - 计时器" Height="450" Width="900">
<Window.Resources>
@@ -26,6 +26,11 @@ namespace Ink_Canvas
// 应用主题
ApplyTheme();
// 初始化隐藏定时器
hideTimer = new Timer(1000); // 每秒检查一次
hideTimer.Elapsed += HideTimer_Elapsed;
lastActivityTime = DateTime.Now;
}
@@ -86,6 +91,9 @@ namespace Ink_Canvas
bool isPaused = false;
Timer timer = new Timer();
private Timer hideTimer;
private MinimizedTimerWindow minimizedWindow;
private DateTime lastActivityTime;
// 最近计时记录
private string recentTimer1 = "--:--";
@@ -194,6 +202,70 @@ namespace Ink_Canvas
SetDigitDisplay("Digit6Display", second % 10);
}
private void HideTimer_Elapsed(object sender, ElapsedEventArgs e)
{
Application.Current.Dispatcher.Invoke(() =>
{
// 只有在计时器运行时才检查自动隐藏
if (isTimerRunning && !isPaused)
{
var timeSinceLastActivity = DateTime.Now - lastActivityTime;
if (timeSinceLastActivity.TotalSeconds >= 5) // 5秒无操作
{
ShowMinimizedWindow();
}
}
});
}
private void ShowMinimizedWindow()
{
if (minimizedWindow == null || !minimizedWindow.IsVisible)
{
minimizedWindow = new MinimizedTimerWindow(this);
minimizedWindow.Show();
// 隐藏主窗口
this.Hide();
}
}
public void UpdateActivityTime()
{
lastActivityTime = DateTime.Now;
}
public bool IsTimerRunning => isTimerRunning;
public TimeSpan? GetRemainingTime()
{
if (!isTimerRunning || isPaused) return null;
var elapsed = DateTime.Now - startTime;
var totalSeconds = hour * 3600 + minute * 60 + second;
var remaining = totalSeconds - elapsed.TotalSeconds;
if (remaining <= 0) return TimeSpan.Zero;
return TimeSpan.FromSeconds(remaining);
}
public void StopTimer()
{
timer.Stop();
isTimerRunning = false;
StartPauseIcon.Data = Geometry.Parse(PlayIconData);
}
private void Window_MouseMove(object sender, MouseEventArgs e)
{
UpdateActivityTime();
}
private void Window_MouseEnter(object sender, MouseEventArgs e)
{
UpdateActivityTime();
}
/// <summary>
/// 根据数字值设置SVG数字显示
/// </summary>
@@ -453,6 +525,9 @@ namespace Ink_Canvas
isPaused = false;
isTimerRunning = true;
timer.Start();
// 启动隐藏定时器
hideTimer.Start();
// 保存到最近计时记录
SaveRecentTimer();