@@ -49,5 +49,5 @@ using System.Windows;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.7.0.0")]
|
[assembly: AssemblyVersion("1.7.0.1")]
|
||||||
[assembly: AssemblyFileVersion("1.7.0.0")]
|
[assembly: AssemblyFileVersion("1.7.0.1")]
|
||||||
|
|||||||
@@ -807,17 +807,48 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"AutoUpdate | Starting version fix for {channel} channel");
|
LogHelper.WriteLogToFile($"AutoUpdate | Starting version fix for {channel} channel");
|
||||||
|
|
||||||
// 获取当前通道的最新版本
|
// 获取远程版本号,而不是检查更新
|
||||||
string latestVersion = await CheckForUpdates(null, channel);
|
string remoteVersion = null;
|
||||||
|
string proxy = null;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(latestVersion))
|
// 根据通道选择URL
|
||||||
|
string primaryUrl, fallbackUrl;
|
||||||
|
|
||||||
|
if (channel == UpdateChannel.Release)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile("AutoUpdate | No newer version found for fixing", LogHelper.LogType.Warning);
|
// Release通道版本信息地址
|
||||||
|
primaryUrl = "https://github.com/InkCanvasForClass/community/raw/refs/heads/beta/AutomaticUpdateVersionControl.txt";
|
||||||
|
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community/raw/refs/heads/main/AutomaticUpdateVersionControl.txt";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Beta通道版本信息地址
|
||||||
|
primaryUrl = "https://github.com/InkCanvasForClass/community-beta/raw/refs/heads/main/AutomaticUpdateVersionControl.txt";
|
||||||
|
fallbackUrl = "https://bgithub.xyz/InkCanvasForClass/community-beta/raw/refs/heads/main/AutomaticUpdateVersionControl.txt";
|
||||||
|
}
|
||||||
|
|
||||||
|
LogHelper.WriteLogToFile($"AutoUpdate | Retrieving remote version from {channel} channel");
|
||||||
|
|
||||||
|
// 先尝试主地址
|
||||||
|
remoteVersion = await GetRemoteVersion(primaryUrl);
|
||||||
|
|
||||||
|
// 如果主地址失败,尝试备用地址
|
||||||
|
if (remoteVersion == null)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"AutoUpdate | Primary URL failed, trying fallback URL");
|
||||||
|
remoteVersion = await GetRemoteVersion(fallbackUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(remoteVersion))
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("AutoUpdate | Failed to retrieve remote version for fixing", LogHelper.LogType.Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下载最新版本
|
LogHelper.WriteLogToFile($"AutoUpdate | Remote version for fixing: {remoteVersion}");
|
||||||
bool downloadResult = await DownloadSetupFileAndSaveStatus(latestVersion, "", channel);
|
|
||||||
|
// 无论版本是否为最新,都下载远程版本
|
||||||
|
bool downloadResult = await DownloadSetupFileAndSaveStatus(remoteVersion, "", channel);
|
||||||
|
|
||||||
if (!downloadResult)
|
if (!downloadResult)
|
||||||
{
|
{
|
||||||
@@ -826,7 +857,7 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 执行安装,非静默模式
|
// 执行安装,非静默模式
|
||||||
InstallNewVersionApp(latestVersion, false);
|
InstallNewVersionApp(remoteVersion, false);
|
||||||
|
|
||||||
// 设置为用户主动退出,避免被看门狗判定为崩溃
|
// 设置为用户主动退出,避免被看门狗判定为崩溃
|
||||||
App.IsAppExitByUser = true;
|
App.IsAppExitByUser = true;
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ namespace Ink_Canvas.Helpers
|
|||||||
class LogHelper
|
class LogHelper
|
||||||
{
|
{
|
||||||
public static string LogFile = "Log.txt";
|
public static string LogFile = "Log.txt";
|
||||||
|
private static string LogsFolder = "Logs";
|
||||||
|
private static string AppStartTime = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
|
||||||
|
private static readonly long MaxLogsFolderSizeBytes = 5 * 1024 * 1024; // 5MB
|
||||||
|
|
||||||
public static void NewLog(string str)
|
public static void NewLog(string str)
|
||||||
{
|
{
|
||||||
@@ -28,14 +31,40 @@ namespace Ink_Canvas.Helpers
|
|||||||
|
|
||||||
public static void WriteLogToFile(string str, LogType logType = LogType.Info)
|
public static void WriteLogToFile(string str, LogType logType = LogType.Info)
|
||||||
{
|
{
|
||||||
|
// 检查日志是否启用
|
||||||
|
if (MainWindow.Settings != null && MainWindow.Settings.Advanced != null && !MainWindow.Settings.Advanced.IsLogEnabled) return;
|
||||||
|
|
||||||
string strLogType = logType.ToString();
|
string strLogType = logType.ToString();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var file = App.RootPath + LogFile;
|
string file;
|
||||||
|
|
||||||
|
// 检查是否启用了日期保存功能
|
||||||
|
if (MainWindow.Settings != null && MainWindow.Settings.Advanced != null && MainWindow.Settings.Advanced.IsSaveLogByDate)
|
||||||
|
{
|
||||||
|
// 确保Logs文件夹存在
|
||||||
|
string logsPath = Path.Combine(App.RootPath, LogsFolder);
|
||||||
|
if (!Directory.Exists(logsPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(logsPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查Logs文件夹大小,如果超过5MB则清空
|
||||||
|
CheckAndCleanLogsFolder(logsPath);
|
||||||
|
|
||||||
|
// 使用软件启动时间作为日志文件名
|
||||||
|
file = Path.Combine(logsPath, $"Log_{AppStartTime}.txt");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file = App.RootPath + LogFile;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Directory.Exists(App.RootPath))
|
if (!Directory.Exists(App.RootPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(App.RootPath);
|
Directory.CreateDirectory(App.RootPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
var threadId = Thread.CurrentThread.ManagedThreadId;
|
var threadId = Thread.CurrentThread.ManagedThreadId;
|
||||||
var callingMethod = new StackTrace(2, true).GetFrame(0);
|
var callingMethod = new StackTrace(2, true).GetFrame(0);
|
||||||
string callerInfo = "<unknown>";
|
string callerInfo = "<unknown>";
|
||||||
@@ -57,6 +86,45 @@ namespace Ink_Canvas.Helpers
|
|||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void CheckAndCleanLogsFolder(string logsPath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
long totalSize = 0;
|
||||||
|
DirectoryInfo dirInfo = new DirectoryInfo(logsPath);
|
||||||
|
|
||||||
|
// 如果目录不存在,直接返回
|
||||||
|
if (!dirInfo.Exists) return;
|
||||||
|
|
||||||
|
// 计算文件夹大小
|
||||||
|
foreach (FileInfo file in dirInfo.GetFiles())
|
||||||
|
{
|
||||||
|
totalSize += file.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果超过5MB,清空文件夹
|
||||||
|
if (totalSize > MaxLogsFolderSizeBytes)
|
||||||
|
{
|
||||||
|
foreach (FileInfo file in dirInfo.GetFiles())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
file.Delete();
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录清理操作
|
||||||
|
string cleanupMessage = $"Logs folder exceeded size limit ({totalSize / 1024.0 / 1024.0:F2} MB > {MaxLogsFolderSizeBytes / 1024.0 / 1024.0:F2} MB). Folder cleaned.";
|
||||||
|
using (StreamWriter sw = new StreamWriter(Path.Combine(logsPath, $"Log_{AppStartTime}.txt"), true))
|
||||||
|
{
|
||||||
|
sw.WriteLine($"{DateTime.Now:O} [Cleanup] {cleanupMessage}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
internal static void WriteLogToFile(string v, object warning)
|
internal static void WriteLogToFile(string v, object warning)
|
||||||
{
|
{
|
||||||
WriteLogToFile($"[Warning] {v}", LogType.Warning);
|
WriteLogToFile($"[Warning] {v}", LogType.Warning);
|
||||||
|
|||||||
@@ -970,7 +970,15 @@
|
|||||||
<TextBlock Foreground="#fafafa" Text="{Binding ElementName=LineStraightenSensitivitySlider, Path=Value, StringFormat={}{0:F2}}"
|
<TextBlock Foreground="#fafafa" Text="{Binding ElementName=LineStraightenSensitivitySlider, Path=Value, StringFormat={}{0:F2}}"
|
||||||
VerticalAlignment="Center" FontSize="14" Margin="16,0,0,0" />
|
VerticalAlignment="Center" FontSize="14" Margin="16,0,0,0" />
|
||||||
</ui:SimpleStackPanel>
|
</ui:SimpleStackPanel>
|
||||||
<TextBlock Text="# 开启后,当绘制的直线超过设定长度阈值时,将自动调整为完美直线。灵敏度范围0.05-2.0,越小要求越严格,弯曲的线条越不容易被拉直;值越大越容易识别为直线。" TextWrapping="Wrap" Foreground="#a1a1aa" />
|
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left"
|
||||||
|
Visibility="{Binding ElementName=ToggleSwitchAutoStraightenLine, Path=IsOn, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
|
<TextBlock Foreground="#fafafa" Text="高精度直线拉直" VerticalAlignment="Center"
|
||||||
|
FontSize="14" Margin="0,0,16,0" />
|
||||||
|
<ui:ToggleSwitch OnContent="" OffContent="" Name="ToggleSwitchHighPrecisionLineStraighten"
|
||||||
|
IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||||
|
Toggled="ToggleSwitchHighPrecisionLineStraighten_Toggled" />
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
|
<TextBlock Text="# 开启后,当绘制的直线超过设定长度阈值时,将自动调整为完美直线。灵敏度范围0.05-2.0,越小要求越严格,弯曲的线条越不容易被拉直;值越大越容易识别为直线。高精度模式下,每隔10像素取一个计数点,获取更准确的平均值用于判断。" TextWrapping="Wrap" Foreground="#a1a1aa" />
|
||||||
<Line HorizontalAlignment="Center" X1="0" Y1="0" X2="400" Y2="0"
|
<Line HorizontalAlignment="Center" X1="0" Y1="0" X2="400" Y2="0"
|
||||||
Stroke="#3f3f46" StrokeThickness="1" Margin="0,4,0,4" />
|
Stroke="#3f3f46" StrokeThickness="1" Margin="0,4,0,4" />
|
||||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
@@ -1693,7 +1701,14 @@
|
|||||||
IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||||
Toggled="ToggleSwitchIsLogEnabled_Toggled" />
|
Toggled="ToggleSwitchIsLogEnabled_Toggled" />
|
||||||
</ui:SimpleStackPanel>
|
</ui:SimpleStackPanel>
|
||||||
<TextBlock Text="# 日志文件超过 512 KB 时会自动删除。" TextWrapping="Wrap" Foreground="#a1a1aa" />
|
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
|
<TextBlock Foreground="#fafafa" Text="日志以日期保存" VerticalAlignment="Center"
|
||||||
|
FontSize="14" Margin="0,0,16,0" />
|
||||||
|
<ui:ToggleSwitch OnContent="" OffContent="" Name="ToggleSwitchIsSaveLogByDate"
|
||||||
|
IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||||
|
Toggled="ToggleSwitchIsSaveLogByDate_Toggled" />
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
|
<TextBlock Text="# 日志文件超过 512 KB 时会自动删除。开启日期保存后,日志将保存在Logs文件夹中,当文件夹大小超过5MB时自动清空。" TextWrapping="Wrap" Foreground="#a1a1aa" />
|
||||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
<TextBlock Foreground="#fafafa" Text="关闭软件时二次弹窗确认" VerticalAlignment="Center"
|
<TextBlock Foreground="#fafafa" Text="关闭软件时二次弹窗确认" VerticalAlignment="Center"
|
||||||
FontSize="14" Margin="0,0,16,0" />
|
FontSize="14" Margin="0,0,16,0" />
|
||||||
@@ -2411,6 +2426,15 @@
|
|||||||
FontWeight="Bold"
|
FontWeight="Bold"
|
||||||
Toggled="ToggleSwitchShowRandomAndSingleDraw_Toggled" />
|
Toggled="ToggleSwitchShowRandomAndSingleDraw_Toggled" />
|
||||||
</ui:SimpleStackPanel>
|
</ui:SimpleStackPanel>
|
||||||
|
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
|
<TextBlock Foreground="#fafafa" Text="直接调用Ci点名"
|
||||||
|
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||||
|
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||||
|
Name="ToggleSwitchDirectCallCiRand"
|
||||||
|
IsOn="False" FontFamily="Microsoft YaHei UI"
|
||||||
|
FontWeight="Bold"
|
||||||
|
Toggled="ToggleSwitchDirectCallCiRand_Toggled" />
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
<Line HorizontalAlignment="Center" X1="0" Y1="0" X2="400" Y2="0"
|
<Line HorizontalAlignment="Center" X1="0" Y1="0" X2="400" Y2="0"
|
||||||
Stroke="#3f3f46" StrokeThickness="1" Margin="0,4,0,4" />
|
Stroke="#3f3f46" StrokeThickness="1" Margin="0,4,0,4" />
|
||||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
@@ -3641,7 +3665,7 @@
|
|||||||
TickFrequency="1" TickPlacement="None"
|
TickFrequency="1" TickPlacement="None"
|
||||||
ValueChanged="HighlighterWidthSlider_ValueChanged" />
|
ValueChanged="HighlighterWidthSlider_ValueChanged" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{Binding Value, ElementName=HighlighterWidthSlider, Mode=OneWay}"
|
Text="{Binding Value, ElementName=BoardHighlighterWidthSlider, Mode=OneWay}"
|
||||||
FontFamily="Consolas"
|
FontFamily="Consolas"
|
||||||
VerticalAlignment="Bottom"
|
VerticalAlignment="Bottom"
|
||||||
Margin="10,0,0,4.5" FontSize="15" />
|
Margin="10,0,0,4.5" FontSize="15" />
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ namespace Ink_Canvas {
|
|||||||
if (string.IsNullOrEmpty(releaseNotes))
|
if (string.IsNullOrEmpty(releaseNotes))
|
||||||
{
|
{
|
||||||
releaseNotes = $@"# InkCanvasForClass v{AvailableLatestVersion}更新
|
releaseNotes = $@"# InkCanvasForClass v{AvailableLatestVersion}更新
|
||||||
|
|
||||||
无法获取更新日志,但新版本已准备就绪。";
|
无法获取更新日志,但新版本已准备就绪。";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ using System.Text;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox;
|
||||||
|
|
||||||
namespace Ink_Canvas {
|
namespace Ink_Canvas {
|
||||||
public partial class MainWindow : Window {
|
public partial class MainWindow : Window {
|
||||||
@@ -825,7 +826,24 @@ namespace Ink_Canvas {
|
|||||||
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
||||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||||
|
|
||||||
new RandWindow(Settings, true).ShowDialog();
|
// 检查是否启用了直接调用ClassIsland点名功能
|
||||||
|
if (Settings.RandSettings.DirectCallCiRand) {
|
||||||
|
try {
|
||||||
|
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo {
|
||||||
|
FileName = "classisland://plugins/IslandCaller/Run",
|
||||||
|
UseShellExecute = true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
MessageBox.Show("无法调用ClassIsland点名:" + ex.Message);
|
||||||
|
|
||||||
|
// 调用失败时回退到默认的随机点名窗口
|
||||||
|
new RandWindow(Settings, true).ShowDialog();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 使用默认的随机点名窗口
|
||||||
|
new RandWindow(Settings, true).ShowDialog();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GridInkReplayButton_MouseUp(object sender, MouseButtonEventArgs e) {
|
private void GridInkReplayButton_MouseUp(object sender, MouseButtonEventArgs e) {
|
||||||
|
|||||||
@@ -782,6 +782,14 @@ namespace Ink_Canvas {
|
|||||||
// 立即保存设置到文件,确保设置不会丢失
|
// 立即保存设置到文件,确保设置不会丢失
|
||||||
SaveSettingsToFile();
|
SaveSettingsToFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ToggleSwitchHighPrecisionLineStraighten_Toggled(object sender, RoutedEventArgs e) {
|
||||||
|
if (!isLoaded) return;
|
||||||
|
|
||||||
|
Settings.Canvas.HighPrecisionLineStraighten = ToggleSwitchHighPrecisionLineStraighten.IsOn;
|
||||||
|
System.Diagnostics.Debug.WriteLine($"HighPrecisionLineStraighten changed: {Settings.Canvas.HighPrecisionLineStraighten}");
|
||||||
|
SaveSettingsToFile();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -1724,6 +1732,12 @@ namespace Ink_Canvas {
|
|||||||
Settings.Advanced.IsLogEnabled = ToggleSwitchIsLogEnabled.IsOn;
|
Settings.Advanced.IsLogEnabled = ToggleSwitchIsLogEnabled.IsOn;
|
||||||
SaveSettingsToFile();
|
SaveSettingsToFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ToggleSwitchIsSaveLogByDate_Toggled(object sender, RoutedEventArgs e) {
|
||||||
|
if (!isLoaded) return;
|
||||||
|
Settings.Advanced.IsSaveLogByDate = ToggleSwitchIsSaveLogByDate.IsOn;
|
||||||
|
SaveSettingsToFile();
|
||||||
|
}
|
||||||
|
|
||||||
private void ToggleSwitchIsSecondConfimeWhenShutdownApp_Toggled(object sender, RoutedEventArgs e) {
|
private void ToggleSwitchIsSecondConfimeWhenShutdownApp_Toggled(object sender, RoutedEventArgs e) {
|
||||||
if (!isLoaded) return;
|
if (!isLoaded) return;
|
||||||
@@ -1769,6 +1783,16 @@ namespace Ink_Canvas {
|
|||||||
// 保存设置到文件
|
// 保存设置到文件
|
||||||
SaveSettingsToFile();
|
SaveSettingsToFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ToggleSwitchDirectCallCiRand_Toggled(object sender, RoutedEventArgs e) {
|
||||||
|
if (!isLoaded) return;
|
||||||
|
|
||||||
|
// 获取开关状态并保存到设置中
|
||||||
|
Settings.RandSettings.DirectCallCiRand = ToggleSwitchDirectCallCiRand.IsOn;
|
||||||
|
|
||||||
|
// 保存设置到文件
|
||||||
|
SaveSettingsToFile();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -533,6 +533,8 @@ namespace Ink_Canvas {
|
|||||||
AutoStraightenLineThresholdSlider.Value = Settings.Canvas.AutoStraightenLineThreshold;
|
AutoStraightenLineThresholdSlider.Value = Settings.Canvas.AutoStraightenLineThreshold;
|
||||||
// 直线拉直灵敏度也在这里初始化,即使它存储在InkToShape中
|
// 直线拉直灵敏度也在这里初始化,即使它存储在InkToShape中
|
||||||
LineStraightenSensitivitySlider.Value = Settings.InkToShape.LineStraightenSensitivity;
|
LineStraightenSensitivitySlider.Value = Settings.InkToShape.LineStraightenSensitivity;
|
||||||
|
// 初始化高精度直线拉直设置
|
||||||
|
ToggleSwitchHighPrecisionLineStraighten.IsOn = Settings.Canvas.HighPrecisionLineStraighten;
|
||||||
|
|
||||||
// 初始化直线端点吸附相关设置
|
// 初始化直线端点吸附相关设置
|
||||||
ToggleSwitchLineEndpointSnapping.IsOn = Settings.Canvas.LineEndpointSnapping;
|
ToggleSwitchLineEndpointSnapping.IsOn = Settings.Canvas.LineEndpointSnapping;
|
||||||
@@ -547,41 +549,30 @@ namespace Ink_Canvas {
|
|||||||
FingerModeBoundsWidthSlider.Value = Settings.Advanced.FingerModeBoundsWidth;
|
FingerModeBoundsWidthSlider.Value = Settings.Advanced.FingerModeBoundsWidth;
|
||||||
NibModeBoundsWidthSlider.Value = Settings.Advanced.NibModeBoundsWidth;
|
NibModeBoundsWidthSlider.Value = Settings.Advanced.NibModeBoundsWidth;
|
||||||
ToggleSwitchIsLogEnabled.IsOn = Settings.Advanced.IsLogEnabled;
|
ToggleSwitchIsLogEnabled.IsOn = Settings.Advanced.IsLogEnabled;
|
||||||
|
ToggleSwitchIsSaveLogByDate.IsOn = Settings.Advanced.IsSaveLogByDate;
|
||||||
ToggleSwitchIsSecondConfimeWhenShutdownApp.IsOn = Settings.Advanced.IsSecondConfirmWhenShutdownApp;
|
ToggleSwitchIsSecondConfimeWhenShutdownApp.IsOn = Settings.Advanced.IsSecondConfirmWhenShutdownApp;
|
||||||
|
|
||||||
ToggleSwitchEraserBindTouchMultiplier.IsOn = Settings.Advanced.EraserBindTouchMultiplier;
|
|
||||||
|
|
||||||
ToggleSwitchIsSpecialScreen.IsOn = Settings.Advanced.IsSpecialScreen;
|
ToggleSwitchIsSpecialScreen.IsOn = Settings.Advanced.IsSpecialScreen;
|
||||||
|
|
||||||
TouchMultiplierSlider.Visibility =
|
|
||||||
ToggleSwitchIsSpecialScreen.IsOn ? Visibility.Visible : Visibility.Collapsed;
|
|
||||||
|
|
||||||
ToggleSwitchIsQuadIR.IsOn = Settings.Advanced.IsQuadIR;
|
ToggleSwitchIsQuadIR.IsOn = Settings.Advanced.IsQuadIR;
|
||||||
|
ToggleSwitchEraserBindTouchMultiplier.IsOn = Settings.Advanced.EraserBindTouchMultiplier;
|
||||||
ToggleSwitchIsEnableFullScreenHelper.IsOn = Settings.Advanced.IsEnableFullScreenHelper;
|
ToggleSwitchIsEnableFullScreenHelper.IsOn = Settings.Advanced.IsEnableFullScreenHelper;
|
||||||
|
ToggleSwitchIsEnableEdgeGestureUtil.IsOn = Settings.Advanced.IsEnableEdgeGestureUtil;
|
||||||
|
ToggleSwitchIsEnableForceFullScreen.IsOn = Settings.Advanced.IsEnableForceFullScreen;
|
||||||
|
ToggleSwitchIsEnableResolutionChangeDetection.IsOn = Settings.Advanced.IsEnableResolutionChangeDetection;
|
||||||
|
ToggleSwitchIsEnableDPIChangeDetection.IsOn = Settings.Advanced.IsEnableDPIChangeDetection;
|
||||||
|
ToggleSwitchIsEnableAvoidFullScreenHelper.IsOn = Settings.Advanced.IsEnableAvoidFullScreenHelper;
|
||||||
if (Settings.Advanced.IsEnableFullScreenHelper) {
|
if (Settings.Advanced.IsEnableFullScreenHelper) {
|
||||||
FullScreenHelper.MarkFullscreenWindowTaskbarList(new WindowInteropHelper(this).Handle, true);
|
FullScreenHelper.MarkFullscreenWindowTaskbarList(new WindowInteropHelper(this).Handle, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ToggleSwitchIsEnableAvoidFullScreenHelper.IsOn = Settings.Advanced.IsEnableAvoidFullScreenHelper;
|
|
||||||
if (Settings.Advanced.IsEnableAvoidFullScreenHelper)
|
if (Settings.Advanced.IsEnableAvoidFullScreenHelper)
|
||||||
{
|
{
|
||||||
AvoidFullScreenHelper.StartAvoidFullScreen(this);
|
AvoidFullScreenHelper.StartAvoidFullScreen(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ToggleSwitchIsEnableEdgeGestureUtil.IsOn = Settings.Advanced.IsEnableEdgeGestureUtil;
|
|
||||||
if (Settings.Advanced.IsEnableEdgeGestureUtil) {
|
if (Settings.Advanced.IsEnableEdgeGestureUtil) {
|
||||||
if (OSVersion.GetOperatingSystem() >= OperatingSystem.Windows10)
|
if (OSVersion.GetOperatingSystem() >= OperatingSystem.Windows10)
|
||||||
EdgeGestureUtil.DisableEdgeGestures(new WindowInteropHelper(this).Handle, true);
|
EdgeGestureUtil.DisableEdgeGestures(new WindowInteropHelper(this).Handle, true);
|
||||||
}
|
}
|
||||||
|
TouchMultiplierSlider.Visibility =
|
||||||
ToggleSwitchIsEnableForceFullScreen.IsOn = Settings.Advanced.IsEnableForceFullScreen;
|
ToggleSwitchIsSpecialScreen.IsOn ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
|
||||||
ToggleSwitchIsEnableDPIChangeDetection.IsOn = Settings.Advanced.IsEnableDPIChangeDetection;
|
|
||||||
|
|
||||||
ToggleSwitchIsEnableResolutionChangeDetection.IsOn =
|
|
||||||
Settings.Advanced.IsEnableResolutionChangeDetection;
|
|
||||||
} else {
|
} else {
|
||||||
Settings.Advanced = new Advanced();
|
Settings.Advanced = new Advanced();
|
||||||
}
|
}
|
||||||
@@ -613,6 +604,7 @@ namespace Ink_Canvas {
|
|||||||
RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency;
|
RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency;
|
||||||
RandWindowOnceMaxStudentsSlider.Value = Settings.RandSettings.RandWindowOnceMaxStudents;
|
RandWindowOnceMaxStudentsSlider.Value = Settings.RandSettings.RandWindowOnceMaxStudents;
|
||||||
ToggleSwitchShowRandomAndSingleDraw.IsOn = Settings.RandSettings.ShowRandomAndSingleDraw;
|
ToggleSwitchShowRandomAndSingleDraw.IsOn = Settings.RandSettings.ShowRandomAndSingleDraw;
|
||||||
|
ToggleSwitchDirectCallCiRand.IsOn = Settings.RandSettings.DirectCallCiRand;
|
||||||
RandomDrawPanel.Visibility = Settings.RandSettings.ShowRandomAndSingleDraw ? Visibility.Visible : Visibility.Collapsed;
|
RandomDrawPanel.Visibility = Settings.RandSettings.ShowRandomAndSingleDraw ? Visibility.Visible : Visibility.Collapsed;
|
||||||
SingleDrawPanel.Visibility = Settings.RandSettings.ShowRandomAndSingleDraw ? Visibility.Visible : Visibility.Collapsed;
|
SingleDrawPanel.Visibility = Settings.RandSettings.ShowRandomAndSingleDraw ? Visibility.Visible : Visibility.Collapsed;
|
||||||
} else {
|
} else {
|
||||||
@@ -620,6 +612,7 @@ namespace Ink_Canvas {
|
|||||||
ToggleSwitchDisplayRandWindowNamesInputBtn.IsOn = Settings.RandSettings.DisplayRandWindowNamesInputBtn;
|
ToggleSwitchDisplayRandWindowNamesInputBtn.IsOn = Settings.RandSettings.DisplayRandWindowNamesInputBtn;
|
||||||
RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency;
|
RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency;
|
||||||
RandWindowOnceMaxStudentsSlider.Value = Settings.RandSettings.RandWindowOnceMaxStudents;
|
RandWindowOnceMaxStudentsSlider.Value = Settings.RandSettings.RandWindowOnceMaxStudents;
|
||||||
|
ToggleSwitchDirectCallCiRand.IsOn = Settings.RandSettings.DirectCallCiRand;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automation
|
// Automation
|
||||||
|
|||||||
@@ -687,20 +687,97 @@ namespace Ink_Canvas {
|
|||||||
double totalDeviation = 0;
|
double totalDeviation = 0;
|
||||||
int pointCount = 0;
|
int pointCount = 0;
|
||||||
|
|
||||||
// Calculate deviation for each point
|
// 检查是否启用了高精度直线拉直
|
||||||
foreach (StylusPoint sp in stroke.StylusPoints) {
|
bool useHighPrecision = Settings.Canvas.HighPrecisionLineStraighten;
|
||||||
Point p = sp.ToPoint();
|
|
||||||
double deviation = DistanceFromLineToPoint(start, end, p);
|
if (useHighPrecision) {
|
||||||
maxDeviation = Math.Max(maxDeviation, deviation);
|
System.Diagnostics.Debug.WriteLine("使用高精度直线拉直模式");
|
||||||
totalDeviation += deviation;
|
|
||||||
pointCount++;
|
// 高精度模式:每隔10像素取一个计数点
|
||||||
|
double strokeLength = 0;
|
||||||
|
double sampleInterval = 10.0; // 10像素间隔
|
||||||
|
|
||||||
|
// 计算笔画的总长度,用于后续采样
|
||||||
|
for (int i = 1; i < stroke.StylusPoints.Count; i++) {
|
||||||
|
Point p1 = stroke.StylusPoints[i-1].ToPoint();
|
||||||
|
Point p2 = stroke.StylusPoints[i].ToPoint();
|
||||||
|
strokeLength += GetDistance(p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果笔画太短,直接使用所有点
|
||||||
|
if (strokeLength < sampleInterval * 5) {
|
||||||
|
foreach (StylusPoint sp in stroke.StylusPoints) {
|
||||||
|
Point p = sp.ToPoint();
|
||||||
|
double deviation = DistanceFromLineToPoint(start, end, p);
|
||||||
|
maxDeviation = Math.Max(maxDeviation, deviation);
|
||||||
|
totalDeviation += deviation;
|
||||||
|
pointCount++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 使用等距采样点
|
||||||
|
double currentLength = 0;
|
||||||
|
double nextSampleAt = 0;
|
||||||
|
|
||||||
|
// 总是包含起点
|
||||||
|
Point lastPoint = start;
|
||||||
|
double deviation = DistanceFromLineToPoint(start, end, lastPoint);
|
||||||
|
maxDeviation = Math.Max(maxDeviation, deviation);
|
||||||
|
totalDeviation += deviation;
|
||||||
|
pointCount++;
|
||||||
|
|
||||||
|
// 采样中间点
|
||||||
|
for (int i = 1; i < stroke.StylusPoints.Count; i++) {
|
||||||
|
Point currentPoint = stroke.StylusPoints[i].ToPoint();
|
||||||
|
double segmentLength = GetDistance(lastPoint, currentPoint);
|
||||||
|
|
||||||
|
// 如果这段线段跨越了下一个采样点
|
||||||
|
while (currentLength + segmentLength >= nextSampleAt) {
|
||||||
|
// 计算采样点在线段上的位置
|
||||||
|
double t = (nextSampleAt - currentLength) / segmentLength;
|
||||||
|
Point samplePoint = new Point(
|
||||||
|
lastPoint.X + t * (currentPoint.X - lastPoint.X),
|
||||||
|
lastPoint.Y + t * (currentPoint.Y - lastPoint.Y)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 计算采样点的偏差
|
||||||
|
deviation = DistanceFromLineToPoint(start, end, samplePoint);
|
||||||
|
maxDeviation = Math.Max(maxDeviation, deviation);
|
||||||
|
totalDeviation += deviation;
|
||||||
|
pointCount++;
|
||||||
|
|
||||||
|
// 设置下一个采样点位置
|
||||||
|
nextSampleAt += sampleInterval;
|
||||||
|
|
||||||
|
// 防止无限循环
|
||||||
|
if (nextSampleAt > strokeLength) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLength += segmentLength;
|
||||||
|
lastPoint = currentPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 总是包含终点
|
||||||
|
deviation = DistanceFromLineToPoint(start, end, end);
|
||||||
|
maxDeviation = Math.Max(maxDeviation, deviation);
|
||||||
|
totalDeviation += deviation;
|
||||||
|
pointCount++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 原始模式:使用所有点
|
||||||
|
foreach (StylusPoint sp in stroke.StylusPoints) {
|
||||||
|
Point p = sp.ToPoint();
|
||||||
|
double deviation = DistanceFromLineToPoint(start, end, p);
|
||||||
|
maxDeviation = Math.Max(maxDeviation, deviation);
|
||||||
|
totalDeviation += deviation;
|
||||||
|
pointCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算平均偏差
|
// 计算平均偏差
|
||||||
double avgDeviation = totalDeviation / pointCount;
|
double avgDeviation = totalDeviation / pointCount;
|
||||||
|
|
||||||
// 更详细的调试信息
|
// 更详细的调试信息
|
||||||
System.Diagnostics.Debug.WriteLine($"Max deviation: {maxDeviation}, Avg: {avgDeviation}, Threshold: {sensitivity * lineLength}");
|
System.Diagnostics.Debug.WriteLine($"Max deviation: {maxDeviation}, Avg: {avgDeviation}, Threshold: {sensitivity * lineLength}, Points: {pointCount}");
|
||||||
|
|
||||||
// 支持更广泛的灵敏度范围 (0.05-2.0)
|
// 支持更广泛的灵敏度范围 (0.05-2.0)
|
||||||
|
|
||||||
@@ -722,11 +799,79 @@ namespace Ink_Canvas {
|
|||||||
else {
|
else {
|
||||||
// 检查点分布的一致性 - 如果有些点偏离很大而其他点很接近直线,表明线条有明显弯曲
|
// 检查点分布的一致性 - 如果有些点偏离很大而其他点很接近直线,表明线条有明显弯曲
|
||||||
double deviationVariance = 0;
|
double deviationVariance = 0;
|
||||||
foreach (StylusPoint sp in stroke.StylusPoints) {
|
|
||||||
Point p = sp.ToPoint();
|
// 使用相同的高精度/原始模式来计算方差
|
||||||
double deviation = DistanceFromLineToPoint(start, end, p);
|
if (useHighPrecision) {
|
||||||
deviationVariance += Math.Pow(deviation - avgDeviation, 2);
|
// 高精度模式:重新采样计算方差
|
||||||
|
double strokeLength = 0;
|
||||||
|
double sampleInterval = 10.0; // 10像素间隔
|
||||||
|
|
||||||
|
// 计算笔画的总长度,用于后续采样
|
||||||
|
for (int i = 1; i < stroke.StylusPoints.Count; i++) {
|
||||||
|
Point p1 = stroke.StylusPoints[i-1].ToPoint();
|
||||||
|
Point p2 = stroke.StylusPoints[i].ToPoint();
|
||||||
|
strokeLength += GetDistance(p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果笔画太短,直接使用所有点
|
||||||
|
if (strokeLength < sampleInterval * 5) {
|
||||||
|
foreach (StylusPoint sp in stroke.StylusPoints) {
|
||||||
|
Point p = sp.ToPoint();
|
||||||
|
double deviation = DistanceFromLineToPoint(start, end, p);
|
||||||
|
deviationVariance += Math.Pow(deviation - avgDeviation, 2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 使用等距采样点
|
||||||
|
double currentLength = 0;
|
||||||
|
double nextSampleAt = 0;
|
||||||
|
Point lastPoint = start;
|
||||||
|
|
||||||
|
// 起点方差
|
||||||
|
double deviation = DistanceFromLineToPoint(start, end, lastPoint);
|
||||||
|
deviationVariance += Math.Pow(deviation - avgDeviation, 2);
|
||||||
|
|
||||||
|
// 采样中间点
|
||||||
|
for (int i = 1; i < stroke.StylusPoints.Count; i++) {
|
||||||
|
Point currentPoint = stroke.StylusPoints[i].ToPoint();
|
||||||
|
double segmentLength = GetDistance(lastPoint, currentPoint);
|
||||||
|
|
||||||
|
// 如果这段线段跨越了下一个采样点
|
||||||
|
while (currentLength + segmentLength >= nextSampleAt) {
|
||||||
|
// 计算采样点在线段上的位置
|
||||||
|
double t = (nextSampleAt - currentLength) / segmentLength;
|
||||||
|
Point samplePoint = new Point(
|
||||||
|
lastPoint.X + t * (currentPoint.X - lastPoint.X),
|
||||||
|
lastPoint.Y + t * (currentPoint.Y - lastPoint.Y)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 计算采样点的方差
|
||||||
|
deviation = DistanceFromLineToPoint(start, end, samplePoint);
|
||||||
|
deviationVariance += Math.Pow(deviation - avgDeviation, 2);
|
||||||
|
|
||||||
|
// 设置下一个采样点位置
|
||||||
|
nextSampleAt += sampleInterval;
|
||||||
|
|
||||||
|
// 防止无限循环
|
||||||
|
if (nextSampleAt > strokeLength) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentLength += segmentLength;
|
||||||
|
lastPoint = currentPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 终点方差
|
||||||
|
deviation = DistanceFromLineToPoint(start, end, end);
|
||||||
|
deviationVariance += Math.Pow(deviation - avgDeviation, 2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 原始模式:使用所有点计算方差
|
||||||
|
foreach (StylusPoint sp in stroke.StylusPoints) {
|
||||||
|
Point p = sp.ToPoint();
|
||||||
|
double deviation = DistanceFromLineToPoint(start, end, p);
|
||||||
|
deviationVariance += Math.Pow(deviation - avgDeviation, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deviationVariance /= pointCount;
|
deviationVariance /= pointCount;
|
||||||
|
|
||||||
// 输出更多调试信息
|
// 输出更多调试信息
|
||||||
|
|||||||
@@ -49,5 +49,5 @@ using System.Windows;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.7.0.0")]
|
[assembly: AssemblyVersion("1.7.0.1")]
|
||||||
[assembly: AssemblyFileVersion("1.7.0.0")]
|
[assembly: AssemblyFileVersion("1.7.0.1")]
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ namespace Ink_Canvas
|
|||||||
public bool AutoStraightenLine { get; set; } = true; // 是否启用直线自动拉直
|
public bool AutoStraightenLine { get; set; } = true; // 是否启用直线自动拉直
|
||||||
[JsonProperty("autoStraightenLineThreshold")]
|
[JsonProperty("autoStraightenLineThreshold")]
|
||||||
public int AutoStraightenLineThreshold { get; set; } = 30; // 直线自动拉直的长度阈值(像素)
|
public int AutoStraightenLineThreshold { get; set; } = 30; // 直线自动拉直的长度阈值(像素)
|
||||||
|
[JsonProperty("highPrecisionLineStraighten")]
|
||||||
|
public bool HighPrecisionLineStraighten { get; set; } = true; // 是否启用高精度直线拉直
|
||||||
[JsonProperty("lineEndpointSnapping")]
|
[JsonProperty("lineEndpointSnapping")]
|
||||||
public bool LineEndpointSnapping { get; set; } = true; // 是否启用直线端点吸附
|
public bool LineEndpointSnapping { get; set; } = true; // 是否启用直线端点吸附
|
||||||
[JsonProperty("lineEndpointSnappingThreshold")]
|
[JsonProperty("lineEndpointSnappingThreshold")]
|
||||||
@@ -381,6 +383,9 @@ namespace Ink_Canvas
|
|||||||
|
|
||||||
[JsonProperty("isLogEnabled")]
|
[JsonProperty("isLogEnabled")]
|
||||||
public bool IsLogEnabled { get; set; } = true;
|
public bool IsLogEnabled { get; set; } = true;
|
||||||
|
|
||||||
|
[JsonProperty("isSaveLogByDate")]
|
||||||
|
public bool IsSaveLogByDate { get; set; } = true;
|
||||||
|
|
||||||
[JsonProperty("isEnableFullScreenHelper")]
|
[JsonProperty("isEnableFullScreenHelper")]
|
||||||
public bool IsEnableFullScreenHelper { get; set; } = false;
|
public bool IsEnableFullScreenHelper { get; set; } = false;
|
||||||
@@ -434,5 +439,7 @@ namespace Ink_Canvas
|
|||||||
public int RandWindowOnceMaxStudents { get; set; } = 10;
|
public int RandWindowOnceMaxStudents { get; set; } = 10;
|
||||||
[JsonProperty("showRandomAndSingleDraw")]
|
[JsonProperty("showRandomAndSingleDraw")]
|
||||||
public bool ShowRandomAndSingleDraw { get; set; } = true;
|
public bool ShowRandomAndSingleDraw { get; set; } = true;
|
||||||
|
[JsonProperty("directCallCiRand")]
|
||||||
|
public bool DirectCallCiRand { get; set; } = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.5 KiB |
Reference in New Issue
Block a user