feat: 添加暂停和恢复功能以优化工作计时管理
This commit is contained in:
@@ -17,6 +17,10 @@ namespace TimerApp
|
|||||||
private TimeSpan _accumulatedWorkTime;
|
private TimeSpan _accumulatedWorkTime;
|
||||||
private DateTime _restStartTime;
|
private DateTime _restStartTime;
|
||||||
private int _restElapsedSeconds; // 休息已过秒数(用于避免时间计算导致的跳变)
|
private int _restElapsedSeconds; // 休息已过秒数(用于避免时间计算导致的跳变)
|
||||||
|
private bool _isPaused = false; // 暂停状态
|
||||||
|
private DateTime _pauseStartTime; // 暂停开始时间
|
||||||
|
private TimeSpan _pauseDuration = TimeSpan.Zero; // 累计暂停时间(用于工作计时)
|
||||||
|
private int _restPauseStartSeconds = 0; // 休息暂停时的已过秒数
|
||||||
|
|
||||||
// 配置 (默认值)
|
// 配置 (默认值)
|
||||||
public TimeSpan WorkDuration { get; set; } = TimeSpan.FromMinutes(20);
|
public TimeSpan WorkDuration { get; set; } = TimeSpan.FromMinutes(20);
|
||||||
@@ -24,6 +28,7 @@ namespace TimerApp
|
|||||||
public TimeSpan IdleThreshold { get; set; } = TimeSpan.FromSeconds(30);
|
public TimeSpan IdleThreshold { get; set; } = TimeSpan.FromSeconds(30);
|
||||||
|
|
||||||
public MonitorState CurrentState { get; private set; } = MonitorState.Idle;
|
public MonitorState CurrentState { get; private set; } = MonitorState.Idle;
|
||||||
|
public bool IsPaused { get; private set; } = false;
|
||||||
|
|
||||||
// 事件
|
// 事件
|
||||||
public event EventHandler<TimeSpan> WorkProgressChanged; // 剩余工作时间
|
public event EventHandler<TimeSpan> WorkProgressChanged; // 剩余工作时间
|
||||||
@@ -68,6 +73,12 @@ namespace TimerApp
|
|||||||
|
|
||||||
private void Timer_Tick(object sender, EventArgs e)
|
private void Timer_Tick(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
// 如果处于暂停状态,不处理计时逻辑
|
||||||
|
if (_isPaused)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
long idleMs = NativeMethods.GetIdleTime();
|
long idleMs = NativeMethods.GetIdleTime();
|
||||||
TimeSpan idleTime = TimeSpan.FromMilliseconds(idleMs);
|
TimeSpan idleTime = TimeSpan.FromMilliseconds(idleMs);
|
||||||
|
|
||||||
@@ -188,6 +199,9 @@ namespace TimerApp
|
|||||||
{
|
{
|
||||||
_accumulatedWorkTime = TimeSpan.Zero;
|
_accumulatedWorkTime = TimeSpan.Zero;
|
||||||
_lastWorkStartTime = DateTime.Now;
|
_lastWorkStartTime = DateTime.Now;
|
||||||
|
_isPaused = false;
|
||||||
|
IsPaused = false;
|
||||||
|
_pauseDuration = TimeSpan.Zero;
|
||||||
|
|
||||||
// Ensure timer is running
|
// Ensure timer is running
|
||||||
if (!_timer.Enabled) _timer.Start();
|
if (!_timer.Enabled) _timer.Start();
|
||||||
@@ -198,5 +212,51 @@ namespace TimerApp
|
|||||||
// Immediately refresh UI to show full duration
|
// Immediately refresh UI to show full duration
|
||||||
RefreshStatus();
|
RefreshStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Pause()
|
||||||
|
{
|
||||||
|
if (!_isPaused && CurrentState != MonitorState.Idle)
|
||||||
|
{
|
||||||
|
_isPaused = true;
|
||||||
|
IsPaused = true;
|
||||||
|
_pauseStartTime = DateTime.Now;
|
||||||
|
|
||||||
|
// 如果正在休息,记录当前已过秒数
|
||||||
|
if (CurrentState == MonitorState.Resting)
|
||||||
|
{
|
||||||
|
_restPauseStartSeconds = _restElapsedSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateChanged?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Resume()
|
||||||
|
{
|
||||||
|
if (_isPaused)
|
||||||
|
{
|
||||||
|
_isPaused = false;
|
||||||
|
IsPaused = false;
|
||||||
|
|
||||||
|
// 计算暂停时长
|
||||||
|
TimeSpan pauseTime = DateTime.Now - _pauseStartTime;
|
||||||
|
|
||||||
|
// 如果正在工作,将暂停时间累加到暂停总时长中
|
||||||
|
// 这样工作时间就不会因为暂停而减少
|
||||||
|
if (CurrentState == MonitorState.Working)
|
||||||
|
{
|
||||||
|
_pauseDuration += pauseTime;
|
||||||
|
}
|
||||||
|
// 如果正在休息,调整已过秒数,使剩余时间保持不变
|
||||||
|
else if (CurrentState == MonitorState.Resting)
|
||||||
|
{
|
||||||
|
// 保持已过秒数不变,这样恢复后剩余时间不会变化
|
||||||
|
// _restElapsedSeconds 保持不变
|
||||||
|
}
|
||||||
|
|
||||||
|
StateChanged?.Invoke(this, EventArgs.Empty);
|
||||||
|
RefreshStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
MainForm.Designer.cs
generated
29
MainForm.Designer.cs
generated
@@ -41,6 +41,7 @@ namespace TimerApp
|
|||||||
|
|
||||||
this.btnStartStop = new System.Windows.Forms.Button();
|
this.btnStartStop = new System.Windows.Forms.Button();
|
||||||
this.btnReset = new System.Windows.Forms.Button();
|
this.btnReset = new System.Windows.Forms.Button();
|
||||||
|
this.btnPause = new System.Windows.Forms.Button();
|
||||||
this.lblStatus = new System.Windows.Forms.Label();
|
this.lblStatus = new System.Windows.Forms.Label();
|
||||||
this.lblTimeLeft = new System.Windows.Forms.Label();
|
this.lblTimeLeft = new System.Windows.Forms.Label();
|
||||||
this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
|
this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
|
||||||
@@ -169,6 +170,7 @@ namespace TimerApp
|
|||||||
// pnlSettings
|
// pnlSettings
|
||||||
//
|
//
|
||||||
this.pnlSettings.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(30)))), ((int)(((byte)(30)))), ((int)(((byte)(30)))));
|
this.pnlSettings.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(30)))), ((int)(((byte)(30)))), ((int)(((byte)(30)))));
|
||||||
|
this.pnlSettings.Controls.Add(this.btnPause);
|
||||||
this.pnlSettings.Controls.Add(this.btnReset);
|
this.pnlSettings.Controls.Add(this.btnReset);
|
||||||
this.pnlSettings.Controls.Add(this.btnStartStop);
|
this.pnlSettings.Controls.Add(this.btnStartStop);
|
||||||
this.pnlSettings.Controls.Add(this.btnRestPlus);
|
this.pnlSettings.Controls.Add(this.btnRestPlus);
|
||||||
@@ -305,11 +307,11 @@ namespace TimerApp
|
|||||||
this.btnStartStop.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
this.btnStartStop.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
this.btnStartStop.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
this.btnStartStop.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||||
this.btnStartStop.ForeColor = System.Drawing.Color.White;
|
this.btnStartStop.ForeColor = System.Drawing.Color.White;
|
||||||
this.btnStartStop.Location = new System.Drawing.Point(170, 110);
|
this.btnStartStop.Location = new System.Drawing.Point(210, 110);
|
||||||
this.btnStartStop.Name = "btnStartStop";
|
this.btnStartStop.Name = "btnStartStop";
|
||||||
this.btnStartStop.Size = new System.Drawing.Size(110, 35);
|
this.btnStartStop.Size = new System.Drawing.Size(70, 35);
|
||||||
this.btnStartStop.TabIndex = 4;
|
this.btnStartStop.TabIndex = 4;
|
||||||
this.btnStartStop.Text = "应用设置";
|
this.btnStartStop.Text = "应用";
|
||||||
this.btnStartStop.UseVisualStyleBackColor = false;
|
this.btnStartStop.UseVisualStyleBackColor = false;
|
||||||
this.btnStartStop.Click += new System.EventHandler(this.btnStartStop_Click);
|
this.btnStartStop.Click += new System.EventHandler(this.btnStartStop_Click);
|
||||||
|
|
||||||
@@ -323,12 +325,28 @@ namespace TimerApp
|
|||||||
this.btnReset.ForeColor = System.Drawing.Color.White;
|
this.btnReset.ForeColor = System.Drawing.Color.White;
|
||||||
this.btnReset.Location = new System.Drawing.Point(40, 110);
|
this.btnReset.Location = new System.Drawing.Point(40, 110);
|
||||||
this.btnReset.Name = "btnReset";
|
this.btnReset.Name = "btnReset";
|
||||||
this.btnReset.Size = new System.Drawing.Size(110, 35);
|
this.btnReset.Size = new System.Drawing.Size(70, 35);
|
||||||
this.btnReset.TabIndex = 8;
|
this.btnReset.TabIndex = 8;
|
||||||
this.btnReset.Text = "重置计时";
|
this.btnReset.Text = "重置";
|
||||||
this.btnReset.UseVisualStyleBackColor = false;
|
this.btnReset.UseVisualStyleBackColor = false;
|
||||||
this.btnReset.Click += new System.EventHandler(this.btnReset_Click);
|
this.btnReset.Click += new System.EventHandler(this.btnReset_Click);
|
||||||
|
|
||||||
|
//
|
||||||
|
// btnPause
|
||||||
|
//
|
||||||
|
this.btnPause.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70)))));
|
||||||
|
this.btnPause.FlatAppearance.BorderSize = 0;
|
||||||
|
this.btnPause.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnPause.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||||
|
this.btnPause.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.btnPause.Location = new System.Drawing.Point(125, 110);
|
||||||
|
this.btnPause.Name = "btnPause";
|
||||||
|
this.btnPause.Size = new System.Drawing.Size(70, 35);
|
||||||
|
this.btnPause.TabIndex = 9;
|
||||||
|
this.btnPause.Text = "暂停";
|
||||||
|
this.btnPause.UseVisualStyleBackColor = false;
|
||||||
|
this.btnPause.Click += new System.EventHandler(this.btnPause_Click);
|
||||||
|
|
||||||
//
|
//
|
||||||
// btnHide
|
// btnHide
|
||||||
//
|
//
|
||||||
@@ -419,6 +437,7 @@ namespace TimerApp
|
|||||||
private System.Windows.Forms.Button btnRestPlus;
|
private System.Windows.Forms.Button btnRestPlus;
|
||||||
private System.Windows.Forms.Button btnStartStop;
|
private System.Windows.Forms.Button btnStartStop;
|
||||||
private System.Windows.Forms.Button btnReset;
|
private System.Windows.Forms.Button btnReset;
|
||||||
|
private System.Windows.Forms.Button btnPause;
|
||||||
private System.Windows.Forms.Label lblStatus;
|
private System.Windows.Forms.Label lblStatus;
|
||||||
private System.Windows.Forms.Label lblTimeLeft;
|
private System.Windows.Forms.Label lblTimeLeft;
|
||||||
private System.Windows.Forms.NotifyIcon notifyIcon1;
|
private System.Windows.Forms.NotifyIcon notifyIcon1;
|
||||||
|
|||||||
32
MainForm.cs
32
MainForm.cs
@@ -61,6 +61,7 @@ namespace TimerApp
|
|||||||
btnRestPlus.BackColor = panelColor;
|
btnRestPlus.BackColor = panelColor;
|
||||||
btnStartStop.BackColor = dark ? Color.FromArgb(63, 63, 70) : Color.White;
|
btnStartStop.BackColor = dark ? Color.FromArgb(63, 63, 70) : Color.White;
|
||||||
btnReset.BackColor = dark ? Color.FromArgb(63, 63, 70) : Color.White;
|
btnReset.BackColor = dark ? Color.FromArgb(63, 63, 70) : Color.White;
|
||||||
|
btnPause.BackColor = dark ? Color.FromArgb(63, 63, 70) : Color.White;
|
||||||
|
|
||||||
// 优化绘制,减少闪烁
|
// 优化绘制,减少闪烁
|
||||||
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
|
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
|
||||||
@@ -256,6 +257,7 @@ namespace TimerApp
|
|||||||
// Update buttons
|
// Update buttons
|
||||||
UpdateButtonStyle(btnStartStop, dark);
|
UpdateButtonStyle(btnStartStop, dark);
|
||||||
UpdateButtonStyle(btnReset, dark);
|
UpdateButtonStyle(btnReset, dark);
|
||||||
|
UpdateButtonStyle(btnPause, dark);
|
||||||
UpdateButtonStyle(btnHide, dark);
|
UpdateButtonStyle(btnHide, dark);
|
||||||
|
|
||||||
// Numeric buttons and text
|
// Numeric buttons and text
|
||||||
@@ -372,6 +374,20 @@ namespace TimerApp
|
|||||||
_monitor.Restart();
|
_monitor.Restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void btnPause_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (_monitor.IsPaused)
|
||||||
|
{
|
||||||
|
_monitor.Resume();
|
||||||
|
btnPause.Text = "暂停";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_monitor.Pause();
|
||||||
|
btnPause.Text = "恢复";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ApplySettings()
|
private void ApplySettings()
|
||||||
{
|
{
|
||||||
int workMin = 20;
|
int workMin = 20;
|
||||||
@@ -400,6 +416,18 @@ namespace TimerApp
|
|||||||
|
|
||||||
bool dark = _settings.IsDarkMode;
|
bool dark = _settings.IsDarkMode;
|
||||||
|
|
||||||
|
// 更新暂停按钮状态
|
||||||
|
if (_monitor.CurrentState == MonitorState.Idle)
|
||||||
|
{
|
||||||
|
btnPause.Enabled = false;
|
||||||
|
btnPause.Text = "暂停";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
btnPause.Enabled = true;
|
||||||
|
btnPause.Text = _monitor.IsPaused ? "恢复" : "暂停";
|
||||||
|
}
|
||||||
|
|
||||||
switch (_monitor.CurrentState)
|
switch (_monitor.CurrentState)
|
||||||
{
|
{
|
||||||
case MonitorState.Idle:
|
case MonitorState.Idle:
|
||||||
@@ -409,12 +437,12 @@ namespace TimerApp
|
|||||||
lblTimeLeft.ForeColor = Color.Gray;
|
lblTimeLeft.ForeColor = Color.Gray;
|
||||||
break;
|
break;
|
||||||
case MonitorState.Working:
|
case MonitorState.Working:
|
||||||
lblStatus.Text = "状态: 工作中";
|
lblStatus.Text = _monitor.IsPaused ? "状态: 工作中 (已暂停)" : "状态: 工作中";
|
||||||
lblStatus.ForeColor = dark ? Color.LightGreen : Color.Green;
|
lblStatus.ForeColor = dark ? Color.LightGreen : Color.Green;
|
||||||
lblTimeLeft.ForeColor = dark ? Color.White : Color.Black;
|
lblTimeLeft.ForeColor = dark ? Color.White : Color.Black;
|
||||||
break;
|
break;
|
||||||
case MonitorState.Resting:
|
case MonitorState.Resting:
|
||||||
lblStatus.Text = "状态: 休息中";
|
lblStatus.Text = _monitor.IsPaused ? "状态: 休息中 (已暂停)" : "状态: 休息中";
|
||||||
lblStatus.ForeColor = dark ? Color.LightSkyBlue : Color.Blue;
|
lblStatus.ForeColor = dark ? Color.LightSkyBlue : Color.Blue;
|
||||||
lblTimeLeft.ForeColor = dark ? Color.LightSkyBlue : Color.Blue;
|
lblTimeLeft.ForeColor = dark ? Color.LightSkyBlue : Color.Blue;
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user