diff --git a/Ink Canvas/InkCanvasForClass.csproj b/Ink Canvas/InkCanvasForClass.csproj
index e7948a37..ac80bfbb 100644
--- a/Ink Canvas/InkCanvasForClass.csproj
+++ b/Ink Canvas/InkCanvasForClass.csproj
@@ -192,6 +192,7 @@
+
diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml
index bb7d4bb9..76068083 100644
--- a/Ink Canvas/MainWindow.xaml
+++ b/Ink Canvas/MainWindow.xaml
@@ -3351,6 +3351,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs
index c135d225..db0d80ff 100644
--- a/Ink Canvas/MainWindow.xaml.cs
+++ b/Ink Canvas/MainWindow.xaml.cs
@@ -2460,6 +2460,7 @@ namespace Ink_Canvas
RandWindowOnceCloseLatencySlider,
RandWindowOnceMaxStudentsSlider,
TimerVolumeSlider,
+ ProgressiveReminderVolumeSlider,
BoardInkWidthSlider,
BoardInkAlphaSlider,
BoardHighlighterWidthSlider,
diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs
index e9ec157f..e5e06c8f 100644
--- a/Ink Canvas/MainWindow_cs/MW_Settings.cs
+++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs
@@ -2664,6 +2664,42 @@ namespace Ink_Canvas
SaveSettingsToFile();
}
+ private void ToggleSwitchEnableProgressiveReminder_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!isLoaded) return;
+ Settings.RandSettings.EnableProgressiveReminder = ToggleSwitchEnableProgressiveReminder.IsOn;
+ SaveSettingsToFile();
+ }
+
+ private void ProgressiveReminderVolumeSlider_ValueChanged(object sender, RoutedEventArgs e)
+ {
+ if (!isLoaded) return;
+ Settings.RandSettings.ProgressiveReminderVolume = ProgressiveReminderVolumeSlider.Value;
+ SaveSettingsToFile();
+ }
+
+ private void ButtonSelectCustomProgressiveReminderSound_Click(object sender, RoutedEventArgs e)
+ {
+ Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog
+ {
+ Title = "选择渐进提醒音频文件",
+ Filter = "音频文件 (*.wav)|*.wav|所有文件 (*.*)|*.*",
+ DefaultExt = "wav"
+ };
+
+ if (openFileDialog.ShowDialog() == true)
+ {
+ Settings.RandSettings.ProgressiveReminderSoundPath = openFileDialog.FileName;
+ SaveSettingsToFile();
+ }
+ }
+
+ private void ButtonResetProgressiveReminderSound_Click(object sender, RoutedEventArgs e)
+ {
+ Settings.RandSettings.ProgressiveReminderSoundPath = "";
+ SaveSettingsToFile();
+ }
+
private void ButtonSelectCustomTimerSound_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog
diff --git a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
index a8383f82..c9699bb8 100644
--- a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
+++ b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
@@ -895,6 +895,10 @@ namespace Ink_Canvas
TimerVolumeSlider.Value = Settings.RandSettings.TimerVolume;
+ // 渐进提醒设置
+ ToggleSwitchEnableProgressiveReminder.IsOn = Settings.RandSettings.EnableProgressiveReminder;
+ ProgressiveReminderVolumeSlider.Value = Settings.RandSettings.ProgressiveReminderVolume;
+
// 加载自定义点名背景
UpdatePickNameBackgroundsInComboBox();
@@ -925,6 +929,10 @@ namespace Ink_Canvas
}
TimerVolumeSlider.Value = Settings.RandSettings.TimerVolume;
+
+ // 渐进提醒设置
+ ToggleSwitchEnableProgressiveReminder.IsOn = Settings.RandSettings.EnableProgressiveReminder;
+ ProgressiveReminderVolumeSlider.Value = Settings.RandSettings.ProgressiveReminderVolume;
}
// ModeSettings
diff --git a/Ink Canvas/Properties/Resources.Designer.cs b/Ink Canvas/Properties/Resources.Designer.cs
index 725984ff..9322cc19 100644
--- a/Ink Canvas/Properties/Resources.Designer.cs
+++ b/Ink Canvas/Properties/Resources.Designer.cs
@@ -74,5 +74,14 @@ namespace Ink_Canvas.Properties {
return ResourceManager.GetStream("TimerDownNotice", resourceCulture);
}
}
+
+ ///
+ /// Looks up a localized resource of type System.IO.UnmanagedMemoryStream similar to System.IO.MemoryStream.
+ ///
+ internal static UnmanagedMemoryStream ProgressiveAudio {
+ get {
+ return ResourceManager.GetStream("ProgressiveAudio", resourceCulture);
+ }
+ }
}
}
diff --git a/Ink Canvas/Properties/Resources.resx b/Ink Canvas/Properties/Resources.resx
index 09ce9aea..610b7b0c 100644
--- a/Ink Canvas/Properties/Resources.resx
+++ b/Ink Canvas/Properties/Resources.resx
@@ -121,4 +121,7 @@
..\Resources\TimerDownNotice.wav;System.IO.MemoryStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ ..\Resources\ProgressiveAudio.wav;System.IO.MemoryStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
\ No newline at end of file
diff --git a/Ink Canvas/Resources/ProgressiveAudio.wav b/Ink Canvas/Resources/ProgressiveAudio.wav
new file mode 100644
index 00000000..0e010cc8
Binary files /dev/null and b/Ink Canvas/Resources/ProgressiveAudio.wav differ
diff --git a/Ink Canvas/Resources/Settings.cs b/Ink Canvas/Resources/Settings.cs
index a61165bf..32d02c87 100644
--- a/Ink Canvas/Resources/Settings.cs
+++ b/Ink Canvas/Resources/Settings.cs
@@ -641,6 +641,12 @@ namespace Ink_Canvas
public bool EnableOvertimeCountUp { get; set; } = false;
[JsonProperty("enableOvertimeRedText")]
public bool EnableOvertimeRedText { get; set; } = false;
+ [JsonProperty("enableProgressiveReminder")]
+ public bool EnableProgressiveReminder { get; set; } = false;
+ [JsonProperty("progressiveReminderVolume")]
+ public double ProgressiveReminderVolume { get; set; } = 1.0;
+ [JsonProperty("progressiveReminderSoundPath")]
+ public string ProgressiveReminderSoundPath { get; set; } = "";
}
public class CustomPickNameBackground
diff --git a/Ink Canvas/Windows/NewStyleTimerWindow.cs b/Ink Canvas/Windows/NewStyleTimerWindow.cs
index 7ab97842..d60d8d05 100644
--- a/Ink Canvas/Windows/NewStyleTimerWindow.cs
+++ b/Ink Canvas/Windows/NewStyleTimerWindow.cs
@@ -65,6 +65,14 @@ namespace Ink_Canvas
SetDigitDisplay("Digit5Display", leftTimeSpan.Seconds / 10);
SetDigitDisplay("Digit6Display", leftTimeSpan.Seconds % 10);
+ if (leftTimeSpan.TotalSeconds == 3 &&
+ MainWindow.Settings.RandSettings?.EnableProgressiveReminder == true &&
+ !hasPlayedProgressiveReminder)
+ {
+ PlayProgressiveReminderSound();
+ hasPlayedProgressiveReminder = true;
+ }
+
if (leftTimeSpan.TotalSeconds <= 0 && MainWindow.Settings.RandSettings?.EnableOvertimeCountUp == true)
{
isOvertimeMode = true;
@@ -121,6 +129,7 @@ namespace Ink_Canvas
bool isPaused = false;
bool isOvertimeMode = false;
TimeSpan remainingTime = TimeSpan.Zero;
+ bool hasPlayedProgressiveReminder = false;
Timer timer = new Timer();
private Timer hideTimer;
@@ -692,7 +701,8 @@ namespace Ink_Canvas
StartPauseIcon.Data = Geometry.Parse(PauseIconData);
isPaused = false;
isTimerRunning = true;
- isOvertimeMode = false;
+ isOvertimeMode = false;
+ hasPlayedProgressiveReminder = false;
timer.Start();
// 启动隐藏定时器
@@ -736,12 +746,10 @@ namespace Ink_Canvas
if (!string.IsNullOrEmpty(MainWindow.Settings.RandSettings?.CustomTimerSoundPath) &&
System.IO.File.Exists(MainWindow.Settings.RandSettings.CustomTimerSoundPath))
{
- // 播放自定义铃声
mediaPlayer.Open(new Uri(MainWindow.Settings.RandSettings.CustomTimerSoundPath));
}
else
{
- // 播放默认铃声
string tempPath = System.IO.Path.GetTempFileName() + ".wav";
using (var stream = Properties.Resources.TimerDownNotice)
{
@@ -757,11 +765,43 @@ namespace Ink_Canvas
}
catch (Exception ex)
{
- // 如果播放失败,静默处理
System.Diagnostics.Debug.WriteLine($"播放计时器铃声失败: {ex.Message}");
}
}
+ private void PlayProgressiveReminderSound()
+ {
+ try
+ {
+ double volume = MainWindow.Settings.RandSettings?.ProgressiveReminderVolume ?? 1.0;
+ mediaPlayer.Volume = volume;
+
+ if (!string.IsNullOrEmpty(MainWindow.Settings.RandSettings?.ProgressiveReminderSoundPath) &&
+ System.IO.File.Exists(MainWindow.Settings.RandSettings.ProgressiveReminderSoundPath))
+ {
+ mediaPlayer.Open(new Uri(MainWindow.Settings.RandSettings.ProgressiveReminderSoundPath));
+ }
+ else
+ {
+ string tempPath = System.IO.Path.GetTempFileName() + ".wav";
+ using (var stream = Properties.Resources.ProgressiveAudio)
+ {
+ using (var fileStream = new System.IO.FileStream(tempPath, System.IO.FileMode.Create))
+ {
+ stream.CopyTo(fileStream);
+ }
+ }
+ mediaPlayer.Open(new Uri(tempPath));
+ }
+
+ mediaPlayer.Play();
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine($"播放渐进提醒音频失败: {ex.Message}");
+ }
+ }
+
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// 窗口加载时的初始化