improve:计时器UI
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user