From 11a5a7fdbe4d375acd17fe0616654754abdd6dcc Mon Sep 17 00:00:00 2001 From: PrefacedCorg <1876568293@qq.com> Date: Sun, 3 Aug 2025 16:46:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/App.xaml.cs | 159 ++-- Ink Canvas/Helpers/AdvancedBezierSmoothing.cs | 2 +- Ink Canvas/Helpers/AutoUpdateHelper.cs | 202 ++--- Ink Canvas/Helpers/AvoidFullScreenHelper.cs | 28 +- Ink Canvas/Helpers/DelAutoSavedFiles.cs | 47 +- Ink Canvas/Helpers/DelayActionHelper.cs | 9 +- Ink Canvas/Helpers/DeviceIdentifier.cs | 38 +- Ink Canvas/Helpers/ForegroundWindowInfo.cs | 25 +- Ink Canvas/Helpers/FullScreenHelper.Win32.cs | 4 +- Ink Canvas/Helpers/FullScreenHelper.cs | 16 +- .../HardwareAcceleratedInkProcessor.cs | 46 +- Ink Canvas/Helpers/IACoreDllExtractor.cs | 11 +- Ink Canvas/Helpers/InkSmoothingManager.cs | 14 +- Ink Canvas/Helpers/IsOutsideOfScreenHelper.cs | 15 +- Ink Canvas/Helpers/LogHelper.cs | 20 +- Ink Canvas/Helpers/PPTInkManager.cs | 26 +- Ink Canvas/Helpers/PPTManager.cs | 13 +- Ink Canvas/Helpers/PPTUIManager.cs | 24 +- .../BuiltIn/SuperLauncher/LauncherButton.cs | 78 +- .../BuiltIn/SuperLauncher/LauncherModels.cs | 66 +- .../LauncherSettingsControl.xaml.cs | 162 ++-- .../SuperLauncher/LauncherWindow.xaml.cs | 152 ++-- .../Plugins/BuiltIn/SuperLauncherPlugin.cs | 174 ++-- .../Helpers/Plugins/ICCPPPluginAdapter.cs | 48 +- Ink Canvas/Helpers/Plugins/IPlugin.cs | 20 +- Ink Canvas/Helpers/Plugins/PluginBase.cs | 20 +- Ink Canvas/Helpers/Plugins/PluginManager.cs | 350 ++++---- Ink Canvas/Helpers/Plugins/PluginTemplate.cs | 36 +- Ink Canvas/Helpers/SoftwareLauncher.cs | 4 +- Ink Canvas/Helpers/WinTabWindowsChecker.cs | 31 +- Ink Canvas/MainWindow.xaml.cs | 468 ++++++---- Ink Canvas/MainWindow_cs/MW_AutoFold.cs | 128 ++- Ink Canvas/MainWindow_cs/MW_AutoStart.cs | 22 +- Ink Canvas/MainWindow_cs/MW_AutoTheme.cs | 47 +- Ink Canvas/MainWindow_cs/MW_BoardControls.cs | 144 +-- Ink Canvas/MainWindow_cs/MW_BoardIcons.cs | 706 +++++++-------- .../MainWindow_cs/MW_ClipboardHandler.cs | 8 +- Ink Canvas/MainWindow_cs/MW_Colors.cs | 195 +++-- .../MainWindow_cs/MW_ElementsControls.cs | 6 +- Ink Canvas/MainWindow_cs/MW_Eraser.cs | 422 ++++++--- .../MainWindow_cs/MW_FloatingBarIcons.cs | 762 ++++++++++------ Ink Canvas/MainWindow_cs/MW_Hotkeys.cs | 63 +- Ink Canvas/MainWindow_cs/MW_Icons.cs | 6 +- Ink Canvas/MainWindow_cs/MW_Notification.cs | 25 +- Ink Canvas/MainWindow_cs/MW_PPT.cs | 151 ++-- Ink Canvas/MainWindow_cs/MW_PageListView.cs | 25 +- .../MainWindow_cs/MW_Save&OpenStrokes.cs | 345 +++++--- Ink Canvas/MainWindow_cs/MW_Screenshot.cs | 121 ++- .../MainWindow_cs/MW_SelectionGestures.cs | 151 ++-- Ink Canvas/MainWindow_cs/MW_Settings.cs | 826 +++++++++++------- Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs | 357 +++++--- Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs | 620 ++++++++----- .../MW_SimulatePressure&InkToShape.cs | 608 ++++++++----- Ink Canvas/MainWindow_cs/MW_TimeMachine.cs | 224 +++-- Ink Canvas/MainWindow_cs/MW_Timer.cs | 329 ++++--- Ink Canvas/MainWindow_cs/MW_TouchEvents.cs | 235 +++-- Ink Canvas/MainWindow_cs/MW_TrayIcon.cs | 100 ++- Ink Canvas/Resources/ChickenSoup.cs | 3 +- Ink Canvas/Resources/Settings.cs | 37 +- .../Windows/AddCustomIconWindow.xaml.cs | 32 +- .../AddPickNameBackgroundWindow.xaml.cs | 32 +- .../Windows/CountdownTimerWindow.xaml.cs | 9 +- Ink Canvas/Windows/CustomIconWindow.xaml.cs | 14 +- Ink Canvas/Windows/HasNewUpdateWindow.xaml.cs | 84 +- .../Windows/HistoryRollbackWindow.xaml.cs | 7 +- .../ManagePickNameBackgroundsWindow.xaml.cs | 22 +- Ink Canvas/Windows/NamesInputWindow.xaml.cs | 4 +- .../Windows/OperatingGuideWindow.xaml.cs | 19 +- .../Windows/PluginSettingsWindow.xaml.cs | 194 ++-- Ink Canvas/Windows/RandWindow.xaml.cs | 143 +-- .../Windows/ScreenshotSelectorWindow.xaml.cs | 53 +- .../Windows/YesOrNoNotificationWindow.xaml.cs | 3 +- ...vasForClass.csproj.AssemblyReference.cache | Bin 35374 -> 35446 bytes 73 files changed, 5733 insertions(+), 3857 deletions(-) diff --git a/Ink Canvas/App.xaml.cs b/Ink Canvas/App.xaml.cs index 299c22e5..e3ac9b51 100644 --- a/Ink Canvas/App.xaml.cs +++ b/Ink Canvas/App.xaml.cs @@ -1,3 +1,8 @@ +using Hardcodet.Wpf.TaskbarNotification; +using Ink_Canvas.Helpers; +using iNKORE.UI.WPF.Modern.Controls; +using Microsoft.Win32; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; @@ -13,11 +18,6 @@ using System.Windows; using System.Windows.Forms; using System.Windows.Input; using System.Windows.Threading; -using Hardcodet.Wpf.TaskbarNotification; -using Ink_Canvas.Helpers; -using iNKORE.UI.WPF.Modern.Controls; -using Microsoft.Win32; -using Newtonsoft.Json; using Application = System.Windows.Application; using MessageBox = System.Windows.MessageBox; using Timer = System.Threading.Timer; @@ -91,19 +91,19 @@ namespace Ink_Canvas // 检测操作系统版本 var osVersion = Environment.OSVersion; bool isWindows7 = osVersion.Version.Major == 6 && osVersion.Version.Minor == 1; - + if (isWindows7) { LogHelper.WriteLogToFile("检测到Windows 7系统,配置TLS协议支持"); - + // 启用所有TLS版本以支持Windows 7 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; - + // 配置ServicePointManager以支持Windows 7 ServicePointManager.DefaultConnectionLimit = 10; ServicePointManager.Expect100Continue = false; ServicePointManager.UseNagleAlgorithm = false; - + LogHelper.WriteLogToFile("TLS协议配置完成,已启用TLS 1.2/1.1/1.0支持"); } else @@ -122,7 +122,7 @@ namespace Ink_Canvas private void InitializeCrashListeners() { if (crashListenersInitialized) return; - + try { // 确保崩溃日志目录存在 @@ -130,22 +130,22 @@ namespace Ink_Canvas { Directory.CreateDirectory(crashLogFile); } - + // 注册非UI线程未处理异常处理程序 AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; - + // 注册控制台Ctrl+C等终止信号处理 Console.CancelKeyPress += Console_CancelKeyPress; - + // 注册系统会话结束事件(关机、注销等) SystemEvents.SessionEnding += SystemEvents_SessionEnding; - + // 注册进程退出处理程序 AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit; - + // 尝试注册Windows关闭消息监听 SetConsoleCtrlHandler(ConsoleCtrlHandler, true); - + // 如果系统支持,添加Windows Management Instrumentation监听器 try { @@ -156,7 +156,7 @@ namespace Ink_Canvas { LogHelper.WriteLogToFile($"设置WMI进程监控失败: {wmiEx.Message}", LogHelper.LogType.Warning); } - + crashListenersInitialized = true; LogHelper.WriteLogToFile("已初始化崩溃监听器"); } @@ -165,7 +165,7 @@ namespace Ink_Canvas LogHelper.WriteLogToFile($"初始化崩溃监听器失败: {ex.Message}", LogHelper.LogType.Error); } } - + // 新增:动态加载WMI监控(避免直接引用System.Management) private void TrySetupWmiMonitoring() { @@ -179,7 +179,7 @@ namespace Ink_Canvas LogHelper.WriteLogToFile("未找到System.Management程序集,跳过WMI监控", LogHelper.LogType.Warning); return; } - + // 使用反射创建WMI查询 var watcherType = assembly.GetType("System.Management.ManagementEventWatcher"); if (watcherType == null) @@ -187,13 +187,13 @@ namespace Ink_Canvas LogHelper.WriteLogToFile("未找到ManagementEventWatcher类型,跳过WMI监控", LogHelper.LogType.Warning); return; } - + // 构建WMI查询字符串 string queryString = $"SELECT * FROM __InstanceDeletionEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.ProcessId = {currentProcessId}"; - + // 创建ManagementEventWatcher实例 object watcher = Activator.CreateInstance(watcherType, queryString); - + // 获取EventArrived事件信息 var eventInfo = watcherType.GetEvent("EventArrived"); if (eventInfo == null) @@ -201,16 +201,16 @@ namespace Ink_Canvas LogHelper.WriteLogToFile("未找到EventArrived事件,跳过WMI监控", LogHelper.LogType.Warning); return; } - + // 创建委托并订阅事件 Type delegateType = eventInfo.EventHandlerType; var handler = Delegate.CreateDelegate(delegateType, this, GetType().GetMethod("WmiEventHandler", BindingFlags.NonPublic | BindingFlags.Instance)); eventInfo.AddEventHandler(watcher, handler); - + // 启动监听 var startMethod = watcherType.GetMethod("Start"); startMethod.Invoke(watcher, null); - + LogHelper.WriteLogToFile("已成功启动WMI进程监控"); } catch (Exception ex) @@ -218,7 +218,7 @@ namespace Ink_Canvas LogHelper.WriteLogToFile($"动态加载WMI监控失败: {ex.Message}", LogHelper.LogType.Warning); } } - + // WMI事件处理方法(通过反射调用) private void WmiEventHandler(object sender, EventArgs e) { @@ -246,13 +246,13 @@ namespace Ink_Canvas // 新增:Windows控制台控制处理程序 [DllImport("kernel32.dll", SetLastError = true)] private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate handler, bool add); - + private delegate bool ConsoleCtrlDelegate(int ctrlType); - + private static bool ConsoleCtrlHandler(int ctrlType) { string eventType = "未知控制类型"; - + // 使用传统switch语句替代switch表达式 switch (ctrlType) { @@ -275,27 +275,27 @@ namespace Ink_Canvas eventType = $"未知控制类型({ctrlType})"; break; } - + WriteCrashLog($"接收到系统控制信号: {eventType}"); - + // 返回true表示已处理该事件 return false; } - + // 新增:系统会话结束事件处理 private void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e) { string reason = e.Reason == SessionEndReasons.Logoff ? "用户注销" : "系统关机"; WriteCrashLog($"系统会话即将结束: {reason}"); } - + // 新增:控制台取消事件处理 private void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e) { WriteCrashLog($"接收到控制台中断信号: {e.SpecialKey}"); e.Cancel = true; // 取消默认处理 } - + // 新增:处理非UI线程的未处理异常 private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { @@ -304,9 +304,9 @@ namespace Ink_Canvas var exception = e.ExceptionObject as Exception; string errorMessage = exception?.ToString() ?? "未知异常"; lastErrorMessage = errorMessage; - + WriteCrashLog($"捕获到未处理的异常: {errorMessage}"); - + if (e.IsTerminating) { WriteCrashLog("应用程序即将终止"); @@ -325,20 +325,20 @@ namespace Ink_Canvas catch { } } } - + // 新增:处理进程退出事件 private void CurrentDomain_ProcessExit(object sender, EventArgs e) { TimeSpan runDuration = DateTime.Now - appStartTime; WriteCrashLog($"应用程序退出,运行时长: {runDuration}"); - + // 如果有最后错误消息,记录到日志 if (!string.IsNullOrEmpty(lastErrorMessage)) { WriteCrashLog($"最后错误信息: {lastErrorMessage}"); } } - + // 新增:记录崩溃日志 private static void WriteCrashLog(string message) { @@ -349,22 +349,22 @@ namespace Ink_Canvas { Directory.CreateDirectory(crashLogFile); } - + string logFileName = Path.Combine(crashLogFile, $"crash_{DateTime.Now:yyyyMMdd}.log"); - + // 收集系统状态信息 string memoryUsage = (Process.GetCurrentProcess().WorkingSet64 / (1024 * 1024)) + " MB"; string cpuTime = Process.GetCurrentProcess().TotalProcessorTime.ToString(); string processUptime = (DateTime.Now - Process.GetCurrentProcess().StartTime).ToString(); - + string statusInfo = $"[内存: {memoryUsage}, CPU时间: {cpuTime}, 运行时长: {processUptime}]"; - + // 写入日志 File.AppendAllText( logFileName, $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [PID:{currentProcessId}] {message}\r\n{statusInfo}\r\n\r\n" ); - + // 同时记录到主日志 LogHelper.WriteLogToFile(message, LogHelper.LogType.Error); } @@ -402,11 +402,11 @@ namespace Ink_Canvas { Ink_Canvas.MainWindow.ShowNewMessage("抱歉,出现未预期的异常,可能导致 InkCanvasForClass 运行不稳定。\n建议保存墨迹后重启应用。"); LogHelper.NewLog(e.Exception.ToString()); - + // 新增:记录到崩溃日志 lastErrorMessage = e.Exception.ToString(); WriteCrashLog($"UI线程未处理异常: {e.Exception}"); - + e.Handled = true; SyncCrashActionFromSettings(); // 新增:崩溃时同步最新设置 @@ -435,7 +435,8 @@ namespace Ink_Canvas void App_Startup(object sender, StartupEventArgs e) { - /*if (!StoreHelper.IsStoreApp) */RootPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; + /*if (!StoreHelper.IsStoreApp) */ + RootPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; LogHelper.NewLog(string.Format("Ink Canvas Starting (Version: {0})", Assembly.GetExecutingAssembly().GetName().Version)); @@ -465,14 +466,16 @@ namespace Ink_Canvas LogHelper.NewLog("Ink Canvas automatically closed"); IsAppExitByUser = true; // 多开时标记为用户主动退出 // 写入退出信号,确保看门狗不会重启 - try { + try + { StartupCount.Reset(); File.WriteAllText(watchdogExitSignalFile, "exit"); if (watchdogProcess != null && !watchdogProcess.HasExited) { watchdogProcess.Kill(); } - } catch { } + } + catch { } Environment.Exit(0); } @@ -484,7 +487,7 @@ namespace Ink_Canvas try { LogHelper.WriteLogToFile("开始Office注册表检测"); - + // 检查Office安装 if (!IsOfficeInstalled()) { @@ -513,7 +516,7 @@ namespace Ink_Canvas { LogHelper.WriteLogToFile($"注册表路径不存在: {regPath}", LogHelper.LogType.Warning); // 尝试创建路径 - try + try { using (RegistryKey createKey = Registry.CurrentUser.CreateSubKey(regPath, true)) { @@ -534,23 +537,23 @@ namespace Ink_Canvas // 备份路径更改为软件根目录下的saves/RegistryBackups文件夹 string backupPath = Path.Combine(RootPath, "saves", "RegistryBackups"); LogHelper.WriteLogToFile($"备份路径: {backupPath}"); - - if (!Directory.Exists(backupPath)) + + if (!Directory.Exists(backupPath)) { Directory.CreateDirectory(backupPath); LogHelper.WriteLogToFile($"创建备份目录: {backupPath}"); } - + string backupFile = Path.Combine(backupPath, $"SecurityBackup_{version}_{DateTime.Now:yyyyMMddHHmmss}.reg"); LogHelper.WriteLogToFile($"创建备份文件: {backupFile}"); - + // 使用UTF8编码写入注册表文件 using (StreamWriter sw = new StreamWriter(backupFile, false, Encoding.UTF8)) { sw.WriteLine("Windows Registry Editor Version 5.00\n"); sw.WriteLine(); sw.WriteLine($"[{Registry.CurrentUser.Name}\\{regPath}]"); - + foreach (string valueName in baseKey.GetValueNames()) { object value = baseKey.GetValue(valueName); @@ -614,9 +617,9 @@ namespace Ink_Canvas SenderScrollViewer.ScrollToVerticalOffset(SenderScrollViewer.VerticalOffset - e.Delta * 10 * SystemInformation.MouseWheelScrollLines / (double)120); e.Handled = true; } - catch { } + catch { } } - catch { } + catch { } } // 新增:用于设置崩溃后操作类型 @@ -731,7 +734,7 @@ namespace Ink_Canvas // 新增:记录应用退出状态 string exitType = IsAppExitByUser ? "用户主动退出" : "应用程序退出"; WriteCrashLog($"{exitType},退出代码: {e.ApplicationExitCode}"); - + // 记录应用退出(设备标识符) try { @@ -742,7 +745,7 @@ namespace Ink_Canvas { LogHelper.WriteLogToFile($"记录设备标识符退出信息失败: {deviceEx.Message}", LogHelper.LogType.Error); } - + if (IsAppExitByUser) { // 写入退出信号文件,通知看门狗正常退出 @@ -754,7 +757,7 @@ namespace Ink_Canvas } } } - catch (Exception ex) + catch (Exception ex) { // 尝试记录最后的错误 try @@ -782,7 +785,7 @@ namespace Ink_Canvas return true; } } - + // 2. 检查64位注册表中的Office using (RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Wow6432Node\\Microsoft\\Office")) { @@ -792,7 +795,7 @@ namespace Ink_Canvas return true; } } - + // 3. 检查Office 365/Click-to-Run安装 using (RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\ClickToRun")) { @@ -802,7 +805,7 @@ namespace Ink_Canvas return true; } } - + // 4. 检查Office 365部署配置 using (RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\15.0\\ClickToRun")) { @@ -812,7 +815,7 @@ namespace Ink_Canvas return true; } } - + using (RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\16.0\\ClickToRun")) { if (key != null) @@ -841,7 +844,7 @@ namespace Ink_Canvas return false; } } - + /// /// 显示权限不足的错误提示 /// @@ -995,7 +998,7 @@ namespace Ink_Canvas { var platformVersion = key.GetValue("Platform") as string; var clickToRunVersion = key.GetValue("VersionToReport") as string; - + if (!string.IsNullOrEmpty(platformVersion)) { var majorVersion = platformVersion.Split('.').FirstOrDefault(); @@ -1055,13 +1058,13 @@ namespace Ink_Canvas // 检查Office 365 Outlook和PowerPoint的特定路径 string[] apps = { "outlook", "powerpoint" }; - + foreach (var app in apps) { // 检查用户级别的注册表 string regPath = $"Software\\Microsoft\\Office\\16.0\\{app}\\Security"; LogHelper.WriteLogToFile($"检查Office 365特定应用注册表: {regPath}"); - + try { // 先检查是否存在该路径 @@ -1072,14 +1075,14 @@ namespace Ink_Canvas { string backupFile = Path.Combine(backupPath, $"SecurityBackup_365_{app}_{DateTime.Now:yyyyMMddHHmmss}.reg"); LogHelper.WriteLogToFile($"创建Office 365 {app}备份文件: {backupFile}"); - + // 使用UTF8编码写入注册表文件 using (StreamWriter sw = new StreamWriter(backupFile, false, Encoding.UTF8)) { sw.WriteLine("Windows Registry Editor Version 5.00\n"); sw.WriteLine(); sw.WriteLine($"[{Registry.CurrentUser.Name}\\{regPath}]"); - + foreach (string valueName in baseKey.GetValueNames()) { object value = baseKey.GetValue(valueName); @@ -1113,11 +1116,11 @@ namespace Ink_Canvas LogHelper.WriteLogToFile($"修改 {app} 注册表时出错: {ex.Message}", LogHelper.LogType.Error); } } - + // 尝试通过Office信任中心路径修改 string trustCenterPath = "Software\\Microsoft\\Office\\16.0\\Common\\Security\\FileValidation"; LogHelper.WriteLogToFile($"检查信任中心路径: {trustCenterPath}"); - + try { // 先检查是否存在该路径 @@ -1128,14 +1131,14 @@ namespace Ink_Canvas { string backupFile = Path.Combine(backupPath, $"SecurityBackup_365_TrustCenter_{DateTime.Now:yyyyMMddHHmmss}.reg"); LogHelper.WriteLogToFile($"创建信任中心备份文件: {backupFile}"); - + // 使用UTF8编码写入注册表文件 using (StreamWriter sw = new StreamWriter(backupFile, false, Encoding.UTF8)) { sw.WriteLine("Windows Registry Editor Version 5.00\n"); sw.WriteLine(); sw.WriteLine($"[{Registry.CurrentUser.Name}\\{trustCenterPath}]"); - + foreach (string valueName in baseKey.GetValueNames()) { object value = baseKey.GetValue(valueName); @@ -1159,7 +1162,7 @@ namespace Ink_Canvas { LogHelper.WriteLogToFile($"修改信任中心路径时出错: {ex.Message}", LogHelper.LogType.Error); } - + // 尝试修改EnableEditWhileViewingPolicy string policyPath = "Software\\Policies\\Microsoft\\Office\\16.0\\Common\\Security"; try @@ -1172,14 +1175,14 @@ namespace Ink_Canvas { string backupFile = Path.Combine(backupPath, $"SecurityBackup_365_Policy_{DateTime.Now:yyyyMMddHHmmss}.reg"); LogHelper.WriteLogToFile($"创建策略备份文件: {backupFile}"); - + // 使用UTF8编码写入注册表文件 using (StreamWriter sw = new StreamWriter(backupFile, false, Encoding.UTF8)) { sw.WriteLine("Windows Registry Editor Version 5.00\n"); sw.WriteLine(); sw.WriteLine($"[{Registry.CurrentUser.Name}\\{policyPath}]"); - + foreach (string valueName in baseKey.GetValueNames()) { object value = baseKey.GetValue(valueName); diff --git a/Ink Canvas/Helpers/AdvancedBezierSmoothing.cs b/Ink Canvas/Helpers/AdvancedBezierSmoothing.cs index c7701754..56a2e6f3 100644 --- a/Ink Canvas/Helpers/AdvancedBezierSmoothing.cs +++ b/Ink Canvas/Helpers/AdvancedBezierSmoothing.cs @@ -354,7 +354,7 @@ namespace Ink_Canvas.Helpers { public double SmoothingStrength { get; set; } = 0.3; public double ResampleInterval { get; set; } = 3.0; - public int InterpolationSteps { get; set; } = 8; + public int InterpolationSteps { get; set; } = 8; public Stroke SmoothStroke(Stroke stroke) { diff --git a/Ink Canvas/Helpers/AutoUpdateHelper.cs b/Ink Canvas/Helpers/AutoUpdateHelper.cs index e0a45e5a..138c0090 100644 --- a/Ink Canvas/Helpers/AutoUpdateHelper.cs +++ b/Ink Canvas/Helpers/AutoUpdateHelper.cs @@ -1,4 +1,6 @@ -using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -16,8 +18,6 @@ using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; namespace Ink_Canvas.Helpers { @@ -129,7 +129,7 @@ namespace Ink_Canvas.Helpers // 检测是否为Windows 7 var osVersion = Environment.OSVersion; bool isWindows7 = osVersion.Version.Major == 6 && osVersion.Version.Minor == 1; - + if (isWindows7) { // Windows 7使用特殊配置 @@ -137,7 +137,7 @@ namespace Ink_Canvas.Helpers { // 配置HttpClientHandler以支持Windows 7 handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; - + using (var client = new HttpClient(handler)) { client.Timeout = TimeSpan.FromSeconds(5); @@ -179,9 +179,9 @@ namespace Ink_Canvas.Helpers { var groups = ChannelLineGroups[channel]; var availableGroups = new List<(UpdateLineGroup group, long delay)>(); - + LogHelper.WriteLogToFile($"AutoUpdate | 开始检测通道 {channel} 下所有线路组延迟..."); - + foreach (var group in groups) { // 跳过"智教联盟"和"inkeys"线路组,不参与延迟检测和排序 @@ -202,13 +202,13 @@ namespace Ink_Canvas.Helpers LogHelper.WriteLogToFile($"AutoUpdate | 线路组 {group.GroupName} 不可用", LogHelper.LogType.Warning); } } - + // 按延迟排序,延迟最小的排在前面 var orderedGroups = availableGroups .OrderBy(x => x.delay) .Select(x => x.group) .ToList(); - + // 将"智教联盟"线路组插入到最前面(如果存在) var zhiJiaoGroup = groups.FirstOrDefault(g => g.GroupName == "智教联盟"); if (zhiJiaoGroup != null) @@ -216,7 +216,7 @@ namespace Ink_Canvas.Helpers orderedGroups.Insert(0, zhiJiaoGroup); LogHelper.WriteLogToFile("AutoUpdate | 智教联盟线路组已插入到首位"); } - + // 将"inkeys"线路组插入到第二位(如果存在) var inkeysGroup = groups.FirstOrDefault(g => g.GroupName == "inkeys"); if (inkeysGroup != null) @@ -224,7 +224,7 @@ namespace Ink_Canvas.Helpers orderedGroups.Insert(1, inkeysGroup); LogHelper.WriteLogToFile("AutoUpdate | inkeys线路组已插入到第二位"); } - + if (orderedGroups.Count > 0) { LogHelper.WriteLogToFile($"AutoUpdate | 找到 {orderedGroups.Count} 个可用线路组,按延迟排序:"); @@ -237,7 +237,7 @@ namespace Ink_Canvas.Helpers { LogHelper.WriteLogToFile("AutoUpdate | 所有线路组均不可用", LogHelper.LogType.Error); } - + return orderedGroups; } @@ -247,7 +247,7 @@ namespace Ink_Canvas.Helpers // 检测是否为Windows 7 var osVersion = Environment.OSVersion; bool isWindows7 = osVersion.Version.Major == 6 && osVersion.Version.Minor == 1; - + if (isWindows7) { // Windows 7使用特殊配置 @@ -257,29 +257,29 @@ namespace Ink_Canvas.Helpers { // 配置HttpClientHandler以支持Windows 7 handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; - + using (HttpClient client = new HttpClient(handler)) { client.Timeout = RequestTimeout; LogHelper.WriteLogToFile($"AutoUpdate | 发送HTTP请求到: {fileUrl}"); - + var downloadTask = client.GetAsync(fileUrl); var timeoutTask = Task.Delay(RequestTimeout); - + var completedTask = await Task.WhenAny(downloadTask, timeoutTask); if (completedTask == timeoutTask) { LogHelper.WriteLogToFile($"AutoUpdate | 请求超时 ({RequestTimeout.TotalSeconds}秒)", LogHelper.LogType.Error); return null; } - + HttpResponseMessage response = await downloadTask; LogHelper.WriteLogToFile($"AutoUpdate | HTTP响应状态: {response.StatusCode}"); response.EnsureSuccessStatusCode(); string content = await response.Content.ReadAsStringAsync(); content = content.Trim(); - + // 如果内容包含HTML(可能是GitHub页面而不是原始内容),尝试提取版本号 if (content.Contains("(); var finishedBlocks = new ConcurrentDictionary(); long[] blockDownloaded = new long[blockCount]; - + for (int i = 0; i < blockCount; i++) { long start = i * blockSize; long end = Math.Min(start + blockSize - 1, totalSize - 1); blockQueue.Enqueue(new BlockTask { Index = i, Start = start, End = end, RetryCount = 0 }); } - + CancellationTokenSource cts = new CancellationTokenSource(); var tasks = new List(); - + for (int t = 0; t < threadCount; t++) { tasks.Add(Task.Run(async () => @@ -837,7 +837,7 @@ namespace Ink_Canvas.Helpers { bool success = false; string tempPath = destinationPath + $".part{block.Index}"; - + for (int retry = block.RetryCount; retry < maxRetry && !success; retry++) { try @@ -850,7 +850,7 @@ namespace Ink_Canvas.Helpers // 增加连接超时设置 client.Timeout = TimeSpan.FromSeconds(30); - + var downloadCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token); var lastReadTime = DateTime.UtcNow; bool dataReceived = false; @@ -865,7 +865,7 @@ namespace Ink_Canvas.Helpers byte[] buffer = new byte[8192]; int read; long blockDownloadedBytes = 0; - + while (true) { var readTask = stream.ReadAsync(buffer, 0, buffer.Length, downloadCts.Token); @@ -885,7 +885,7 @@ namespace Ink_Canvas.Helpers blockDownloaded[block.Index] = blockDownloadedBytes; lastReadTime = DateTime.UtcNow; dataReceived = true; - + // 合并所有块进度 long totalDownloaded = blockDownloaded.Sum(); double percent = (double)totalDownloaded / totalSize * 100; @@ -893,12 +893,12 @@ namespace Ink_Canvas.Helpers } } } - + if (!dataReceived) { throw new IOException("分块下载超时无数据"); } - + // 验证分块大小是否正确 var fileInfo = new FileInfo(tempPath); long expectedSize = block.End - block.Start + 1; @@ -915,13 +915,13 @@ namespace Ink_Canvas.Helpers { LogHelper.WriteLogToFile($"AutoUpdate | 分块{block.Index}下载失败,第{retry + 1}次: {ex.Message}", LogHelper.LogType.Warning); progressCallback?.Invoke(0, $"分块{block.Index}下载失败,第{retry + 1}次: {ex.Message}"); - + // 清理可能损坏的分块文件 if (File.Exists(tempPath)) { try { File.Delete(tempPath); } catch { } } - + // 增加重试间隔,避免频繁重试 await Task.Delay(2000 * (retry + 1)); } @@ -946,21 +946,21 @@ namespace Ink_Canvas.Helpers } })); } - + await Task.WhenAll(tasks); - + if (cts.IsCancellationRequested || finishedBlocks.Count != blockCount) { LogHelper.WriteLogToFile($"AutoUpdate | {threadCount}线程下载失败,完成分块数: {finishedBlocks.Count}/{blockCount}", LogHelper.LogType.Warning); progressCallback?.Invoke(0, $"{threadCount}线程下载失败,完成分块数: {finishedBlocks.Count}/{blockCount}"); - + // 清理分块文件 for (int i = 0; i < blockCount; i++) { string tempPath = destinationPath + $".part{i}"; if (File.Exists(tempPath)) File.Delete(tempPath); } - + if (threadCount == threadOptions.Last()) { // 已经是最后一次尝试,降级为单线程 @@ -973,7 +973,7 @@ namespace Ink_Canvas.Helpers progressCallback?.Invoke(0, $"{threadCount}线程下载失败,尝试降级为{threadOptions[Array.IndexOf(threadOptions, threadCount) + 1]}线程"); continue; } - + // 合并所有块 try { @@ -986,7 +986,7 @@ namespace Ink_Canvas.Helpers { throw new FileNotFoundException($"分块文件不存在: {tempPath}"); } - + using (var input = new FileStream(tempPath, FileMode.Open, FileAccess.Read)) { await input.CopyToAsync(output); @@ -994,7 +994,7 @@ namespace Ink_Canvas.Helpers File.Delete(tempPath); } } - + progressCallback?.Invoke(100, $"多线程下载完成({threadCount}线程)"); LogHelper.WriteLogToFile($"AutoUpdate | 多线程下载完成({threadCount}线程)"); @@ -1007,7 +1007,7 @@ namespace Ink_Canvas.Helpers progressCallback?.Invoke(0, "文件大小校验失败,已删除损坏文件"); return false; } - + // ZIP文件完整性校验 if (destinationPath.EndsWith(".zip", StringComparison.OrdinalIgnoreCase)) { @@ -1043,12 +1043,12 @@ namespace Ink_Canvas.Helpers { LogHelper.WriteLogToFile($"AutoUpdate | 开始单线程下载: {fileUrl}"); progressCallback?.Invoke(0, "开始单线程下载"); - + using (var client = new HttpClient()) { client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"); client.Timeout = TimeSpan.FromMinutes(10); // 单线程下载设置更长的超时时间 - + using (var resp = await client.GetAsync(fileUrl, HttpCompletionOption.ResponseHeadersRead)) { resp.EnsureSuccessStatusCode(); @@ -1059,12 +1059,12 @@ namespace Ink_Canvas.Helpers int read; long downloaded = 0; var lastProgressUpdate = DateTime.UtcNow; - + while ((read = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0) { await fs.WriteAsync(buffer, 0, read); downloaded += read; - + // 限制进度更新频率,避免UI卡顿 if (DateTime.UtcNow - lastProgressUpdate > TimeSpan.FromMilliseconds(500)) { @@ -1079,7 +1079,7 @@ namespace Ink_Canvas.Helpers } } } - + progressCallback?.Invoke(100, "单线程下载完成"); LogHelper.WriteLogToFile("AutoUpdate | 单线程下载完成"); return true; @@ -1103,9 +1103,9 @@ namespace Ink_Canvas.Helpers var resp = await client.SendAsync(req); if (resp.IsSuccessStatusCode && resp.Content.Headers.ContentLength.HasValue) return resp.Content.Headers.ContentLength.Value; - } - } - catch { } + } + } + catch { } return -1; } @@ -1146,13 +1146,13 @@ namespace Ink_Canvas.Helpers Directory.CreateDirectory(backupDir); LogHelper.WriteLogToFile($"创建备份目录: {backupDir}"); } - + string backupFileName = $"Settings_BeforeUpdate_v{version}_{DateTime.Now:yyyyMMdd_HHmmss}.json"; string backupPath = Path.Combine(backupDir, backupFileName); - + string settingsJson = JsonConvert.SerializeObject(MainWindow.Settings, Formatting.Indented); File.WriteAllText(backupPath, settingsJson); - + LogHelper.WriteLogToFile($"更新前自动备份设置成功: {backupPath}"); } else @@ -1164,7 +1164,7 @@ namespace Ink_Canvas.Helpers { LogHelper.WriteLogToFile($"更新前自动备份设置时出错: {ex.Message}", LogHelper.LogType.Error); } - + string zipFilePath = Path.Combine(updatesFolderPath, $"InkCanvasForClass.CE.{version}.zip"); LogHelper.WriteLogToFile($"AutoUpdate | 检查ZIP文件: {zipFilePath}"); @@ -1185,21 +1185,21 @@ namespace Ink_Canvas.Helpers string currentAppDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); int currentProcessId = Process.GetCurrentProcess().Id; string appPath = Assembly.GetExecutingAssembly().Location; - + LogHelper.WriteLogToFile($"AutoUpdate | 当前应用程序目录: {currentAppDir}"); LogHelper.WriteLogToFile($"AutoUpdate | 当前进程ID: {currentProcessId}"); LogHelper.WriteLogToFile($"AutoUpdate | 静默更新模式: {isInSilence}"); string batchFilePath = Path.Combine(Path.GetTempPath(), "UpdateICC_" + Guid.NewGuid().ToString().Substring(0, 8) + ".bat"); LogHelper.WriteLogToFile($"AutoUpdate | 创建更新批处理文件: {batchFilePath}"); - + StringBuilder batchContent = new StringBuilder(); batchContent.AppendLine("@echo off"); - + batchContent.AppendLine("echo Set objShell = CreateObject(\"WScript.Shell\") > \"%temp%\\hideme.vbs\""); batchContent.AppendLine("echo objShell.Run \"cmd /c \"\"\" ^& WScript.Arguments(0) ^& \"\"\"\", 0, True >> \"%temp%\\hideme.vbs\""); batchContent.AppendLine("echo Wscript.Sleep 100 >> \"%temp%\\hideme.vbs\""); - + string updateBatPath = Path.Combine(Path.GetTempPath(), "ICCUpdate_" + Guid.NewGuid().ToString().Substring(0, 8) + ".bat"); batchContent.AppendLine($"echo @echo off > \"{updateBatPath}\""); batchContent.AppendLine($"echo set PROC_ID={currentProcessId} >> \"{updateBatPath}\""); @@ -1209,32 +1209,32 @@ namespace Ink_Canvas.Helpers batchContent.AppendLine($"echo timeout /t 1 /nobreak ^> nul >> \"{updateBatPath}\""); batchContent.AppendLine($"echo goto CHECK_PROCESS >> \"{updateBatPath}\""); batchContent.AppendLine($"echo ) >> \"{updateBatPath}\""); - + batchContent.AppendLine($"echo echo Application closed, starting update process... >> \"{updateBatPath}\""); batchContent.AppendLine($"echo timeout /t 2 /nobreak ^> nul >> \"{updateBatPath}\""); - + string extractPath = Path.Combine(updatesFolderPath, $"Extract_{version}"); batchContent.AppendLine($"echo echo Extracting update files... >> \"{updateBatPath}\""); batchContent.AppendLine($"echo if exist \"{extractPath}\" rd /s /q \"{extractPath}\" >> \"{updateBatPath}\""); batchContent.AppendLine($"echo mkdir \"{extractPath}\" >> \"{updateBatPath}\""); - + batchContent.AppendLine($"echo powershell -command \"Expand-Archive -Path '{zipFilePath.Replace("'", "''")}' -DestinationPath '{extractPath.Replace("'", "''")}' -Force\" >> \"{updateBatPath}\""); batchContent.AppendLine($"echo if %%ERRORLEVEL%% neq 0 ( >> \"{updateBatPath}\""); batchContent.AppendLine($"echo goto ERROR_EXIT >> \"{updateBatPath}\""); batchContent.AppendLine($"echo ) >> \"{updateBatPath}\""); - + batchContent.AppendLine($"echo echo Copying updated files to application directory... >> \"{updateBatPath}\""); batchContent.AppendLine($"echo xcopy /s /y /e \"{extractPath}\\*\" \"{currentAppDir}\\\" >> \"{updateBatPath}\""); batchContent.AppendLine($"echo if %%ERRORLEVEL%% neq 0 ( >> \"{updateBatPath}\""); batchContent.AppendLine($"echo goto ERROR_EXIT >> \"{updateBatPath}\""); batchContent.AppendLine($"echo ) >> \"{updateBatPath}\""); - + batchContent.AppendLine($"echo echo Cleaning up temporary files... >> \"{updateBatPath}\""); batchContent.AppendLine($"echo if exist \"{extractPath}\" rd /s /q \"{extractPath}\" >> \"{updateBatPath}\""); batchContent.AppendLine($"echo if exist \"{zipFilePath}\" del /f /q \"{zipFilePath}\" >> \"{updateBatPath}\""); - + batchContent.AppendLine($"echo echo Update completed successfully! >> \"{updateBatPath}\""); - + if (isInSilence) { batchContent.AppendLine($"echo echo 自动启动应用程序... >> \"{updateBatPath}\""); @@ -1242,7 +1242,7 @@ namespace Ink_Canvas.Helpers } else { - batchContent.AppendLine($"echo taskkill /F /IM \"InkCanvasForClass.exe\" >nul 2>nul >> \"{updateBatPath}\""); + batchContent.AppendLine($"echo taskkill /F /IM \"InkCanvasForClass.exe\" >nul 2>nul >> \"{updateBatPath}\""); batchContent.AppendLine($"echo :: 检查应用程序是否已经在运行 >> \"{updateBatPath}\""); batchContent.AppendLine($"echo tasklist /FI \"IMAGENAME eq InkCanvasForClass.exe\" | find /i \"InkCanvasForClass.exe\" > nul >> \"{updateBatPath}\""); batchContent.AppendLine($"echo if %%ERRORLEVEL%% neq 0 ( >> \"{updateBatPath}\""); @@ -1252,10 +1252,10 @@ namespace Ink_Canvas.Helpers batchContent.AppendLine($"echo echo 应用程序已经在运行,不再重复启动 >> \"{updateBatPath}\""); batchContent.AppendLine($"echo ) >> \"{updateBatPath}\""); } - + batchContent.AppendLine($"echo exit /b 0 >> \"{updateBatPath}\""); batchContent.AppendLine($"echo goto EXIT >> \"{updateBatPath}\""); - + if (isInSilence) { batchContent.AppendLine($"echo :ERROR_EXIT >> \"{updateBatPath}\""); @@ -1268,7 +1268,7 @@ namespace Ink_Canvas.Helpers batchContent.AppendLine($"echo start \"\" cmd /c \"echo Update failed! ^& pause\" >> \"{updateBatPath}\""); batchContent.AppendLine($"echo exit /b 1 >> \"{updateBatPath}\""); } - + batchContent.AppendLine($"echo :EXIT >> \"{updateBatPath}\""); batchContent.AppendLine($"echo del \"{updateBatPath}\" >> \"{updateBatPath}\""); batchContent.AppendLine($"echo exit >> \"{updateBatPath}\""); @@ -1276,10 +1276,10 @@ namespace Ink_Canvas.Helpers batchContent.AppendLine($"wscript \"%temp%\\hideme.vbs\" \"{updateBatPath}\""); batchContent.AppendLine("del \"%temp%\\hideme.vbs\""); batchContent.AppendLine("exit"); - + File.WriteAllText(batchFilePath, batchContent.ToString()); LogHelper.WriteLogToFile("AutoUpdate | 创建更新批处理文件完成"); - + Process.Start(new ProcessStartInfo { FileName = batchFilePath, @@ -1287,7 +1287,7 @@ namespace Ink_Canvas.Helpers UseShellExecute = true, WindowStyle = ProcessWindowStyle.Hidden }); - + LogHelper.WriteLogToFile("AutoUpdate | 启动更新批处理进程(隐藏窗口)"); } catch (Exception ex) @@ -1306,7 +1306,7 @@ namespace Ink_Canvas.Helpers // 检测是否为Windows 7 var osVersion = Environment.OSVersion; bool isWindows7 = osVersion.Version.Major == 6 && osVersion.Version.Minor == 1; - + if (isWindows7) { // Windows 7使用特殊配置 @@ -1316,7 +1316,7 @@ namespace Ink_Canvas.Helpers { // 配置HttpClientHandler以支持Windows 7 handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; - + using (HttpClient client = new HttpClient(handler)) { client.Timeout = RequestTimeout; @@ -1430,7 +1430,7 @@ namespace Ink_Canvas.Helpers try { LogHelper.WriteLogToFile($"AutoUpdate | 开始修复版本,通道: {channel}"); - + // 获取远程版本号(自动选择最快线路组,始终下载远程版本,版本修复模式) var (remoteVersion, group, _) = await CheckForUpdates(channel, true, true); if (string.IsNullOrEmpty(remoteVersion) || group == null) @@ -1438,9 +1438,9 @@ namespace Ink_Canvas.Helpers LogHelper.WriteLogToFile("AutoUpdate | 修复版本时获取远程版本失败", LogHelper.LogType.Error); return false; } - + LogHelper.WriteLogToFile($"AutoUpdate | 修复版本远程版本: {remoteVersion}"); - + // 无论版本是否为最新,都下载远程版本 bool downloadResult = await DownloadSetupFile(remoteVersion, group); if (!downloadResult) @@ -1448,11 +1448,12 @@ namespace Ink_Canvas.Helpers LogHelper.WriteLogToFile("AutoUpdate | 修复版本时下载更新失败", LogHelper.LogType.Error); return false; } - + // 执行安装,非静默模式 InstallNewVersionApp(remoteVersion, false); App.IsAppExitByUser = true; - Application.Current.Dispatcher.Invoke(() => { + Application.Current.Dispatcher.Invoke(() => + { Application.Current.Shutdown(); }); return true; @@ -1503,27 +1504,27 @@ namespace Ink_Canvas.Helpers // 检测是否为Windows 7 var osVersion = Environment.OSVersion; bool isWindows7 = osVersion.Version.Major == 6 && osVersion.Version.Minor == 1; - + if (!isWindows7) { LogHelper.WriteLogToFile("AutoUpdate | 当前系统不是Windows 7,跳过TLS连接测试"); return true; // 非Windows 7系统直接返回成功 } - + LogHelper.WriteLogToFile("AutoUpdate | 开始测试Windows 7 TLS连接..."); - + // 测试GitHub连接 var testUrl = "https://github.com/InkCanvasForClass/community/raw/refs/heads/main/AutomaticUpdateVersionControl.txt"; - + using (var handler = new HttpClientHandler()) { handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; - + using (var client = new HttpClient(handler)) { client.Timeout = TimeSpan.FromSeconds(10); var response = await client.GetAsync(testUrl); - + if (response.IsSuccessStatusCode) { LogHelper.WriteLogToFile("AutoUpdate | Windows 7 TLS连接测试成功"); @@ -1580,7 +1581,8 @@ namespace Ink_Canvas.Helpers LogHelper.WriteLogToFile($"AutoUpdate | 手动安装版本: {version}"); InstallNewVersionApp(version, false); App.IsAppExitByUser = true; - Application.Current.Dispatcher.Invoke(() => { + Application.Current.Dispatcher.Invoke(() => + { Application.Current.Shutdown(); }); return true; diff --git a/Ink Canvas/Helpers/AvoidFullScreenHelper.cs b/Ink Canvas/Helpers/AvoidFullScreenHelper.cs index 88a6cdc2..06ef4db8 100644 --- a/Ink Canvas/Helpers/AvoidFullScreenHelper.cs +++ b/Ink Canvas/Helpers/AvoidFullScreenHelper.cs @@ -13,8 +13,8 @@ namespace Ink_Canvas.Helpers { private static readonly DependencyProperty IsAvoidFullScreenEnabledProperty = DependencyProperty.RegisterAttached( - "IsAvoidFullScreenEnabled", - typeof(bool), + "IsAvoidFullScreenEnabled", + typeof(bool), typeof(AvoidFullScreenHelper)); private static bool _isBoardMode; @@ -122,19 +122,19 @@ namespace Ink_Canvas.Helpers { // 获取所有显示器 var screens = Screen.AllScreens; - + // 确定窗口主要位于哪个显示器上 Screen targetScreen = null; double maxIntersection = 0; - + foreach (var screen in screens) { var screenRect = new Rect( - screen.WorkingArea.X, - screen.WorkingArea.Y, - screen.WorkingArea.Width, + screen.WorkingArea.X, + screen.WorkingArea.Y, + screen.WorkingArea.Width, screen.WorkingArea.Height); - + var intersection = Rect.Intersect(windowRect, screenRect); if (intersection.Width * intersection.Height > maxIntersection) { @@ -142,11 +142,11 @@ namespace Ink_Canvas.Helpers targetScreen = screen; } } - + // 如果没找到,使用主显示器 if (targetScreen == null) targetScreen = Screen.PrimaryScreen; - + return new Rect( targetScreen.WorkingArea.X, targetScreen.WorkingArea.Y, @@ -159,21 +159,21 @@ namespace Ink_Canvas.Helpers // 调整尺寸以适应工作区域 if (windowRect.Width > workingArea.Width) windowRect.Width = workingArea.Width; - + if (windowRect.Height > workingArea.Height) windowRect.Height = workingArea.Height; - + // 调整位置以确保窗口完全在工作区域内 if (windowRect.Left < workingArea.Left) windowRect.X = workingArea.Left; else if (windowRect.Right > workingArea.Right) windowRect.X = workingArea.Right - windowRect.Width; - + if (windowRect.Top < workingArea.Top) windowRect.Y = workingArea.Top; else if (windowRect.Bottom > workingArea.Bottom) windowRect.Y = workingArea.Bottom - windowRect.Height; - + return windowRect; } } diff --git a/Ink Canvas/Helpers/DelAutoSavedFiles.cs b/Ink Canvas/Helpers/DelAutoSavedFiles.cs index b88a8388..c541753f 100644 --- a/Ink Canvas/Helpers/DelAutoSavedFiles.cs +++ b/Ink Canvas/Helpers/DelAutoSavedFiles.cs @@ -1,47 +1,64 @@ using System; using System.IO; -namespace Ink_Canvas.Helpers { - internal class DelAutoSavedFiles { - public static void DeleteFilesOlder(string directoryPath, int daysThreshold) { +namespace Ink_Canvas.Helpers +{ + internal class DelAutoSavedFiles + { + public static void DeleteFilesOlder(string directoryPath, int daysThreshold) + { string[] extensionsToDel = { ".icstk", ".png" }; - if (Directory.Exists(directoryPath)) { + if (Directory.Exists(directoryPath)) + { // 获取目录中的所有子目录 string[] subDirectories = Directory.GetDirectories(directoryPath, "*", SearchOption.AllDirectories); - foreach (string subDirectory in subDirectories) { - try { + foreach (string subDirectory in subDirectories) + { + try + { // 获取子目录下的所有文件 string[] files = Directory.GetFiles(subDirectory); - foreach (string filePath in files) { + foreach (string filePath in files) + { // 获取文件的创建日期 DateTime creationDate = File.GetCreationTime(filePath); // 获取文件的扩展名 string fileExtension = Path.GetExtension(filePath); // 如果文件的创建日期早于指定天数且是要删除的扩展名,则删除文件 - if (creationDate < DateTime.Now.AddDays(-daysThreshold)) { + if (creationDate < DateTime.Now.AddDays(-daysThreshold)) + { if (Array.Exists(extensionsToDel, ext => ext.Equals(fileExtension, StringComparison.OrdinalIgnoreCase)) - || Path.GetFileName(filePath).Equals("Position", StringComparison.OrdinalIgnoreCase)) { + || Path.GetFileName(filePath).Equals("Position", StringComparison.OrdinalIgnoreCase)) + { File.Delete(filePath); } } } - } catch (Exception ex) { + } + catch (Exception ex) + { LogHelper.WriteLogToFile("DelAutoSavedFiles | 处理文件时出错: " + ex, LogHelper.LogType.Error); } } - try { // 递归删除空文件夹 + try + { // 递归删除空文件夹 DeleteEmptyFolders(directoryPath); - } catch (Exception ex) { + } + catch (Exception ex) + { LogHelper.WriteLogToFile("DelAutoSavedFiles | 处理文件时出错: " + ex, LogHelper.LogType.Error); } } } - private static void DeleteEmptyFolders(string directoryPath) { - foreach (string dir in Directory.GetDirectories(directoryPath)) { + private static void DeleteEmptyFolders(string directoryPath) + { + foreach (string dir in Directory.GetDirectories(directoryPath)) + { DeleteEmptyFolders(dir); - if (Directory.GetFiles(dir).Length == 0 && Directory.GetDirectories(dir).Length == 0) { + if (Directory.GetFiles(dir).Length == 0 && Directory.GetDirectories(dir).Length == 0) + { Directory.Delete(dir, false); } } diff --git a/Ink Canvas/Helpers/DelayActionHelper.cs b/Ink Canvas/Helpers/DelayActionHelper.cs index 5f2dd0e7..66cb70c8 100644 --- a/Ink Canvas/Helpers/DelayActionHelper.cs +++ b/Ink Canvas/Helpers/DelayActionHelper.cs @@ -14,10 +14,13 @@ namespace Ink_Canvas.Helpers /// 同步的對象,一般傳入控件,不需要可null public void DebounceAction(int timeMs, ISynchronizeInvoke inv, Action action) { - lock (this) { - if (_timerDebounce == null) { + lock (this) + { + if (_timerDebounce == null) + { _timerDebounce = new Timer(timeMs) { AutoReset = false }; - _timerDebounce.Elapsed += (o, e) => { + _timerDebounce.Elapsed += (o, e) => + { _timerDebounce.Stop(); _timerDebounce.Close(); _timerDebounce = null; InvokeAction(action, inv); }; diff --git a/Ink Canvas/Helpers/DeviceIdentifier.cs b/Ink Canvas/Helpers/DeviceIdentifier.cs index 51912ee6..a82fe3a8 100644 --- a/Ink Canvas/Helpers/DeviceIdentifier.cs +++ b/Ink Canvas/Helpers/DeviceIdentifier.cs @@ -1,3 +1,5 @@ +using Microsoft.Win32; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; @@ -5,8 +7,6 @@ using System.Linq; using System.Reflection; using System.Security.Cryptography; using System.Text; -using Microsoft.Win32; -using Newtonsoft.Json; namespace Ink_Canvas.Helpers { @@ -128,7 +128,7 @@ namespace Ink_Canvas.Helpers { // 收集硬件信息 var hardwareInfo = new StringBuilder(); - + // 使用反射获取硬件信息,避免直接引用System.Management try { @@ -143,10 +143,10 @@ namespace Ink_Canvas.Helpers var searcher = Activator.CreateInstance(searcherType, "SELECT ProcessorId FROM Win32_Processor"); var getMethod = searcherType.GetMethod("Get"); var enumerator = getMethod.Invoke(searcher, null); - + var moveNextMethod = enumerator.GetType().GetMethod("MoveNext"); var currentProperty = enumerator.GetType().GetProperty("Current"); - + if ((bool)moveNextMethod.Invoke(enumerator, null)) { var obj = currentProperty.GetValue(enumerator); @@ -154,7 +154,7 @@ namespace Ink_Canvas.Helpers var processorId = indexer.GetValue(obj, new object[] { "ProcessorId" }); hardwareInfo.Append(processorId?.ToString() ?? ""); } - + var disposeMethod = searcher.GetType().GetMethod("Dispose"); disposeMethod?.Invoke(searcher, null); } @@ -167,10 +167,10 @@ namespace Ink_Canvas.Helpers var searcher = Activator.CreateInstance(searcherType, "SELECT SerialNumber FROM Win32_BaseBoard"); var getMethod = searcherType.GetMethod("Get"); var enumerator = getMethod.Invoke(searcher, null); - + var moveNextMethod = enumerator.GetType().GetMethod("MoveNext"); var currentProperty = enumerator.GetType().GetProperty("Current"); - + if ((bool)moveNextMethod.Invoke(enumerator, null)) { var obj = currentProperty.GetValue(enumerator); @@ -178,7 +178,7 @@ namespace Ink_Canvas.Helpers var serialNumber = indexer.GetValue(obj, new object[] { "SerialNumber" }); hardwareInfo.Append(serialNumber?.ToString() ?? ""); } - + var disposeMethod = searcher.GetType().GetMethod("Dispose"); disposeMethod?.Invoke(searcher, null); } @@ -191,10 +191,10 @@ namespace Ink_Canvas.Helpers var searcher = Activator.CreateInstance(searcherType, "SELECT SerialNumber FROM Win32_BIOS"); var getMethod = searcherType.GetMethod("Get"); var enumerator = getMethod.Invoke(searcher, null); - + var moveNextMethod = enumerator.GetType().GetMethod("MoveNext"); var currentProperty = enumerator.GetType().GetProperty("Current"); - + if ((bool)moveNextMethod.Invoke(enumerator, null)) { var obj = currentProperty.GetValue(enumerator); @@ -202,7 +202,7 @@ namespace Ink_Canvas.Helpers var serialNumber = indexer.GetValue(obj, new object[] { "SerialNumber" }); hardwareInfo.Append(serialNumber?.ToString() ?? ""); } - + var disposeMethod = searcher.GetType().GetMethod("Dispose"); disposeMethod?.Invoke(searcher, null); } @@ -215,10 +215,10 @@ namespace Ink_Canvas.Helpers var searcher = Activator.CreateInstance(searcherType, "SELECT SerialNumber FROM Win32_DiskDrive WHERE MediaType='Fixed hard disk media'"); var getMethod = searcherType.GetMethod("Get"); var enumerator = getMethod.Invoke(searcher, null); - + var moveNextMethod = enumerator.GetType().GetMethod("MoveNext"); var currentProperty = enumerator.GetType().GetProperty("Current"); - + if ((bool)moveNextMethod.Invoke(enumerator, null)) { var obj = currentProperty.GetValue(enumerator); @@ -226,7 +226,7 @@ namespace Ink_Canvas.Helpers var serialNumber = indexer.GetValue(obj, new object[] { "SerialNumber" }); hardwareInfo.Append(serialNumber?.ToString() ?? ""); } - + var disposeMethod = searcher.GetType().GetMethod("Dispose"); disposeMethod?.Invoke(searcher, null); } @@ -251,7 +251,7 @@ namespace Ink_Canvas.Helpers // 取前25个字符,确保唯一性 string deviceId = hashString.Substring(0, 25); - + // 添加校验位(第25位) int checksum = 0; for (int i = 0; i < 24; i++) @@ -260,7 +260,7 @@ namespace Ink_Canvas.Helpers } checksum %= 36; // 0-9, A-Z char checksumChar = checksum < 10 ? (char)(checksum + '0') : (char)(checksum - 10 + 'A'); - + return deviceId.Substring(0, 24) + checksumChar; } } @@ -281,7 +281,7 @@ namespace Ink_Canvas.Helpers string timestamp = DateTime.Now.Ticks.ToString("X"); string random = Guid.NewGuid().ToString("N").Substring(0, 8); string combined = timestamp + random; - + using (var sha256 = SHA256.Create()) { byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(combined)); @@ -2746,4 +2746,4 @@ namespace Ink_Canvas.Helpers } } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/ForegroundWindowInfo.cs b/Ink Canvas/Helpers/ForegroundWindowInfo.cs index baaee5a1..6926a610 100644 --- a/Ink Canvas/Helpers/ForegroundWindowInfo.cs +++ b/Ink Canvas/Helpers/ForegroundWindowInfo.cs @@ -25,7 +25,8 @@ namespace Ink_Canvas.Helpers private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); [StructLayout(LayoutKind.Sequential)] - public struct RECT { + public struct RECT + { public int Left; public int Top; public int Right; @@ -35,7 +36,8 @@ namespace Ink_Canvas.Helpers public int Height => Bottom - Top; } - public static string WindowTitle() { + public static string WindowTitle() + { IntPtr foregroundWindowHandle = GetForegroundWindow(); const int nChars = 256; @@ -45,7 +47,8 @@ namespace Ink_Canvas.Helpers return windowTitle.ToString(); } - public static string WindowClassName() { + public static string WindowClassName() + { IntPtr foregroundWindowHandle = GetForegroundWindow(); const int nChars = 256; @@ -55,7 +58,8 @@ namespace Ink_Canvas.Helpers return className.ToString(); } - public static RECT WindowRect() { + public static RECT WindowRect() + { IntPtr foregroundWindowHandle = GetForegroundWindow(); RECT windowRect; @@ -64,15 +68,19 @@ namespace Ink_Canvas.Helpers return windowRect; } - public static string ProcessName() { + public static string ProcessName() + { IntPtr foregroundWindowHandle = GetForegroundWindow(); uint processId; GetWindowThreadProcessId(foregroundWindowHandle, out processId); - try { + try + { Process process = Process.GetProcessById((int)processId); return process.ProcessName; - } catch (ArgumentException) { + } + catch (ArgumentException) + { // Process with the given ID not found return "Unknown"; } @@ -89,7 +97,8 @@ namespace Ink_Canvas.Helpers Process process = Process.GetProcessById((int)processId); return process.MainModule.FileName; } - catch { + catch + { // Process with the given ID not found return "Unknown"; } diff --git a/Ink Canvas/Helpers/FullScreenHelper.Win32.cs b/Ink Canvas/Helpers/FullScreenHelper.Win32.cs index 6cae5edd..cc109c54 100644 --- a/Ink Canvas/Helpers/FullScreenHelper.Win32.cs +++ b/Ink Canvas/Helpers/FullScreenHelper.Win32.cs @@ -81,7 +81,7 @@ namespace Ink_Canvas.Helpers public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); public static IntPtr GetWindowLongPtr(IntPtr hWnd, GetWindowLongFields nIndex) => - GetWindowLongPtr(hWnd, (int) nIndex); + GetWindowLongPtr(hWnd, (int)nIndex); public static IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex) { @@ -99,7 +99,7 @@ namespace Ink_Canvas.Helpers public static extern IntPtr GetWindowLongPtr_x64(IntPtr hWnd, int nIndex); public static IntPtr SetWindowLongPtr(IntPtr hWnd, GetWindowLongFields nIndex, IntPtr dwNewLong) => - SetWindowLongPtr(hWnd, (int) nIndex, dwNewLong); + SetWindowLongPtr(hWnd, (int)nIndex, dwNewLong); public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong) { diff --git a/Ink Canvas/Helpers/FullScreenHelper.cs b/Ink Canvas/Helpers/FullScreenHelper.cs index 3aed061f..a1dced48 100644 --- a/Ink Canvas/Helpers/FullScreenHelper.cs +++ b/Ink Canvas/Helpers/FullScreenHelper.cs @@ -67,12 +67,12 @@ namespace Ink_Canvas.Helpers //获取当前窗口的位置大小状态并保存 var placement = new WINDOWPLACEMENT(); - placement.Size = (uint) Marshal.SizeOf(placement); + placement.Size = (uint)Marshal.SizeOf(placement); Win32.User32.GetWindowPlacement(hwnd, ref placement); window.SetValue(BeforeFullScreenWindowPlacementProperty, placement); //修改窗口样式 - var style = (WindowStyles) Win32.User32.GetWindowLongPtr(hwnd, GetWindowLongFields.GWL_STYLE); + var style = (WindowStyles)Win32.User32.GetWindowLongPtr(hwnd, GetWindowLongFields.GWL_STYLE); window.SetValue(BeforeFullScreenWindowStyleProperty, style); //将窗口恢复到还原模式,在有标题栏的情况下最大化模式下无法全屏, //这里采用还原,不修改标题栏的方式 @@ -81,7 +81,7 @@ namespace Ink_Canvas.Helpers //去掉WS_MAXIMIZEBOX,禁用最大化,如果最大化会退出全屏 //去掉WS_MAXIMIZE,使窗口变成还原状态,不使用ShowWindow(hwnd, ShowWindowCommands.SW_RESTORE),避免看到窗口变成还原状态这一过程(也避免影响窗口的Visible状态) style &= (~(WindowStyles.WS_THICKFRAME | WindowStyles.WS_MAXIMIZEBOX | WindowStyles.WS_MAXIMIZE)); - Win32.User32.SetWindowLongPtr(hwnd, GetWindowLongFields.GWL_STYLE, (IntPtr) style); + Win32.User32.SetWindowLongPtr(hwnd, GetWindowLongFields.GWL_STYLE, (IntPtr)style); //禁用 DWM 过渡动画 忽略返回值,若DWM关闭不做处理 Win32.Dwmapi.DwmSetWindowAttribute(hwnd, DWMWINDOWATTRIBUTE.DWMWA_TRANSITIONS_FORCEDISABLED, 1, @@ -95,8 +95,8 @@ namespace Ink_Canvas.Helpers //不能用 placement 的坐标,placement是工作区坐标,不是屏幕坐标。 //使用窗口当前的矩形调用下设置窗口位置和尺寸的方法,让Hook来进行调整窗口位置和尺寸到全屏模式 - Win32.User32.SetWindowPos(hwnd, (IntPtr) HwndZOrder.HWND_TOPMOST, rect.Left, rect.Top, rect.Width, - rect.Height, (int) WindowPositionFlags.SWP_NOZORDER); + Win32.User32.SetWindowPos(hwnd, (IntPtr)HwndZOrder.HWND_TOPMOST, rect.Left, rect.Top, rect.Width, + rect.Height, (int)WindowPositionFlags.SWP_NOZORDER); } } } @@ -139,7 +139,7 @@ namespace Ink_Canvas.Helpers //不要改变Style里的WS_MAXIMIZE,否则会使窗口变成最大化状态,但是尺寸不对 //也不要设置回Style里的WS_MINIMIZE,否则会导致窗口最小化按钮显示成还原按钮 Win32.User32.SetWindowLongPtr(hwnd, GetWindowLongFields.GWL_STYLE, - (IntPtr) (style & (~(WindowStyles.WS_MAXIMIZE | WindowStyles.WS_MINIMIZE)))); + (IntPtr)(style & (~(WindowStyles.WS_MAXIMIZE | WindowStyles.WS_MINIMIZE)))); if ((style & WindowStyles.WS_MINIMIZE) != 0) { @@ -201,7 +201,7 @@ namespace Ink_Canvas.Helpers try { //得到WINDOWPOS结构体 - var pos = (WindowPosition) Marshal.PtrToStructure(lParam, typeof(WindowPosition)); + var pos = (WindowPosition)Marshal.PtrToStructure(lParam, typeof(WindowPosition)); if ((pos.Flags & WindowPositionFlags.SWP_NOMOVE) != 0 && (pos.Flags & WindowPositionFlags.SWP_NOSIZE) != 0) @@ -245,7 +245,7 @@ namespace Ink_Canvas.Helpers //使用目标矩形获取显示器信息 var monitor = Win32.User32.MonitorFromRect(targetRect, MonitorFlag.MONITOR_DEFAULTTOPRIMARY); var info = new MonitorInfo(); - info.Size = (uint) Marshal.SizeOf(info); + info.Size = (uint)Marshal.SizeOf(info); if (Win32.User32.GetMonitorInfo(monitor, ref info)) { //基于显示器信息设置窗口尺寸位置 diff --git a/Ink Canvas/Helpers/HardwareAcceleratedInkProcessor.cs b/Ink Canvas/Helpers/HardwareAcceleratedInkProcessor.cs index 9ac6f811..ccea253c 100644 --- a/Ink Canvas/Helpers/HardwareAcceleratedInkProcessor.cs +++ b/Ink Canvas/Helpers/HardwareAcceleratedInkProcessor.cs @@ -24,11 +24,11 @@ namespace Ink_Canvas.Helpers // 创建硬件加速的渲染目标 _renderTarget = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32); _drawingVisual = new DrawingVisual(); - + // 启用硬件加速 RenderOptions.SetBitmapScalingMode(_drawingVisual, BitmapScalingMode.HighQuality); RenderOptions.SetEdgeMode(_drawingVisual, EdgeMode.Aliased); - + _isInitialized = true; } @@ -46,10 +46,10 @@ namespace Ink_Canvas.Helpers { // 使用PathGeometry进行硬件加速的曲线拟合 var pathGeometry = CreateSmoothPathGeometry(originalStroke.StylusPoints); - + // 将PathGeometry转换回StylusPoint集合 var smoothedPoints = ConvertPathGeometryToStylusPoints(pathGeometry, originalStroke.StylusPoints); - + return new Stroke(new StylusPointCollection(smoothedPoints)) { DrawingAttributes = originalStroke.DrawingAttributes.Clone() @@ -69,11 +69,11 @@ namespace Ink_Canvas.Helpers { var pathGeometry = new PathGeometry(); var pathFigure = new PathFigure(); - + if (points.Count < 2) return pathGeometry; - + pathFigure.StartPoint = new Point(points[0].X, points[0].Y); - + // 使用贝塞尔曲线段创建平滑路径,增加插点密度 for (int i = 0; i < points.Count - 1; i += 2) // 从i+=3改为i+=2,增加插点密度 { @@ -84,7 +84,7 @@ namespace Ink_Canvas.Helpers var bezierSegment = new BezierSegment(p1, p2, p3, true); pathFigure.Segments.Add(bezierSegment); } - + pathGeometry.Figures.Add(pathFigure); return pathGeometry; } @@ -96,11 +96,11 @@ namespace Ink_Canvas.Helpers { var result = new List(); var flattened = pathGeometry.GetFlattenedPathGeometry(); - + foreach (var figure in flattened.Figures) { result.Add(new StylusPoint(figure.StartPoint.X, figure.StartPoint.Y, 0.5f)); - + foreach (var segment in figure.Segments) { if (segment is LineSegment lineSegment) @@ -116,10 +116,10 @@ namespace Ink_Canvas.Helpers } } } - + // 保持原始压感信息 InterpolatePressure(result, originalPoints); - + return result; } @@ -129,13 +129,13 @@ namespace Ink_Canvas.Helpers private void InterpolatePressure(List smoothedPoints, StylusPointCollection originalPoints) { if (originalPoints.Count == 0 || smoothedPoints.Count == 0) return; - + for (int i = 0; i < smoothedPoints.Count; i++) { double ratio = (double)i / (smoothedPoints.Count - 1); int originalIndex = (int)(ratio * (originalPoints.Count - 1)); originalIndex = Math.Max(0, Math.Min(originalIndex, originalPoints.Count - 1)); - + var point = smoothedPoints[i]; float pressure = originalPoints[originalIndex].PressureFactor; smoothedPoints[i] = new StylusPoint(point.X, point.Y, Math.Max(pressure, 0.1f)); @@ -148,23 +148,23 @@ namespace Ink_Canvas.Helpers public static StylusPoint[] ParallelBezierInterpolation(StylusPoint[] controlPoints, int segments = 32) { if (controlPoints.Length < 4) return controlPoints; - + var result = new StylusPoint[segments * (controlPoints.Length / 4)]; - + Parallel.For(0, controlPoints.Length / 4, segmentIndex => { var p0 = controlPoints[segmentIndex * 4]; var p1 = controlPoints[segmentIndex * 4 + 1]; var p2 = controlPoints[segmentIndex * 4 + 2]; var p3 = controlPoints[segmentIndex * 4 + 3]; - + for (int i = 0; i < segments; i++) { double t = (double)i / (segments - 1); result[segmentIndex * segments + i] = CubicBezierFast(p0, p1, p2, p3, t); } }); - + return result; } @@ -178,11 +178,11 @@ namespace Ink_Canvas.Helpers double uu = u * u; double uuu = uu * u; double ttt = tt * t; - + double x = uuu * p0.X + 3 * uu * t * p1.X + 3 * u * tt * p2.X + ttt * p3.X; double y = uuu * p0.Y + 3 * uu * t * p1.Y + 3 * u * tt * p2.Y + ttt * p3.Y; float pressure = (float)(p1.PressureFactor * u + p2.PressureFactor * t); - + return new StylusPoint(x, y, Math.Max(pressure, 0.1f)); } @@ -239,17 +239,17 @@ namespace Ink_Canvas.Helpers case InkSmoothingQuality.HighPerformance: SmoothingStrength = 0.4; ResampleInterval = 2.0; - InterpolationSteps = 16; + InterpolationSteps = 16; break; case InkSmoothingQuality.Balanced: SmoothingStrength = 0.6; ResampleInterval = 1.2; - InterpolationSteps = 32; + InterpolationSteps = 32; break; case InkSmoothingQuality.HighQuality: SmoothingStrength = 0.8; ResampleInterval = 0.8; - InterpolationSteps = 64; + InterpolationSteps = 64; break; } } diff --git a/Ink Canvas/Helpers/IACoreDllExtractor.cs b/Ink Canvas/Helpers/IACoreDllExtractor.cs index de717826..a2f9dc37 100644 --- a/Ink Canvas/Helpers/IACoreDllExtractor.cs +++ b/Ink Canvas/Helpers/IACoreDllExtractor.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.Reflection; -using System.Windows; namespace Ink_Canvas.Helpers { @@ -13,7 +12,7 @@ namespace Ink_Canvas.Helpers { private static readonly string[] RequiredDlls = { "IACore.dll", - "IALoader.dll", + "IALoader.dll", "IAWinFX.dll" }; @@ -30,7 +29,7 @@ namespace Ink_Canvas.Helpers foreach (string dllName in RequiredDlls) { string targetPath = Path.Combine(appDirectory, dllName); - + // 检查文件是否已存在且有效 if (File.Exists(targetPath) && IsValidDll(targetPath)) { @@ -109,7 +108,7 @@ namespace Ink_Canvas.Helpers return false; FileInfo fileInfo = new FileInfo(filePath); - + // 检查文件大小(空文件或过小的文件可能无效) if (fileInfo.Length < 1024) // 小于1KB可能无效 return false; @@ -140,11 +139,11 @@ namespace Ink_Canvas.Helpers try { string appDirectory = AppDomain.CurrentDomain.BaseDirectory; - + foreach (string dllName in RequiredDlls) { string filePath = Path.Combine(appDirectory, dllName); - + if (File.Exists(filePath)) { try diff --git a/Ink Canvas/Helpers/InkSmoothingManager.cs b/Ink Canvas/Helpers/InkSmoothingManager.cs index c6490e41..3d2e5db5 100644 --- a/Ink Canvas/Helpers/InkSmoothingManager.cs +++ b/Ink Canvas/Helpers/InkSmoothingManager.cs @@ -25,7 +25,7 @@ namespace Ink_Canvas.Helpers _uiDispatcher = uiDispatcher; _config = InkSmoothingConfig.FromSettings(); _config.ApplyQualitySettings(); - + _asyncSmoothing = new AsyncAdvancedBezierSmoothing(uiDispatcher) { SmoothingStrength = _config.SmoothingStrength, @@ -34,7 +34,7 @@ namespace Ink_Canvas.Helpers UseHardwareAcceleration = _config.UseHardwareAcceleration, MaxConcurrentTasks = _config.MaxConcurrentTasks }; - + _hardwareProcessor = new HardwareAcceleratedInkProcessor(); _performanceMonitor = new InkSmoothingPerformanceMonitor(); } @@ -42,7 +42,7 @@ namespace Ink_Canvas.Helpers /// /// 平滑笔画(自动选择最佳方法) /// - public async Task SmoothStrokeAsync(Stroke originalStroke, + public async Task SmoothStrokeAsync(Stroke originalStroke, Action onCompleted = null, CancellationToken cancellationToken = default) { @@ -142,7 +142,7 @@ namespace Ink_Canvas.Helpers { var newConfig = InkSmoothingConfig.FromSettings(); newConfig.ApplyQualitySettings(); - + _asyncSmoothing.SmoothingStrength = newConfig.SmoothingStrength; _asyncSmoothing.ResampleInterval = newConfig.ResampleInterval; _asyncSmoothing.InterpolationSteps = newConfig.InterpolationSteps; @@ -189,11 +189,11 @@ namespace Ink_Canvas.Helpers public static InkSmoothingConfig GetRecommendedConfig() { var config = new InkSmoothingConfig(); - + // 根据系统性能调整配置 var processorCount = Environment.ProcessorCount; var isHardwareAccelerated = IsHardwareAccelerationSupported(); - + if (processorCount >= 4 && isHardwareAccelerated) { // 降低高质量模式的门槛,4核以上且支持硬件加速就使用高质量 @@ -218,7 +218,7 @@ namespace Ink_Canvas.Helpers config.UseAsyncProcessing = false; config.MaxConcurrentTasks = 1; } - + config.ApplyQualitySettings(); return config; } diff --git a/Ink Canvas/Helpers/IsOutsideOfScreenHelper.cs b/Ink Canvas/Helpers/IsOutsideOfScreenHelper.cs index 618169ba..2621572b 100644 --- a/Ink Canvas/Helpers/IsOutsideOfScreenHelper.cs +++ b/Ink Canvas/Helpers/IsOutsideOfScreenHelper.cs @@ -5,11 +5,15 @@ using System.Windows.Forms; using System.Windows.Interop; using Point = System.Windows.Point; -namespace Ink_Canvas.Helpers { - internal class IsOutsideOfScreenHelper { - public static bool IsOutsideOfScreen(FrameworkElement target) { +namespace Ink_Canvas.Helpers +{ + internal class IsOutsideOfScreenHelper + { + public static bool IsOutsideOfScreen(FrameworkElement target) + { var hwndSource = (HwndSource)PresentationSource.FromVisual(target); - if (hwndSource is null) { + if (hwndSource is null) + { return true; } @@ -19,7 +23,8 @@ namespace Ink_Canvas.Helpers { var screens = Screen.AllScreens; return !screens.Any(x => x.Bounds.IntersectsWith(targetBounds)); - Rectangle GetPixelBoundsToScreen(FrameworkElement visual) { + Rectangle GetPixelBoundsToScreen(FrameworkElement visual) + { var pixelBoundsToScreen = Rect.Empty; pixelBoundsToScreen.Union(visual.PointToScreen(new Point(0, 0))); pixelBoundsToScreen.Union(visual.PointToScreen(new Point(visual.ActualWidth, 0))); diff --git a/Ink Canvas/Helpers/LogHelper.cs b/Ink Canvas/Helpers/LogHelper.cs index 29436f64..ce628ca8 100644 --- a/Ink Canvas/Helpers/LogHelper.cs +++ b/Ink Canvas/Helpers/LogHelper.cs @@ -33,12 +33,12 @@ namespace Ink_Canvas.Helpers { // 检查日志是否启用 if (MainWindow.Settings != null && MainWindow.Settings.Advanced != null && !MainWindow.Settings.Advanced.IsLogEnabled) return; - + string strLogType = logType.ToString(); try { string file; - + // 检查是否启用了日期保存功能 if (MainWindow.Settings != null && MainWindow.Settings.Advanced != null && MainWindow.Settings.Advanced.IsSaveLogByDate) { @@ -48,10 +48,10 @@ namespace Ink_Canvas.Helpers { Directory.CreateDirectory(logsPath); } - + // 检查Logs文件夹大小,如果超过5MB则清空 CheckAndCleanLogsFolder(logsPath); - + // 使用软件启动时间作为日志文件名 file = Path.Combine(logsPath, $"Log_{AppStartTime}.txt"); } @@ -59,12 +59,12 @@ namespace Ink_Canvas.Helpers { file = App.RootPath + LogFile; } - + if (!Directory.Exists(App.RootPath)) { Directory.CreateDirectory(App.RootPath); } - + var threadId = Thread.CurrentThread.ManagedThreadId; var callingMethod = new StackTrace(2, true).GetFrame(0); string callerInfo = ""; @@ -92,16 +92,16 @@ namespace Ink_Canvas.Helpers { 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) { @@ -113,7 +113,7 @@ namespace Ink_Canvas.Helpers } 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)) diff --git a/Ink Canvas/Helpers/PPTInkManager.cs b/Ink Canvas/Helpers/PPTInkManager.cs index 549ab5ab..0c548829 100644 --- a/Ink Canvas/Helpers/PPTInkManager.cs +++ b/Ink Canvas/Helpers/PPTInkManager.cs @@ -1,11 +1,9 @@ -using System; -using System.Collections.Generic; +using Microsoft.Office.Interop.PowerPoint; +using System; using System.IO; using System.Security.Cryptography; using System.Text; using System.Windows.Ink; -using System.Windows.Threading; -using Microsoft.Office.Interop.PowerPoint; namespace Ink_Canvas.Helpers { @@ -26,7 +24,7 @@ namespace Ink_Canvas.Helpers private string _currentPresentationId = ""; private readonly object _lockObject = new object(); private bool _disposed = false; - + // 墨迹锁定机制,防止翻页时的墨迹冲突 private DateTime _inkLockUntil = DateTime.MinValue; private int _lockedSlideIndex = -1; @@ -59,17 +57,17 @@ namespace Ink_Canvas.Helpers { // 生成演示文稿唯一标识符 _currentPresentationId = GeneratePresentationId(presentation); - + // 重新初始化内存流数组 var slideCount = presentation.Slides.Count; _memoryStreams = new MemoryStream[slideCount + 2]; - + // 如果启用自动保存,尝试加载已保存的墨迹 if (IsAutoSaveEnabled && !string.IsNullOrEmpty(AutoSaveLocation)) { LoadSavedStrokes(); } - + LogHelper.WriteLogToFile($"已初始化演示文稿墨迹管理: {presentation.Name}, 幻灯片数量: {slideCount}", LogHelper.LogType.Trace); } catch (Exception ex) @@ -102,11 +100,11 @@ namespace Ink_Canvas.Helpers var ms = new MemoryStream(); strokes.Save(ms); ms.Position = 0; - + // 释放旧的内存流 _memoryStreams[slideIndex]?.Dispose(); _memoryStreams[slideIndex] = ms; - + LogHelper.WriteLogToFile($"已保存第{slideIndex}页墨迹,大小: {ms.Length} bytes", LogHelper.LogType.Trace); } } @@ -214,11 +212,11 @@ namespace Ink_Canvas.Helpers var srcBuf = new byte[_memoryStreams[i].Length]; _memoryStreams[i].Position = 0; var byteLength = _memoryStreams[i].Read(srcBuf, 0, srcBuf.Length); - + var filePath = Path.Combine(folderPath, i.ToString("0000") + ".icstk"); File.WriteAllBytes(filePath, srcBuf); savedCount++; - + LogHelper.WriteLogToFile($"已保存第{i}页墨迹,大小: {byteLength} bytes", LogHelper.LogType.Trace); } else @@ -308,7 +306,7 @@ namespace Ink_Canvas.Helpers _memoryStreams[i]?.Dispose(); _memoryStreams[i] = null; } - + CurrentStrokes.Clear(); LogHelper.WriteLogToFile("已清除所有墨迹", LogHelper.LogType.Trace); } @@ -360,7 +358,7 @@ namespace Ink_Canvas.Helpers try { if (string.IsNullOrEmpty(filePath)) return "unknown"; - + using (var md5 = MD5.Create()) { byte[] hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(filePath)); diff --git a/Ink Canvas/Helpers/PPTManager.cs b/Ink Canvas/Helpers/PPTManager.cs index 59a2f553..1a2d5a90 100644 --- a/Ink Canvas/Helpers/PPTManager.cs +++ b/Ink Canvas/Helpers/PPTManager.cs @@ -1,18 +1,13 @@ -using System; +using Microsoft.Office.Interop.PowerPoint; +using System; using System.Collections.Generic; using System.Diagnostics; -using System.IO; using System.Linq; using System.Runtime.InteropServices; -using System.Security.Cryptography; using System.Text; using System.Threading; -using System.Threading.Tasks; using System.Timers; -using System.Windows; using System.Windows.Threading; -using Microsoft.Office.Core; -using Microsoft.Office.Interop.PowerPoint; using Application = System.Windows.Application; using Timer = System.Timers.Timer; @@ -514,7 +509,7 @@ namespace Ink_Canvas.Helpers { PresentationClose?.Invoke(pres); LogHelper.WriteLogToFile($"演示文稿已关闭: {pres?.Name}", LogHelper.LogType.Event); - + // 重新启动连接检查 _connectionCheckTimer?.Start(); } @@ -986,7 +981,7 @@ namespace Ink_Canvas.Helpers StopWpsProcessCheckTimer(); return; } - + // 检查前台WPS窗口是否存在(优化版) bool isForegroundWpsWindowActive = IsForegroundWpsWindowStillActiveOptimized(); diff --git a/Ink Canvas/Helpers/PPTUIManager.cs b/Ink Canvas/Helpers/PPTUIManager.cs index 3bd1713d..ca235958 100644 --- a/Ink Canvas/Helpers/PPTUIManager.cs +++ b/Ink Canvas/Helpers/PPTUIManager.cs @@ -77,13 +77,13 @@ namespace Ink_Canvas.Helpers { _mainWindow.BtnPPTSlideShow.Visibility = Visibility.Collapsed; _mainWindow.BtnPPTSlideShowEnd.Visibility = Visibility.Visible; - + if (currentSlide > 0 && totalSlides > 0) { _mainWindow.PPTBtnPageNow.Text = currentSlide.ToString(); _mainWindow.PPTBtnPageTotal.Text = $"/ {totalSlides}"; } - + UpdateNavigationPanelsVisibility(); UpdateNavigationButtonStyles(); } @@ -147,25 +147,25 @@ namespace Ink_Canvas.Helpers if (displayOption.Length >= 4) { var options = displayOption.ToCharArray(); - + // 左下角面板 if (options[0] == '2') AnimationsHelper.ShowWithFadeIn(_mainWindow.LeftBottomPanelForPPTNavigation); else _mainWindow.LeftBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; - + // 右下角面板 if (options[1] == '2') AnimationsHelper.ShowWithFadeIn(_mainWindow.RightBottomPanelForPPTNavigation); else _mainWindow.RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; - + // 左侧面板 if (options[2] == '2') AnimationsHelper.ShowWithFadeIn(_mainWindow.LeftSidePanelForPPTNavigation); else _mainWindow.LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; - + // 右侧面板 if (options[3] == '2') AnimationsHelper.ShowWithFadeIn(_mainWindow.RightSidePanelForPPTNavigation); @@ -230,10 +230,10 @@ namespace Ink_Canvas.Helpers try { var visibility = show ? Visibility.Visible : Visibility.Collapsed; - + if (_mainWindow.BtnExitPptFromSidebarLeft != null) _mainWindow.BtnExitPptFromSidebarLeft.Visibility = visibility; - + if (_mainWindow.BtnExitPptFromSidebarRight != null) _mainWindow.BtnExitPptFromSidebarRight.Visibility = visibility; } @@ -290,7 +290,7 @@ namespace Ink_Canvas.Helpers if (sideOption.Length < 3) return; var options = sideOption.ToCharArray(); - + // 页码按钮显示 var pageButtonVisibility = options[0] == '2' ? Visibility.Visible : Visibility.Collapsed; _mainWindow.PPTLSPageButton.Visibility = pageButtonVisibility; @@ -319,7 +319,7 @@ namespace Ink_Canvas.Helpers if (bottomOption.Length < 3) return; var options = bottomOption.ToCharArray(); - + // 页码按钮显示 var pageButtonVisibility = options[0] == '2' ? Visibility.Visible : Visibility.Collapsed; _mainWindow.PPTLBPageButton.Visibility = pageButtonVisibility; @@ -345,7 +345,7 @@ namespace Ink_Canvas.Helpers try { Color backgroundColor, borderColor, foregroundColor, feedbackColor; - + if (isDarkTheme) { backgroundColor = Color.FromRgb(39, 39, 42); @@ -364,7 +364,7 @@ namespace Ink_Canvas.Helpers // 应用背景和边框颜色 var backgroundBrush = new SolidColorBrush(backgroundColor); var borderBrush = new SolidColorBrush(borderColor); - + leftBorder.Background = backgroundBrush; leftBorder.BorderBrush = borderBrush; rightBorder.Background = backgroundBrush; diff --git a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherButton.cs b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherButton.cs index 4ccc2abb..54eb84bd 100644 --- a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherButton.cs +++ b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherButton.cs @@ -1,9 +1,9 @@ +using iNKORE.UI.WPF.Modern.Controls; using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; -using iNKORE.UI.WPF.Modern.Controls; namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { @@ -16,17 +16,17 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher /// 父插件 /// private readonly SuperLauncherPlugin _plugin; - + /// /// 实际按钮控件 /// private readonly SimpleStackPanel _panel; - + /// /// 获取按钮UI元素 /// public UIElement Element => _panel; - + /// /// 构造函数 /// @@ -37,7 +37,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { _plugin = plugin; LogHelper.WriteLogToFile("开始创建启动台按钮"); - + // 创建SimpleStackPanel _panel = new SimpleStackPanel { @@ -48,13 +48,13 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher Margin = new Thickness(0, -2, 0, 0), Background = Brushes.Transparent }; - + LogHelper.WriteLogToFile("创建SimpleStackPanel完成"); - + // 添加图标 var image = CreateIconImage(); _panel.Children.Add(image); - + // 添加文本 TextBlock textBlock = new TextBlock { @@ -65,18 +65,18 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher TextAlignment = TextAlignment.Center }; _panel.Children.Add(textBlock); - + // 设置鼠标事件 _panel.MouseDown += Panel_MouseDown; _panel.MouseUp += Panel_MouseUp; _panel.MouseLeave += Panel_MouseLeave; - + // 右键菜单支持 _panel.ContextMenu = CreateContextMenu(); - + // 设置工具提示 _panel.ToolTip = "启动台"; - + LogHelper.WriteLogToFile("启动台按钮创建完成"); } catch (Exception ex) @@ -85,7 +85,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher LogHelper.NewLog(ex); } } - + /// /// 创建右键菜单 /// @@ -95,31 +95,31 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { // 创建菜单 ContextMenu menu = new ContextMenu(); - + // 创建位置切换菜单项 MenuItem positionMenuItem = new MenuItem(); - positionMenuItem.Header = _plugin.Config.ButtonPosition == LauncherButtonPosition.Left ? + positionMenuItem.Header = _plugin.Config.ButtonPosition == LauncherButtonPosition.Left ? "移至右侧" : "移至左侧"; - positionMenuItem.Click += (s, e) => + positionMenuItem.Click += (s, e) => { // 切换位置 - _plugin.Config.ButtonPosition = _plugin.Config.ButtonPosition == LauncherButtonPosition.Left ? + _plugin.Config.ButtonPosition = _plugin.Config.ButtonPosition == LauncherButtonPosition.Left ? LauncherButtonPosition.Right : LauncherButtonPosition.Left; - + // 更新按钮位置 _plugin.UpdateButtonPosition(); - + // 保存配置 _plugin.SaveConfig(); - + LogHelper.WriteLogToFile($"通过右键菜单切换启动台按钮位置为: {_plugin.Config.ButtonPosition}"); }; menu.Items.Add(positionMenuItem); - + // 添加设置菜单项 MenuItem settingsMenuItem = new MenuItem(); settingsMenuItem.Header = "打开设置"; - settingsMenuItem.Click += (s, e) => + settingsMenuItem.Click += (s, e) => { // 打开插件设置窗口 var mainWindow = Application.Current.MainWindow; @@ -142,7 +142,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher } }; menu.Items.Add(settingsMenuItem); - + return menu; } catch (Exception ex) @@ -151,7 +151,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher return null; } } - + /// /// 获取实际的UI元素 /// @@ -160,7 +160,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { return _panel; } - + /// /// 创建图标图像 /// @@ -174,40 +174,40 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher Height = 17, Margin = new Thickness(0, 3, 0, 0) }; - + // 设置位图缩放模式 RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.HighQuality); - + // 创建绘图图像 DrawingImage drawingImage = new DrawingImage(); DrawingGroup drawingGroup = new DrawingGroup(); drawingGroup.ClipGeometry = Geometry.Parse("M0,0 V24 H24 V0 H0 Z"); - + // 使用提供的应用网格图标 GeometryDrawing geometryDrawing = new GeometryDrawing { Brush = new SolidColorBrush(Color.FromRgb(0x1B, 0x1B, 0x1B)), Geometry = Geometry.Parse("F0 M24,24z M0,0z M4.41721,4.29873C4.35178,4.29873,4.29873,4.35178,4.29873,4.41721L4.29873,9.15646C4.29873,9.22189,4.35178,9.27494,4.41721,9.27494L9.15646,9.27494C9.22189,9.27494,9.27494,9.22189,9.27494,9.15646L9.27494,4.41721C9.27494,4.35178,9.22189,4.29873,9.15646,4.29873L4.41721,4.29873z M2.64,4.41721C2.64,3.43569,3.43569,2.64,4.41721,2.64L9.15646,2.64C10.138,2.64,10.9337,3.43569,10.9337,4.41721L10.9337,9.15646C10.9337,10.138,10.138,10.9337,9.15646,10.9337L4.41721,10.9337C3.43569,10.9337,2.64,10.138,2.64,9.15646L2.64,4.41721z M14.8435,4.29873C14.7781,4.29873,14.7251,4.35178,14.7251,4.41721L14.7251,9.15646C14.7251,9.22189,14.7781,9.27494,14.8435,9.27494L19.5828,9.27494C19.6482,9.27494,19.7013,9.22189,19.7013,9.15646L19.7013,4.41721C19.7013,4.35178,19.6482,4.29873,19.5828,4.29873L14.8435,4.29873z M13.0663,4.41721C13.0663,3.43569,13.862,2.64,14.8435,2.64L19.5828,2.64C20.5643,2.64,21.36,3.43569,21.36,4.41721L21.36,9.15646C21.36,10.138,20.5643,10.9337,19.5828,10.9337L14.8435,10.9337C13.862,10.9337,13.0663,10.138,13.0663,9.15646L13.0663,4.41721z M14.8435,14.7251C14.7781,14.7251,14.7251,14.7781,14.7251,14.8435L14.7251,19.5828C14.7251,19.6482,14.7781,19.7013,14.8435,19.7013L19.5828,19.7013C19.6482,19.7013,19.7013,19.6482,19.7013,19.5828L19.7013,14.8435C19.7013,14.7781,19.6482,14.7251,19.5828,14.7251L14.8435,14.7251z M13.0663,14.8435C13.0663,13.862,13.862,13.0663,14.8435,13.0663L19.5828,13.0663C20.5643,13.0663,21.36,13.862,21.36,14.8435L21.36,19.5828C21.36,20.5643,20.5643,21.36,19.5828,21.36L14.8435,21.36C13.862,21.36,13.0663,20.5643,13.0663,19.5828L13.0663,14.8435z M4.41721,14.7251C4.35178,14.7251,4.29873,14.7781,4.29873,14.8435L4.29873,19.5828C4.29873,19.6482,4.35178,19.7013,4.41721,19.7013L9.15646,19.7013C9.22189,19.7013,9.27494,19.6482,9.27494,19.5828L9.27494,14.8435C9.27494,14.7781,9.22189,14.7251,9.15646,14.7251L4.41721,14.7251z M2.64,14.8435C2.64,13.862,3.43569,13.0663,4.41721,13.0663L9.15646,13.0663C10.138,13.0663,10.9337,13.862,10.9337,14.8435L10.9337,19.5828C10.9337,20.5643,10.138,21.36,9.15646,21.36L4.41721,21.36C3.43569,21.36,2.64,20.5643,2.64,19.5828L2.64,14.8435z") }; - + drawingGroup.Children.Add(geometryDrawing); - + // 设置图像源 drawingImage.Drawing = drawingGroup; image.Source = drawingImage; - + return image; } catch (Exception ex) { LogHelper.WriteLogToFile($"创建图标图像时出错: {ex.Message}", LogHelper.LogType.Error); LogHelper.NewLog(ex); - + // 返回一个空图像 return new Image(); } } - + /// /// 鼠标按下事件 /// @@ -224,7 +224,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher LogHelper.WriteLogToFile($"启动台按钮鼠标按下事件出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 鼠标抬起事件 /// @@ -237,14 +237,14 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { return; } - + // 恢复背景 _panel.Background = Brushes.Transparent; LogHelper.WriteLogToFile("启动台按钮鼠标抬起,准备显示启动台窗口"); - + // 获取按钮在屏幕上的位置 Point buttonPosition = _panel.PointToScreen(new Point(_panel.ActualWidth / 2, 0)); - + // 显示启动台窗口 _plugin.ShowLauncherWindow(buttonPosition); } @@ -254,7 +254,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher LogHelper.NewLog(ex); } } - + /// /// 鼠标离开事件 /// @@ -271,4 +271,4 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher } } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherModels.cs b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherModels.cs index a3a63d15..9b6ac63b 100644 --- a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherModels.cs +++ b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherModels.cs @@ -1,3 +1,5 @@ +using Microsoft.Win32; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; @@ -8,8 +10,6 @@ using System.Windows; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; -using Microsoft.Win32; -using Newtonsoft.Json; namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { @@ -22,13 +22,13 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher /// 左侧 /// Left, - + /// /// 右侧 /// Right } - + /// /// 启动台配置 /// @@ -38,13 +38,13 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher /// 启动台按钮位置 /// public LauncherButtonPosition ButtonPosition { get; set; } = LauncherButtonPosition.Right; - + /// /// 启动台应用程序列表 /// public List Items { get; set; } = new List(); } - + /// /// 启动台应用项 /// @@ -54,33 +54,33 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher /// 应用程序名称 /// public string Name { get; set; } - + /// /// 应用程序路径 /// public string Path { get; set; } - + /// /// 是否可见 /// public bool IsVisible { get; set; } = true; - + /// /// 在启动台中的位置(0-39) /// public int Position { get; set; } = -1; - + /// /// 是否已固定位置 /// public bool IsPositionFixed { get; set; } = false; - + /// /// 图标缓存 /// [JsonIgnore] private ImageSource _iconCache; - + /// /// 获取应用程序图标 /// @@ -93,7 +93,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { return _iconCache; } - + try { if (File.Exists(Path)) @@ -106,7 +106,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); - + icon.Dispose(); return _iconCache; } @@ -126,7 +126,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher string[] parts = iconPath.Split(','); string iconFile = parts[0].Trim('"'); int iconIndex = parts.Length > 1 ? Convert.ToInt32(parts[1]) : 0; - + if (File.Exists(iconFile)) { Icon icon = IconExtractor.Extract(iconFile, iconIndex, true); @@ -136,7 +136,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); - + icon.Dispose(); return _iconCache; } @@ -150,12 +150,12 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { LogHelper.WriteLogToFile($"获取应用图标时出错: {ex.Message}", LogHelper.LogType.Error); } - + // 返回默认图标 return GetDefaultIcon(); } } - + /// /// 获取默认图标 /// @@ -179,7 +179,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); - + icon.Dispose(); return _iconCache; } @@ -190,7 +190,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher LogHelper.WriteLogToFile($"获取资源管理器图标时出错: {ex.Message}", LogHelper.LogType.Warning); // 如果获取Windows图标失败,回退到默认图标 } - + // 回退到备用图标 string explorerIconPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "Icons-Fluent", "ic_fluent_folder_24_regular.png"); if (File.Exists(explorerIconPath)) @@ -201,7 +201,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher return _iconCache; } } - + // 返回一个简单的默认图标 string iconPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "Icons-png", "icc.png"); if (File.Exists(iconPath)) @@ -211,7 +211,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher _iconCache = image; return _iconCache; } - + // 如果还是没有找到,尝试使用应用程序图标 string appIconPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "Icons-Fluent", "ic_fluent_apps_24_regular.png"); if (File.Exists(appIconPath)) @@ -222,14 +222,14 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher return _iconCache; } } - catch (Exception ex) + catch (Exception ex) { LogHelper.WriteLogToFile($"获取默认图标时出错: {ex.Message}", LogHelper.LogType.Error); } - + return null; } - + /// /// 启动应用程序 /// @@ -242,7 +242,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher LogHelper.WriteLogToFile("无法启动应用程序:路径为空", LogHelper.LogType.Error); return; } - + // 检查文件是否存在 if (!File.Exists(Path) && !Path.Contains(":\\")) { @@ -264,7 +264,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher }; Process.Start(psi); } - + LogHelper.WriteLogToFile($"已启动应用程序: {Path}"); } catch (Exception ex) @@ -274,7 +274,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher } } } - + /// /// 图标提取工具类 /// @@ -294,7 +294,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher IntPtr large; IntPtr small; ExtractIconEx(file, index, out large, out small, 1); - + try { return Icon.FromHandle(largeIcon ? large : small); @@ -307,7 +307,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { if (large != IntPtr.Zero) DestroyIcon(large); - + if (small != IntPtr.Zero) DestroyIcon(small); } @@ -317,7 +317,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher return null; } } - + [DllImport("Shell32.dll", EntryPoint = "ExtractIconEx")] private static extern int ExtractIconEx( [MarshalAs(UnmanagedType.LPStr)] string lpszFile, @@ -325,8 +325,8 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher out IntPtr phiconLarge, out IntPtr phiconSmall, int nIcons); - + [DllImport("User32.dll")] private static extern int DestroyIcon(IntPtr hIcon); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherSettingsControl.xaml.cs b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherSettingsControl.xaml.cs index 9d254245..6666f10d 100644 --- a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherSettingsControl.xaml.cs +++ b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherSettingsControl.xaml.cs @@ -1,10 +1,10 @@ +using Ink_Canvas.Windows; +using Microsoft.Win32; using System; using System.ComponentModel; using System.IO; using System.Windows; using System.Windows.Controls; -using Ink_Canvas.Windows; -using Microsoft.Win32; namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { @@ -17,7 +17,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher /// 父插件 /// private readonly SuperLauncherPlugin _plugin; - + /// /// 构造函数 /// @@ -25,20 +25,20 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher public LauncherSettingsControl(SuperLauncherPlugin plugin) { InitializeComponent(); - + _plugin = plugin; - + // 设置按钮位置 RbtnLeft.IsChecked = _plugin.Config.ButtonPosition == LauncherButtonPosition.Left; RbtnRight.IsChecked = _plugin.Config.ButtonPosition == LauncherButtonPosition.Right; - + // 绑定应用列表 DgApps.ItemsSource = _plugin.LauncherItems; - + // 初始化按钮状态 UpdateButtonStates(); } - + /// /// 更新按钮状态 /// @@ -48,16 +48,16 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher BtnEdit.IsEnabled = hasSelection; BtnDelete.IsEnabled = hasSelection; } - + /// /// 位置单选按钮选择事件 /// private void RbtnPosition_Checked(object sender, RoutedEventArgs e) { if (!IsLoaded) return; - + LauncherButtonPosition oldPosition = _plugin.Config.ButtonPosition; - + if (sender == RbtnLeft) { _plugin.Config.ButtonPosition = LauncherButtonPosition.Left; @@ -66,7 +66,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { _plugin.Config.ButtonPosition = LauncherButtonPosition.Right; } - + // 如果位置发生变化,更新按钮位置 if (oldPosition != _plugin.Config.ButtonPosition) { @@ -74,10 +74,10 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { // 更新按钮位置 _plugin.UpdateButtonPosition(); - + // 保存配置 _plugin.SaveConfig(); - + LogHelper.WriteLogToFile($"启动台按钮位置已更改为: {_plugin.Config.ButtonPosition}"); } catch (Exception ex) @@ -87,7 +87,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher } } } - + /// /// 添加按钮点击事件 /// @@ -103,7 +103,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher IsVisible = true, Position = -1 // 让插件管理器分配位置 }; - + // 直接显示编辑对话框 EditLauncherItem(item, true); } @@ -113,7 +113,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher MessageBox.Show($"添加启动项时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } - + /// /// 编辑应用按钮点击事件 /// @@ -124,7 +124,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher EditLauncherItem(item, false); } } - + /// /// 删除应用按钮点击事件 /// @@ -134,22 +134,22 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { // 确认删除 MessageBoxResult result = MessageBox.Show( - $"确定要删除 {item.Name} 吗?", - "删除确认", - MessageBoxButton.YesNo, + $"确定要删除 {item.Name} 吗?", + "删除确认", + MessageBoxButton.YesNo, MessageBoxImage.Question); - + if (result == MessageBoxResult.Yes) { // 从集合中移除 _plugin.LauncherItems.Remove(item); - + // 保存配置 _plugin.SaveConfig(); } } } - + /// /// 保存设置按钮点击事件 /// @@ -159,7 +159,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { // 保存配置 _plugin.SaveConfig(); - + // 如果插件已启用,重新加载启动台按钮 if (_plugin.IsEnabled) { @@ -170,7 +170,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { // 如果插件未启用,则启用它 _plugin.Enable(); - + // 通知PluginSettingsWindow刷新插件列表 var window = Window.GetWindow(this); if (window is PluginSettingsWindow pluginSettingsWindow) @@ -179,7 +179,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher pluginSettingsWindow.RefreshPluginList(); } } - + MessageBox.Show("设置已保存并应用!", "提示", MessageBoxButton.OK, MessageBoxImage.Information); } catch (Exception ex) @@ -188,7 +188,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher MessageBox.Show($"保存设置时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } - + /// /// 应用项选择变更事件 /// @@ -196,7 +196,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { UpdateButtonStates(); } - + /// /// 编辑启动项 /// @@ -213,63 +213,63 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher WindowStartupLocation = WindowStartupLocation.CenterScreen, ResizeMode = ResizeMode.NoResize }; - + // 创建编辑表单 Grid grid = new Grid { Margin = new Thickness(20) }; - + grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); - + grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(80) }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); - + // 名称输入框 - TextBlock nameLabel = new TextBlock - { - Text = "名称:", - VerticalAlignment = VerticalAlignment.Center + TextBlock nameLabel = new TextBlock + { + Text = "名称:", + VerticalAlignment = VerticalAlignment.Center }; - TextBox nameTextBox = new TextBox - { - Text = item.Name, - Margin = new Thickness(0, 5, 0, 5) + TextBox nameTextBox = new TextBox + { + Text = item.Name, + Margin = new Thickness(0, 5, 0, 5) }; - + Grid.SetRow(nameLabel, 0); Grid.SetColumn(nameLabel, 0); Grid.SetRow(nameTextBox, 0); Grid.SetColumn(nameTextBox, 1); - + grid.Children.Add(nameLabel); grid.Children.Add(nameTextBox); - + // 路径输入框 - TextBlock pathLabel = new TextBlock - { - Text = "路径:", - VerticalAlignment = VerticalAlignment.Center + TextBlock pathLabel = new TextBlock + { + Text = "路径:", + VerticalAlignment = VerticalAlignment.Center }; Grid pathGrid = new Grid(); pathGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); pathGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength() }); - - TextBox pathTextBox = new TextBox - { - Text = item.Path, - Margin = new Thickness(0, 5, 5, 5) + + TextBox pathTextBox = new TextBox + { + Text = item.Path, + Margin = new Thickness(0, 5, 5, 5) }; - Button browseButton = new Button - { - Content = "浏览", + Button browseButton = new Button + { + Content = "浏览", Padding = new Thickness(5, 0, 5, 0), Margin = new Thickness(0, 5, 0, 5) }; - - browseButton.Click += (s, e) => + + browseButton.Click += (s, e) => { OpenFileDialog dialog = new OpenFileDialog { @@ -278,11 +278,11 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher Multiselect = false, FileName = pathTextBox.Text }; - + if (dialog.ShowDialog() == true) { pathTextBox.Text = dialog.FileName; - + // 如果选择的是.exe文件,自动获取文件名填入名称字段 if (Path.GetExtension(dialog.FileName).ToLower() == ".exe") { @@ -295,20 +295,20 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher } } }; - + Grid.SetColumn(pathTextBox, 0); Grid.SetColumn(browseButton, 1); pathGrid.Children.Add(pathTextBox); pathGrid.Children.Add(browseButton); - + Grid.SetRow(pathLabel, 1); Grid.SetColumn(pathLabel, 0); Grid.SetRow(pathGrid, 1); Grid.SetColumn(pathGrid, 1); - + grid.Children.Add(pathLabel); grid.Children.Add(pathGrid); - + // 确认和取消按钮 StackPanel buttonPanel = new StackPanel { @@ -316,7 +316,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 10, 0, 0) }; - + Button okButton = new Button { Content = "确定", @@ -324,15 +324,15 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher Margin = new Thickness(0, 0, 10, 0), IsDefault = true }; - + Button cancelButton = new Button { Content = "取消", Padding = new Thickness(15, 5, 15, 5), IsCancel = true }; - - okButton.Click += (s, e) => + + okButton.Click += (s, e) => { // 验证输入 if (string.IsNullOrWhiteSpace(nameTextBox.Text)) @@ -340,17 +340,17 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher MessageBox.Show("请输入应用名称!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); return; } - + if (string.IsNullOrWhiteSpace(pathTextBox.Text)) { MessageBox.Show("请输入应用路径!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); return; } - + // 更新项目 item.Name = nameTextBox.Text; item.Path = pathTextBox.Text; - + // 如果是新建,添加到集合 if (isNew) { @@ -363,34 +363,34 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { view.Refresh(); } - + // 保存配置 _plugin.SaveConfig(); } - + editWindow.DialogResult = true; editWindow.Close(); }; - - cancelButton.Click += (s, e) => + + cancelButton.Click += (s, e) => { editWindow.DialogResult = false; editWindow.Close(); }; - + buttonPanel.Children.Add(okButton); buttonPanel.Children.Add(cancelButton); - + Grid.SetRow(buttonPanel, 2); Grid.SetColumnSpan(buttonPanel, 2); - + grid.Children.Add(buttonPanel); - + // 设置窗口内容 editWindow.Content = grid; - + // 显示窗口 editWindow.ShowDialog(); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherWindow.xaml.cs b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherWindow.xaml.cs index a1978d29..affaf22f 100644 --- a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherWindow.xaml.cs +++ b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherWindow.xaml.cs @@ -23,39 +23,39 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher /// 父插件 /// private readonly SuperLauncherPlugin _plugin; - + /// /// 是否处于固定模式 /// private bool _isFixMode; - + /// /// 应用项按钮列表 /// private readonly Dictionary _appButtons = new Dictionary(); - + /// /// 拖拽中的按钮 /// private Button _draggingButton; - + /// /// 拖拽开始位置 /// private Point _dragStartPoint; - + /// /// 构造函数 /// public LauncherWindow(SuperLauncherPlugin plugin) { InitializeComponent(); - + _plugin = plugin; - + // 加载应用项 LoadLauncherItems(); - + // 添加鼠标按下事件(用于拖动窗口) MouseDown += (s, e) => { @@ -64,11 +64,11 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher DragMove(); } }; - + // 根据应用数量调整窗口大小 AdjustWindowSize(); } - + /// /// 加载启动台应用项 /// @@ -77,13 +77,13 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher // 清空现有应用项 AppPanel.Children.Clear(); _appButtons.Clear(); - + // 获取显示的应用项 var visibleItems = _plugin.LauncherItems .Where(item => item.IsVisible) .OrderBy(item => item.Position) .ToList(); - + foreach (var item in visibleItems) { // 创建应用按钮 @@ -93,23 +93,23 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher DataContext = item, Tag = item.Position }; - + // 添加点击事件 appButton.Click += AppButton_Click; - + // 在固定模式下,添加拖拽事件 appButton.PreviewMouseDown += AppButton_PreviewMouseDown; appButton.PreviewMouseMove += AppButton_PreviewMouseMove; appButton.PreviewMouseUp += AppButton_PreviewMouseUp; - + // 记录按钮和项目的对应关系 _appButtons.Add(appButton, item); - + // 添加到面板 AppPanel.Children.Add(appButton); } } - + /// /// 根据应用数量调整窗口大小 /// @@ -119,14 +119,14 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { // 每行最多显示4个应用 const int appsPerRow = 4; - + // 计算行数 int visibleCount = _appButtons.Count; int rowCount = (int)Math.Ceiling(visibleCount / (double)appsPerRow); - + // 设置窗口宽度(每个应用90像素宽 = 80 + 5*2) Width = Math.Min(appsPerRow * 90 + 40, 400); // 最大宽度400 - + // 设置窗口高度(每个应用90像素高 = 80 + 5*2) Height = Math.Min(rowCount * 90 + 60, 600); // 最大高度600,标题栏40 + 边距20 } @@ -135,7 +135,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher LogHelper.WriteLogToFile($"调整启动台窗口大小时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 应用按钮点击事件 /// @@ -144,18 +144,18 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher try { if (_isFixMode) return; // 在固定模式下,不响应点击事件 - + if (sender is Button button && _appButtons.TryGetValue(button, out LauncherItem item)) { // 获取应用路径和名称,用于后续启动 string appPath = item.Path; string appName = item.Name; - + LogHelper.WriteLogToFile($"点击启动应用: {appName}, 路径: {appPath}"); - + // 首先标记窗口正在关闭 IsClosing = true; - + // 创建一个应用启动任务 var launchTask = new Task(() => { @@ -163,9 +163,9 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { // 等待一段时间,确保窗口关闭流程已经开始 Thread.Sleep(200); - + // 使用UI线程启动应用 - Application.Current.Dispatcher.Invoke(() => + Application.Current.Dispatcher.Invoke(() => { try { @@ -174,11 +174,11 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { // 创建进程启动信息 var psi = new ProcessStartInfo - { - FileName = appPath, + { + FileName = appPath, UseShellExecute = true, - }; - + }; + // 启动应用程序 var process = Process.Start(psi); LogHelper.WriteLogToFile($"应用程序 {appName} 已启动"); @@ -201,14 +201,14 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher LogHelper.WriteLogToFile($"应用启动任务出错: {ex.Message}", LogHelper.LogType.Error); } }); - + // 关闭窗口 try { Dispatcher.BeginInvoke(new Action(() => { try { Close(); } catch { } - + // 启动应用程序任务 launchTask.Start(); }), DispatcherPriority.Background); @@ -227,86 +227,86 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher try { IsClosing = true; Close(); } catch { } } } - + #region 固定模式拖拽事件 - + /// /// 应用按钮鼠标按下事件 /// private void AppButton_PreviewMouseDown(object sender, MouseButtonEventArgs e) { if (!_isFixMode) return; - + if (e.ChangedButton == MouseButton.Left && sender is Button button) { _draggingButton = button; _dragStartPoint = e.GetPosition(AppPanel); button.CaptureMouse(); button.Opacity = 0.7; - + // 阻止事件冒泡,以避免触发按钮点击 e.Handled = true; } } - + /// /// 应用按钮鼠标移动事件 /// private void AppButton_PreviewMouseMove(object sender, MouseEventArgs e) { if (!_isFixMode || _draggingButton == null) return; - + if (e.LeftButton == MouseButtonState.Pressed) { Point currentPosition = e.GetPosition(AppPanel); - + // 移动按钮 System.Windows.Controls.Canvas.SetLeft(_draggingButton, currentPosition.X - _draggingButton.ActualWidth / 2); System.Windows.Controls.Canvas.SetTop(_draggingButton, currentPosition.Y - _draggingButton.ActualHeight / 2); - + // 将按钮移到最上层 Panel.SetZIndex(_draggingButton, 100); - + // 阻止事件冒泡 e.Handled = true; } } - + /// /// 应用按钮鼠标释放事件 /// private void AppButton_PreviewMouseUp(object sender, MouseButtonEventArgs e) { if (!_isFixMode || _draggingButton == null) return; - + // 释放鼠标捕获 _draggingButton.ReleaseMouseCapture(); - + // 计算新位置 Point releasePoint = e.GetPosition(AppPanel); int newPosition = CalculateGridPosition(releasePoint); - + // 获取当前项目 LauncherItem currentItem = _appButtons[_draggingButton]; - + // 重新排序 ReorderItems(currentItem, newPosition); - + // 重新加载应用项 LoadLauncherItems(); - + // 保存配置 _plugin.SaveConfig(); - + // 清除拖拽状态 _draggingButton.Opacity = 1; Panel.SetZIndex(_draggingButton, 0); _draggingButton = null; - + // 阻止事件冒泡 e.Handled = true; } - + /// /// 计算网格位置 /// @@ -316,18 +316,18 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher int columnCount = 4; // 每行最多4个应用 int columnWidth = 90; // 应用宽度(包括边距) int rowHeight = 90; // 应用高度(包括边距) - + int column = (int)(point.X / columnWidth); int row = (int)(point.Y / rowHeight); - + // 确保在有效范围内 column = Math.Max(0, Math.Min(column, columnCount - 1)); row = Math.Max(0, row); - + // 计算位置索引 return row * columnCount + column; } - + /// /// 重新排序应用项 /// @@ -337,22 +337,22 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { // 设置项目为固定位置 item.IsPositionFixed = true; - + // 如果位置相同,无需调整 if (item.Position == newPosition) { return; } - + // 获取所有可见项目 var visibleItems = _plugin.LauncherItems .Where(i => i.IsVisible) .OrderBy(i => i.Position) .ToList(); - + // 移除当前项目 visibleItems.Remove(item); - + // 查找插入位置 int insertIndex = 0; for (int i = 0; i < visibleItems.Count; i++) @@ -364,10 +364,10 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher } insertIndex = i + 1; } - + // 插入项目 visibleItems.Insert(insertIndex, item); - + // 重新分配位置 for (int i = 0; i < visibleItems.Count; i++) { @@ -379,11 +379,11 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher LogHelper.WriteLogToFile($"重新排序应用项时出错: {ex.Message}", LogHelper.LogType.Error); } } - + #endregion - + #region 窗口事件处理 - + /// /// 窗口失去焦点事件 /// @@ -396,7 +396,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { // 标记为正在关闭 IsClosing = true; - + // 使用Dispatcher.BeginInvoke而不是直接调用Close,避免冲突 Dispatcher.BeginInvoke(new Action(() => { @@ -404,8 +404,8 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { // 再次检查窗口状态 if (IsLoaded && !IsClosing) - { - Close(); + { + Close(); } } catch (Exception ex) @@ -420,12 +420,12 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher LogHelper.WriteLogToFile($"窗口失去焦点关闭时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 窗口是否正在关闭 /// private bool IsClosing { get; set; } - + /// /// 重写OnClosing方法,标记窗口正在关闭 /// @@ -434,7 +434,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher IsClosing = true; base.OnClosing(e); } - + /// /// 关闭按钮点击事件 /// @@ -442,7 +442,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { Close(); } - + /// /// 固定模式按钮点击事件 /// @@ -450,17 +450,17 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher { // 切换固定模式 _isFixMode = !_isFixMode; - + // 更新固定模式按钮图标颜色 FixModeIcon.Fill = _isFixMode ? Brushes.Yellow : Brushes.White; - + // 显示提示 if (_isFixMode) { MessageBox.Show("已进入固定模式,您可以拖动应用图标调整位置。", "提示", MessageBoxButton.OK, MessageBoxImage.Information); } } - + #endregion } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncherPlugin.cs b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncherPlugin.cs index cd22668f..555c7bf9 100644 --- a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncherPlugin.cs +++ b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncherPlugin.cs @@ -1,3 +1,5 @@ +using Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -5,8 +7,6 @@ using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Media; -using Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher; -using Newtonsoft.Json; namespace Ink_Canvas.Helpers.Plugins.BuiltIn { @@ -16,71 +16,71 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn public class SuperLauncherPlugin : PluginBase { #region 插件基本信息 - + public override string Name => "超级启动台"; - + public override string Description => "在浮动栏添加一个启动台按钮,可快速启动常用应用程序。"; - + public override Version Version => new Version(1, 0, 1); - + public override string Author => "ICC CE 团队"; - + public override bool IsBuiltIn => true; - + #endregion #region 插件属性和字段 - + /// /// 启动台配置 /// public LauncherConfig Config { get; private set; } - + /// /// 启动台应用程序列表 /// public ObservableCollection LauncherItems { get; private set; } - + /// /// 启动台按钮 /// private LauncherButton _launcherButton; - + /// /// 启动台窗口 /// private LauncherWindow _launcherWindow; - + /// /// 配置文件路径 /// private readonly string _configPath = Path.Combine(App.RootPath, "PluginConfigs", "SuperLauncher.json"); - + /// /// 标记是否已添加到浮动栏 /// private bool _isAddedToFloatingBar; - + #endregion #region 插件生命周期 - + public override void Initialize() { try { base.Initialize(); - + // 创建配置目录 string configDir = Path.Combine(App.RootPath, "PluginConfigs"); if (!Directory.Exists(configDir)) { Directory.CreateDirectory(configDir); } - + // 加载配置 LoadConfig(); - + LogHelper.WriteLogToFile("超级启动台插件已初始化"); } catch (Exception ex) @@ -89,29 +89,29 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn LogHelper.NewLog(ex); } } - + public override void Enable() { try { if (IsEnabled) return; // 防止重复启用 - + // 创建启动台按钮 if (_launcherButton == null) { _launcherButton = new LauncherButton(this); LogHelper.WriteLogToFile("超级启动台按钮已创建"); } - + // 添加启动台按钮到浮动栏 AddLauncherButtonToFloatingBar(); - + // 设置启用状态 base.Enable(); - + // 保存插件配置 SavePluginSettings(); - + LogHelper.WriteLogToFile("超级启动台插件已启用"); } catch (Exception ex) @@ -120,29 +120,29 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn LogHelper.NewLog(ex); } } - + public override void Disable() { try { if (!IsEnabled) return; // 防止重复禁用 - + // 从浮动栏移除启动台按钮 RemoveLauncherButtonFromFloatingBar(); - + // 如果启动台窗口打开,则关闭 if (_launcherWindow != null && _launcherWindow.IsVisible) { _launcherWindow.Close(); _launcherWindow = null; } - + // 设置禁用状态 base.Disable(); - + // 保存插件配置 SavePluginSettings(); - + LogHelper.WriteLogToFile("超级启动台插件已禁用"); } catch (Exception ex) @@ -151,30 +151,30 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn LogHelper.NewLog(ex); } } - + public override UserControl GetSettingsView() { return new LauncherSettingsControl(this); } - + public override void Cleanup() { // 保存配置 SaveConfig(); - + // 从浮动栏移除启动台按钮 RemoveLauncherButtonFromFloatingBar(); - + // 如果启动台窗口打开,则关闭 if (_launcherWindow != null && _launcherWindow.IsVisible) { _launcherWindow.Close(); _launcherWindow = null; } - + base.Cleanup(); } - + /// /// 保存插件设置 /// @@ -187,12 +187,12 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn { LoadConfig(); } - + // 更新其他设置,但不更改插件启用状态 - + // 保存配置 SaveConfig(); - + LogHelper.WriteLogToFile("超级启动台插件设置已保存"); } catch (Exception ex) @@ -200,11 +200,11 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn LogHelper.WriteLogToFile($"保存超级启动台插件设置时出错: {ex.Message}", LogHelper.LogType.Error); } } - + #endregion #region 配置管理 - + /// /// 加载配置 /// @@ -217,7 +217,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn string json = File.ReadAllText(_configPath); Config = JsonConvert.DeserializeObject(json) ?? CreateDefaultConfig(); LauncherItems = new ObservableCollection(Config.Items ?? new List()); - + // 注意:不再根据配置更改插件启用状态 // 插件状态由PluginManager统一管理 } @@ -235,7 +235,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn LauncherItems = new ObservableCollection(Config.Items); } } - + /// /// 保存配置 /// @@ -245,11 +245,11 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn { // 同步LauncherItems到Config Config.Items = new List(LauncherItems); - + // 序列化并保存配置 string json = JsonConvert.SerializeObject(Config, Formatting.Indented); File.WriteAllText(_configPath, json); - + LogHelper.WriteLogToFile("超级启动台配置已保存"); } catch (Exception ex) @@ -257,7 +257,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn LogHelper.WriteLogToFile($"保存超级启动台配置时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 创建默认配置 /// @@ -278,14 +278,14 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn } } }; - + return config; } - + #endregion #region 启动台按钮管理 - + /// /// 将启动台按钮添加到浮动栏 /// @@ -299,7 +299,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn RemoveLauncherButtonFromFloatingBar(); _isAddedToFloatingBar = false; } - + // 获取主窗口实例 var mainWindow = Application.Current.MainWindow; if (mainWindow == null) @@ -307,11 +307,11 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn LogHelper.WriteLogToFile("未找到主窗口实例,无法添加启动台按钮", LogHelper.LogType.Error); return; } - + // 创建启动台按钮 _launcherButton = new LauncherButton(this); var buttonElement = _launcherButton.Element; - + // 查找浮动栏 var floatingBar = mainWindow.FindName("StackPanelFloatingBar") as Panel; if (floatingBar == null) @@ -321,13 +321,13 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn FindStackPanelFloatingBar(mainWindow, ref floatingBarPanelFromTree); floatingBar = floatingBarPanelFromTree; } - + if (floatingBar == null) { LogHelper.WriteLogToFile("未找到浮动栏,无法添加启动台按钮", LogHelper.LogType.Error); return; } - + // 添加启动台按钮到浮动栏 if (Config.ButtonPosition == LauncherButtonPosition.Left) { @@ -339,7 +339,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn floatingBar.Children.Add(buttonElement); LogHelper.WriteLogToFile("启动台按钮已添加到浮动栏右侧"); } - + _isAddedToFloatingBar = true; } catch (Exception ex) @@ -348,14 +348,14 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn LogHelper.NewLog(ex); } } - + /// /// 递归查找StackPanelFloatingBar /// private void FindStackPanelFloatingBar(DependencyObject parent, ref Panel result) { if (parent == null || result != null) return; - + try { // 检查当前对象是否为我们要找的面板 @@ -364,10 +364,10 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn result = panel; return; } - + // 获取子元素数量 int childCount = VisualTreeHelper.GetChildrenCount(parent); - + // 遍历所有子元素 for (int i = 0; i < childCount; i++) { @@ -380,7 +380,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn LogHelper.WriteLogToFile($"查找StackPanelFloatingBar时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 从浮动栏移除启动台按钮 /// @@ -392,7 +392,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn { return; } - + // 获取主窗口实例 var mainWindow = Application.Current.MainWindow; if (mainWindow == null) @@ -400,10 +400,10 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn LogHelper.WriteLogToFile("未找到主窗口实例,无法移除启动台按钮", LogHelper.LogType.Error); return; } - + // 获取按钮元素 var buttonElement = _launcherButton.Element; - + // 查找浮动栏 var floatingBar = mainWindow.FindName("StackPanelFloatingBar") as Panel; if (floatingBar == null) @@ -413,20 +413,20 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn FindStackPanelFloatingBar(mainWindow, ref floatingBarPanelFromTree); floatingBar = floatingBarPanelFromTree; } - + if (floatingBar == null) { LogHelper.WriteLogToFile("未找到浮动栏,无法移除启动台按钮", LogHelper.LogType.Error); return; } - + // 从浮动栏移除启动台按钮 if (floatingBar.Children.Contains(buttonElement)) { floatingBar.Children.Remove(buttonElement); LogHelper.WriteLogToFile("启动台按钮已从浮动栏移除"); } - + _isAddedToFloatingBar = false; } catch (Exception ex) @@ -435,7 +435,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn LogHelper.NewLog(ex); } } - + /// /// 更新启动台按钮位置 /// @@ -457,11 +457,11 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn LogHelper.NewLog(ex); } } - + #endregion #region 启动台功能 - + /// /// 显示启动台窗口 /// @@ -477,13 +477,13 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn _launcherWindow = null; return; } - + // 创建新的启动台窗口 _launcherWindow = new LauncherWindow(this); - + // 计算窗口位置,使其位于按钮上方 PositionLauncherWindow(_launcherWindow, buttonPosition); - + // 显示窗口 _launcherWindow.Show(); } @@ -492,7 +492,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn LogHelper.WriteLogToFile($"显示启动台窗口时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 设置启动台窗口位置 /// @@ -504,18 +504,18 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn if (window.ActualWidth == 0 || window.ActualHeight == 0) { window.WindowStartupLocation = WindowStartupLocation.CenterScreen; - + // 设置窗口加载完成后的位置 window.Loaded += (s, e) => { // 窗口位于按钮上方居中 double left = buttonPosition.X - (window.ActualWidth / 2); double top = buttonPosition.Y - window.ActualHeight - 10; // 在按钮上方留出一些间距 - + // 确保窗口在屏幕内 left = Math.Max(0, Math.Min(left, SystemParameters.WorkArea.Width - window.ActualWidth)); top = Math.Max(0, Math.Min(top, SystemParameters.WorkArea.Height - window.ActualHeight)); - + window.Left = left; window.Top = top; }; @@ -525,16 +525,16 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn // 窗口位于按钮上方居中 double left = buttonPosition.X - (window.ActualWidth / 2); double top = buttonPosition.Y - window.ActualHeight - 10; // 在按钮上方留出一些间距 - + // 确保窗口在屏幕内 left = Math.Max(0, Math.Min(left, SystemParameters.WorkArea.Width - window.ActualWidth)); top = Math.Max(0, Math.Min(top, SystemParameters.WorkArea.Height - window.ActualHeight)); - + window.Left = left; window.Top = top; } } - + /// /// 添加应用到启动台 /// @@ -547,18 +547,18 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn MessageBox.Show("启动台项目数量已达上限(40个)!", "提示", MessageBoxButton.OK, MessageBoxImage.Information); return; } - + // 寻找合适的位置 if (item.Position < 0) { item.Position = FindNextAvailablePosition(); } - + // 添加项目并保存配置 LauncherItems.Add(item); SaveConfig(); } - + /// /// 查找下一个可用位置 /// @@ -570,7 +570,7 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn { usedPositions.Add(item.Position); } - + // 查找第一个可用位置 for (int i = 0; i < 40; i++) { @@ -579,11 +579,11 @@ namespace Ink_Canvas.Helpers.Plugins.BuiltIn return i; } } - + // 如果所有位置都已使用,则返回0 return 0; } - + #endregion } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/ICCPPPluginAdapter.cs b/Ink Canvas/Helpers/Plugins/ICCPPPluginAdapter.cs index a346282b..e018ac0d 100644 --- a/Ink Canvas/Helpers/Plugins/ICCPPPluginAdapter.cs +++ b/Ink Canvas/Helpers/Plugins/ICCPPPluginAdapter.cs @@ -13,7 +13,7 @@ namespace Ink_Canvas.Helpers.Plugins private readonly string _pluginName; private readonly Version _pluginVersion; private bool _isInitialized; - + /// /// 创建 ICCPP 插件适配器 /// @@ -24,11 +24,11 @@ namespace Ink_Canvas.Helpers.Plugins _pluginPath = pluginPath; _pluginData = pluginData; PluginPath = pluginPath; - + // 从文件名获取插件名称 _pluginName = Path.GetFileNameWithoutExtension(pluginPath); _pluginVersion = new Version(1, 0, 0); // 默认版本 - + // 尝试从插件数据中读取更多信息 TryReadPluginMetadata(); } @@ -42,7 +42,7 @@ namespace Ink_Canvas.Helpers.Plugins _pluginVersion = new Version(1, 0, 0); // 可选:初始化其他字段 } - + /// /// 尝试从插件数据中读取元数据 /// @@ -52,7 +52,7 @@ namespace Ink_Canvas.Helpers.Plugins { // 这里可以根据 .iccpp 文件的实际格式解析元数据 // 例如,如果文件有特定的头部结构,可以在这里解析 - + // 示例:如果前100字节包含元数据 if (_pluginData.Length > 100) { @@ -64,46 +64,46 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"解析插件 {_pluginName} 元数据时出错: {ex.Message}", LogHelper.LogType.Error); } } - + #region IPlugin 接口实现 - + /// /// 插件名称 /// public override string Name => _pluginName; - + /// /// 插件描述 /// public override string Description => $"{_pluginName} (ICCPP 格式插件)"; - + /// /// 插件版本 /// public override Version Version => _pluginVersion; - + /// /// 插件作者 /// public override string Author => "未知"; - + /// /// 是否为内置插件 /// public override bool IsBuiltIn => false; - + /// /// 初始化插件 /// public override void Initialize() { if (_isInitialized) return; - + try { // 这里可以添加 .iccpp 插件的初始化逻辑 // 例如,根据文件格式加载特定资源 - + LogHelper.WriteLogToFile($"ICCPP 插件 {Name} 已初始化"); _isInitialized = true; } @@ -112,19 +112,19 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"初始化 ICCPP 插件 {Name} 时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 启用插件 /// public override void Enable() { if (IsEnabled) return; - + try { // 这里可以添加 .iccpp 插件的启用逻辑 // 例如,加载动态库、注册事件等 - + base.Enable(); // 设置启用状态并触发事件 LogHelper.WriteLogToFile($"ICCPP 插件 {Name} 已启用"); } @@ -133,19 +133,19 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"启用 ICCPP 插件 {Name} 时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 禁用插件 /// public override void Disable() { if (!IsEnabled) return; - + try { // 这里可以添加 .iccpp 插件的禁用逻辑 // 例如,卸载动态库、注销事件等 - + base.Disable(); // 设置禁用状态并触发事件 LogHelper.WriteLogToFile($"ICCPP 插件 {Name} 已禁用"); } @@ -154,7 +154,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"禁用 ICCPP 插件 {Name} 时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 清理插件资源 /// @@ -164,7 +164,7 @@ namespace Ink_Canvas.Helpers.Plugins { // 这里可以添加 .iccpp 插件的清理逻辑 // 例如,释放资源等 - + LogHelper.WriteLogToFile($"ICCPP 插件 {Name} 已清理资源"); } catch (Exception ex) @@ -172,7 +172,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"清理 ICCPP 插件 {Name} 资源时出错: {ex.Message}", LogHelper.LogType.Error); } } - + #endregion } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/IPlugin.cs b/Ink Canvas/Helpers/Plugins/IPlugin.cs index 6a527021..0a43ab15 100644 --- a/Ink Canvas/Helpers/Plugins/IPlugin.cs +++ b/Ink Canvas/Helpers/Plugins/IPlugin.cs @@ -12,56 +12,56 @@ namespace Ink_Canvas.Helpers.Plugins /// 插件名称 /// string Name { get; } - + /// /// 插件描述 /// string Description { get; } - + /// /// 插件版本 /// Version Version { get; } - + /// /// 插件作者 /// string Author { get; } - + /// /// 是否为内置插件 /// bool IsBuiltIn { get; } - + /// /// 初始化插件 /// 此方法在插件加载时被调用,用于执行一些初始化工作 /// void Initialize(); - + /// /// 启用插件 /// 此方法在插件被用户或系统启用时调用,激活插件功能 /// void Enable(); - + /// /// 禁用插件 /// 此方法在插件被用户或系统禁用时调用,停用插件功能 /// void Disable(); - + /// /// 获取插件设置界面 /// 此方法返回插件的设置界面控件,用于展示在设置窗口 /// /// 插件设置界面 UserControl GetSettingsView(); - + /// /// 插件卸载时的清理工作 /// 此方法在插件被卸载前调用,用于释放资源和执行清理 /// void Cleanup(); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/PluginBase.cs b/Ink Canvas/Helpers/Plugins/PluginBase.cs index c00ecbc5..716b7e61 100644 --- a/Ink Canvas/Helpers/Plugins/PluginBase.cs +++ b/Ink Canvas/Helpers/Plugins/PluginBase.cs @@ -12,11 +12,11 @@ namespace Ink_Canvas.Helpers.Plugins /// 插件状态(私有字段) /// private bool _isEnabled; - + /// /// 插件状态(公共属性) /// - public bool IsEnabled + public bool IsEnabled { get => _isEnabled; protected set @@ -28,12 +28,12 @@ namespace Ink_Canvas.Helpers.Plugins } } } - + /// /// 插件ID /// public string Id { get; protected set; } - + /// /// 插件路径 /// @@ -75,13 +75,13 @@ namespace Ink_Canvas.Helpers.Plugins public virtual void Initialize() { Id = GetType().FullName; - + // 添加日志,记录插件名称 try { string name = Name; LogHelper.WriteLogToFile($"初始化插件: ID={Id}, 名称={name ?? "未命名"}"); - + if (string.IsNullOrEmpty(name)) { LogHelper.WriteLogToFile($"警告: 插件 {Id} 的名称为空", LogHelper.LogType.Warning); @@ -91,7 +91,7 @@ namespace Ink_Canvas.Helpers.Plugins { LogHelper.WriteLogToFile($"获取插件名称时出错: {ex.Message}", LogHelper.LogType.Error); } - + LogHelper.WriteLogToFile($"插件 {Name} 已初始化"); } @@ -136,7 +136,7 @@ namespace Ink_Canvas.Helpers.Plugins { LogHelper.WriteLogToFile($"插件 {Name} 已卸载"); } - + /// /// 保存插件自身的设置 /// 注意:此方法仅用于保存插件的特定设置,不应影响插件启用/禁用状态 @@ -148,7 +148,7 @@ namespace Ink_Canvas.Helpers.Plugins // 子类可以重写此方法,将自身设置保存到配置文件中 LogHelper.WriteLogToFile($"插件 {Name} 设置已保存", LogHelper.LogType.Event); } - + /// /// 触发状态变更事件 /// @@ -158,4 +158,4 @@ namespace Ink_Canvas.Helpers.Plugins EnabledStateChanged?.Invoke(this, isEnabled); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/PluginManager.cs b/Ink Canvas/Helpers/Plugins/PluginManager.cs index c2775f65..27b7742e 100644 --- a/Ink Canvas/Helpers/Plugins/PluginManager.cs +++ b/Ink Canvas/Helpers/Plugins/PluginManager.cs @@ -1,3 +1,5 @@ +using Ink_Canvas.Windows; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -8,8 +10,6 @@ using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; using System.Windows; -using Ink_Canvas.Windows; -using Newtonsoft.Json; using Timer = System.Timers.Timer; namespace Ink_Canvas.Helpers.Plugins @@ -22,10 +22,10 @@ namespace Ink_Canvas.Helpers.Plugins private static readonly string PluginsDirectory = Path.Combine(App.RootPath, "Plugins"); private static readonly string PluginConfigFile = Path.Combine(App.RootPath, "PluginConfig.json"); private static readonly string PluginConfigBackupFile = Path.Combine(App.RootPath, "PluginConfig.json.bak"); - + private static PluginManager _instance; private static SemaphoreSlim _configLock = new SemaphoreSlim(1, 1); - + /// /// 插件管理器单例 /// @@ -40,12 +40,12 @@ namespace Ink_Canvas.Helpers.Plugins return _instance; } } - + /// /// 已加载的插件集合 /// public ObservableCollection Plugins { get; } = new ObservableCollection(); - + /// /// 插件配置信息 /// @@ -55,22 +55,22 @@ namespace Ink_Canvas.Helpers.Plugins /// 配置是否已更改但未保存 /// private bool _configDirty; - + /// /// 配置自动保存计时器 /// private Timer _autoSaveTimer; - + /// /// 加载的程序集缓存 /// private Dictionary _loadedAssemblies = new Dictionary(); - + /// /// 插件文件哈希缓存,用于热重载检测 /// private Dictionary _pluginHashes = new Dictionary(); - + private PluginManager() { // 确保插件目录存在 @@ -78,13 +78,13 @@ namespace Ink_Canvas.Helpers.Plugins { Directory.CreateDirectory(PluginsDirectory); } - + // 加载插件配置 LoadConfig(); - + // 初始化自动保存计时器(3秒) _autoSaveTimer = new Timer(3000); - _autoSaveTimer.Elapsed += (s, e) => + _autoSaveTimer.Elapsed += (s, e) => { if (_configDirty) { @@ -92,9 +92,9 @@ namespace Ink_Canvas.Helpers.Plugins } }; _autoSaveTimer.AutoReset = false; - + // 注册插件状态变更事件处理 - AppDomain.CurrentDomain.ProcessExit += (s, e) => + AppDomain.CurrentDomain.ProcessExit += (s, e) => { // 应用退出时强制保存配置 if (_configDirty) @@ -103,7 +103,7 @@ namespace Ink_Canvas.Helpers.Plugins } }; } - + /// /// 初始化插件系统 /// @@ -112,29 +112,29 @@ namespace Ink_Canvas.Helpers.Plugins try { LogHelper.WriteLogToFile("开始初始化插件系统"); - + // 加载配置 LoadConfig(); LogHelper.WriteLogToFile($"已从配置文件加载 {PluginStates.Count} 个插件状态记录"); - + // 加载内置插件 LogHelper.WriteLogToFile("正在加载内置插件..."); LoadBuiltInPlugins(); - + // 加载外部插件 LogHelper.WriteLogToFile("正在加载外部插件..."); LoadExternalPlugins(); - + // 启用已配置为启用的插件 LogHelper.WriteLogToFile("正在应用配置的插件状态..."); EnableConfiguredPlugins(); - + // 设置定期检查热重载 StartHotReloadWatcher(); - + // 保存初始化后的配置(可能有新插件) SaveConfig(); - + LogHelper.WriteLogToFile($"插件系统初始化完成,共加载 {Plugins.Count} 个插件"); } catch (Exception ex) @@ -142,7 +142,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"初始化插件系统时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 加载内置插件 /// @@ -152,18 +152,18 @@ namespace Ink_Canvas.Helpers.Plugins { // 获取当前程序集 Assembly currentAssembly = Assembly.GetExecutingAssembly(); - + // 查找实现了IPlugin接口的所有类型 var pluginTypes = currentAssembly.GetTypes() .Where(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsAbstract && t.IsClass); - + foreach (var pluginType in pluginTypes) { try { // 创建插件实例 IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType); - + // 只处理内置插件 if (plugin.IsBuiltIn) { @@ -183,7 +183,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"加载内置插件时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 加载外部插件 /// @@ -197,14 +197,14 @@ namespace Ink_Canvas.Helpers.Plugins Directory.CreateDirectory(PluginsDirectory); return; } - + // 获取所有插件文件(支持 .iccpp 和 .dll 格式) var pluginFiles = Directory.GetFiles(PluginsDirectory, "*.iccpp", SearchOption.TopDirectoryOnly) .Concat(Directory.GetFiles(PluginsDirectory, "*.dll", SearchOption.TopDirectoryOnly)) .ToArray(); - + LogHelper.WriteLogToFile($"发现 {pluginFiles.Length} 个外部插件文件"); - + foreach (var pluginFile in pluginFiles) { LoadExternalPlugin(pluginFile); @@ -215,7 +215,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"加载外部插件时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 加载单个外部插件 /// @@ -228,7 +228,7 @@ namespace Ink_Canvas.Helpers.Plugins // 计算文件哈希 string fileHash = CalculateFileHash(pluginPath); _pluginHashes[pluginPath] = fileHash; - + // 检查文件扩展名 string extension = Path.GetExtension(pluginPath).ToLowerInvariant(); if (extension == ".iccpp") @@ -236,33 +236,33 @@ namespace Ink_Canvas.Helpers.Plugins // 创建 ICCPP 插件适配器 return CreateICCPPPluginAdapter(pluginPath); } - + // 加载插件程序集 Assembly pluginAssembly = LoadPluginAssembly(pluginPath); if (pluginAssembly == null) return null; - + // 查找实现了IPlugin接口的类型 var pluginTypes = pluginAssembly.GetTypes() .Where(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsAbstract && t.IsClass); - + foreach (var pluginType in pluginTypes) { try { // 创建插件实例 IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType); - + // 设置插件路径 if (plugin is PluginBase pluginBase) { pluginBase.PluginPath = pluginPath; } - + plugin.Initialize(); Plugins.Add(plugin); - + LogHelper.WriteLogToFile($"已加载外部插件: {plugin.Name} v{plugin.Version} 来自 {Path.GetFileName(pluginPath)}"); - + return plugin; } catch (Exception ex) @@ -270,7 +270,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"实例化插件类型 {pluginType.Name} 时出错: {ex.Message}", LogHelper.LogType.Error); } } - + LogHelper.WriteLogToFile($"在程序集 {Path.GetFileName(pluginPath)} 中未找到有效的插件类型", LogHelper.LogType.Warning); return null; } @@ -280,7 +280,7 @@ namespace Ink_Canvas.Helpers.Plugins return null; } } - + /// /// 创建 ICCPP 插件适配器 /// @@ -292,15 +292,15 @@ namespace Ink_Canvas.Helpers.Plugins { // 读取插件文件内容 byte[] pluginData = File.ReadAllBytes(pluginPath); - + // 创建适配器插件实例 var pluginAdapter = new ICCPPPluginAdapter(pluginPath, pluginData); - + // 添加到插件列表 Plugins.Add(pluginAdapter); - + LogHelper.WriteLogToFile($"已创建 ICCPP 插件适配器: {pluginAdapter.Name} 来自 {Path.GetFileName(pluginPath)}"); - + return pluginAdapter; } catch (Exception ex) @@ -309,7 +309,7 @@ namespace Ink_Canvas.Helpers.Plugins return null; } } - + /// /// 加载插件程序集 /// @@ -324,11 +324,11 @@ namespace Ink_Canvas.Helpers.Plugins { return loadedAssembly; } - + // 直接加载程序集 Assembly pluginAssembly = Assembly.LoadFrom(pluginPath); _loadedAssemblies[pluginPath] = pluginAssembly; - + return pluginAssembly; } catch (Exception ex) @@ -337,7 +337,7 @@ namespace Ink_Canvas.Helpers.Plugins return null; } } - + /// /// 启用已配置为启用的插件 /// @@ -346,19 +346,19 @@ namespace Ink_Canvas.Helpers.Plugins int enabledCount = 0; int disabledCount = 0; int errorCount = 0; - + foreach (var plugin in Plugins) { try { string pluginTypeName = plugin.GetType().FullName; - + // 检查配置中的插件状态 if (PluginStates.TryGetValue(pluginTypeName, out bool enabled)) { // 获取当前实际状态 bool currentState = plugin is PluginBase pluginBase && pluginBase.IsEnabled; - + // 如果配置状态与当前状态不一致,则应用配置状态 if (currentState != enabled) { @@ -367,7 +367,7 @@ namespace Ink_Canvas.Helpers.Plugins { pb.EnabledStateChanged += Plugin_EnabledStateChanged; } - + if (enabled) { plugin.Enable(); @@ -395,13 +395,13 @@ namespace Ink_Canvas.Helpers.Plugins // 插件不在配置中,添加默认状态(禁用) PluginStates[pluginTypeName] = false; _configDirty = true; - + // 注册插件状态变更事件 if (plugin is PluginBase pb) { pb.EnabledStateChanged += Plugin_EnabledStateChanged; } - + // 如果当前是启用状态,则禁用 if (plugin is PluginBase pluginBase && pluginBase.IsEnabled) { @@ -417,16 +417,16 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"应用插件 {plugin.Name} 配置时出错: {ex.Message}", LogHelper.LogType.Error); } } - + // 如果有配置变更,启动自动保存 if (_configDirty) { TriggerAutoSave(); } - + LogHelper.WriteLogToFile($"已应用插件配置: 启用 {enabledCount} 个,禁用 {disabledCount} 个,错误 {errorCount} 个"); } - + /// /// 插件状态变更事件处理 /// @@ -437,15 +437,15 @@ namespace Ink_Canvas.Helpers.Plugins if (sender is IPlugin plugin) { string pluginTypeName = plugin.GetType().FullName; - + // 更新配置状态 if (!PluginStates.ContainsKey(pluginTypeName) || PluginStates[pluginTypeName] != isEnabled) { PluginStates[pluginTypeName] = isEnabled; _configDirty = true; - + LogHelper.WriteLogToFile($"插件状态变更: {plugin.Name} = {(isEnabled ? "启用" : "禁用")}"); - + // 立即同步保存配置(不再使用延迟自动保存) SaveConfig(); LogHelper.WriteLogToFile($"插件 {plugin.Name} 状态已立即保存到配置文件"); @@ -457,7 +457,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"处理插件状态变更事件时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 触发自动保存计时器 /// @@ -467,7 +467,7 @@ namespace Ink_Canvas.Helpers.Plugins _autoSaveTimer.Stop(); _autoSaveTimer.Start(); } - + /// /// 启动热重载监视器 /// @@ -482,12 +482,12 @@ namespace Ink_Canvas.Helpers.Plugins { // 每5秒检查一次 await Task.Delay(5000); - + // 获取所有外部插件 var externalPlugins = Plugins.OfType() .Where(p => !p.IsBuiltIn && !string.IsNullOrEmpty(p.PluginPath)) .ToList(); - + foreach (var plugin in externalPlugins) { // 检查插件文件是否存在 @@ -495,13 +495,13 @@ namespace Ink_Canvas.Helpers.Plugins { continue; } - + // 计算当前文件哈希 string currentHash = CalculateFileHash(plugin.PluginPath); - + // 比较哈希值是否变化 - if (_pluginHashes.TryGetValue(plugin.PluginPath, out string oldHash) && - !string.IsNullOrEmpty(oldHash) && + if (_pluginHashes.TryGetValue(plugin.PluginPath, out string oldHash) && + !string.IsNullOrEmpty(oldHash) && oldHash != currentHash) { // 文件已变化,执行热重载 @@ -519,7 +519,7 @@ namespace Ink_Canvas.Helpers.Plugins } }); } - + /// /// 重新加载插件 /// @@ -534,29 +534,29 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"无法重新加载插件 {plugin.Name}: 插件文件不存在", LogHelper.LogType.Error); return; } - + LogHelper.WriteLogToFile($"开始热重载插件: {plugin.Name} ({Path.GetFileName(pluginPath)})"); - + // 保存插件的当前状态 bool wasEnabled = plugin.IsEnabled; string pluginTypeName = plugin.GetType().FullName; - + // 卸载插件 UnloadPlugin(plugin); - + // 从加载缓存中移除 if (_loadedAssemblies.ContainsKey(pluginPath)) { _loadedAssemblies.Remove(pluginPath); } - + // 计算新的文件哈希 string newHash = CalculateFileHash(pluginPath); _pluginHashes[pluginPath] = newHash; - + // 重新加载插件 IPlugin newPlugin = LoadExternalPlugin(pluginPath); - + if (newPlugin != null) { // 恢复插件状态 @@ -564,7 +564,7 @@ namespace Ink_Canvas.Helpers.Plugins { newPlugin.Enable(); } - + // 更新配置(如果类型名称变化) string newPluginTypeName = newPlugin.GetType().FullName; if (pluginTypeName != newPluginTypeName && PluginStates.ContainsKey(pluginTypeName)) @@ -575,9 +575,9 @@ namespace Ink_Canvas.Helpers.Plugins _configDirty = true; SaveConfig(); } - + LogHelper.WriteLogToFile($"插件 {newPlugin.Name} v{newPlugin.Version} 热重载成功"); - + // 通知UI刷新 NotifyUIRefresh(); } @@ -591,7 +591,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"重新加载插件 {plugin.Name} 时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 卸载插件 /// @@ -603,19 +603,19 @@ namespace Ink_Canvas.Helpers.Plugins { // 保存插件名称,以便在卸载后使用 string pluginName = plugin.Name; - + // 如果插件已启用,先禁用它 if (plugin is PluginBase pluginBase && pluginBase.IsEnabled) { plugin.Disable(); } - + // 执行插件清理 plugin.Cleanup(); - + // 从插件集合中移除 Plugins.Remove(plugin); - + // 从配置中移除(如果需要) if (removeFromConfig && plugin.GetType() != null) { @@ -626,7 +626,7 @@ namespace Ink_Canvas.Helpers.Plugins SaveConfig(); } } - + LogHelper.WriteLogToFile($"已卸载插件: {pluginName}"); } catch (Exception ex) @@ -634,7 +634,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"卸载插件时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 删除插件 /// @@ -649,35 +649,35 @@ namespace Ink_Canvas.Helpers.Plugins { return false; } - + // 保存插件名称,以便在删除后使用 string pluginName = plugin.Name; - + // 获取插件路径 string pluginPath = null; if (plugin is PluginBase pluginBase) { pluginPath = pluginBase.PluginPath; } - + if (string.IsNullOrEmpty(pluginPath) || !File.Exists(pluginPath)) { return false; } - + // 卸载插件(并从配置中移除状态) UnloadPlugin(plugin, true); - + // 删除插件文件 File.Delete(pluginPath); - + // 清理缓存 _loadedAssemblies.Remove(pluginPath); _pluginHashes.Remove(pluginPath); - + // 保存配置 SaveConfig(); - + LogHelper.WriteLogToFile($"已删除插件: {pluginName}"); return true; } @@ -687,7 +687,7 @@ namespace Ink_Canvas.Helpers.Plugins return false; } } - + /// /// 切换插件启用状态 /// @@ -705,17 +705,17 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"插件 {plugin.Name} 已经是 {(enable ? "启用" : "禁用")} 状态,无需切换"); return; } - + // 记录插件信息,用于日志 string pluginName = plugin.Name; string pluginTypeName = plugin.GetType().FullName; - + LogHelper.WriteLogToFile($"开始切换插件 {pluginName} 状态为: {(enable ? "启用" : "禁用")}"); - + // 首先更新配置状态 PluginStates[pluginTypeName] = enable; _configDirty = true; - + // 更新插件状态 try { @@ -727,7 +727,7 @@ namespace Ink_Canvas.Helpers.Plugins // 重新订阅 pb.EnabledStateChanged += Plugin_EnabledStateChanged; } - + // 更新插件状态 if (enable) { @@ -739,17 +739,17 @@ namespace Ink_Canvas.Helpers.Plugins // 禁用前先记录是否为内置插件 bool isBuiltIn = plugin.IsBuiltIn; LogHelper.WriteLogToFile($"尝试禁用{(isBuiltIn ? "内置" : "外部")}插件 {pluginName}"); - + // 禁用插件 plugin.Disable(); - + // 禁用后立即检查状态,确保禁用成功 bool actuallyDisabled = !(plugin is PluginBase pb2 && pb2.IsEnabled); if (!actuallyDisabled) { LogHelper.WriteLogToFile($"警告: 插件 {pluginName} 禁用失败,再次尝试禁用", LogHelper.LogType.Warning); plugin.Disable(); // 再次尝试禁用 - + // 再次检查 actuallyDisabled = !(plugin is PluginBase pb3 && pb3.IsEnabled); if (!actuallyDisabled) @@ -768,7 +768,7 @@ namespace Ink_Canvas.Helpers.Plugins } } } - + LogHelper.WriteLogToFile($"插件 {pluginName} 已禁用"); } } @@ -776,10 +776,10 @@ namespace Ink_Canvas.Helpers.Plugins { LogHelper.WriteLogToFile($"更改插件 {pluginName} 状态时出错: {ex.Message}", LogHelper.LogType.Error); } - + // 立即保存配置 SaveConfigAsync().ConfigureAwait(false); - + // 插件状态切换后,始终进行重载(无论是启用还是禁用) if (plugin is PluginBase pluginInstance) { @@ -787,15 +787,15 @@ namespace Ink_Canvas.Helpers.Plugins if (pluginInstance.IsBuiltIn) { LogHelper.WriteLogToFile($"处理内置插件 {pluginName} 状态变更"); - + // 对于内置插件,我们需要确保状态正确应用 bool finalState = pluginInstance.IsEnabled; bool expectedState = enable; - + if (finalState != expectedState) { LogHelper.WriteLogToFile($"内置插件状态不匹配: 当前={finalState}, 期望={expectedState},尝试纠正", LogHelper.LogType.Warning); - + // 再次尝试设置状态 if (expectedState) { @@ -804,7 +804,7 @@ namespace Ink_Canvas.Helpers.Plugins else { plugin.Disable(); - + // 最后一次检查,如果仍然不匹配,强制设置 if (pluginInstance.IsEnabled != expectedState) { @@ -817,7 +817,7 @@ namespace Ink_Canvas.Helpers.Plugins } } } - + // 通知UI刷新 NotifyUIRefresh(); } @@ -829,7 +829,7 @@ namespace Ink_Canvas.Helpers.Plugins if (!string.IsNullOrEmpty(pluginInstance.PluginPath) && File.Exists(pluginInstance.PluginPath)) { LogHelper.WriteLogToFile($"开始重载外部插件 {pluginName}"); - + // 使用调度器确保在UI线程执行热重载 if (Application.Current != null && Application.Current.Dispatcher != null) { @@ -865,7 +865,7 @@ namespace Ink_Canvas.Helpers.Plugins // 通知UI刷新 NotifyUIRefresh(); } - + LogHelper.WriteLogToFile($"插件 {pluginName} 状态切换完成"); } catch (Exception ex) @@ -873,7 +873,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"切换插件状态时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 应用插件实时状态 /// @@ -897,7 +897,7 @@ namespace Ink_Canvas.Helpers.Plugins plugin.Disable(); LogHelper.WriteLogToFile($"实时应用: 已禁用插件 {plugin.Name}"); } - + // 同步状态到插件自身的配置 if (plugin is PluginBase pluginSettings) { @@ -913,7 +913,7 @@ namespace Ink_Canvas.Helpers.Plugins } } } - + // 对于外部插件,尝试执行热重载以确保状态立即生效 if (plugin is PluginBase externalPlugin && !externalPlugin.IsBuiltIn) { @@ -923,7 +923,7 @@ namespace Ink_Canvas.Helpers.Plugins // 记录插件类型名称,用于后续状态检查 string pluginTypeName = plugin.GetType().FullName; bool targetState = enable; - + // 使用调度器确保在UI线程执行热重载 if (Application.Current != null && Application.Current.Dispatcher != null) { @@ -938,7 +938,7 @@ namespace Ink_Canvas.Helpers.Plugins PluginStates[pluginTypeName] = targetState; SaveConfig(); } - + // 执行热重载 ReloadPlugin(externalPlugin); LogHelper.WriteLogToFile($"插件 {plugin.Name} 已成功热重载以应用实时状态"); @@ -959,12 +959,12 @@ namespace Ink_Canvas.Helpers.Plugins PluginStates[pluginTypeName] = targetState; SaveConfig(); } - + ReloadPlugin(externalPlugin); } } } - + LogHelper.WriteLogToFile($"插件 {plugin.Name} 实时状态已应用: {(enable ? "启用" : "禁用")}"); } catch (Exception ex) @@ -972,7 +972,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"应用插件实时状态时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 通知UI刷新 /// @@ -983,7 +983,8 @@ namespace Ink_Canvas.Helpers.Plugins // 通知UI刷新 if (Application.Current != null && Application.Current.Dispatcher != null) { - Application.Current.Dispatcher.BeginInvoke(new Action(() => { + Application.Current.Dispatcher.BeginInvoke(new Action(() => + { // 通知任何可能打开的插件设置窗口刷新 foreach (Window window in Application.Current.Windows) { @@ -1001,7 +1002,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"通知UI刷新时出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 加载插件配置 /// @@ -1009,15 +1010,15 @@ namespace Ink_Canvas.Helpers.Plugins { const int maxRetries = 3; // 最大重试次数 const int retryDelayMs = 300; // 重试延迟时间(毫秒) - + LogHelper.WriteLogToFile($"开始从配置文件加载插件状态: {PluginConfigFile}"); - + // 确保至少有一个默认配置 Dictionary defaultConfig = new Dictionary(); - + // 尝试获取配置锁 _configLock.Wait(); - + try { for (int attempt = 1; attempt <= maxRetries; attempt++) @@ -1033,9 +1034,9 @@ namespace Ink_Canvas.Helpers.Plugins { json = reader.ReadToEnd(); } - + var loadedStates = JsonConvert.DeserializeObject>(json); - + if (loadedStates != null && loadedStates.Count > 0) { PluginStates = loadedStates; @@ -1052,7 +1053,7 @@ namespace Ink_Canvas.Helpers.Plugins { string backupJson = File.ReadAllText(PluginConfigBackupFile); var backupStates = JsonConvert.DeserializeObject>(backupJson); - + if (backupStates != null && backupStates.Count > 0) { PluginStates = backupStates; @@ -1066,7 +1067,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"从备份恢复配置失败: {backupEx.Message}", LogHelper.LogType.Error); } } - + // 备份也失败,使用默认配置 PluginStates = defaultConfig; _configDirty = true; @@ -1075,7 +1076,7 @@ namespace Ink_Canvas.Helpers.Plugins else { LogHelper.WriteLogToFile($"配置文件不存在,尝试使用备份: {PluginConfigFile}", LogHelper.LogType.Warning); - + // 尝试加载备份 if (File.Exists(PluginConfigBackupFile)) { @@ -1083,7 +1084,7 @@ namespace Ink_Canvas.Helpers.Plugins { string backupJson = File.ReadAllText(PluginConfigBackupFile); var backupStates = JsonConvert.DeserializeObject>(backupJson); - + if (backupStates != null && backupStates.Count > 0) { PluginStates = backupStates; @@ -1097,12 +1098,12 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"从备份恢复配置失败: {backupEx.Message}", LogHelper.LogType.Error); } } - + PluginStates = defaultConfig; _configDirty = true; LogHelper.WriteLogToFile("使用默认空配置", LogHelper.LogType.Warning); } - + // 没有成功加载或使用备份,使用默认配置 break; } @@ -1116,7 +1117,7 @@ namespace Ink_Canvas.Helpers.Plugins else { LogHelper.WriteLogToFile($"加载插件配置失败,已达最大重试次数 ({maxRetries}): {ex.Message}", LogHelper.LogType.Error); - + // 最终失败,使用默认配置 PluginStates = defaultConfig; _configDirty = true; @@ -1130,7 +1131,7 @@ namespace Ink_Canvas.Helpers.Plugins _configLock.Release(); } } - + /// /// 异步保存插件配置 /// @@ -1141,7 +1142,7 @@ namespace Ink_Canvas.Helpers.Plugins { return; } - + // 尝试获取配置锁(异步) if (!await _configLock.WaitAsync(0)) { @@ -1149,7 +1150,7 @@ namespace Ink_Canvas.Helpers.Plugins TriggerAutoSave(); return; } - + try { // 创建配置任务 @@ -1161,7 +1162,7 @@ namespace Ink_Canvas.Helpers.Plugins _configLock.Release(); } } - + /// /// 保存插件配置 /// @@ -1172,18 +1173,18 @@ namespace Ink_Canvas.Helpers.Plugins { return; } - + const int maxRetries = 3; // 最大重试次数 const int retryDelayMs = 500; // 重试延迟时间(毫秒) - + try { LogHelper.WriteLogToFile($"开始保存插件配置到: {PluginConfigFile}"); - + // 生成JSON数据 string json = JsonConvert.SerializeObject(PluginStates, Formatting.Indented); string tempFile = PluginConfigFile + ".temp"; // 临时文件路径 - + // 确保目录存在 string configDir = Path.GetDirectoryName(PluginConfigFile); if (!Directory.Exists(configDir)) @@ -1191,7 +1192,7 @@ namespace Ink_Canvas.Helpers.Plugins Directory.CreateDirectory(configDir); LogHelper.WriteLogToFile($"创建配置目录: {configDir}"); } - + // 先备份当前配置 try { @@ -1204,14 +1205,14 @@ namespace Ink_Canvas.Helpers.Plugins { LogHelper.WriteLogToFile($"备份配置文件失败: {ex.Message}", LogHelper.LogType.Warning); } - + for (int attempt = 1; attempt <= maxRetries; attempt++) { try { // 直接写入目标文件 File.WriteAllText(PluginConfigFile, json); - + // 验证写入是否成功 if (File.Exists(PluginConfigFile)) { @@ -1231,7 +1232,7 @@ namespace Ink_Canvas.Helpers.Plugins else { LogHelper.WriteLogToFile($"保存插件配置失败,已达最大重试次数 ({maxRetries}): {ex.Message}", LogHelper.LogType.Error); - + // 尝试使用临时文件方式 try { @@ -1240,19 +1241,19 @@ namespace Ink_Canvas.Helpers.Plugins { File.Delete(tempFile); } - + // 写入临时文件 File.WriteAllText(tempFile, json); - + // 如果目标文件存在,先删除 if (File.Exists(PluginConfigFile)) { File.Delete(PluginConfigFile); } - + // 重命名临时文件 File.Move(tempFile, PluginConfigFile); - + // 重置脏标记 _configDirty = false; LogHelper.WriteLogToFile($"使用临时文件方式成功保存配置: {PluginConfigFile}"); @@ -1271,7 +1272,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"保存插件配置时发生未处理异常: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 计算文件哈希 /// @@ -1303,13 +1304,13 @@ namespace Ink_Canvas.Helpers.Plugins try { LogHelper.WriteLogToFile("开始从配置文件重新加载插件状态"); - + // 保存当前配置状态,以便在加载失败时回滚 Dictionary previousStates = new Dictionary(PluginStates); - + // 重新加载配置文件 LoadConfig(); - + // 如果配置文件加载失败,PluginStates可能为空,这时使用之前的状态 if (PluginStates == null || PluginStates.Count == 0) { @@ -1317,24 +1318,24 @@ namespace Ink_Canvas.Helpers.Plugins PluginStates = previousStates; return; } - + LogHelper.WriteLogToFile($"已加载 {PluginStates.Count} 个插件状态,开始应用..."); - + // 对比配置,查找变更的插件 foreach (var plugin in Plugins.ToList()) // 创建副本进行遍历,避免集合修改异常 { string pluginTypeName = plugin.GetType().FullName; - + // 检查插件在配置中是否存在 if (PluginStates.TryGetValue(pluginTypeName, out bool shouldBeEnabled)) { bool currentlyEnabled = plugin is PluginBase pluginBase && pluginBase.IsEnabled; - + // 如果状态需要变更 if (currentlyEnabled != shouldBeEnabled) { LogHelper.WriteLogToFile($"应用插件 {plugin.Name} 的配置状态: {(shouldBeEnabled ? "启用" : "禁用")}"); - + if (shouldBeEnabled) { try @@ -1353,10 +1354,10 @@ namespace Ink_Canvas.Helpers.Plugins // 记录禁用信息,特别是内置插件 bool isBuiltIn = plugin.IsBuiltIn; LogHelper.WriteLogToFile($"尝试禁用{(isBuiltIn ? "内置" : "外部")}插件 {plugin.Name}"); - + // 禁用插件 plugin.Disable(); - + // 对于内置插件,特别检查禁用状态 if (isBuiltIn && plugin is PluginBase builtInPluginBase) { @@ -1378,7 +1379,7 @@ namespace Ink_Canvas.Helpers.Plugins LogHelper.WriteLogToFile($"禁用插件 {plugin.Name} 时出错: {ex.Message}", LogHelper.LogType.Error); } } - + // 如果是外部插件,执行重载 if (!plugin.IsBuiltIn && plugin is PluginBase externalPlugin && !string.IsNullOrEmpty(externalPlugin.PluginPath)) { @@ -1398,7 +1399,7 @@ namespace Ink_Canvas.Helpers.Plugins // 插件不在配置中,将其添加为禁用状态 PluginStates[pluginTypeName] = false; LogHelper.WriteLogToFile($"插件 {plugin.Name} 不在配置中,默认设置为禁用状态"); - + // 如果当前是启用状态,则禁用它 if (plugin is PluginBase pluginBase && pluginBase.IsEnabled) { @@ -1406,9 +1407,9 @@ namespace Ink_Canvas.Helpers.Plugins { bool isBuiltIn = plugin.IsBuiltIn; LogHelper.WriteLogToFile($"尝试禁用未配置的{(isBuiltIn ? "内置" : "外部")}插件 {plugin.Name}"); - + plugin.Disable(); - + // 对于内置插件,特别检查禁用状态 if (isBuiltIn && pluginBase.IsEnabled) { @@ -1429,14 +1430,15 @@ namespace Ink_Canvas.Helpers.Plugins } } } - + // 保存更新后的配置 SaveConfig(); - + // 通知UI更新 if (Application.Current != null && Application.Current.Dispatcher != null) { - Application.Current.Dispatcher.Invoke(() => { + Application.Current.Dispatcher.Invoke(() => + { // 通知任何可能打开的插件设置窗口刷新 foreach (Window window in Application.Current.Windows) { @@ -1447,7 +1449,7 @@ namespace Ink_Canvas.Helpers.Plugins } }); } - + LogHelper.WriteLogToFile("插件状态已从配置文件重新加载完成"); } catch (Exception ex) @@ -1456,4 +1458,4 @@ namespace Ink_Canvas.Helpers.Plugins } } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/PluginTemplate.cs b/Ink Canvas/Helpers/Plugins/PluginTemplate.cs index ba28dee4..bd6979d8 100644 --- a/Ink Canvas/Helpers/Plugins/PluginTemplate.cs +++ b/Ink Canvas/Helpers/Plugins/PluginTemplate.cs @@ -49,18 +49,18 @@ namespace Ink_Canvas.Helpers.Plugins { // 先调用基类方法,这样会设置插件ID和记录日志 base.Initialize(); - + // TODO: 在这里进行插件初始化工作 - + // 示例:记录初始化信息 LogHelper.WriteLogToFile($"插件 {Name} 开始初始化"); - + // 示例:加载配置 LoadConfig(); - + // 示例:注册自定义事件 // MainWindow.Instance.SomeEvent += OnSomeEvent; - + LogHelper.WriteLogToFile($"插件 {Name} 初始化完成"); } @@ -72,9 +72,9 @@ namespace Ink_Canvas.Helpers.Plugins { // 先调用基类方法,这样会设置插件状态和记录日志 base.Enable(); - + // TODO: 在这里启用插件功能 - + LogHelper.WriteLogToFile($"插件 {Name} 已启用"); } @@ -86,9 +86,9 @@ namespace Ink_Canvas.Helpers.Plugins { // 先调用基类方法,这样会设置插件状态和记录日志 base.Disable(); - + // TODO: 在这里禁用插件功能 - + LogHelper.WriteLogToFile($"插件 {Name} 已禁用"); } @@ -99,13 +99,13 @@ namespace Ink_Canvas.Helpers.Plugins public override void Cleanup() { // TODO: 在这里清理插件资源 - + // 示例:取消注册事件 // MainWindow.Instance.SomeEvent -= OnSomeEvent; - + // 示例:保存配置 SaveConfig(); - + // 最后调用基类方法 base.Cleanup(); } @@ -186,7 +186,7 @@ namespace Ink_Canvas.Helpers.Plugins public void DoSomething() { if (!IsEnabled) return; - + try { // TODO: 实现你的功能 @@ -245,7 +245,7 @@ namespace Ink_Canvas.Helpers.Plugins Text = "设置项:", Margin = new Thickness(0, 5, 0, 5) }); - + panel.Children.Add(new TextBox { Margin = new Thickness(0, 0, 0, 10), @@ -261,16 +261,16 @@ namespace Ink_Canvas.Helpers.Plugins Margin = new Thickness(0, 10, 0, 0), HorizontalAlignment = HorizontalAlignment.Left }; - - button.Click += (sender, e) => + + button.Click += (sender, e) => { MessageBox.Show("设置已保存!", "插件模板", MessageBoxButton.OK, MessageBoxImage.Information); }; - + panel.Children.Add(button); // 设置控件内容 Content = panel; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/SoftwareLauncher.cs b/Ink Canvas/Helpers/SoftwareLauncher.cs index 5f2e405d..e3dc7188 100644 --- a/Ink Canvas/Helpers/SoftwareLauncher.cs +++ b/Ink Canvas/Helpers/SoftwareLauncher.cs @@ -1,8 +1,8 @@ -using System; +using Microsoft.Win32; +using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; -using Microsoft.Win32; namespace Ink_Canvas.Helpers { diff --git a/Ink Canvas/Helpers/WinTabWindowsChecker.cs b/Ink Canvas/Helpers/WinTabWindowsChecker.cs index e97e58d3..0f1a7577 100644 --- a/Ink Canvas/Helpers/WinTabWindowsChecker.cs +++ b/Ink Canvas/Helpers/WinTabWindowsChecker.cs @@ -1,7 +1,9 @@ using System.Windows.Automation; -namespace Ink_Canvas.Helpers { - internal class WinTabWindowsChecker { +namespace Ink_Canvas.Helpers +{ + internal class WinTabWindowsChecker + { /* public static bool IsWindowMinimized(string windowName, bool matchFullName = true) { // 获取Win+Tab预览中的窗口 @@ -40,28 +42,37 @@ namespace Ink_Canvas.Helpers { } */ - public static bool IsWindowExisted(string windowName, bool matchFullName = true) { + public static bool IsWindowExisted(string windowName, bool matchFullName = true) + { // 获取Win+Tab预览中的窗口 AutomationElementCollection windows = AutomationElement.RootElement.FindAll( TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window)); - foreach (AutomationElement window in windows) { + foreach (AutomationElement window in windows) + { //LogHelper.WriteLogToFile("" + window.Current.Name); string windowTitle = window.Current.Name; // 如果窗口标题包含 windowName,则进行检查 - if (!string.IsNullOrEmpty(windowTitle) && windowTitle.Contains(windowName)) { - if (matchFullName) { - if (windowTitle.Length == windowName.Length) { + if (!string.IsNullOrEmpty(windowTitle) && windowTitle.Contains(windowName)) + { + if (matchFullName) + { + if (windowTitle.Length == windowName.Length) + { WindowPattern windowPattern = window.GetCurrentPattern(WindowPattern.Pattern) as WindowPattern; - if (windowPattern != null) { + if (windowPattern != null) + { return true; } } - } else { + } + else + { WindowPattern windowPattern = window.GetCurrentPattern(WindowPattern.Pattern) as WindowPattern; - if (windowPattern != null) { + if (windowPattern != null) + { return true; } } diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs index 4691bd5d..7d05c22d 100644 --- a/Ink Canvas/MainWindow.xaml.cs +++ b/Ink Canvas/MainWindow.xaml.cs @@ -1,3 +1,9 @@ +using Ink_Canvas.Helpers; +using Ink_Canvas.Helpers.Plugins; +using Ink_Canvas.Windows; +using iNKORE.UI.WPF.Modern; +using iNKORE.UI.WPF.Modern.Controls; +using Microsoft.Win32; using System; using System.Collections.Generic; using System.ComponentModel; @@ -15,25 +21,21 @@ using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Threading; -using Ink_Canvas.Helpers; -using Ink_Canvas.Helpers.Plugins; -using Ink_Canvas.Windows; -using iNKORE.UI.WPF.Modern; -using iNKORE.UI.WPF.Modern.Controls; -using Microsoft.Win32; using Application = System.Windows.Application; -using File = System.IO.File; -using MessageBox = System.Windows.MessageBox; using Brushes = System.Windows.Media.Brushes; using Button = System.Windows.Controls.Button; using Cursor = System.Windows.Input.Cursor; using Cursors = System.Windows.Input.Cursors; using DpiChangedEventArgs = System.Windows.DpiChangedEventArgs; +using File = System.IO.File; using GroupBox = System.Windows.Controls.GroupBox; +using MessageBox = System.Windows.MessageBox; using Point = System.Windows.Point; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { // 新增:每一页一个Canvas对象 private List whiteboardPages = new List(); private int currentPageIndex; @@ -44,7 +46,8 @@ namespace Ink_Canvas { #region Window Initialization - public MainWindow() { + public MainWindow() + { /* 处于画板模式内:Topmost == false / currentMode != 0 处于 PPT 放映内:BtnPPTSlideShowEnd.Visibility @@ -76,32 +79,39 @@ namespace Ink_Canvas { -2000, -200); ViewboxFloatingBarMarginAnimation(100, true); - try { + try + { if (File.Exists("debug.ini")) Label.Visibility = Visibility.Visible; } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error); } - try { - if (File.Exists("Log.txt")) { + try + { + if (File.Exists("Log.txt")) + { var fileInfo = new FileInfo("Log.txt"); var fileSizeInKB = fileInfo.Length / 1024; if (fileSizeInKB > 512) - try { + try + { File.Delete("Log.txt"); LogHelper.WriteLogToFile( "The Log.txt file has been successfully deleted. Original file size: " + fileSizeInKB + " KB"); } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile( ex + " | Can not delete the Log.txt file. File size: " + fileSizeInKB + " KB", LogHelper.LogType.Error); } } } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error); } @@ -111,10 +121,12 @@ namespace Ink_Canvas { inkCanvas.Strokes.StrokesChanged += StrokesOnStrokesChanged; SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged; - try { + try + { if (File.Exists("SpecialVersion.ini")) SpecialVersionResetToSuggestion_Click(); } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error); } @@ -140,22 +152,26 @@ namespace Ink_Canvas { double leftTouchStartY = 0; double leftScrollStartOffset = 0; bool leftIsTouching = false; - BlackBoardLeftSidePageListScrollViewer.TouchDown += (s, e) => { + BlackBoardLeftSidePageListScrollViewer.TouchDown += (s, e) => + { leftIsTouching = true; leftTouchStartY = e.GetTouchPoint(BlackBoardLeftSidePageListScrollViewer).Position.Y; leftScrollStartOffset = BlackBoardLeftSidePageListScrollViewer.VerticalOffset; BlackBoardLeftSidePageListScrollViewer.CaptureTouch(e.TouchDevice); e.Handled = true; }; - BlackBoardLeftSidePageListScrollViewer.TouchMove += (s, e) => { - if (leftIsTouching) { + BlackBoardLeftSidePageListScrollViewer.TouchMove += (s, e) => + { + if (leftIsTouching) + { double currentY = e.GetTouchPoint(BlackBoardLeftSidePageListScrollViewer).Position.Y; double delta = leftTouchStartY - currentY; BlackBoardLeftSidePageListScrollViewer.ScrollToVerticalOffset(leftScrollStartOffset + delta); e.Handled = true; } }; - BlackBoardLeftSidePageListScrollViewer.TouchUp += (s, e) => { + BlackBoardLeftSidePageListScrollViewer.TouchUp += (s, e) => + { leftIsTouching = false; BlackBoardLeftSidePageListScrollViewer.ReleaseTouchCapture(e.TouchDevice); e.Handled = true; @@ -163,22 +179,26 @@ namespace Ink_Canvas { double rightTouchStartY = 0; double rightScrollStartOffset = 0; bool rightIsTouching = false; - BlackBoardRightSidePageListScrollViewer.TouchDown += (s, e) => { + BlackBoardRightSidePageListScrollViewer.TouchDown += (s, e) => + { rightIsTouching = true; rightTouchStartY = e.GetTouchPoint(BlackBoardRightSidePageListScrollViewer).Position.Y; rightScrollStartOffset = BlackBoardRightSidePageListScrollViewer.VerticalOffset; BlackBoardRightSidePageListScrollViewer.CaptureTouch(e.TouchDevice); e.Handled = true; }; - BlackBoardRightSidePageListScrollViewer.TouchMove += (s, e) => { - if (rightIsTouching) { + BlackBoardRightSidePageListScrollViewer.TouchMove += (s, e) => + { + if (rightIsTouching) + { double currentY = e.GetTouchPoint(BlackBoardRightSidePageListScrollViewer).Position.Y; double delta = rightTouchStartY - currentY; BlackBoardRightSidePageListScrollViewer.ScrollToVerticalOffset(rightScrollStartOffset + delta); e.Handled = true; } }; - BlackBoardRightSidePageListScrollViewer.TouchUp += (s, e) => { + BlackBoardRightSidePageListScrollViewer.TouchUp += (s, e) => + { rightIsTouching = false; BlackBoardRightSidePageListScrollViewer.ReleaseTouchCapture(e.TouchDevice); e.Handled = true; @@ -199,8 +219,10 @@ namespace Ink_Canvas { private DrawingAttributes drawingAttributes; private InkSmoothingManager _inkSmoothingManager; - private void loadPenCanvas() { - try { + private void loadPenCanvas() + { + try + { //drawingAttributes = new DrawingAttributes(); drawingAttributes = inkCanvas.DefaultDrawingAttributes; drawingAttributes.Color = Ink_DefaultColor; @@ -228,12 +250,15 @@ namespace Ink_Canvas { //ApplicationGesture lastApplicationGesture = ApplicationGesture.AllGestures; private DateTime lastGestureTime = DateTime.Now; - private void InkCanvas_Gesture(object sender, InkCanvasGestureEventArgs e) { + private void InkCanvas_Gesture(object sender, InkCanvasGestureEventArgs e) + { var gestures = e.GetGestureRecognitionResults(); - try { + try + { foreach (var gest in gestures) //Trace.WriteLine(string.Format("Gesture: {0}, Confidence: {1}", gest.ApplicationGesture, gest.RecognitionConfidence)); - if (StackPanelPPTControls.Visibility == Visibility.Visible) { + if (StackPanelPPTControls.Visibility == Visibility.Visible) + { if (gest.ApplicationGesture == ApplicationGesture.Left) BtnPPTSlidesDown_Click(BtnPPTSlidesDown, null); if (gest.ApplicationGesture == ApplicationGesture.Right) @@ -243,38 +268,49 @@ namespace Ink_Canvas { catch { } } - private void inkCanvas_EditingModeChanged(object sender, RoutedEventArgs e) { + private void inkCanvas_EditingModeChanged(object sender, RoutedEventArgs e) + { var inkCanvas1 = sender as InkCanvas; if (inkCanvas1 == null) return; // 使用辅助方法设置光标 SetCursorBasedOnEditingMode(inkCanvas1); - if (Settings.Canvas.IsShowCursor) { + if (Settings.Canvas.IsShowCursor) + { if (inkCanvas1.EditingMode == InkCanvasEditingMode.Ink || inkCanvas1.EditingMode == InkCanvasEditingMode.Select || drawingShapeMode != 0) inkCanvas1.ForceCursor = true; else inkCanvas1.ForceCursor = false; - } else { + } + else + { // 套索选择模式下始终强制显示光标,即使用户设置不显示光标 - if (inkCanvas1.EditingMode == InkCanvasEditingMode.Select) { + if (inkCanvas1.EditingMode == InkCanvasEditingMode.Select) + { inkCanvas1.ForceCursor = true; - } else { + } + else + { inkCanvas1.ForceCursor = false; } } if (inkCanvas1.EditingMode == InkCanvasEditingMode.Ink) forcePointEraser = !forcePointEraser; - + // 处理高级橡皮擦覆盖层的启用/禁用 var eraserOverlay = FindName("AdvancedEraserOverlay") as Border; - if (eraserOverlay != null) { - if (inkCanvas1.EditingMode == InkCanvasEditingMode.EraseByPoint) { + if (eraserOverlay != null) + { + if (inkCanvas1.EditingMode == InkCanvasEditingMode.EraseByPoint) + { // 橡皮擦模式下启用覆盖层 eraserOverlay.IsHitTestVisible = true; Trace.WriteLine("Advanced Eraser: Overlay enabled in eraser mode"); - } else { + } + else + { // 其他模式下禁用覆盖层 eraserOverlay.IsHitTestVisible = false; // 同时禁用高级橡皮擦系统 @@ -293,7 +329,8 @@ namespace Ink_Canvas { private bool isLoaded; private bool forcePointEraser; - private void Window_Loaded(object sender, RoutedEventArgs e) { + private void Window_Loaded(object sender, RoutedEventArgs e) + { loadPenCanvas(); //加载设置 LoadSettings(true); @@ -334,7 +371,7 @@ namespace Ink_Canvas { { LogHelper.WriteLogToFile($"检测或修正保存路径时出错: {ex.Message}", LogHelper.LogType.Error); } - + // 加载自定义背景颜色 LoadCustomBackgroundColor(); @@ -352,7 +389,7 @@ namespace Ink_Canvas { { StartPPTMonitoring(); } - + // HasNewUpdateWindow hasNewUpdateWindow = new HasNewUpdateWindow(); if (Environment.Is64BitProcess) GroupBoxInkRecognition.Visibility = Visibility.Collapsed; @@ -376,12 +413,13 @@ namespace Ink_Canvas { // 应用颜色主题,这将考虑自定义背景色 CheckColorTheme(true); - + BtnWhiteBoardSwitchPrevious.IsEnabled = CurrentWhiteboardIndex != 1; BorderInkReplayToolBox.Visibility = Visibility.Collapsed; // 提前加载IA库,优化第一笔等待时间 - if (Settings.InkToShape.IsInkToShapeEnabled && !Environment.Is64BitProcess) { + if (Settings.InkToShape.IsInkToShapeEnabled && !Environment.Is64BitProcess) + { var strokeEmpty = new StrokeCollection(); InkRecognizeHelper.RecognizeShape(strokeEmpty); } @@ -398,23 +436,24 @@ namespace Ink_Canvas { RadioCrashSilentRestart.IsChecked = true; else RadioCrashNoAction.IsChecked = true; - - + + // 如果当前不是黑板模式,则切换到黑板模式 if (currentMode == 0) { // 延迟执行,确保UI已完全加载 - Dispatcher.BeginInvoke(new Action(() => { + Dispatcher.BeginInvoke(new Action(() => + { // 重新加载自定义背景颜色 LoadCustomBackgroundColor(); - + // 模拟点击切换按钮进入黑板模式 if (GridTransparencyFakeBackground.Background != Brushes.Transparent) { BtnSwitch_Click(BtnSwitch, null); } - + // 确保背景颜色正确设置为黑板颜色 CheckColorTheme(true); }), DispatcherPriority.Loaded); @@ -433,17 +472,21 @@ namespace Ink_Canvas { InitializeClipboardMonitoring(); } - private void SystemEventsOnDisplaySettingsChanged(object sender, EventArgs e) { + private void SystemEventsOnDisplaySettingsChanged(object sender, EventArgs e) + { if (!Settings.Advanced.IsEnableResolutionChangeDetection) return; ShowNotification($"检测到显示器信息变化,变为{Screen.PrimaryScreen.Bounds.Width}x{Screen.PrimaryScreen.Bounds.Height})"); - new Thread(() => { + new Thread(() => + { var isFloatingBarOutsideScreen = false; var isInPPTPresentationMode = false; - Dispatcher.Invoke(() => { + Dispatcher.Invoke(() => + { isFloatingBarOutsideScreen = IsOutsideOfScreenHelper.IsOutsideOfScreen(ViewboxFloatingBar); isInPPTPresentationMode = BtnPPTSlideShowEnd.Visibility == Visibility.Visible; }); - if (isFloatingBarOutsideScreen) dpiChangedDelayAction.DebounceAction(3000, null, () => { + if (isFloatingBarOutsideScreen) dpiChangedDelayAction.DebounceAction(3000, null, () => + { if (!isFloatingBarFolded) { if (isInPPTPresentationMode) ViewboxFloatingBarMarginAnimation(60); @@ -461,14 +504,17 @@ namespace Ink_Canvas { { ShowNotification($"系统DPI发生变化,从 {e.OldDpi.DpiScaleX}x{e.OldDpi.DpiScaleY} 变化为 {e.NewDpi.DpiScaleX}x{e.NewDpi.DpiScaleY}"); - new Thread(() => { + new Thread(() => + { var isFloatingBarOutsideScreen = false; var isInPPTPresentationMode = false; - Dispatcher.Invoke(() => { + Dispatcher.Invoke(() => + { isFloatingBarOutsideScreen = IsOutsideOfScreenHelper.IsOutsideOfScreen(ViewboxFloatingBar); isInPPTPresentationMode = BtnPPTSlideShowEnd.Visibility == Visibility.Visible; }); - if (isFloatingBarOutsideScreen) dpiChangedDelayAction.DebounceAction(3000,null, () => { + if (isFloatingBarOutsideScreen) dpiChangedDelayAction.DebounceAction(3000, null, () => + { if (!isFloatingBarFolded) { if (isInPPTPresentationMode) ViewboxFloatingBarMarginAnimation(60); @@ -479,39 +525,44 @@ namespace Ink_Canvas { } } - private void Window_Closing(object sender, CancelEventArgs e) { + private void Window_Closing(object sender, CancelEventArgs e) + { LogHelper.WriteLogToFile("Ink Canvas closing", LogHelper.LogType.Event); - if (!CloseIsFromButton && Settings.Advanced.IsSecondConfirmWhenShutdownApp) { + if (!CloseIsFromButton && Settings.Advanced.IsSecondConfirmWhenShutdownApp) + { // 第一个确认对话框 var result1 = MessageBox.Show("是否继续关闭 InkCanvasForClass,这将丢失当前未保存的墨迹。", "InkCanvasForClass", MessageBoxButton.OKCancel, MessageBoxImage.Warning); - - if (result1 == MessageBoxResult.Cancel) { + + if (result1 == MessageBoxResult.Cancel) + { e.Cancel = true; LogHelper.WriteLogToFile("Ink Canvas closing cancelled at first confirmation", LogHelper.LogType.Event); return; } - + // 第二个确认对话框 - var result2 = MessageBox.Show("真的狠心关闭 InkCanvasForClass吗?", "InkCanvasForClass", + var result2 = MessageBox.Show("真的狠心关闭 InkCanvasForClass吗?", "InkCanvasForClass", MessageBoxButton.OKCancel, MessageBoxImage.Error); - - if (result2 == MessageBoxResult.Cancel) { + + if (result2 == MessageBoxResult.Cancel) + { e.Cancel = true; LogHelper.WriteLogToFile("Ink Canvas closing cancelled at second confirmation", LogHelper.LogType.Event); return; } - + // 第三个最终确认对话框 - var result3 = MessageBox.Show("最后确认:确定要关闭 InkCanvasForClass 吗?", "InkCanvasForClass", + var result3 = MessageBox.Show("最后确认:确定要关闭 InkCanvasForClass 吗?", "InkCanvasForClass", MessageBoxButton.OKCancel, MessageBoxImage.Question); - - if (result3 == MessageBoxResult.Cancel) { + + if (result3 == MessageBoxResult.Cancel) + { e.Cancel = true; LogHelper.WriteLogToFile("Ink Canvas closing cancelled at final confirmation", LogHelper.LogType.Event); return; } - + // 所有确认都通过,允许关闭 e.Cancel = false; LogHelper.WriteLogToFile("Ink Canvas closing confirmed by user", LogHelper.LogType.Event); @@ -522,9 +573,11 @@ namespace Ink_Canvas { [DllImport("user32.dll", SetLastError = true)] public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); - - private void MainWindow_OnSizeChanged(object sender, SizeChangedEventArgs e) { - if (Settings.Advanced.IsEnableForceFullScreen) { + + private void MainWindow_OnSizeChanged(object sender, SizeChangedEventArgs e) + { + if (Settings.Advanced.IsEnableForceFullScreen) + { if (isLoaded) ShowNotification( $"检测到窗口大小变化,已自动恢复到全屏:{Screen.PrimaryScreen.Bounds.Width}x{Screen.PrimaryScreen.Bounds.Height}(缩放比例为{Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth}x{Screen.PrimaryScreen.Bounds.Height / SystemParameters.PrimaryScreenHeight})"); WindowState = WindowState.Maximized; @@ -535,7 +588,8 @@ namespace Ink_Canvas { } - private void Window_Closed(object sender, EventArgs e) { + private void Window_Closed(object sender, EventArgs e) + { SystemEvents.DisplaySettingsChanged -= SystemEventsOnDisplaySettingsChanged; // 释放PPT管理器资源 @@ -550,7 +604,7 @@ namespace Ink_Canvas { // 检查是否有待安装的更新 CheckPendingUpdates(); } - + private void CheckPendingUpdates() { try @@ -561,14 +615,14 @@ namespace Ink_Canvas { // 检查更新文件是否已下载 string updatesFolderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "AutoUpdate"); string statusFilePath = Path.Combine(updatesFolderPath, $"DownloadV{AvailableLatestVersion}Status.txt"); - + if (File.Exists(statusFilePath) && File.ReadAllText(statusFilePath).Trim().ToLower() == "true") { LogHelper.WriteLogToFile($"AutoUpdate | Installing pending update v{AvailableLatestVersion} on application close"); - + // 设置为用户主动退出,避免被看门狗判定为崩溃 App.IsAppExitByUser = true; - + // 创建批处理脚本并启动,软件关闭后会执行更新操作 AutoUpdateHelper.InstallNewVersionApp(AvailableLatestVersion, true); } @@ -591,7 +645,7 @@ namespace Ink_Canvas { LogHelper.WriteLogToFile($"AutoUpdate | 使用主要线路组下载: {primaryGroup.GroupName}"); return await AutoUpdateHelper.DownloadSetupFile(version, primaryGroup); } - + // 如果主要线路组不可用,获取所有可用线路组 LogHelper.WriteLogToFile("AutoUpdate | 主要线路组不可用,获取所有可用线路组"); var availableGroups = await AutoUpdateHelper.GetAvailableLineGroupsOrdered(channel); @@ -600,7 +654,7 @@ namespace Ink_Canvas { LogHelper.WriteLogToFile("AutoUpdate | 没有可用的线路组", LogHelper.LogType.Error); return false; } - + LogHelper.WriteLogToFile($"AutoUpdate | 使用 {availableGroups.Count} 个可用线路组进行下载"); return await AutoUpdateHelper.DownloadSetupFileWithFallback(version, availableGroups); } @@ -611,67 +665,75 @@ namespace Ink_Canvas { } } - private async void AutoUpdate() { + private async void AutoUpdate() + { // 清除之前的更新状态,确保使用新通道重新检查 AvailableLatestVersion = null; AvailableLatestLineGroup = null; - + // 使用当前选择的更新通道检查更新 var (remoteVersion, lineGroup, apiReleaseNotes) = await AutoUpdateHelper.CheckForUpdates(Settings.Startup.UpdateChannel); AvailableLatestVersion = remoteVersion; AvailableLatestLineGroup = lineGroup; - + // 声明下载状态变量,用于整个方法 bool isDownloadSuccessful = false; - if (AvailableLatestVersion != null) { + if (AvailableLatestVersion != null) + { // 检测到新版本 LogHelper.WriteLogToFile($"AutoUpdate | New version available: {AvailableLatestVersion}"); - + // 检查是否是用户选择跳过的版本 - if (!string.IsNullOrEmpty(Settings.Startup.SkippedVersion) && - Settings.Startup.SkippedVersion == AvailableLatestVersion) { + if (!string.IsNullOrEmpty(Settings.Startup.SkippedVersion) && + Settings.Startup.SkippedVersion == AvailableLatestVersion) + { LogHelper.WriteLogToFile($"AutoUpdate | Version {AvailableLatestVersion} was marked to be skipped by the user"); return; // 跳过此版本,不执行更新操作 } - + // 如果检测到的版本与跳过的版本不同,则清除跳过版本记录 // 这确保用户只能跳过当前最新版本,而不是永久跳过所有更新 - if (!string.IsNullOrEmpty(Settings.Startup.SkippedVersion) && - Settings.Startup.SkippedVersion != AvailableLatestVersion) { + if (!string.IsNullOrEmpty(Settings.Startup.SkippedVersion) && + Settings.Startup.SkippedVersion != AvailableLatestVersion) + { LogHelper.WriteLogToFile($"AutoUpdate | Detected new version {AvailableLatestVersion} different from skipped version {Settings.Startup.SkippedVersion}, clearing skip record"); Settings.Startup.SkippedVersion = ""; SaveSettingsToFile(); } - + // 获取当前版本 string currentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); - + // 如果启用了静默更新,则自动下载更新而不显示提示 - if (Settings.Startup.IsAutoUpdateWithSilence) { + if (Settings.Startup.IsAutoUpdateWithSilence) + { LogHelper.WriteLogToFile("AutoUpdate | Silent update enabled, downloading update automatically without notification"); - + // 静默下载更新,使用多线路组下载功能 isDownloadSuccessful = await DownloadUpdateWithFallback(AvailableLatestVersion, AvailableLatestLineGroup, Settings.Startup.UpdateChannel); - - if (isDownloadSuccessful) { + + if (isDownloadSuccessful) + { LogHelper.WriteLogToFile("AutoUpdate | Update downloaded successfully, will install when conditions are met"); - + // 启动检查定时器,定期检查是否可以安装 timerCheckAutoUpdateWithSilence.Start(); - } else { + } + else + { LogHelper.WriteLogToFile("AutoUpdate | Silent update download failed", LogHelper.LogType.Error); } - + return; } - + // 如果没有启用静默更新,则显示常规更新窗口 string releaseDate = DateTime.Now.ToString("yyyy年MM月dd日"); - + // 从服务器获取更新日志 string releaseNotes = await AutoUpdateHelper.GetUpdateLog(Settings.Startup.UpdateChannel); - + // 如果获取失败,使用默认文本 if (string.IsNullOrEmpty(releaseNotes)) { @@ -679,97 +741,110 @@ namespace Ink_Canvas { 无法获取更新日志,但新版本已准备就绪。"; } - + // 创建并显示更新窗口 HasNewUpdateWindow updateWindow = new HasNewUpdateWindow(currentVersion, AvailableLatestVersion, releaseDate, releaseNotes); bool? dialogResult = updateWindow.ShowDialog(); - + // 如果窗口被关闭但没有点击按钮,则不执行任何操作 - if (dialogResult != true) { + if (dialogResult != true) + { LogHelper.WriteLogToFile("AutoUpdate | Update dialog closed without selection"); return; } - + // 不再从更新窗口获取自动更新设置 - + // 根据用户选择处理更新 - switch (updateWindow.Result) { + switch (updateWindow.Result) + { case HasNewUpdateWindow.UpdateResult.UpdateNow: // 立即更新:显示下载进度,下载完成后立即安装 LogHelper.WriteLogToFile("AutoUpdate | User chose to update now"); - + // 显示下载进度提示 MessageBox.Show("开始下载更新,请稍候...", "正在更新", MessageBoxButton.OK, MessageBoxImage.Information); - + // 下载更新文件,使用多线路组下载功能 isDownloadSuccessful = await DownloadUpdateWithFallback(AvailableLatestVersion, AvailableLatestLineGroup, Settings.Startup.UpdateChannel); - - if (isDownloadSuccessful) { + + if (isDownloadSuccessful) + { // 下载成功,提示用户准备安装 MessageBoxResult result = MessageBox.Show("更新已下载完成,点击确定后将关闭软件并安装新版本!", "安装更新", MessageBoxButton.OKCancel, MessageBoxImage.Information); - + // 只有当用户点击确定按钮后才关闭软件 - if (result == MessageBoxResult.OK) { + if (result == MessageBoxResult.OK) + { // 设置为用户主动退出,避免被看门狗判定为崩溃 App.IsAppExitByUser = true; - + // 准备批处理脚本 - AutoUpdateHelper.InstallNewVersionApp(AvailableLatestVersion, false); - + AutoUpdateHelper.InstallNewVersionApp(AvailableLatestVersion, false); + // 关闭软件,让安装程序接管 Application.Current.Shutdown(); - } else { + } + else + { LogHelper.WriteLogToFile("AutoUpdate | User cancelled update installation"); } - } else { + } + else + { // 下载失败 MessageBox.Show("更新下载失败,请检查网络连接后重试。", "下载失败", MessageBoxButton.OK, MessageBoxImage.Error); } break; - + case HasNewUpdateWindow.UpdateResult.UpdateLater: // 稍后更新:静默下载,在软件关闭时自动安装 LogHelper.WriteLogToFile("AutoUpdate | User chose to update later"); - + // 不管设置如何,都进行下载,使用多线路组下载功能 isDownloadSuccessful = await DownloadUpdateWithFallback(AvailableLatestVersion, AvailableLatestLineGroup, Settings.Startup.UpdateChannel); - - if (isDownloadSuccessful) { + + if (isDownloadSuccessful) + { LogHelper.WriteLogToFile("AutoUpdate | Update downloaded successfully, will install when application closes"); - + // 设置标志,在应用程序关闭时安装 Settings.Startup.IsAutoUpdate = true; Settings.Startup.IsAutoUpdateWithSilence = true; - + // 启动检查定时器 timerCheckAutoUpdateWithSilence.Start(); - + // 通知用户 MessageBox.Show("更新已下载完成,将在软件关闭时自动安装。", "更新已准备就绪", MessageBoxButton.OK, MessageBoxImage.Information); - } else { + } + else + { LogHelper.WriteLogToFile("AutoUpdate | Update download failed", LogHelper.LogType.Error); MessageBox.Show("更新下载失败,请检查网络连接后重试。", "下载失败", MessageBoxButton.OK, MessageBoxImage.Error); } break; - + case HasNewUpdateWindow.UpdateResult.SkipVersion: // 跳过该版本:记录到设置中 LogHelper.WriteLogToFile($"AutoUpdate | User chose to skip version {AvailableLatestVersion}"); - + // 记录要跳过的版本号 Settings.Startup.SkippedVersion = AvailableLatestVersion; - + // 保存设置到文件 SaveSettingsToFile(); - + // 通知用户 - MessageBox.Show($"已设置跳过版本 {AvailableLatestVersion},在下次发布新版本之前不会再提示更新。", - "已跳过此版本", - MessageBoxButton.OK, + MessageBox.Show($"已设置跳过版本 {AvailableLatestVersion},在下次发布新版本之前不会再提示更新。", + "已跳过此版本", + MessageBoxButton.OK, MessageBoxImage.Information); break; } - } else { + } + else + { AutoUpdateHelper.DeleteUpdatesFolder(); } } @@ -796,7 +871,8 @@ namespace Ink_Canvas { public void SetCursorBasedOnEditingMode(InkCanvas canvas) { // 套索选择模式下光标始终显示,无论用户设置如何 - if (canvas.EditingMode == InkCanvasEditingMode.Select) { + if (canvas.EditingMode == InkCanvasEditingMode.Select) + { canvas.UseCustomCursor = true; canvas.ForceCursor = true; canvas.Cursor = Cursors.Cross; @@ -805,14 +881,18 @@ namespace Ink_Canvas { } // 其他模式按照用户设置处理 - if (Settings.Canvas.IsShowCursor) { + if (Settings.Canvas.IsShowCursor) + { canvas.UseCustomCursor = true; canvas.ForceCursor = true; // 根据编辑模式设置不同的光标 - if (canvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { + if (canvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { canvas.Cursor = Cursors.Cross; - } else if (canvas.EditingMode == InkCanvasEditingMode.Ink) { + } + else if (canvas.EditingMode == InkCanvasEditingMode.Ink) + { var sri = Application.GetResourceStream(new Uri("Resources/Cursors/Pen.cur", UriKind.Relative)); if (sri != null) canvas.Cursor = new Cursor(sri.Stream); @@ -822,16 +902,21 @@ namespace Ink_Canvas { System.Windows.Forms.Cursor.Show(); // 确保手写笔模式下也能显示光标 - if (Tablet.TabletDevices.Count > 0) { - foreach (TabletDevice device in Tablet.TabletDevices) { - if (device.Type == TabletDeviceType.Stylus) { + if (Tablet.TabletDevices.Count > 0) + { + foreach (TabletDevice device in Tablet.TabletDevices) + { + if (device.Type == TabletDeviceType.Stylus) + { // 手写笔设备存在,强制显示光标 System.Windows.Forms.Cursor.Show(); break; } } } - } else { + } + else + { canvas.UseCustomCursor = false; canvas.ForceCursor = false; System.Windows.Forms.Cursor.Show(); @@ -1041,7 +1126,7 @@ namespace Ink_Canvas { catch (Exception ex) { LogHelper.WriteLogToFile($"MainWindow | 刷新设备信息失败: {ex.Message}", LogHelper.LogType.Error); - + // 显示错误信息 DeviceIdTextBlock.Text = "获取失败"; UsageFrequencyTextBlock.Text = "获取失败"; @@ -1067,7 +1152,7 @@ namespace Ink_Canvas { columnDefinitions[0].Width = new GridLength(50); } } - + // 新增:显示侧边栏 private void ShowNavSidebar_Click(object sender, RoutedEventArgs e) { @@ -1084,11 +1169,11 @@ namespace Ink_Canvas { // 设置蒙版为可点击,并添加半透明背景 BorderSettingsMask.IsHitTestVisible = true; BorderSettingsMask.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0)); - + // 获取SettingsPanelScrollViewer中的所有GroupBox var stackPanel = SettingsPanelScrollViewer.Content as StackPanel; if (stackPanel == null) return; - + // 确保所有GroupBox都是可见的 foreach (var child in stackPanel.Children) { @@ -1097,13 +1182,13 @@ namespace Ink_Canvas { groupBox.Visibility = Visibility.Visible; } } - + // 确保UI完全更新 - await Dispatcher.InvokeAsync(() => {}, DispatcherPriority.Render); - + await Dispatcher.InvokeAsync(() => { }, DispatcherPriority.Render); + // 根据传入的sectionTag滚动到相应的设置部分 GroupBox targetGroupBox = null; - + switch (sectionTag.ToLower()) { case "startup": @@ -1151,13 +1236,13 @@ namespace Ink_Canvas { SettingsPanelScrollViewer.ScrollToTop(); return; } - + // 如果找到目标GroupBox,则滚动到它的位置 if (targetGroupBox != null) { // 使用动画平滑滚动到目标位置 ScrollToElement(targetGroupBox); - + // 高亮显示当前选中的导航项 UpdateNavigationButtonState(sectionTag); } @@ -1167,7 +1252,7 @@ namespace Ink_Canvas { SettingsPanelScrollViewer.ScrollToTop(); } } - + // 根据Header文本查找GroupBox private GroupBox FindGroupBoxByHeader(StackPanel parent, string headerText) { @@ -1176,8 +1261,8 @@ namespace Ink_Canvas { if (child is GroupBox groupBox) { // 查找GroupBox的Header - if (groupBox.Header is TextBlock headerTextBlock && - headerTextBlock.Text != null && + if (groupBox.Header is TextBlock headerTextBlock && + headerTextBlock.Text != null && headerTextBlock.Text.Contains(headerText)) { return groupBox; @@ -1186,39 +1271,40 @@ namespace Ink_Canvas { } return null; } - + // 平滑滚动到指定元素 private async void ScrollToElement(FrameworkElement element) { if (element == null || SettingsPanelScrollViewer == null) return; - + try { // 暂时禁用滚动事件处理 SettingsPanelScrollViewer.ScrollChanged -= SettingsPanelScrollViewer_ScrollChanged; - + // 记录当前滚动位置 double originalOffset = SettingsPanelScrollViewer.VerticalOffset; - + // 将ScrollViewer内部的位置信息重置到顶部(不会触发视觉更新) SettingsPanelScrollViewer.ScrollToHome(); - + // 使用Dispatcher进行延迟处理,确保布局更新 - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { try { // 强制更新布局 SettingsPanelScrollViewer.UpdateLayout(); - + // 获取元素相对于顶部的准确位置 Point elementPosition = element.TransformToAncestor(SettingsPanelScrollViewer).Transform(new Point(0, 0)); - + // 计算目标位置,减去一些偏移,使元素不会贴在顶部 double targetPosition = elementPosition.Y - 20; - + // 确保目标位置不小于0 targetPosition = Math.Max(0, targetPosition); - + // 直接设置滚动位置,不使用动画 SettingsPanelScrollViewer.ScrollToVerticalOffset(targetPosition); } @@ -1240,19 +1326,19 @@ namespace Ink_Canvas { SettingsPanelScrollViewer.ScrollChanged += SettingsPanelScrollViewer_ScrollChanged; } } - + // 滚动条变化事件处理 private void SettingsPanelScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e) { // 可以在这里添加滚动事件的处理逻辑,如果需要的话 } - + // 更新导航按钮状态 private void UpdateNavigationButtonState(string activeTag) { // 清除所有导航按钮的Tag属性 ClearAllNavButtonTags(); - + // 设置当前活动按钮的Tag属性 switch (activeTag.ToLower()) { @@ -1297,25 +1383,25 @@ namespace Ink_Canvas { break; } } - + // 清除所有导航按钮的Tag属性 private void ClearAllNavButtonTags() { var grid = BorderSettings.Child as Grid; if (grid == null) return; - + var navSidebar = grid.Children[0] as Border; if (navSidebar == null) return; - + var navGrid = navSidebar.Child as Grid; if (navGrid == null) return; - + var scrollViewer = navGrid.Children[1] as ScrollViewer; if (scrollViewer == null) return; - + var stackPanel = scrollViewer.Content as StackPanel; if (stackPanel == null) return; - + foreach (var child in stackPanel.Children) { if (child is Button button) @@ -1324,32 +1410,32 @@ namespace Ink_Canvas { } } } - + // 设置导航按钮的Tag属性 private void SetNavButtonTag(string tag) { var grid = BorderSettings.Child as Grid; if (grid == null) return; - + var navSidebar = grid.Children[0] as Border; if (navSidebar == null) return; - + var navGrid = navSidebar.Child as Grid; if (navGrid == null) return; - + var scrollViewer = navGrid.Children[1] as ScrollViewer; if (scrollViewer == null) return; - + var stackPanel = scrollViewer.Content as StackPanel; if (stackPanel == null) return; - + foreach (var child in stackPanel.Children) { if (child is Button button) { // 检查按钮的ToolTip属性,根据tag设置对应的按钮 string buttonTag = button.Tag as string; - + // 如果按钮的Tag与要设置的tag匹配,则设置Tag if (buttonTag != null && buttonTag.ToLower() == tag.ToLower()) { @@ -1359,7 +1445,7 @@ namespace Ink_Canvas { } } } - + // 根据Header文本查找并显示GroupBox private void ShowGroupBoxByHeader(StackPanel parent, string headerText) { @@ -1368,8 +1454,8 @@ namespace Ink_Canvas { if (child is GroupBox groupBox) { // 查找GroupBox的Header - if (groupBox.Header is TextBlock headerTextBlock && - headerTextBlock.Text != null && + if (groupBox.Header is TextBlock headerTextBlock && + headerTextBlock.Text != null && headerTextBlock.Text.Contains(headerText)) { groupBox.Visibility = Visibility.Visible; @@ -1410,10 +1496,10 @@ namespace Ink_Canvas { // 暂时隐藏设置面板 BorderSettings.Visibility = Visibility.Hidden; BorderSettingsMask.Visibility = Visibility.Hidden; - + // 创建并显示插件设置窗口 PluginSettingsWindow pluginSettingsWindow = new PluginSettingsWindow(); - + // 设置窗口关闭事件,用于在插件管理窗口关闭后恢复设置面板 pluginSettingsWindow.Closed += (s, args) => { @@ -1421,7 +1507,7 @@ namespace Ink_Canvas { BorderSettings.Visibility = Visibility.Visible; BorderSettingsMask.Visibility = Visibility.Visible; }; - + // 显示插件设置窗口 pluginSettingsWindow.ShowDialog(); } @@ -1430,7 +1516,7 @@ namespace Ink_Canvas { // 确保在发生错误时也恢复设置面板显示 BorderSettings.Visibility = Visibility.Visible; BorderSettingsMask.Visibility = Visibility.Visible; - + LogHelper.WriteLogToFile($"打开插件管理器时出错: {ex.Message}", LogHelper.LogType.Error); MessageBox.Show($"打开插件管理器时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } diff --git a/Ink Canvas/MainWindow_cs/MW_AutoFold.cs b/Ink Canvas/MainWindow_cs/MW_AutoFold.cs index 5708ef05..109cd178 100644 --- a/Ink Canvas/MainWindow_cs/MW_AutoFold.cs +++ b/Ink Canvas/MainWindow_cs/MW_AutoFold.cs @@ -1,4 +1,6 @@ -using System; +using Ink_Canvas.Helpers; +using iNKORE.UI.WPF.Modern; +using System; using System.Threading; using System.Threading.Tasks; using System.Windows; @@ -6,15 +8,16 @@ using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; -using Ink_Canvas.Helpers; -using iNKORE.UI.WPF.Modern; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { public bool isFloatingBarFolded; private bool isFloatingBarChangingHideMode; - private void CloseWhiteboardImmediately() { + private void CloseWhiteboardImmediately() + { if (isDisplayingOrHidingBlackboard) return; isDisplayingOrHidingBlackboard = true; HideSubPanelsImmediately(); @@ -28,13 +31,15 @@ namespace Ink_Canvas { BtnSwitch_Click(BtnSwitch, null); BtnExit.Foreground = Brushes.White; ThemeManager.Current.ApplicationTheme = ApplicationTheme.Dark; - new Thread(() => { + new Thread(() => + { Thread.Sleep(200); Application.Current.Dispatcher.Invoke(() => { isDisplayingOrHidingBlackboard = false; }); }).Start(); } - public async void FoldFloatingBar_MouseUp(object sender, MouseButtonEventArgs e) { + public async void FoldFloatingBar_MouseUp(object sender, MouseButtonEventArgs e) + { await FoldFloatingBar(sender); } @@ -42,7 +47,8 @@ namespace Ink_Canvas { { var isShouldRejectAction = false; - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel) ((Panel)lastBorderMouseDownObject).Background = new SolidColorBrush(Colors.Transparent); if (sender == Fold_Icon && lastBorderMouseDownObject != Fold_Icon) isShouldRejectAction = true; @@ -59,7 +65,8 @@ namespace Ink_Canvas { if (isFloatingBarChangingHideMode) return; - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { InkCanvasForInkReplay.Visibility = Visibility.Collapsed; InkCanvasGridForInkReplay.Visibility = Visibility.Visible; InkCanvasGridForInkReplay.IsHitTestVisible = true; @@ -71,7 +78,8 @@ namespace Ink_Canvas { isStopInkReplay = true; }); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { isFloatingBarChangingHideMode = true; isFloatingBarFolded = true; if (currentMode != 0) CloseWhiteboardImmediately(); @@ -84,7 +92,8 @@ namespace Ink_Canvas { await Task.Delay(300); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { LeftBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; @@ -97,12 +106,16 @@ namespace Ink_Canvas { isFloatingBarChangingHideMode = false; } - private async void LeftUnFoldButtonDisplayQuickPanel_MouseUp(object sender, MouseButtonEventArgs e) { - if (Settings.Appearance.IsShowQuickPanel) { + private async void LeftUnFoldButtonDisplayQuickPanel_MouseUp(object sender, MouseButtonEventArgs e) + { + if (Settings.Appearance.IsShowQuickPanel) + { HideRightQuickPanel(); LeftUnFoldButtonQuickPanel.Visibility = Visibility.Visible; - await Dispatcher.InvokeAsync(() => { - var marginAnimation = new ThicknessAnimation { + await Dispatcher.InvokeAsync(() => + { + var marginAnimation = new ThicknessAnimation + { Duration = TimeSpan.FromSeconds(0.1), From = new Thickness(-50, 0, 0, -150), To = new Thickness(-1, 0, 0, -150) @@ -112,21 +125,27 @@ namespace Ink_Canvas { }); await Task.Delay(100); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { LeftUnFoldButtonQuickPanel.Margin = new Thickness(-1, 0, 0, -150); }); } - else { + else + { UnFoldFloatingBar_MouseUp(sender, e); } } - private async void RightUnFoldButtonDisplayQuickPanel_MouseUp(object sender, MouseButtonEventArgs e) { - if (Settings.Appearance.IsShowQuickPanel) { + private async void RightUnFoldButtonDisplayQuickPanel_MouseUp(object sender, MouseButtonEventArgs e) + { + if (Settings.Appearance.IsShowQuickPanel) + { HideLeftQuickPanel(); RightUnFoldButtonQuickPanel.Visibility = Visibility.Visible; - await Dispatcher.InvokeAsync(() => { - var marginAnimation = new ThicknessAnimation { + await Dispatcher.InvokeAsync(() => + { + var marginAnimation = new ThicknessAnimation + { Duration = TimeSpan.FromSeconds(0.1), From = new Thickness(0, 0, -50, -150), To = new Thickness(0, 0, -1, -150) @@ -136,19 +155,25 @@ namespace Ink_Canvas { }); await Task.Delay(100); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { RightUnFoldButtonQuickPanel.Margin = new Thickness(0, 0, -1, -150); }); } - else { + else + { UnFoldFloatingBar_MouseUp(sender, e); } } - private async void HideLeftQuickPanel() { - if (LeftUnFoldButtonQuickPanel.Visibility == Visibility.Visible) { - await Dispatcher.InvokeAsync(() => { - var marginAnimation = new ThicknessAnimation { + private async void HideLeftQuickPanel() + { + if (LeftUnFoldButtonQuickPanel.Visibility == Visibility.Visible) + { + await Dispatcher.InvokeAsync(() => + { + var marginAnimation = new ThicknessAnimation + { Duration = TimeSpan.FromSeconds(0.1), From = new Thickness(-1, 0, 0, -150), To = new Thickness(-50, 0, 0, -150) @@ -158,17 +183,22 @@ namespace Ink_Canvas { }); await Task.Delay(100); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { LeftUnFoldButtonQuickPanel.Margin = new Thickness(0, 0, -50, -150); LeftUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed; }); } } - private async void HideRightQuickPanel() { - if (RightUnFoldButtonQuickPanel.Visibility == Visibility.Visible) { - await Dispatcher.InvokeAsync(() => { - var marginAnimation = new ThicknessAnimation { + private async void HideRightQuickPanel() + { + if (RightUnFoldButtonQuickPanel.Visibility == Visibility.Visible) + { + await Dispatcher.InvokeAsync(() => + { + var marginAnimation = new ThicknessAnimation + { Duration = TimeSpan.FromSeconds(0.1), From = new Thickness(0, 0, -1, -150), To = new Thickness(0, 0, -50, -150) @@ -178,25 +208,29 @@ namespace Ink_Canvas { }); await Task.Delay(100); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { RightUnFoldButtonQuickPanel.Margin = new Thickness(0, 0, -50, -150); RightUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed; }); } } - private void HideQuickPanel_MouseUp(object sender, MouseButtonEventArgs e) { + private void HideQuickPanel_MouseUp(object sender, MouseButtonEventArgs e) + { HideLeftQuickPanel(); HideRightQuickPanel(); } - public async void UnFoldFloatingBar_MouseUp(object sender, MouseButtonEventArgs e) { + public async void UnFoldFloatingBar_MouseUp(object sender, MouseButtonEventArgs e) + { await UnFoldFloatingBar(sender); } public async Task UnFoldFloatingBar(object sender) { - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { LeftUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed; RightUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed; }); @@ -208,21 +242,23 @@ namespace Ink_Canvas { if (isFloatingBarChangingHideMode) return; - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { isFloatingBarChangingHideMode = true; isFloatingBarFolded = false; }); await Task.Delay(0); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { // 根据设置决定是否自动切换至批注模式 if (Settings.Automation.IsAutoEnterAnnotationModeWhenExitFoldMode && currentMode == 0) { // 切换至批注模式 PenIcon_Click(null, null); } - + if (StackPanelPPTControls.Visibility == Visibility.Visible) { var dops = Settings.PowerPointSettings.PPTButtonsDisplayOption.ToString(); @@ -245,16 +281,19 @@ namespace Ink_Canvas { private async void SidePannelMarginAnimation(int MarginFromEdge, bool isNoAnimation = false) // Possible value: -50, -10 { - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { if (MarginFromEdge == -10) LeftSidePanel.Visibility = Visibility.Visible; - var LeftSidePanelmarginAnimation = new ThicknessAnimation { + var LeftSidePanelmarginAnimation = new ThicknessAnimation + { Duration = isNoAnimation ? TimeSpan.FromSeconds(0) : TimeSpan.FromSeconds(0.175), From = LeftSidePanel.Margin, To = new Thickness(MarginFromEdge, 0, 0, -150) }; LeftSidePanelmarginAnimation.EasingFunction = new CubicEase(); - var RightSidePanelmarginAnimation = new ThicknessAnimation { + var RightSidePanelmarginAnimation = new ThicknessAnimation + { Duration = isNoAnimation ? TimeSpan.FromSeconds(0) : TimeSpan.FromSeconds(0.175), From = RightSidePanel.Margin, To = new Thickness(0, 0, MarginFromEdge, -150) @@ -266,7 +305,8 @@ namespace Ink_Canvas { await Task.Delay(600); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { LeftSidePanel.Margin = new Thickness(MarginFromEdge, 0, 0, -150); RightSidePanel.Margin = new Thickness(0, 0, MarginFromEdge, -150); diff --git a/Ink Canvas/MainWindow_cs/MW_AutoStart.cs b/Ink Canvas/MainWindow_cs/MW_AutoStart.cs index 165414b8..a86808cc 100644 --- a/Ink Canvas/MainWindow_cs/MW_AutoStart.cs +++ b/Ink Canvas/MainWindow_cs/MW_AutoStart.cs @@ -1,13 +1,17 @@ -using System; +using IWshRuntimeLibrary; +using System; using System.Windows; -using IWshRuntimeLibrary; using Application = System.Windows.Forms.Application; using File = System.IO.File; -namespace Ink_Canvas { - public partial class MainWindow : Window { - public static bool StartAutomaticallyCreate(string exeName) { - try { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { + public static bool StartAutomaticallyCreate(string exeName) + { + try + { var shell = new WshShell(); var shortcut = (IWshShortcut)shell.CreateShortcut( Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\" + exeName + ".lnk"); @@ -30,8 +34,10 @@ namespace Ink_Canvas { return false; } - public static bool StartAutomaticallyDel(string exeName) { - try { + public static bool StartAutomaticallyDel(string exeName) + { + try + { File.Delete(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\" + exeName + ".lnk"); return true; diff --git a/Ink Canvas/MainWindow_cs/MW_AutoTheme.cs b/Ink Canvas/MainWindow_cs/MW_AutoTheme.cs index a909b52a..f908c2ad 100644 --- a/Ink Canvas/MainWindow_cs/MW_AutoTheme.cs +++ b/Ink Canvas/MainWindow_cs/MW_AutoTheme.cs @@ -1,50 +1,55 @@ -using System; +using iNKORE.UI.WPF.Modern; +using Microsoft.Win32; +using System; using System.Windows; using System.Windows.Media; -using iNKORE.UI.WPF.Modern; -using Microsoft.Win32; using Application = System.Windows.Application; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { private Color FloatBarForegroundColor = Color.FromRgb(102, 102, 102); - private void SetTheme(string theme) { - if (theme == "Light") { + private void SetTheme(string theme) + { + if (theme == "Light") + { var rd1 = new ResourceDictionary - { Source = new Uri("Resources/Styles/Light.xaml", UriKind.Relative) }; + { Source = new Uri("Resources/Styles/Light.xaml", UriKind.Relative) }; Application.Current.Resources.MergedDictionaries.Add(rd1); var rd2 = new ResourceDictionary - { Source = new Uri("Resources/DrawShapeImageDictionary.xaml", UriKind.Relative) }; + { Source = new Uri("Resources/DrawShapeImageDictionary.xaml", UriKind.Relative) }; Application.Current.Resources.MergedDictionaries.Add(rd2); var rd3 = new ResourceDictionary - { Source = new Uri("Resources/SeewoImageDictionary.xaml", UriKind.Relative) }; + { Source = new Uri("Resources/SeewoImageDictionary.xaml", UriKind.Relative) }; Application.Current.Resources.MergedDictionaries.Add(rd3); var rd4 = new ResourceDictionary - { Source = new Uri("Resources/IconImageDictionary.xaml", UriKind.Relative) }; + { Source = new Uri("Resources/IconImageDictionary.xaml", UriKind.Relative) }; Application.Current.Resources.MergedDictionaries.Add(rd4); ThemeManager.SetRequestedTheme(window, ElementTheme.Light); FloatBarForegroundColor = (Color)Application.Current.FindResource("FloatBarForegroundColor"); } - else if (theme == "Dark") { + else if (theme == "Dark") + { var rd1 = new ResourceDictionary { Source = new Uri("Resources/Styles/Dark.xaml", UriKind.Relative) }; Application.Current.Resources.MergedDictionaries.Add(rd1); var rd2 = new ResourceDictionary - { Source = new Uri("Resources/DrawShapeImageDictionary.xaml", UriKind.Relative) }; + { Source = new Uri("Resources/DrawShapeImageDictionary.xaml", UriKind.Relative) }; Application.Current.Resources.MergedDictionaries.Add(rd2); var rd3 = new ResourceDictionary - { Source = new Uri("Resources/SeewoImageDictionary.xaml", UriKind.Relative) }; + { Source = new Uri("Resources/SeewoImageDictionary.xaml", UriKind.Relative) }; Application.Current.Resources.MergedDictionaries.Add(rd3); var rd4 = new ResourceDictionary - { Source = new Uri("Resources/IconImageDictionary.xaml", UriKind.Relative) }; + { Source = new Uri("Resources/IconImageDictionary.xaml", UriKind.Relative) }; Application.Current.Resources.MergedDictionaries.Add(rd4); ThemeManager.SetRequestedTheme(window, ElementTheme.Dark); @@ -53,8 +58,10 @@ namespace Ink_Canvas { } } - private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) { - switch (Settings.Appearance.Theme) { + private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) + { + switch (Settings.Appearance.Theme) + { case 0: SetTheme("Light"); break; @@ -68,9 +75,11 @@ namespace Ink_Canvas { } } - private bool IsSystemThemeLight() { + private bool IsSystemThemeLight() + { var light = false; - try { + try + { var registryKey = Registry.CurrentUser; var themeKey = registryKey.OpenSubKey("software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"); diff --git a/Ink Canvas/MainWindow_cs/MW_BoardControls.cs b/Ink Canvas/MainWindow_cs/MW_BoardControls.cs index de356541..f011d0c8 100644 --- a/Ink Canvas/MainWindow_cs/MW_BoardControls.cs +++ b/Ink Canvas/MainWindow_cs/MW_BoardControls.cs @@ -1,19 +1,17 @@ using Ink_Canvas.Helpers; using System; +using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Threading.Tasks; using System.Windows; +using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Controls; -using Newtonsoft.Json; -using System.Collections.Generic; -using System.IO; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { private StrokeCollection[] strokeCollections = new StrokeCollection[101]; private bool[] whiteboadLastModeIsRedo = new bool[101]; private StrokeCollection lastTouchDownStrokeCollection = new StrokeCollection(); @@ -23,17 +21,21 @@ namespace Ink_Canvas { private TimeMachineHistory[][] TimeMachineHistories = new TimeMachineHistory[101][]; //最多99页,0用来存储非白板时的墨迹以便还原 // 保存每页白板图片信息 - private void SaveStrokes(bool isBackupMain = false) { + private void SaveStrokes(bool isBackupMain = false) + { // 确保画布上的所有UI元素都被保存到时间机器历史记录中 var currentHistory = timeMachine.ExportTimeMachineHistory(); var elementsInHistory = new HashSet(); // 收集已经在历史记录中的元素 - if (currentHistory != null) { - foreach (var h in currentHistory) { + if (currentHistory != null) + { + foreach (var h in currentHistory) + { if (h.CommitType == TimeMachineHistoryType.ElementInsert && h.InsertedElement != null && - !h.StrokeHasBeenCleared) { + !h.StrokeHasBeenCleared) + { elementsInHistory.Add(h.InsertedElement); } } @@ -41,26 +43,34 @@ namespace Ink_Canvas { // 检查画布上的所有UI元素,确保它们都在历史记录中 var missingElements = 0; - foreach (UIElement child in inkCanvas.Children) { - if (child is Image || child is MediaElement) { - if (!elementsInHistory.Contains(child)) { + foreach (UIElement child in inkCanvas.Children) + { + if (child is Image || child is MediaElement) + { + if (!elementsInHistory.Contains(child)) + { timeMachine.CommitElementInsertHistory(child); missingElements++; } } } - + // 确保画布上的所有墨迹都被保存 - if (inkCanvas.Strokes.Count > 0) { + if (inkCanvas.Strokes.Count > 0) + { // 检查是否有墨迹没有在时间机器历史记录中 var strokesInHistory = new HashSet(); - if (currentHistory != null) { - foreach (var h in currentHistory) { + if (currentHistory != null) + { + foreach (var h in currentHistory) + { if (h.CommitType == TimeMachineHistoryType.UserInput && h.CurrentStroke != null && - !h.StrokeHasBeenCleared) { - foreach (Stroke stroke in h.CurrentStroke) { + !h.StrokeHasBeenCleared) + { + foreach (Stroke stroke in h.CurrentStroke) + { strokesInHistory.Add(stroke); } } @@ -69,24 +79,30 @@ namespace Ink_Canvas { // 收集没有在历史记录中的墨迹 var missingStrokes = new StrokeCollection(); - foreach (Stroke stroke in inkCanvas.Strokes) { - if (!strokesInHistory.Contains(stroke)) { + foreach (Stroke stroke in inkCanvas.Strokes) + { + if (!strokesInHistory.Contains(stroke)) + { missingStrokes.Add(stroke); } } - if (missingStrokes.Count > 0) { + if (missingStrokes.Count > 0) + { timeMachine.CommitStrokeUserInputHistory(missingStrokes); } } - if (isBackupMain) { + if (isBackupMain) + { var timeMachineHistory = timeMachine.ExportTimeMachineHistory(); TimeMachineHistories[0] = timeMachineHistory; timeMachine.ClearStrokeHistory(); - } else { + } + else + { var timeMachineHistory = timeMachine.ExportTimeMachineHistory(); TimeMachineHistories[CurrentWhiteboardIndex] = timeMachineHistory; timeMachine.ClearStrokeHistory(); @@ -95,7 +111,8 @@ namespace Ink_Canvas { } } - private void ClearStrokes(bool isErasedByCode) { + private void ClearStrokes(bool isErasedByCode) + { _currentCommitType = CommitReason.ClearingCanvas; if (isErasedByCode) _currentCommitType = CommitReason.CodeInput; @@ -110,8 +127,10 @@ namespace Ink_Canvas { } // 恢复每页白板图片信息 - private void RestoreStrokes(bool isBackupMain = false) { - try { + private void RestoreStrokes(bool isBackupMain = false) + { + try + { var targetIndex = isBackupMain ? 0 : CurrentWhiteboardIndex; // 先清空当前画布的墨迹 @@ -122,35 +141,46 @@ namespace Ink_Canvas { inkCanvas.Children.Clear(); // 如果历史记录为空,直接返回(新页面或空页面) - if (TimeMachineHistories[targetIndex] == null) { + if (TimeMachineHistories[targetIndex] == null) + { timeMachine.ClearStrokeHistory(); return; } - if (isBackupMain) { + if (isBackupMain) + { timeMachine.ImportTimeMachineHistory(TimeMachineHistories[0]); foreach (var item in TimeMachineHistories[0]) ApplyHistoryToCanvas(item); - } else { + } + else + { timeMachine.ImportTimeMachineHistory(TimeMachineHistories[CurrentWhiteboardIndex]); // 通过时间机器历史恢复所有内容(墨迹和图片) foreach (var item in TimeMachineHistories[CurrentWhiteboardIndex]) ApplyHistoryToCanvas(item); } // 确保选中状态被清除,因为我们切换了页面 - if (selectedUIElement != null) { + if (selectedUIElement != null) + { DeselectUIElement(); } } - catch { + catch + { // ignored } } - private async void BtnWhiteBoardPageIndex_Click(object sender, EventArgs e) { - if (sender == BtnLeftPageListWB) { - if (BoardBorderLeftPageListView.Visibility == Visibility.Visible) { + private async void BtnWhiteBoardPageIndex_Click(object sender, EventArgs e) + { + if (sender == BtnLeftPageListWB) + { + if (BoardBorderLeftPageListView.Visibility == Visibility.Visible) + { AnimationsHelper.HideWithSlideAndFade(BoardBorderLeftPageListView); - } else { + } + else + { AnimationsHelper.HideWithSlideAndFade(BoardBorderRightPageListView); RefreshBlackBoardSidePageListView(); AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardBorderLeftPageListView); @@ -159,11 +189,15 @@ namespace Ink_Canvas { (ListViewItem)BlackBoardLeftSidePageListView.ItemContainerGenerator.ContainerFromIndex( CurrentWhiteboardIndex - 1), BlackBoardLeftSidePageListScrollViewer); } - } else if (sender == BtnRightPageListWB) + } + else if (sender == BtnRightPageListWB) { - if (BoardBorderRightPageListView.Visibility == Visibility.Visible) { + if (BoardBorderRightPageListView.Visibility == Visibility.Visible) + { AnimationsHelper.HideWithSlideAndFade(BoardBorderRightPageListView); - } else { + } + else + { AnimationsHelper.HideWithSlideAndFade(BoardBorderLeftPageListView); RefreshBlackBoardSidePageListView(); AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardBorderRightPageListView); @@ -176,7 +210,8 @@ namespace Ink_Canvas { } - private void BtnWhiteBoardSwitchPrevious_Click(object sender, EventArgs e) { + private void BtnWhiteBoardSwitchPrevious_Click(object sender, EventArgs e) + { if (CurrentWhiteboardIndex <= 1) return; // 取消任何UI元素的选择 @@ -192,12 +227,14 @@ namespace Ink_Canvas { UpdateIndexInfoDisplay(); } - private void BtnWhiteBoardSwitchNext_Click(object sender, EventArgs e) { + private void BtnWhiteBoardSwitchNext_Click(object sender, EventArgs e) + { Trace.WriteLine("113223234"); if (Settings.Automation.IsAutoSaveStrokesAtClear && inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) SaveScreenShot(true); - if (CurrentWhiteboardIndex >= WhiteboardTotalCount) { + if (CurrentWhiteboardIndex >= WhiteboardTotalCount) + { // 在最后一页时,点击“新页面”按钮直接新增一页 BtnWhiteBoardAdd_Click(sender, e); return; @@ -216,7 +253,8 @@ namespace Ink_Canvas { UpdateIndexInfoDisplay(); } - private void BtnWhiteBoardAdd_Click(object sender, EventArgs e) { + private void BtnWhiteBoardAdd_Click(object sender, EventArgs e) + { if (WhiteboardTotalCount >= 99) return; if (Settings.Automation.IsAutoSaveStrokesAtClear && inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) SaveScreenShot(true); @@ -244,12 +282,14 @@ namespace Ink_Canvas { if (WhiteboardTotalCount >= 99) BtnWhiteBoardAdd.IsEnabled = false; - if (BlackBoardLeftSidePageListView.Visibility == Visibility.Visible) { + if (BlackBoardLeftSidePageListView.Visibility == Visibility.Visible) + { RefreshBlackBoardSidePageListView(); } } - private void BtnWhiteBoardDelete_Click(object sender, RoutedEventArgs e) { + private void BtnWhiteBoardDelete_Click(object sender, RoutedEventArgs e) + { ClearStrokes(true); if (CurrentWhiteboardIndex != WhiteboardTotalCount) @@ -267,7 +307,8 @@ namespace Ink_Canvas { if (WhiteboardTotalCount < 99) BtnWhiteBoardAdd.IsEnabled = true; } - private void UpdateIndexInfoDisplay() { + private void UpdateIndexInfoDisplay() + { TextBlockWhiteBoardIndexInfo.Text = $"{CurrentWhiteboardIndex}/{WhiteboardTotalCount}"; @@ -289,13 +330,16 @@ namespace Ink_Canvas { BtnWhiteBoardSwitchPrevious.IsEnabled = true; - if (CurrentWhiteboardIndex == 1) { + if (CurrentWhiteboardIndex == 1) + { BtnWhiteBoardSwitchPrevious.IsEnabled = false; BtnLeftWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(127, 24, 24, 27)); BtnLeftWhiteBoardSwitchPreviousLabel.Opacity = 0.5; BtnRightWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(127, 24, 24, 27)); BtnRightWhiteBoardSwitchPreviousLabel.Opacity = 0.5; - } else { + } + else + { BtnLeftWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27)); BtnLeftWhiteBoardSwitchPreviousLabel.Opacity = 1; BtnRightWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27)); diff --git a/Ink Canvas/MainWindow_cs/MW_BoardIcons.cs b/Ink Canvas/MainWindow_cs/MW_BoardIcons.cs index b7ae1687..96bbe77a 100644 --- a/Ink Canvas/MainWindow_cs/MW_BoardIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_BoardIcons.cs @@ -1,4 +1,5 @@ -using System; +using Ink_Canvas.Helpers; +using System; using System.Diagnostics; using System.Windows; using System.Windows.Controls; @@ -6,11 +7,13 @@ using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; -using Ink_Canvas.Helpers; -namespace Ink_Canvas { - public partial class MainWindow : Window { - private void BoardChangeBackgroundColorBtn_MouseUp(object sender, RoutedEventArgs e) { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { + private void BoardChangeBackgroundColorBtn_MouseUp(object sender, RoutedEventArgs e) + { if (!isLoaded) return; // 创建背景选项面板(如果不存在) @@ -50,66 +53,68 @@ namespace Ink_Canvas { // 原有的背景切换代码 Settings.Canvas.UsingWhiteboard = !Settings.Canvas.UsingWhiteboard; SaveSettingsToFile(); - if (Settings.Canvas.UsingWhiteboard) { + if (Settings.Canvas.UsingWhiteboard) + { if (inkColor == 5) lastBoardInkColor = 0; ICCWaterMarkDark.Visibility = Visibility.Visible; ICCWaterMarkWhite.Visibility = Visibility.Collapsed; - + // 设置为白板默认背景色 Color defaultWhiteboardColor = Color.FromRgb(234, 235, 237); - + if (currentMode == 1) // 白板模式 { // 设置背景为默认白板背景色 GridBackgroundCover.Background = new SolidColorBrush(defaultWhiteboardColor); - + // 更新RGB滑块的值为默认白板背景色 if (BackgroundPalette != null && BackgroundPalette.Visibility == Visibility.Visible) { UpdateRGBSliders(defaultWhiteboardColor); } - + // 更新自定义背景色为默认白板背景色 CustomBackgroundColor = defaultWhiteboardColor; - + // 保存到设置 string colorHex = $"#{defaultWhiteboardColor.R:X2}{defaultWhiteboardColor.G:X2}{defaultWhiteboardColor.B:X2}"; Settings.Canvas.CustomBackgroundColor = colorHex; SaveSettingsToFile(); } - + // 设置墨迹颜色为黑色 CheckLastColor(0); forceEraser = false; } - else { + else + { if (inkColor == 0) lastBoardInkColor = 5; ICCWaterMarkWhite.Visibility = Visibility.Visible; ICCWaterMarkDark.Visibility = Visibility.Collapsed; - + // 设置为黑板默认背景色 Color defaultBlackboardColor = Color.FromRgb(22, 41, 36); - + if (currentMode == 1) // 黑板模式 { // 设置背景为默认黑板背景色 GridBackgroundCover.Background = new SolidColorBrush(defaultBlackboardColor); - + // 更新RGB滑块的值为默认黑板背景色 if (BackgroundPalette != null && BackgroundPalette.Visibility == Visibility.Visible) { UpdateRGBSliders(defaultBlackboardColor); } - + // 更新自定义背景色为默认黑板背景色 CustomBackgroundColor = defaultBlackboardColor; - + // 保存到设置 string colorHex = $"#{defaultBlackboardColor.R:X2}{defaultBlackboardColor.G:X2}{defaultBlackboardColor.B:X2}"; Settings.Canvas.CustomBackgroundColor = colorHex; SaveSettingsToFile(); } - + // 设置墨迹颜色为白色 CheckLastColor(5); forceEraser = false; @@ -123,7 +128,7 @@ namespace Ink_Canvas { { // 确保加载自定义背景色 LoadCustomBackgroundColor(); - + // 创建一个类似于PenPalette的面板 BackgroundPalette = new Border { @@ -137,7 +142,7 @@ namespace Ink_Canvas { Width = 300, MaxHeight = 400 }; - + // 确保面板显示在顶层 Panel.SetZIndex(BackgroundPalette, 1000); @@ -201,7 +206,7 @@ namespace Ink_Canvas { contentPanel.Children.Add(modeTitle); var modePanel = new StackPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Center }; - + // 白板按钮 var whiteboardButton = new Border { @@ -219,41 +224,42 @@ namespace Ink_Canvas { VerticalAlignment = VerticalAlignment.Center }; whiteboardButton.Child = whiteboardText; - whiteboardButton.MouseUp += (s, args) => { + whiteboardButton.MouseUp += (s, args) => + { Settings.Canvas.UsingWhiteboard = true; SaveSettingsToFile(); ICCWaterMarkDark.Visibility = Visibility.Visible; ICCWaterMarkWhite.Visibility = Visibility.Collapsed; - + // 设置为白板默认背景色 Color defaultWhiteboardColor = Color.FromRgb(234, 235, 237); - + if (currentMode == 1) // 白板模式 { // 设置背景为默认白板背景色 GridBackgroundCover.Background = new SolidColorBrush(defaultWhiteboardColor); - + // 更新RGB滑块的值为默认白板背景色 UpdateRGBSliders(defaultWhiteboardColor); - + // 更新自定义背景色为默认白板背景色 CustomBackgroundColor = defaultWhiteboardColor; - + // 保存到设置 string colorHex = $"#{defaultWhiteboardColor.R:X2}{defaultWhiteboardColor.G:X2}{defaultWhiteboardColor.B:X2}"; Settings.Canvas.CustomBackgroundColor = colorHex; SaveSettingsToFile(); } - + // 设置墨迹颜色为黑色 CheckLastColor(0); forceEraser = false; - + CheckColorTheme(true); UpdateBackgroundButtonsState(); }; modePanel.Children.Add(whiteboardButton); - + // 黑板按钮 var blackboardButton = new Border { @@ -270,264 +276,269 @@ namespace Ink_Canvas { VerticalAlignment = VerticalAlignment.Center }; blackboardButton.Child = blackboardText; - blackboardButton.MouseUp += (s, args) => { + blackboardButton.MouseUp += (s, args) => + { Settings.Canvas.UsingWhiteboard = false; SaveSettingsToFile(); ICCWaterMarkWhite.Visibility = Visibility.Visible; ICCWaterMarkDark.Visibility = Visibility.Collapsed; - + // 设置为黑板默认背景色 Color defaultBlackboardColor = Color.FromRgb(22, 41, 36); - + if (currentMode == 1) // 黑板模式 { // 设置背景为默认黑板背景色 GridBackgroundCover.Background = new SolidColorBrush(defaultBlackboardColor); - + // 更新RGB滑块的值为默认黑板背景色 UpdateRGBSliders(defaultBlackboardColor); - + // 更新自定义背景色为默认黑板背景色 CustomBackgroundColor = defaultBlackboardColor; - + // 保存到设置 string colorHex = $"#{defaultBlackboardColor.R:X2}{defaultBlackboardColor.G:X2}{defaultBlackboardColor.B:X2}"; Settings.Canvas.CustomBackgroundColor = colorHex; SaveSettingsToFile(); } - + // 设置墨迹颜色为白色 CheckLastColor(5); forceEraser = false; - + CheckColorTheme(true); UpdateBackgroundButtonsState(); }; modePanel.Children.Add(blackboardButton); contentPanel.Children.Add(modePanel); - - // 添加一条分隔线 - var separator = new Border - { - Height = 1, - Background = new SolidColorBrush(Color.FromRgb(0xd4, 0xd4, 0xd8)), - Margin = new Thickness(0, 12, 0, 12) - }; - contentPanel.Children.Add(separator); - - // 添加RGB颜色选择器部分 - var colorTitle = new TextBlock - { - Text = "背景颜色", - Foreground = new SolidColorBrush(Color.FromRgb(0x17, 0x25, 0x54)), - FontSize = 10, - FontWeight = FontWeights.Bold, - HorizontalAlignment = HorizontalAlignment.Center, - Margin = new Thickness(0, 4, 0, 8) - }; - contentPanel.Children.Add(colorTitle); - - // 创建颜色预览 - Border colorPreview = new Border - { - Width = 100, - Height = 40, - BorderThickness = new Thickness(1), - BorderBrush = new SolidColorBrush(Color.FromRgb(0xd4, 0xd4, 0xd8)), - Background = new SolidColorBrush(Colors.White), - CornerRadius = new CornerRadius(4), - Margin = new Thickness(0, 0, 0, 10), - HorizontalAlignment = HorizontalAlignment.Center - }; - contentPanel.Children.Add(colorPreview); - - // 获取当前背景颜色 - Color currentBackgroundColor; - if (currentMode == 1) // 白板或黑板模式 - { - if (GridBackgroundCover.Background is SolidColorBrush brush) - { - currentBackgroundColor = brush.Color; - } - else - { - // 默认颜色 - currentBackgroundColor = Settings.Canvas.UsingWhiteboard ? - Color.FromRgb(234, 235, 237) : // 白板默认颜色 - Color.FromRgb(22, 41, 36); // 黑板默认颜色 - } - } - else - { - // 默认白色 - currentBackgroundColor = Colors.White; - } - - // 更新颜色预览 - colorPreview.Background = new SolidColorBrush(currentBackgroundColor); - - // 先创建所有滑块控件 - // R滑块和文本框 - var rPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(10, 0, 10, 5) }; - var rLabel = new TextBlock { Text = "R:", Width = 20, VerticalAlignment = VerticalAlignment.Center }; - var rSlider = new Slider - { - Minimum = 0, - Maximum = 255, - Value = currentBackgroundColor.R, - Width = 150, - Margin = new Thickness(5, 0, 5, 0), - VerticalAlignment = VerticalAlignment.Center - }; - var rValueText = new TextBlock - { - Text = currentBackgroundColor.R.ToString(), - Width = 30, - VerticalAlignment = VerticalAlignment.Center, - TextAlignment = TextAlignment.Right - }; - - // G滑块和文本框 - var gPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(10, 0, 10, 5) }; - var gLabel = new TextBlock { Text = "G:", Width = 20, VerticalAlignment = VerticalAlignment.Center }; - var gSlider = new Slider - { - Minimum = 0, - Maximum = 255, - Value = currentBackgroundColor.G, - Width = 150, - Margin = new Thickness(5, 0, 5, 0), - VerticalAlignment = VerticalAlignment.Center - }; - var gValueText = new TextBlock - { - Text = currentBackgroundColor.G.ToString(), - Width = 30, - VerticalAlignment = VerticalAlignment.Center, - TextAlignment = TextAlignment.Right - }; - - // B滑块和文本框 - var bPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(10, 0, 10, 5) }; - var bLabel = new TextBlock { Text = "B:", Width = 20, VerticalAlignment = VerticalAlignment.Center }; - var bSlider = new Slider - { - Minimum = 0, - Maximum = 255, - Value = currentBackgroundColor.B, - Width = 150, - Margin = new Thickness(5, 0, 5, 0), - VerticalAlignment = VerticalAlignment.Center - }; - var bValueText = new TextBlock - { - Text = currentBackgroundColor.B.ToString(), - Width = 30, - VerticalAlignment = VerticalAlignment.Center, - TextAlignment = TextAlignment.Right - }; - - // 现在添加事件处理程序 - rSlider.ValueChanged += (s, e) => { - int value = (int)e.NewValue; - rValueText.Text = value.ToString(); - UpdateColorPreview(colorPreview, rSlider, gSlider, bSlider); - }; - - gSlider.ValueChanged += (s, e) => { - int value = (int)e.NewValue; - gValueText.Text = value.ToString(); - UpdateColorPreview(colorPreview, rSlider, gSlider, bSlider); - }; - - bSlider.ValueChanged += (s, e) => { - int value = (int)e.NewValue; - bValueText.Text = value.ToString(); - UpdateColorPreview(colorPreview, rSlider, gSlider, bSlider); - }; - - // 添加控件到面板 - rPanel.Children.Add(rLabel); - rPanel.Children.Add(rSlider); - rPanel.Children.Add(rValueText); - contentPanel.Children.Add(rPanel); - - gPanel.Children.Add(gLabel); - gPanel.Children.Add(gSlider); - gPanel.Children.Add(gValueText); - contentPanel.Children.Add(gPanel); - - bPanel.Children.Add(bLabel); - bPanel.Children.Add(bSlider); - bPanel.Children.Add(bValueText); - contentPanel.Children.Add(bPanel); - - // 应用按钮 - var applyButton = new Button - { - Content = "应用颜色", - Margin = new Thickness(0, 10, 0, 0), - Padding = new Thickness(10, 5, 10, 5), - Background = new SolidColorBrush(Color.FromRgb(0x25, 0x63, 0xeb)), - Foreground = new SolidColorBrush(Colors.White), - BorderThickness = new Thickness(0), - HorizontalAlignment = HorizontalAlignment.Center - }; - - applyButton.Click += (s, e) => { - Color selectedColor = Color.FromRgb( - (byte)rSlider.Value, - (byte)gSlider.Value, - (byte)bSlider.Value - ); - ApplyCustomBackgroundColor(selectedColor); - }; - - contentPanel.Children.Add(applyButton); + + // 添加一条分隔线 + var separator = new Border + { + Height = 1, + Background = new SolidColorBrush(Color.FromRgb(0xd4, 0xd4, 0xd8)), + Margin = new Thickness(0, 12, 0, 12) + }; + contentPanel.Children.Add(separator); + + // 添加RGB颜色选择器部分 + var colorTitle = new TextBlock + { + Text = "背景颜色", + Foreground = new SolidColorBrush(Color.FromRgb(0x17, 0x25, 0x54)), + FontSize = 10, + FontWeight = FontWeights.Bold, + HorizontalAlignment = HorizontalAlignment.Center, + Margin = new Thickness(0, 4, 0, 8) + }; + contentPanel.Children.Add(colorTitle); + + // 创建颜色预览 + Border colorPreview = new Border + { + Width = 100, + Height = 40, + BorderThickness = new Thickness(1), + BorderBrush = new SolidColorBrush(Color.FromRgb(0xd4, 0xd4, 0xd8)), + Background = new SolidColorBrush(Colors.White), + CornerRadius = new CornerRadius(4), + Margin = new Thickness(0, 0, 0, 10), + HorizontalAlignment = HorizontalAlignment.Center + }; + contentPanel.Children.Add(colorPreview); + + // 获取当前背景颜色 + Color currentBackgroundColor; + if (currentMode == 1) // 白板或黑板模式 + { + if (GridBackgroundCover.Background is SolidColorBrush brush) + { + currentBackgroundColor = brush.Color; + } + else + { + // 默认颜色 + currentBackgroundColor = Settings.Canvas.UsingWhiteboard ? + Color.FromRgb(234, 235, 237) : // 白板默认颜色 + Color.FromRgb(22, 41, 36); // 黑板默认颜色 + } + } + else + { + // 默认白色 + currentBackgroundColor = Colors.White; + } + + // 更新颜色预览 + colorPreview.Background = new SolidColorBrush(currentBackgroundColor); + + // 先创建所有滑块控件 + // R滑块和文本框 + var rPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(10, 0, 10, 5) }; + var rLabel = new TextBlock { Text = "R:", Width = 20, VerticalAlignment = VerticalAlignment.Center }; + var rSlider = new Slider + { + Minimum = 0, + Maximum = 255, + Value = currentBackgroundColor.R, + Width = 150, + Margin = new Thickness(5, 0, 5, 0), + VerticalAlignment = VerticalAlignment.Center + }; + var rValueText = new TextBlock + { + Text = currentBackgroundColor.R.ToString(), + Width = 30, + VerticalAlignment = VerticalAlignment.Center, + TextAlignment = TextAlignment.Right + }; + + // G滑块和文本框 + var gPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(10, 0, 10, 5) }; + var gLabel = new TextBlock { Text = "G:", Width = 20, VerticalAlignment = VerticalAlignment.Center }; + var gSlider = new Slider + { + Minimum = 0, + Maximum = 255, + Value = currentBackgroundColor.G, + Width = 150, + Margin = new Thickness(5, 0, 5, 0), + VerticalAlignment = VerticalAlignment.Center + }; + var gValueText = new TextBlock + { + Text = currentBackgroundColor.G.ToString(), + Width = 30, + VerticalAlignment = VerticalAlignment.Center, + TextAlignment = TextAlignment.Right + }; + + // B滑块和文本框 + var bPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(10, 0, 10, 5) }; + var bLabel = new TextBlock { Text = "B:", Width = 20, VerticalAlignment = VerticalAlignment.Center }; + var bSlider = new Slider + { + Minimum = 0, + Maximum = 255, + Value = currentBackgroundColor.B, + Width = 150, + Margin = new Thickness(5, 0, 5, 0), + VerticalAlignment = VerticalAlignment.Center + }; + var bValueText = new TextBlock + { + Text = currentBackgroundColor.B.ToString(), + Width = 30, + VerticalAlignment = VerticalAlignment.Center, + TextAlignment = TextAlignment.Right + }; + + // 现在添加事件处理程序 + rSlider.ValueChanged += (s, e) => + { + int value = (int)e.NewValue; + rValueText.Text = value.ToString(); + UpdateColorPreview(colorPreview, rSlider, gSlider, bSlider); + }; + + gSlider.ValueChanged += (s, e) => + { + int value = (int)e.NewValue; + gValueText.Text = value.ToString(); + UpdateColorPreview(colorPreview, rSlider, gSlider, bSlider); + }; + + bSlider.ValueChanged += (s, e) => + { + int value = (int)e.NewValue; + bValueText.Text = value.ToString(); + UpdateColorPreview(colorPreview, rSlider, gSlider, bSlider); + }; + + // 添加控件到面板 + rPanel.Children.Add(rLabel); + rPanel.Children.Add(rSlider); + rPanel.Children.Add(rValueText); + contentPanel.Children.Add(rPanel); + + gPanel.Children.Add(gLabel); + gPanel.Children.Add(gSlider); + gPanel.Children.Add(gValueText); + contentPanel.Children.Add(gPanel); + + bPanel.Children.Add(bLabel); + bPanel.Children.Add(bSlider); + bPanel.Children.Add(bValueText); + contentPanel.Children.Add(bPanel); + + // 应用按钮 + var applyButton = new Button + { + Content = "应用颜色", + Margin = new Thickness(0, 10, 0, 0), + Padding = new Thickness(10, 5, 10, 5), + Background = new SolidColorBrush(Color.FromRgb(0x25, 0x63, 0xeb)), + Foreground = new SolidColorBrush(Colors.White), + BorderThickness = new Thickness(0), + HorizontalAlignment = HorizontalAlignment.Center + }; + + applyButton.Click += (s, e) => + { + Color selectedColor = Color.FromRgb( + (byte)rSlider.Value, + (byte)gSlider.Value, + (byte)bSlider.Value + ); + ApplyCustomBackgroundColor(selectedColor); + }; + + contentPanel.Children.Add(applyButton); stackPanel.Children.Add(contentPanel); - // 将面板添加到父容器 - BackgroundPalette.Child = stackPanel; - - // 获取主窗口中的根网格,确保面板添加到顶层 - Grid mainGrid = FindName("Main_Grid") as Grid; - if (mainGrid != null) - { - // 删除可能已存在的BackgroundPalette - foreach (UIElement element in mainGrid.Children) - { - if (element is Border border && border.Name == "BackgroundPalette") - { - mainGrid.Children.Remove(border); - break; - } - } - - // 重新定位面板 - BackgroundPalette.HorizontalAlignment = HorizontalAlignment.Center; - BackgroundPalette.VerticalAlignment = VerticalAlignment.Center; - BackgroundPalette.Margin = new Thickness(0, 0, 0, 0); - - // 添加到主网格 - mainGrid.Children.Add(BackgroundPalette); - - // 设置面板位置 - var clickElement = FindName("BoardChangeBackgroundColorBtn") as FrameworkElement; - if (clickElement != null) - { - Point position = clickElement.TranslatePoint(new Point(0, 0), mainGrid); - BackgroundPalette.Margin = new Thickness( - position.X - 150, - position.Y + clickElement.ActualHeight + 5, - 0, 0); - BackgroundPalette.HorizontalAlignment = HorizontalAlignment.Left; - BackgroundPalette.VerticalAlignment = VerticalAlignment.Top; - } - } + // 将面板添加到父容器 + BackgroundPalette.Child = stackPanel; + + // 获取主窗口中的根网格,确保面板添加到顶层 + Grid mainGrid = FindName("Main_Grid") as Grid; + if (mainGrid != null) + { + // 删除可能已存在的BackgroundPalette + foreach (UIElement element in mainGrid.Children) + { + if (element is Border border && border.Name == "BackgroundPalette") + { + mainGrid.Children.Remove(border); + break; + } + } + + // 重新定位面板 + BackgroundPalette.HorizontalAlignment = HorizontalAlignment.Center; + BackgroundPalette.VerticalAlignment = VerticalAlignment.Center; + BackgroundPalette.Margin = new Thickness(0, 0, 0, 0); + + // 添加到主网格 + mainGrid.Children.Add(BackgroundPalette); + + // 设置面板位置 + var clickElement = FindName("BoardChangeBackgroundColorBtn") as FrameworkElement; + if (clickElement != null) + { + Point position = clickElement.TranslatePoint(new Point(0, 0), mainGrid); + BackgroundPalette.Margin = new Thickness( + position.X - 150, + position.Y + clickElement.ActualHeight + 5, + 0, 0); + BackgroundPalette.HorizontalAlignment = HorizontalAlignment.Left; + BackgroundPalette.VerticalAlignment = VerticalAlignment.Top; + } + } } - + // 更新背景按钮状态 private void UpdateBackgroundButtonsState() { @@ -541,17 +552,17 @@ namespace Ink_Canvas { { var whiteboardButton = modePanel.Children[0] as Border; var blackboardButton = modePanel.Children[1] as Border; - + if (whiteboardButton != null && whiteboardButton.Child is TextBlock whiteboardText) { - whiteboardButton.Background = Settings.Canvas.UsingWhiteboard ? - new SolidColorBrush(Color.FromRgb(0x25, 0x63, 0xeb)) : + whiteboardButton.Background = Settings.Canvas.UsingWhiteboard ? + new SolidColorBrush(Color.FromRgb(0x25, 0x63, 0xeb)) : new SolidColorBrush(Colors.LightGray); whiteboardText.Foreground = Settings.Canvas.UsingWhiteboard ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Colors.Black); } - + if (blackboardButton != null && blackboardButton.Child is TextBlock blackboardText) { blackboardButton.Background = !Settings.Canvas.UsingWhiteboard ? @@ -566,58 +577,58 @@ namespace Ink_Canvas { } } } - - // 添加成员变量保存背景面板引用 - private Border BackgroundPalette { get; set; } - - // 添加成员变量保存当前自定义背景色 - private Color? CustomBackgroundColor { get; set; } - - /// - /// 更新颜色预览框的颜色 - /// - private void UpdateColorPreview(Border colorPreview, Slider rSlider, Slider gSlider, Slider bSlider) - { - Color previewColor = Color.FromRgb( - (byte)rSlider.Value, - (byte)gSlider.Value, - (byte)bSlider.Value - ); - colorPreview.Background = new SolidColorBrush(previewColor); - } - - /// - /// 应用自定义背景颜色 - /// - private void ApplyCustomBackgroundColor(Color color) - { - // 保存当前选择的颜色 - CustomBackgroundColor = color; - - // 将颜色转换为十六进制字符串并保存到设置中 - string colorHex = $"#{color.R:X2}{color.G:X2}{color.B:X2}"; - Settings.Canvas.CustomBackgroundColor = colorHex; - - // 只在白板或黑板模式下应用自定义背景色 - if (currentMode == 1) // 白板或黑板模式 - { - // 设置白板/黑板模式下的背景 - GridBackgroundCover.Background = new SolidColorBrush(color); - } - - // 保存设置 - SaveSettingsToFile(); - - // 立即更新界面 - if (BackgroundPalette != null) - { - UpdateBackgroundButtonsState(); - UpdateRGBSliders(color); // 更新RGB滑块的值 - } - - // 显示提示信息 - ShowNotification($"已应用自定义背景色: {colorHex}"); - } + + // 添加成员变量保存背景面板引用 + private Border BackgroundPalette { get; set; } + + // 添加成员变量保存当前自定义背景色 + private Color? CustomBackgroundColor { get; set; } + + /// + /// 更新颜色预览框的颜色 + /// + private void UpdateColorPreview(Border colorPreview, Slider rSlider, Slider gSlider, Slider bSlider) + { + Color previewColor = Color.FromRgb( + (byte)rSlider.Value, + (byte)gSlider.Value, + (byte)bSlider.Value + ); + colorPreview.Background = new SolidColorBrush(previewColor); + } + + /// + /// 应用自定义背景颜色 + /// + private void ApplyCustomBackgroundColor(Color color) + { + // 保存当前选择的颜色 + CustomBackgroundColor = color; + + // 将颜色转换为十六进制字符串并保存到设置中 + string colorHex = $"#{color.R:X2}{color.G:X2}{color.B:X2}"; + Settings.Canvas.CustomBackgroundColor = colorHex; + + // 只在白板或黑板模式下应用自定义背景色 + if (currentMode == 1) // 白板或黑板模式 + { + // 设置白板/黑板模式下的背景 + GridBackgroundCover.Background = new SolidColorBrush(color); + } + + // 保存设置 + SaveSettingsToFile(); + + // 立即更新界面 + if (BackgroundPalette != null) + { + UpdateBackgroundButtonsState(); + UpdateRGBSliders(color); // 更新RGB滑块的值 + } + + // 显示提示信息 + ShowNotification($"已应用自定义背景色: {colorHex}"); + } /// /// 从设置中加载自定义背景色 @@ -635,7 +646,7 @@ namespace Ink_Canvas { byte r = Convert.ToByte(colorHex.Substring(1, 2), 16); byte g = Convert.ToByte(colorHex.Substring(3, 2), 16); byte b = Convert.ToByte(colorHex.Substring(5, 2), 16); - + // 保存到内存中 CustomBackgroundColor = Color.FromRgb(r, g, b); } @@ -653,7 +664,7 @@ namespace Ink_Canvas { // 白板模式默认颜色 CustomBackgroundColor = Color.FromRgb(234, 235, 237); } - + // 可以在这里记录日志 Console.WriteLine($"解析自定义背景色失败: {ex.Message}"); } @@ -672,13 +683,13 @@ namespace Ink_Canvas { CustomBackgroundColor = Color.FromRgb(234, 235, 237); } } - + // 只在白板或黑板模式下应用自定义背景色 if (currentMode == 1 && CustomBackgroundColor.HasValue) // 白板或黑板模式 { // 设置白板/黑板模式下的背景 GridBackgroundCover.Background = new SolidColorBrush(CustomBackgroundColor.Value); - + // 更新RGB滑块的值(如果调色板已经创建) if (BackgroundPalette != null && BackgroundPalette.Visibility == Visibility.Visible) { @@ -687,7 +698,8 @@ namespace Ink_Canvas { } } - private void BoardLassoIcon_Click(object sender, RoutedEventArgs e) { + private void BoardLassoIcon_Click(object sender, RoutedEventArgs e) + { forceEraser = false; forcePointEraser = false; drawingShapeMode = 0; @@ -695,43 +707,48 @@ namespace Ink_Canvas { SetCursorBasedOnEditingMode(inkCanvas); } - private void BoardEraserIconByStrokes_Click(object sender, RoutedEventArgs e) { + private void BoardEraserIconByStrokes_Click(object sender, RoutedEventArgs e) + { //if (BoardEraserByStrokes.Background.ToString() == "#FF679CF4") { // AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardDeleteIcon); //} //else { - // 禁用高级橡皮擦系统 - DisableAdvancedEraserSystem(); + // 禁用高级橡皮擦系统 + DisableAdvancedEraserSystem(); - forceEraser = true; - forcePointEraser = false; + forceEraser = true; + forcePointEraser = false; - inkCanvas.EraserShape = new EllipseStylusShape(5, 5); - inkCanvas.EditingMode = InkCanvasEditingMode.EraseByStroke; - drawingShapeMode = 0; + inkCanvas.EraserShape = new EllipseStylusShape(5, 5); + inkCanvas.EditingMode = InkCanvasEditingMode.EraseByStroke; + drawingShapeMode = 0; - // 修复:切换到线擦时,确保重置笔的状态 - penType = 0; - drawingAttributes.IsHighlighter = false; - drawingAttributes.StylusTip = StylusTip.Ellipse; + // 修复:切换到线擦时,确保重置笔的状态 + penType = 0; + drawingAttributes.IsHighlighter = false; + drawingAttributes.StylusTip = StylusTip.Ellipse; - inkCanvas_EditingModeChanged(inkCanvas, null); - CancelSingleFingerDragMode(); + inkCanvas_EditingModeChanged(inkCanvas, null); + CancelSingleFingerDragMode(); - HideSubPanels("eraserByStrokes"); + HideSubPanels("eraserByStrokes"); //} } - private void BoardSymbolIconDelete_MouseUp(object sender, RoutedEventArgs e) { + private void BoardSymbolIconDelete_MouseUp(object sender, RoutedEventArgs e) + { PenIcon_Click(null, null); SymbolIconDelete_MouseUp(null, null); // 根据设置决定是否清空图片 - if (Settings.Canvas.ClearCanvasAlsoClearImages) { + if (Settings.Canvas.ClearCanvasAlsoClearImages) + { // 如果设置为清空图片,则直接清空所有子元素 Debug.WriteLine("BoardSymbolIconDelete: Clearing all children including images"); inkCanvas.Children.Clear(); - } else { + } + else + { // 保存非笔画元素(如图片) Debug.WriteLine("BoardSymbolIconDelete: Preserving non-stroke elements (images)"); var preservedElements = PreserveNonStrokeElements(); @@ -749,11 +766,14 @@ namespace Ink_Canvas { if (Settings.Canvas.ClearCanvasAndClearTimeMachine == false) timeMachine.ClearStrokeHistory(); // 根据设置决定是否清空图片 - if (Settings.Canvas.ClearCanvasAlsoClearImages) { + if (Settings.Canvas.ClearCanvasAlsoClearImages) + { // 如果设置为清空图片,则直接清空所有子元素 Debug.WriteLine("BoardSymbolIconDeleteInkAndHistories: Clearing all children including images"); inkCanvas.Children.Clear(); - } else { + } + else + { // 保存非笔画元素(如图片) Debug.WriteLine("BoardSymbolIconDeleteInkAndHistories: Preserving non-stroke elements (images)"); var preservedElements = PreserveNonStrokeElements(); @@ -765,12 +785,14 @@ namespace Ink_Canvas { } } - private void BoardLaunchEasiCamera_MouseUp(object sender, MouseButtonEventArgs e) { + private void BoardLaunchEasiCamera_MouseUp(object sender, MouseButtonEventArgs e) + { ImageBlackboard_MouseUp(null, null); SoftwareLauncher.LaunchEasiCamera("希沃视频展台"); } - private void BoardLaunchDesmos_MouseUp(object sender, MouseButtonEventArgs e) { + private void BoardLaunchDesmos_MouseUp(object sender, MouseButtonEventArgs e) + { HideSubPanelsImmediately(); ImageBlackboard_MouseUp(null, null); Process.Start("https://www.desmos.com/calculator?lang=zh-CN"); @@ -789,7 +811,7 @@ namespace Ink_Canvas { Slider rSlider = null; Slider gSlider = null; Slider bSlider = null; - + // 遍历面板查找RGB滑块 foreach (var child in contentPanel.Children) { @@ -818,7 +840,7 @@ namespace Ink_Canvas { } } } - + // 更新滑块值 if (rSlider != null && gSlider != null && bSlider != null) { diff --git a/Ink Canvas/MainWindow_cs/MW_ClipboardHandler.cs b/Ink Canvas/MainWindow_cs/MW_ClipboardHandler.cs index 30aa9cc5..de6b9ba3 100644 --- a/Ink Canvas/MainWindow_cs/MW_ClipboardHandler.cs +++ b/Ink Canvas/MainWindow_cs/MW_ClipboardHandler.cs @@ -1,10 +1,10 @@ -using System; +using Ink_Canvas.Helpers; +using System; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media.Imaging; -using Ink_Canvas.Helpers; namespace Ink_Canvas { @@ -78,12 +78,12 @@ namespace Ink_Canvas // 创建右键菜单 var contextMenu = new ContextMenu(); - + var pasteMenuItem = new MenuItem { Header = "粘贴图片" }; - + pasteMenuItem.Click += async (s, e) => await PasteImageFromClipboard(position); contextMenu.Items.Add(pasteMenuItem); diff --git a/Ink Canvas/MainWindow_cs/MW_Colors.cs b/Ink Canvas/MainWindow_cs/MW_Colors.cs index 6be7fac3..339b767e 100644 --- a/Ink Canvas/MainWindow_cs/MW_Colors.cs +++ b/Ink Canvas/MainWindow_cs/MW_Colors.cs @@ -1,4 +1,5 @@ -using System; +using Ink_Canvas.Helpers; +using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Windows; @@ -8,16 +9,20 @@ using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; -using Ink_Canvas.Helpers; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { private int inkColor = 1; - private void ColorSwitchCheck() { + private void ColorSwitchCheck() + { HideSubPanels("color"); - if (GridTransparencyFakeBackground.Background == Brushes.Transparent) { - if (currentMode == 1) { + if (GridTransparencyFakeBackground.Background == Brushes.Transparent) + { + if (currentMode == 1) + { currentMode = 0; GridBackgroundCover.Visibility = Visibility.Collapsed; AnimationsHelper.HideWithSlideAndFade(BlackboardLeftSide); @@ -29,12 +34,15 @@ namespace Ink_Canvas { } var strokes = inkCanvas.GetSelectedStrokes(); - if (strokes.Count != 0) { + if (strokes.Count != 0) + { foreach (var stroke in strokes) - try { + try + { stroke.DrawingAttributes.Color = inkCanvas.DefaultDrawingAttributes.Color; } - catch { + catch + { // ignored } } @@ -47,7 +55,8 @@ namespace Ink_Canvas { item.Value.Clear(); } } - else { + else + { inkCanvas.IsManipulationEnabled = true; drawingShapeMode = 0; inkCanvas.EditingMode = InkCanvasEditingMode.Ink; @@ -63,14 +72,20 @@ namespace Ink_Canvas { private int lastDesktopInkColor = 1, lastBoardInkColor = 5; private int highlighterColor = 102; - private void CheckColorTheme(bool changeColorTheme = false) { + private void CheckColorTheme(bool changeColorTheme = false) + { if (changeColorTheme) - if (currentMode != 0) { - if (Settings.Canvas.UsingWhiteboard) { + if (currentMode != 0) + { + if (Settings.Canvas.UsingWhiteboard) + { // 检查是否有自定义背景色,如果有则使用自定义背景色 - if (CustomBackgroundColor.HasValue) { + if (CustomBackgroundColor.HasValue) + { GridBackgroundCover.Background = new SolidColorBrush(CustomBackgroundColor.Value); - } else { + } + else + { GridBackgroundCover.Background = new SolidColorBrush(Color.FromRgb(234, 235, 237)); } WaterMarkTime.Foreground = new SolidColorBrush(Color.FromRgb(22, 41, 36)); @@ -78,11 +93,15 @@ namespace Ink_Canvas { BlackBoardWaterMark.Foreground = new SolidColorBrush(Color.FromRgb(22, 41, 36)); isUselightThemeColor = false; } - else { + else + { // 黑板模式下,检查是否有自定义背景色 - if (CustomBackgroundColor.HasValue) { + if (CustomBackgroundColor.HasValue) + { GridBackgroundCover.Background = new SolidColorBrush(CustomBackgroundColor.Value); - } else { + } + else + { GridBackgroundCover.Background = new SolidColorBrush(Color.FromRgb(22, 41, 36)); } WaterMarkTime.Foreground = new SolidColorBrush(Color.FromRgb(234, 235, 237)); @@ -92,26 +111,32 @@ namespace Ink_Canvas { } } - if (currentMode == 0) { + if (currentMode == 0) + { isUselightThemeColor = isDesktopUselightThemeColor; inkColor = lastDesktopInkColor; } - else { + else + { inkColor = lastBoardInkColor; } double alpha = inkCanvas.DefaultDrawingAttributes.Color.A; - if (penType == 0) { - if (inkColor == 0) { + if (penType == 0) + { + if (inkColor == 0) + { // Black inkCanvas.DefaultDrawingAttributes.Color = Color.FromArgb((byte)alpha, 0, 0, 0); } - else if (inkColor == 5) { + else if (inkColor == 5) + { // White inkCanvas.DefaultDrawingAttributes.Color = Color.FromArgb((byte)alpha, 255, 255, 255); } - else if (isUselightThemeColor) { + else if (isUselightThemeColor) + { if (inkColor == 1) // Red inkCanvas.DefaultDrawingAttributes.Color = Color.FromArgb((byte)alpha, 239, 68, 68); @@ -134,7 +159,8 @@ namespace Ink_Canvas { // Orange (亮色) inkCanvas.DefaultDrawingAttributes.Color = Color.FromArgb((byte)alpha, 249, 115, 22); } - else { + else + { if (inkColor == 1) // Red inkCanvas.DefaultDrawingAttributes.Color = Color.FromArgb((byte)alpha, 220, 38, 38); @@ -158,7 +184,8 @@ namespace Ink_Canvas { inkCanvas.DefaultDrawingAttributes.Color = Color.FromArgb((byte)alpha, 234, 88, 12); } } - else if (penType == 1) { + else if (penType == 1) + { if (highlighterColor == 100) // Black inkCanvas.DefaultDrawingAttributes.Color = Color.FromRgb(0, 0, 0); @@ -191,7 +218,8 @@ namespace Ink_Canvas { inkCanvas.DefaultDrawingAttributes.Color = Color.FromRgb(249, 115, 22); } - if (isUselightThemeColor) { + if (isUselightThemeColor) + { // 亮系 // 亮色的红色 BorderPenColorRed.Background = new SolidColorBrush(Color.FromRgb(239, 68, 68)); @@ -226,7 +254,8 @@ namespace Ink_Canvas { ColorThemeSwitchTextBlock.Text = "暗系"; BoardColorThemeSwitchTextBlock.Text = "暗系"; } - else { + else + { // 暗系 // 暗色的红色 BorderPenColorRed.Background = new SolidColorBrush(Color.FromRgb(220, 38, 38)); @@ -305,7 +334,8 @@ namespace Ink_Canvas { BoardHighlighterPenViewboxBtnColorYellowContent.Visibility = Visibility.Collapsed; BoardHighlighterPenViewboxBtnColorZincContent.Visibility = Visibility.Collapsed; - switch (inkColor) { + switch (inkColor) + { case 0: ViewboxBtnColorBlackContent.Visibility = Visibility.Visible; BoardViewboxBtnColorBlackContent.Visibility = Visibility.Visible; @@ -342,7 +372,8 @@ namespace Ink_Canvas { break; } - switch (highlighterColor) { + switch (highlighterColor) + { case 100: HighlighterPenViewboxBtnColorBlackContent.Visibility = Visibility.Visible; BoardHighlighterPenViewboxBtnColorBlackContent.Visibility = Visibility.Visible; @@ -386,18 +417,23 @@ namespace Ink_Canvas { } } - private void CheckLastColor(int inkColor, bool isHighlighter = false) { - if (isHighlighter) { + private void CheckLastColor(int inkColor, bool isHighlighter = false) + { + if (isHighlighter) + { highlighterColor = inkColor; } - else { + else + { if (currentMode == 0) lastDesktopInkColor = inkColor; else lastBoardInkColor = inkColor; } } - private async void CheckPenTypeUIState() { - if (penType == 0) { + private async void CheckPenTypeUIState() + { + if (penType == 0) + { DefaultPenPropsPanel.Visibility = Visibility.Visible; DefaultPenColorsPanel.Visibility = Visibility.Visible; HighlighterPenColorsPanel.Visibility = Visibility.Collapsed; @@ -433,7 +469,8 @@ namespace Ink_Canvas { BoardHighlightPenTabButtonIndicator.Visibility = Visibility.Collapsed; // PenPalette.Margin = new Thickness(-160, -200, -33, 32); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { var marginAnimation = new ThicknessAnimation { Duration = TimeSpan.FromSeconds(0.1), @@ -444,7 +481,8 @@ namespace Ink_Canvas { PenPalette.BeginAnimation(MarginProperty, marginAnimation); }); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { var marginAnimation = new ThicknessAnimation { Duration = TimeSpan.FromSeconds(0.1), @@ -462,7 +500,8 @@ namespace Ink_Canvas { await Dispatcher.InvokeAsync(() => { BoardPenPaletteGrid.Margin = new Thickness(-160, -200, -33, 50); }); } - else if (penType == 1) { + else if (penType == 1) + { DefaultPenPropsPanel.Visibility = Visibility.Collapsed; DefaultPenColorsPanel.Visibility = Visibility.Collapsed; HighlighterPenColorsPanel.Visibility = Visibility.Visible; @@ -498,7 +537,8 @@ namespace Ink_Canvas { BoardHighlightPenTabButtonIndicator.Visibility = Visibility.Visible; // PenPalette.Margin = new Thickness(-160, -157, -33, 32); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { var marginAnimation = new ThicknessAnimation { Duration = TimeSpan.FromSeconds(0.1), @@ -509,7 +549,8 @@ namespace Ink_Canvas { PenPalette.BeginAnimation(MarginProperty, marginAnimation); }); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { var marginAnimation = new ThicknessAnimation { Duration = TimeSpan.FromSeconds(0.1), @@ -528,7 +569,8 @@ namespace Ink_Canvas { } } - private void SwitchToDefaultPen(object sender, MouseButtonEventArgs e) { + private void SwitchToDefaultPen(object sender, MouseButtonEventArgs e) + { penType = 0; CheckPenTypeUIState(); CheckColorTheme(); @@ -538,7 +580,8 @@ namespace Ink_Canvas { drawingAttributes.IsHighlighter = false; } - private void SwitchToHighlighterPen(object sender, MouseButtonEventArgs e) { + private void SwitchToHighlighterPen(object sender, MouseButtonEventArgs e) + { penType = 1; CheckPenTypeUIState(); CheckColorTheme(); @@ -548,124 +591,145 @@ namespace Ink_Canvas { drawingAttributes.IsHighlighter = true; } - private void BtnColorBlack_Click(object sender, RoutedEventArgs e) { + private void BtnColorBlack_Click(object sender, RoutedEventArgs e) + { CheckLastColor(0); ColorSwitchCheck(); } - private void BtnColorRed_Click(object sender, RoutedEventArgs e) { + private void BtnColorRed_Click(object sender, RoutedEventArgs e) + { CheckLastColor(1); ColorSwitchCheck(); } - private void BtnColorGreen_Click(object sender, RoutedEventArgs e) { + private void BtnColorGreen_Click(object sender, RoutedEventArgs e) + { CheckLastColor(2); ColorSwitchCheck(); } - private void BtnColorBlue_Click(object sender, RoutedEventArgs e) { + private void BtnColorBlue_Click(object sender, RoutedEventArgs e) + { CheckLastColor(3); ColorSwitchCheck(); } - private void BtnColorYellow_Click(object sender, RoutedEventArgs e) { + private void BtnColorYellow_Click(object sender, RoutedEventArgs e) + { CheckLastColor(4); ColorSwitchCheck(); } - private void BtnColorWhite_Click(object sender, RoutedEventArgs e) { + private void BtnColorWhite_Click(object sender, RoutedEventArgs e) + { CheckLastColor(5); ColorSwitchCheck(); } - private void BtnColorPink_Click(object sender, RoutedEventArgs e) { + private void BtnColorPink_Click(object sender, RoutedEventArgs e) + { CheckLastColor(6); ColorSwitchCheck(); } - private void BtnColorOrange_Click(object sender, RoutedEventArgs e) { + private void BtnColorOrange_Click(object sender, RoutedEventArgs e) + { CheckLastColor(8); ColorSwitchCheck(); } - private void BtnColorTeal_Click(object sender, RoutedEventArgs e) { + private void BtnColorTeal_Click(object sender, RoutedEventArgs e) + { CheckLastColor(7); ColorSwitchCheck(); } - private void BtnHighlighterColorBlack_Click(object sender, RoutedEventArgs e) { + private void BtnHighlighterColorBlack_Click(object sender, RoutedEventArgs e) + { CheckLastColor(100, true); penType = 1; CheckPenTypeUIState(); ColorSwitchCheck(); } - private void BtnHighlighterColorWhite_Click(object sender, RoutedEventArgs e) { + private void BtnHighlighterColorWhite_Click(object sender, RoutedEventArgs e) + { CheckLastColor(101, true); penType = 1; CheckPenTypeUIState(); ColorSwitchCheck(); } - private void BtnHighlighterColorRed_Click(object sender, RoutedEventArgs e) { + private void BtnHighlighterColorRed_Click(object sender, RoutedEventArgs e) + { CheckLastColor(102, true); penType = 1; CheckPenTypeUIState(); ColorSwitchCheck(); } - private void BtnHighlighterColorYellow_Click(object sender, RoutedEventArgs e) { + private void BtnHighlighterColorYellow_Click(object sender, RoutedEventArgs e) + { CheckLastColor(103, true); penType = 1; CheckPenTypeUIState(); ColorSwitchCheck(); } - private void BtnHighlighterColorGreen_Click(object sender, RoutedEventArgs e) { + private void BtnHighlighterColorGreen_Click(object sender, RoutedEventArgs e) + { CheckLastColor(104, true); penType = 1; CheckPenTypeUIState(); ColorSwitchCheck(); } - private void BtnHighlighterColorZinc_Click(object sender, RoutedEventArgs e) { + private void BtnHighlighterColorZinc_Click(object sender, RoutedEventArgs e) + { CheckLastColor(105, true); penType = 1; CheckPenTypeUIState(); ColorSwitchCheck(); } - private void BtnHighlighterColorBlue_Click(object sender, RoutedEventArgs e) { + private void BtnHighlighterColorBlue_Click(object sender, RoutedEventArgs e) + { CheckLastColor(106, true); penType = 1; CheckPenTypeUIState(); ColorSwitchCheck(); } - private void BtnHighlighterColorPurple_Click(object sender, RoutedEventArgs e) { + private void BtnHighlighterColorPurple_Click(object sender, RoutedEventArgs e) + { CheckLastColor(107, true); penType = 1; CheckPenTypeUIState(); ColorSwitchCheck(); } - private void BtnHighlighterColorTeal_Click(object sender, RoutedEventArgs e) { + private void BtnHighlighterColorTeal_Click(object sender, RoutedEventArgs e) + { CheckLastColor(108, true); penType = 1; CheckPenTypeUIState(); ColorSwitchCheck(); } - private void BtnHighlighterColorOrange_Click(object sender, RoutedEventArgs e) { + private void BtnHighlighterColorOrange_Click(object sender, RoutedEventArgs e) + { CheckLastColor(109, true); penType = 1; CheckPenTypeUIState(); ColorSwitchCheck(); } - private Color StringToColor(string colorStr) { + private Color StringToColor(string colorStr) + { var argb = new byte[4]; - for (var i = 0; i < 4; i++) { + for (var i = 0; i < 4; i++) + { var charArray = colorStr.Substring(i * 2 + 1, 2).ToCharArray(); var b1 = toByte(charArray[0]); var b2 = toByte(charArray[1]); @@ -675,7 +739,8 @@ namespace Ink_Canvas { return Color.FromArgb(argb[0], argb[1], argb[2], argb[3]); //#FFFFFFFF } - private static byte toByte(char c) { + private static byte toByte(char c) + { var b = (byte)"0123456789ABCDEF".IndexOf(c); return b; } diff --git a/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs b/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs index 1591aa7f..ea0176cc 100644 --- a/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs +++ b/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs @@ -1,13 +1,11 @@ -using System; +using Microsoft.Win32; +using System; using System.IO; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; -using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; -using Ink_Canvas.Helpers; -using Microsoft.Win32; namespace Ink_Canvas { diff --git a/Ink Canvas/MainWindow_cs/MW_Eraser.cs b/Ink Canvas/MainWindow_cs/MW_Eraser.cs index 3b0fc6f8..d49cfe1a 100644 --- a/Ink Canvas/MainWindow_cs/MW_Eraser.cs +++ b/Ink Canvas/MainWindow_cs/MW_Eraser.cs @@ -1,4 +1,5 @@ -using System; +using Ink_Canvas.Helpers; +using System; using System.Diagnostics; using System.Linq; using System.Windows; @@ -6,10 +7,11 @@ using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; -using Ink_Canvas.Helpers; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { // 新橡皮擦系统的核心变量 public bool isUsingAdvancedEraser; @@ -79,19 +81,21 @@ namespace Ink_Canvas { /// /// 新橡皮擦覆盖层加载事件处理 /// - private void EraserOverlay_Loaded(object sender, RoutedEventArgs e) { + private void EraserOverlay_Loaded(object sender, RoutedEventArgs e) + { var border = (Border)sender; - + // 初始化覆盖层 InitializeEraserOverlay(border); - + Trace.WriteLine("Advanced Eraser: Overlay loaded and initialized"); } /// /// 开始高级橡皮擦操作 /// - private void StartAdvancedEraserOperation(object sender) { + private void StartAdvancedEraserOperation(object sender) + { if (isUsingAdvancedEraser) return; // 设置操作状态 @@ -119,7 +123,8 @@ namespace Ink_Canvas { /// private StylusShape CreateEraserShape() { - if (isCurrentEraserCircle) { + if (isCurrentEraserCircle) + { return new EllipseStylusShape(currentEraserSize, currentEraserSize); } @@ -130,14 +135,18 @@ namespace Ink_Canvas { /// /// 初始化橡皮擦变换矩阵 /// - private void InitializeEraserTransform() { + private void InitializeEraserTransform() + { eraserTransformMatrix = new Matrix(); - if (isCurrentEraserCircle) { + if (isCurrentEraserCircle) + { // 圆形橡皮擦:等比例缩放 var scale = currentEraserSize / 56.0; // 基于56x56的基准尺寸 eraserTransformMatrix.ScaleAt(scale, scale, 0, 0); - } else { + } + else + { // 矩形橡皮擦:保持传统比例 var scaleX = currentEraserSize / 38.0; var scaleY = (currentEraserSize * 56 / 38) / 56.0; @@ -148,11 +157,13 @@ namespace Ink_Canvas { /// /// 更新橡皮擦尺寸 /// - private void UpdateEraserSize() { + private void UpdateEraserSize() + { // 使用与原来相同的逻辑计算橡皮擦尺寸 double k = 1.0; - - switch (Settings.Canvas.EraserSize) { + + switch (Settings.Canvas.EraserSize) + { case 0: k = Settings.Canvas.EraserShapeType == 0 ? 0.5 : 0.7; break; case 1: k = Settings.Canvas.EraserShapeType == 0 ? 0.8 : 0.9; break; case 2: k = 1.0; break; @@ -162,11 +173,14 @@ namespace Ink_Canvas { // 更新形状类型 isCurrentEraserCircle = (Settings.Canvas.EraserShapeType == 0); - + // 根据形状类型设置尺寸 - if (isCurrentEraserCircle) { + if (isCurrentEraserCircle) + { currentEraserSize = k * 90; // 圆形橡皮擦 - } else { + } + else + { currentEraserSize = k * 90 * 0.6; // 矩形橡皮擦宽度 } } @@ -174,7 +188,8 @@ namespace Ink_Canvas { /// /// 结束高级橡皮擦操作 /// - private void EndAdvancedEraserOperation(object sender) { + private void EndAdvancedEraserOperation(object sender) + { if (!isUsingAdvancedEraser) return; // 重置操作状态 @@ -182,7 +197,8 @@ namespace Ink_Canvas { isEraserVisible = false; // 释放鼠标捕获 - if (sender is Border border) { + if (sender is Border border) + { border.ReleaseMouseCapture(); } @@ -190,7 +206,8 @@ namespace Ink_Canvas { HideEraserFeedback(); // 结束碰撞检测 - if (advancedHitTester != null) { + if (advancedHitTester != null) + { advancedHitTester.EndHitTesting(); advancedHitTester = null; } @@ -202,12 +219,17 @@ namespace Ink_Canvas { /// /// 隐藏橡皮擦视觉反馈 /// - private void HideEraserFeedback() { - try { - if (eraserVisualBorder != null) { + private void HideEraserFeedback() + { + try + { + if (eraserVisualBorder != null) + { eraserVisualBorder.Visibility = Visibility.Collapsed; } - } catch (Exception ex) { + } + catch (Exception ex) + { Trace.WriteLine($"Advanced Eraser: Error hiding feedback - {ex.Message}"); } } @@ -215,14 +237,19 @@ namespace Ink_Canvas { /// /// 提交橡皮擦历史记录 /// - private void CommitEraserHistory() { - try { - if (ReplacedStroke != null || AddedStroke != null) { + private void CommitEraserHistory() + { + try + { + if (ReplacedStroke != null || AddedStroke != null) + { timeMachine.CommitStrokeEraseHistory(ReplacedStroke, AddedStroke); AddedStroke = null; ReplacedStroke = null; } - } catch (Exception ex) { + } + catch (Exception ex) + { Trace.WriteLine($"Advanced Eraser: Error committing history - {ex.Message}"); } } @@ -230,8 +257,10 @@ namespace Ink_Canvas { /// /// 高级橡皮擦笔画碰撞事件处理 /// - private void OnAdvancedEraserStrokeHit(object sender, StrokeHitEventArgs args) { - try { + private void OnAdvancedEraserStrokeHit(object sender, StrokeHitEventArgs args) + { + try + { var inkCanvas = FindName("inkCanvas") as InkCanvas; if (inkCanvas == null) return; @@ -248,15 +277,20 @@ namespace Ink_Canvas { var filteredResultArray = filteredResult as Stroke[] ?? filteredResult.ToArray(); // 执行笔画替换或删除 - if (filteredResultArray.Any()) { + if (filteredResultArray.Any()) + { inkCanvas.Strokes.Replace( new StrokeCollection(filteredToReplaceArray), new StrokeCollection(filteredResultArray) ); - } else { + } + else + { inkCanvas.Strokes.Remove(new StrokeCollection(filteredToReplaceArray)); } - } catch (Exception ex) { + } + catch (Exception ex) + { Trace.WriteLine($"Advanced Eraser: Error in stroke hit - {ex.Message}"); } } @@ -264,13 +298,15 @@ namespace Ink_Canvas { /// /// 更新高级橡皮擦位置 /// - private void UpdateAdvancedEraserPosition(object sender, Point position) { + private void UpdateAdvancedEraserPosition(object sender, Point position) + { // 移除isUsingAdvancedEraser检查,让视觉反馈始终更新 // if (!isUsingAdvancedEraser) return; // 性能优化:限制更新频率 var now = DateTime.Now; - if ((now - lastEraserUpdate).TotalMilliseconds < ERASER_UPDATE_INTERVAL) { + if ((now - lastEraserUpdate).TotalMilliseconds < ERASER_UPDATE_INTERVAL) + { return; } lastEraserUpdate = now; @@ -282,11 +318,15 @@ namespace Ink_Canvas { UpdateEraserVisualFeedback(position); // 只有在实际使用橡皮擦时才处理擦除 - if (isUsingAdvancedEraser) { + if (isUsingAdvancedEraser) + { // 处理不同的橡皮擦模式 - if (isUsingStrokeEraser) { + if (isUsingStrokeEraser) + { ProcessStrokeEraserAtPosition(position); - } else { + } + else + { ProcessGeometryEraserAtPosition(position); } } @@ -295,8 +335,10 @@ namespace Ink_Canvas { /// /// 在指定位置处理笔画橡皮擦 /// - private void ProcessStrokeEraserAtPosition(Point position) { - try { + private void ProcessStrokeEraserAtPosition(Point position) + { + try + { var inkCanvas = FindName("inkCanvas") as InkCanvas; if (inkCanvas == null) return; @@ -304,10 +346,13 @@ namespace Ink_Canvas { .Where(stroke => !stroke.ContainsPropertyData(IsLockGuid)); var strokesArray = hitStrokes as Stroke[] ?? hitStrokes.ToArray(); - if (strokesArray.Any()) { + if (strokesArray.Any()) + { inkCanvas.Strokes.Remove(new StrokeCollection(strokesArray)); } - } catch (Exception ex) { + } + catch (Exception ex) + { Trace.WriteLine($"Advanced Eraser: Error in stroke eraser - {ex.Message}"); } } @@ -315,12 +360,17 @@ namespace Ink_Canvas { /// /// 在指定位置处理几何橡皮擦 /// - private void ProcessGeometryEraserAtPosition(Point position) { - try { - if (advancedHitTester != null) { + private void ProcessGeometryEraserAtPosition(Point position) + { + try + { + if (advancedHitTester != null) + { advancedHitTester.AddPoint(position); } - } catch (Exception ex) { + } + catch (Exception ex) + { Trace.WriteLine($"Advanced Eraser: Error in geometry eraser - {ex.Message}"); } } @@ -328,11 +378,15 @@ namespace Ink_Canvas { /// /// 更新橡皮擦视觉反馈 /// - private void UpdateEraserVisualFeedback(Point position) { - try { + private void UpdateEraserVisualFeedback(Point position) + { + try + { // 获取或创建橡皮擦视觉反馈Border - if (eraserVisualBorder == null) { - eraserVisualBorder = new Border { + if (eraserVisualBorder == null) + { + eraserVisualBorder = new Border + { Background = new SolidColorBrush(Colors.Transparent), BorderBrush = new SolidColorBrush(Colors.Transparent), BorderThickness = new Thickness(0), @@ -342,53 +396,62 @@ namespace Ink_Canvas { Opacity = 1 }; Panel.SetZIndex(eraserVisualBorder, 1001); - + // 将Border添加到InkCanvasGridForInkReplay中 var inkCanvasGrid = FindName("InkCanvasGridForInkReplay") as Grid; - if (inkCanvasGrid != null) { + if (inkCanvasGrid != null) + { inkCanvasGrid.Children.Add(eraserVisualBorder); Trace.WriteLine("Advanced Eraser: Visual feedback border added to grid"); - } else { + } + else + { Trace.WriteLine("Advanced Eraser: Failed to find InkCanvasGridForInkReplay"); return; // 如果找不到Grid,直接返回 } } - if (eraserVisualBorder != null) { + if (eraserVisualBorder != null) + { // 创建橡皮擦视觉反馈 var eraserImage = CreateEraserVisualImage(); - + // 清除Border的内容并添加新的图像 eraserVisualBorder.Child = eraserImage; - + // 更新橡皮擦位置和大小 - if (isCurrentEraserCircle) { + if (isCurrentEraserCircle) + { var radius = currentEraserSize / 2; eraserVisualBorder.Width = currentEraserSize; eraserVisualBorder.Height = currentEraserSize; - + // 使用Margin来定位,因为Border在Grid中 eraserVisualBorder.Margin = new Thickness( - position.X - radius, - position.Y - radius, + position.X - radius, + position.Y - radius, 0, 0); - } else { + } + else + { // 矩形橡皮擦,使用与原来相同的逻辑 var height = currentEraserSize / 0.6; eraserVisualBorder.Width = currentEraserSize; eraserVisualBorder.Height = height; - + // 使用Margin来定位,因为Border在Grid中 eraserVisualBorder.Margin = new Thickness( - position.X - currentEraserSize / 2, - position.Y - height / 2, + position.X - currentEraserSize / 2, + position.Y - height / 2, 0, 0); } - + eraserVisualBorder.Visibility = Visibility.Visible; Trace.WriteLine($"Advanced Eraser: Visual feedback updated to ({position.X:F1}, {position.Y:F1})"); } - } catch (Exception ex) { + } + catch (Exception ex) + { Trace.WriteLine($"Advanced Eraser: Error updating visual feedback - {ex.Message}"); } } @@ -396,14 +459,17 @@ namespace Ink_Canvas { /// /// 创建橡皮擦视觉图像 /// - private Image CreateEraserVisualImage() { - try { + private Image CreateEraserVisualImage() + { + try + { // 根据橡皮擦形状选择对应的DrawingGroup资源 string resourceKey = isCurrentEraserCircle ? "EraserCircleDrawingGroup" : "EraserDrawingGroup"; - + // 尝试从资源字典中获取DrawingGroup var drawingGroup = TryFindResource(resourceKey) as DrawingGroup; - if (drawingGroup == null) { + if (drawingGroup == null) + { // 如果找不到资源,创建默认的橡皮擦图像 return CreateDefaultEraserImage(); } @@ -411,14 +477,17 @@ namespace Ink_Canvas { // 创建变换后的DrawingGroup var transformedGroup = new DrawingGroup(); transformedGroup.Children.Add(drawingGroup); - + // 应用缩放变换 var transform = new ScaleTransform(); - if (isCurrentEraserCircle) { + if (isCurrentEraserCircle) + { var scale = currentEraserSize / 56.0; // 基于56x56的基准尺寸 transform.ScaleX = scale; transform.ScaleY = scale; - } else { + } + else + { var scaleX = currentEraserSize / 38.0; var scaleY = (currentEraserSize / 0.6) / 56.0; transform.ScaleX = scaleX; @@ -428,16 +497,19 @@ namespace Ink_Canvas { // 创建DrawingImage var drawingImage = new DrawingImage(transformedGroup); - + // 创建Image控件 - var image = new Image { + var image = new Image + { Source = drawingImage, Stretch = Stretch.None }; RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.HighQuality); return image; - } catch (Exception ex) { + } + catch (Exception ex) + { Trace.WriteLine($"Advanced Eraser: Error creating eraser visual image - {ex.Message}"); return CreateDefaultEraserImage(); } @@ -446,13 +518,18 @@ namespace Ink_Canvas { /// /// 创建默认的橡皮擦图像(当资源不可用时) /// - private Image CreateDefaultEraserImage() { - try { + private Image CreateDefaultEraserImage() + { + try + { // 创建一个简单的几何图形作为默认橡皮擦 Geometry geometry; - if (isCurrentEraserCircle) { + if (isCurrentEraserCircle) + { geometry = new EllipseGeometry(new Point(28, 28), 28, 28); - } else { + } + else + { geometry = new RectangleGeometry(new Rect(0, 0, 38, 56)); } @@ -465,11 +542,14 @@ namespace Ink_Canvas { // 应用缩放变换 var transform = new ScaleTransform(); - if (isCurrentEraserCircle) { + if (isCurrentEraserCircle) + { var scale = currentEraserSize / 56.0; transform.ScaleX = scale; transform.ScaleY = scale; - } else { + } + else + { var scaleX = currentEraserSize / 38.0; var scaleY = (currentEraserSize / 0.6) / 56.0; transform.ScaleX = scaleX; @@ -478,13 +558,16 @@ namespace Ink_Canvas { drawingGroup.Transform = transform; var drawingImage = new DrawingImage(drawingGroup); - var image = new Image { + var image = new Image + { Source = drawingImage, Stretch = Stretch.None }; return image; - } catch (Exception ex) { + } + catch (Exception ex) + { Trace.WriteLine($"Advanced Eraser: Error creating default eraser image - {ex.Message}"); return null; } @@ -494,7 +577,8 @@ namespace Ink_Canvas { /// 兼容性方法:旧版橡皮擦几何碰撞处理 /// [Obsolete("使用 OnAdvancedEraserStrokeHit 替代")] - private void EraserGeometry_StrokeHit(object sender, StrokeHitEventArgs args) { + private void EraserGeometry_StrokeHit(object sender, StrokeHitEventArgs args) + { OnAdvancedEraserStrokeHit(sender, args); } @@ -502,7 +586,8 @@ namespace Ink_Canvas { /// 兼容性方法:旧版橡皮擦移动处理 /// [Obsolete("使用 UpdateAdvancedEraserPosition 替代")] - private void EraserOverlay_PointerMove(object sender, Point pt) { + private void EraserOverlay_PointerMove(object sender, Point pt) + { UpdateAdvancedEraserPosition(sender, pt); } @@ -510,7 +595,8 @@ namespace Ink_Canvas { /// 兼容性方法:旧版橡皮擦按下处理 /// [Obsolete("使用 StartAdvancedEraserOperation 替代")] - private void EraserOverlay_PointerDown(object sender) { + private void EraserOverlay_PointerDown(object sender) + { StartAdvancedEraserOperation(sender); } @@ -518,14 +604,16 @@ namespace Ink_Canvas { /// 兼容性方法:旧版橡皮擦抬起处理 /// [Obsolete("使用 EndAdvancedEraserOperation 替代")] - private void EraserOverlay_PointerUp(object sender) { + private void EraserOverlay_PointerUp(object sender) + { EndAdvancedEraserOperation(sender); } /// /// 获取当前橡皮擦状态信息(用于调试) /// - public string GetEraserStatusInfo() { + public string GetEraserStatusInfo() + { return "Advanced Eraser Status:\n" + $"- Active: {isUsingAdvancedEraser}\n" + $"- Size: {currentEraserSize:F1}\n" + @@ -538,22 +626,26 @@ namespace Ink_Canvas { /// /// 重置橡皮擦状态 /// - public void ResetEraserState() { + public void ResetEraserState() + { isUsingAdvancedEraser = false; isEraserVisible = false; lastEraserPosition = new Point(); - if (advancedHitTester != null) { + if (advancedHitTester != null) + { advancedHitTester.EndHitTesting(); advancedHitTester = null; } HideEraserFeedback(); - + // 清理视觉反馈Border - if (eraserVisualBorder != null) { + if (eraserVisualBorder != null) + { var inkCanvasGrid = FindName("InkCanvasGridForInkReplay") as Grid; - if (inkCanvasGrid != null) { + if (inkCanvasGrid != null) + { inkCanvasGrid.Children.Remove(eraserVisualBorder); } eraserVisualBorder = null; @@ -563,8 +655,10 @@ namespace Ink_Canvas { /// /// 应用高级橡皮擦形状到InkCanvas /// - public void ApplyAdvancedEraserShape() { - try { + public void ApplyAdvancedEraserShape() + { + try + { var inkCanvas = FindName("inkCanvas") as InkCanvas; if (inkCanvas == null) return; @@ -578,13 +672,18 @@ namespace Ink_Canvas { inkCanvas.EraserShape = eraserShape; Trace.WriteLine($"Advanced Eraser: Applied shape - Size: {currentEraserSize}, Circle: {isCurrentEraserCircle}"); - } catch (Exception ex) { + } + catch (Exception ex) + { Trace.WriteLine($"Advanced Eraser: Error applying shape - {ex.Message}"); // 回退到传统方法 - try { + try + { ApplyCurrentEraserShape(); - } catch (Exception fallbackEx) { + } + catch (Exception fallbackEx) + { Trace.WriteLine($"Advanced Eraser: Fallback also failed - {fallbackEx.Message}"); } } @@ -593,33 +692,42 @@ namespace Ink_Canvas { /// /// 启用高级橡皮擦系统 /// - public void EnableAdvancedEraserSystem() { - try { + public void EnableAdvancedEraserSystem() + { + try + { // 获取橡皮擦覆盖层 var eraserOverlay = FindName("AdvancedEraserOverlay") as Border; - if (eraserOverlay != null) { + if (eraserOverlay != null) + { // 启用覆盖层的交互 eraserOverlay.IsHitTestVisible = true; - + // 确保覆盖层在橡皮擦模式下启用 - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { eraserOverlay.IsHitTestVisible = true; Trace.WriteLine("Advanced Eraser: Overlay enabled for eraser mode"); } - + // 设置覆盖层的大小以覆盖整个InkCanvas var inkCanvasControl = FindName("inkCanvas") as InkCanvas; - if (inkCanvasControl != null) { + if (inkCanvasControl != null) + { eraserOverlay.Width = inkCanvasControl.ActualWidth; eraserOverlay.Height = inkCanvasControl.ActualHeight; Trace.WriteLine($"Advanced Eraser: Overlay size set to {eraserOverlay.Width}x{eraserOverlay.Height}"); } - + Trace.WriteLine("Advanced Eraser: System enabled successfully"); - } else { + } + else + { Trace.WriteLine("Advanced Eraser: Failed to find eraser overlay"); } - } catch (Exception ex) { + } + catch (Exception ex) + { Trace.WriteLine($"Advanced Eraser: Error enabling system - {ex.Message}"); } } @@ -627,69 +735,89 @@ namespace Ink_Canvas { /// /// 初始化橡皮擦覆盖层 /// - private void InitializeEraserOverlay(Border overlay) { - try { + private void InitializeEraserOverlay(Border overlay) + { + try + { // 设置覆盖层的基本属性 overlay.Background = new SolidColorBrush(Colors.Transparent); overlay.IsHitTestVisible = false; // 默认禁用,只在橡皮擦模式下启用 - + // 绑定事件处理 - overlay.MouseDown += (sender, e) => { - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { + overlay.MouseDown += (sender, e) => + { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { overlay.CaptureMouse(); StartAdvancedEraserOperation(sender); } }; - - overlay.MouseUp += (sender, e) => { - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { + + overlay.MouseUp += (sender, e) => + { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { overlay.ReleaseMouseCapture(); EndAdvancedEraserOperation(sender); } }; - - overlay.MouseMove += (sender, e) => { - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { + + overlay.MouseMove += (sender, e) => + { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { var position = e.GetPosition((UIElement)FindName("inkCanvas")); Trace.WriteLine($"Advanced Eraser: Mouse move event triggered at ({position.X:F1}, {position.Y:F1})"); UpdateAdvancedEraserPosition(sender, position); - } else { + } + else + { Trace.WriteLine($"Advanced Eraser: Mouse move ignored - not in eraser mode, current mode: {inkCanvas.EditingMode}"); } }; - + // 触控笔事件 - overlay.StylusDown += (sender, e) => { - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { + overlay.StylusDown += (sender, e) => + { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { e.Handled = true; - if (e.StylusDevice.TabletDevice.Type == TabletDeviceType.Stylus) { + if (e.StylusDevice.TabletDevice.Type == TabletDeviceType.Stylus) + { overlay.CaptureStylus(); } StartAdvancedEraserOperation(sender); } }; - - overlay.StylusUp += (sender, e) => { - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { + + overlay.StylusUp += (sender, e) => + { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { e.Handled = true; - if (e.StylusDevice.TabletDevice.Type == TabletDeviceType.Stylus) { + if (e.StylusDevice.TabletDevice.Type == TabletDeviceType.Stylus) + { overlay.ReleaseStylusCapture(); } EndAdvancedEraserOperation(sender); } }; - - overlay.StylusMove += (sender, e) => { - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { + + overlay.StylusMove += (sender, e) => + { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { e.Handled = true; var position = e.GetPosition((UIElement)FindName("inkCanvas")); UpdateAdvancedEraserPosition(sender, position); Trace.WriteLine($"Advanced Eraser: Stylus move at ({position.X:F1}, {position.Y:F1})"); } }; - + Trace.WriteLine("Advanced Eraser: Overlay initialized successfully"); - } catch (Exception ex) { + } + catch (Exception ex) + { Trace.WriteLine($"Advanced Eraser: Error initializing overlay - {ex.Message}"); } } @@ -697,22 +825,27 @@ namespace Ink_Canvas { /// /// 禁用高级橡皮擦系统 /// - public void DisableAdvancedEraserSystem() { - try { + public void DisableAdvancedEraserSystem() + { + try + { // 重置橡皮擦状态 ResetEraserState(); - + // 获取橡皮擦覆盖层并禁用 var eraserOverlay = FindName("AdvancedEraserOverlay") as Border; - if (eraserOverlay != null) { + if (eraserOverlay != null) + { eraserOverlay.IsHitTestVisible = false; } - + // 确保视觉反馈被隐藏 HideEraserFeedback(); - + Trace.WriteLine("Advanced Eraser: System disabled successfully"); - } catch (Exception ex) { + } + catch (Exception ex) + { Trace.WriteLine($"Advanced Eraser: Error disabling system - {ex.Message}"); } } @@ -720,7 +853,8 @@ namespace Ink_Canvas { /// /// 切换橡皮擦形状(圆形/矩形) /// - public void ToggleEraserShape() { + public void ToggleEraserShape() + { isCurrentEraserCircle = !isCurrentEraserCircle; // 更新设置 @@ -730,6 +864,6 @@ namespace Ink_Canvas { ApplyAdvancedEraserShape(); Trace.WriteLine($"Advanced Eraser: Toggled to {(isCurrentEraserCircle ? "Circle" : "Rectangle")}"); - } + } } } diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index e11933fa..63e48bf8 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -1,3 +1,5 @@ +using Ink_Canvas.Helpers; +using iNKORE.UI.WPF.Modern; using System; using System.Diagnostics; using System.Threading; @@ -11,27 +13,29 @@ using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; -using Ink_Canvas.Helpers; -using iNKORE.UI.WPF.Modern; using Application = System.Windows.Application; using Button = System.Windows.Controls.Button; using HorizontalAlignment = System.Windows.HorizontalAlignment; -using Point = System.Windows.Point; using Image = System.Windows.Controls.Image; using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox; using MouseEventArgs = System.Windows.Input.MouseEventArgs; using OpenFileDialog = Microsoft.Win32.OpenFileDialog; using Panel = System.Windows.Controls.Panel; +using Point = System.Windows.Point; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { #region “手勢”按鈕 /// /// 用於浮動工具欄的"手勢"按鈕和白板工具欄的"手勢"按鈕的點擊事件 /// - private void TwoFingerGestureBorder_MouseUp(object sender, RoutedEventArgs e) { - if (TwoFingerGestureBorder.Visibility == Visibility.Visible) { + private void TwoFingerGestureBorder_MouseUp(object sender, RoutedEventArgs e) + { + if (TwoFingerGestureBorder.Visibility == Visibility.Visible) + { AnimationsHelper.HideWithSlideAndFade(EraserSizePanel); AnimationsHelper.HideWithSlideAndFade(BorderTools); AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); @@ -45,7 +49,8 @@ namespace Ink_Canvas { AnimationsHelper.HideWithSlideAndFade(TwoFingerGestureBorder); AnimationsHelper.HideWithSlideAndFade(BoardTwoFingerGestureBorder); } - else { + else + { AnimationsHelper.HideWithSlideAndFade(EraserSizePanel); AnimationsHelper.HideWithSlideAndFade(BorderTools); AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); @@ -64,13 +69,15 @@ namespace Ink_Canvas { /// /// 用於更新浮動工具欄的"手勢"按鈕和白板工具欄的"手勢"按鈕的樣式(開啟和關閉狀態) /// - private void CheckEnableTwoFingerGestureBtnColorPrompt() { - if (ToggleSwitchEnableMultiTouchMode.IsOn) { + private void CheckEnableTwoFingerGestureBtnColorPrompt() + { + if (ToggleSwitchEnableMultiTouchMode.IsOn) + { TwoFingerGestureSimpleStackPanel.Opacity = 0.5; TwoFingerGestureSimpleStackPanel.IsHitTestVisible = false; EnableTwoFingerGestureBtn.Source = new BitmapImage(new Uri("/Resources/new-icons/gesture.png", UriKind.Relative)); - + BoardGesture.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); @@ -79,25 +86,28 @@ namespace Ink_Canvas { BoardGestureGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.DisabledGestureIcon); BoardGestureGeometry2.Geometry = Geometry.Parse("F0 M24,24z M0,0z"); } - else { + else + { TwoFingerGestureSimpleStackPanel.Opacity = 1; TwoFingerGestureSimpleStackPanel.IsHitTestVisible = true; - if (Settings.Gesture.IsEnableTwoFingerGesture) { + if (Settings.Gesture.IsEnableTwoFingerGesture) + { EnableTwoFingerGestureBtn.Source = new BitmapImage(new Uri("/Resources/new-icons/gesture-enabled.png", UriKind.Relative)); - + BoardGesture.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); BoardGestureGeometry.Brush = new SolidColorBrush(Colors.GhostWhite); BoardGestureGeometry2.Brush = new SolidColorBrush(Colors.GhostWhite); BoardGestureLabel.Foreground = new SolidColorBrush(Colors.GhostWhite); BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235)); BoardGestureGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.EnabledGestureIcon); - BoardGestureGeometry2.Geometry = Geometry.Parse("F0 M24,24z M0,0z "+XamlGraphicsIconGeometries.EnabledGestureIconBadgeCheck); + BoardGestureGeometry2.Geometry = Geometry.Parse("F0 M24,24z M0,0z " + XamlGraphicsIconGeometries.EnabledGestureIconBadgeCheck); } - else { + else + { EnableTwoFingerGestureBtn.Source = new BitmapImage(new Uri("/Resources/new-icons/gesture.png", UriKind.Relative)); - + BoardGesture.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); @@ -112,17 +122,21 @@ namespace Ink_Canvas { /// /// 控制是否顯示浮動工具欄的"手勢"按鈕 /// - private void CheckEnableTwoFingerGestureBtnVisibility(bool isVisible) { + private void CheckEnableTwoFingerGestureBtnVisibility(bool isVisible) + { if (StackPanelCanvasControls.Visibility != Visibility.Visible - || BorderFloatingBarMainControls.Visibility != Visibility.Visible) { + || BorderFloatingBarMainControls.Visibility != Visibility.Visible) + { EnableTwoFingerGestureBorder.Visibility = Visibility.Collapsed; } - else if (isVisible) { + else if (isVisible) + { if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) EnableTwoFingerGestureBorder.Visibility = Visibility.Collapsed; else EnableTwoFingerGestureBorder.Visibility = Visibility.Visible; } - else { + else + { EnableTwoFingerGestureBorder.Visibility = Visibility.Collapsed; } } @@ -137,8 +151,10 @@ namespace Ink_Canvas { private Point pointDesktop = new Point(-1, -1); //用于记录上次在桌面时的坐标 private Point pointPPT = new Point(-1, -1); //用于记录上次在PPT中的坐标 - private void SymbolIconEmoji_MouseMove(object sender, MouseEventArgs e) { - if (isDragDropInEffect) { + private void SymbolIconEmoji_MouseMove(object sender, MouseEventArgs e) + { + if (isDragDropInEffect) + { var xPos = e.GetPosition(null).X - pos.X + ViewboxFloatingBar.Margin.Left; var yPos = e.GetPosition(null).Y - pos.Y + ViewboxFloatingBar.Margin.Top; ViewboxFloatingBar.Margin = new Thickness(xPos, yPos, -2000, -200); @@ -151,8 +167,10 @@ namespace Ink_Canvas { } } - private void SymbolIconEmoji_MouseDown(object sender, MouseButtonEventArgs e) { - if (isViewboxFloatingBarMarginAnimationRunning) { + private void SymbolIconEmoji_MouseDown(object sender, MouseButtonEventArgs e) + { + if (isViewboxFloatingBarMarginAnimationRunning) + { ViewboxFloatingBar.BeginAnimation(MarginProperty, null); isViewboxFloatingBarMarginAnimationRunning = false; } @@ -163,16 +181,20 @@ namespace Ink_Canvas { GridForFloatingBarDraging.Visibility = Visibility.Visible; } - private void SymbolIconEmoji_MouseUp(object sender, MouseButtonEventArgs e) { + private void SymbolIconEmoji_MouseUp(object sender, MouseButtonEventArgs e) + { isDragDropInEffect = false; if (e is null || (Math.Abs(downPos.X - e.GetPosition(null).X) <= 10 && - Math.Abs(downPos.Y - e.GetPosition(null).Y) <= 10)) { - if (BorderFloatingBarMainControls.Visibility == Visibility.Visible) { + Math.Abs(downPos.Y - e.GetPosition(null).Y) <= 10)) + { + if (BorderFloatingBarMainControls.Visibility == Visibility.Visible) + { BorderFloatingBarMainControls.Visibility = Visibility.Collapsed; CheckEnableTwoFingerGestureBtnVisibility(false); } - else { + else + { BorderFloatingBarMainControls.Visibility = Visibility.Visible; CheckEnableTwoFingerGestureBtnVisibility(true); } @@ -270,7 +292,8 @@ namespace Ink_Canvas { /// /// 是否自動居中浮動工具欄 /// - private async void HideSubPanels(string mode = null, bool autoAlignCenter = false) { + private async void HideSubPanels(string mode = null, bool autoAlignCenter = false) + { AnimationsHelper.HideWithSlideAndFade(BorderTools); AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); AnimationsHelper.HideWithSlideAndFade(PenPalette); @@ -288,14 +311,16 @@ namespace Ink_Canvas { AnimationsHelper.HideWithSlideAndFade(bgPalette); } - if (BorderSettings.Visibility == Visibility.Visible) { + if (BorderSettings.Visibility == Visibility.Visible) + { // 设置蒙版为不可点击,并移除背景 BorderSettingsMask.IsHitTestVisible = false; BorderSettingsMask.Background = null; var sb = new Storyboard(); // 滑动动画 - var slideAnimation = new DoubleAnimation { + var slideAnimation = new DoubleAnimation + { From = 0, // 滑动距离 To = BorderSettings.RenderTransform.Value.OffsetX - 440, Duration = TimeSpan.FromSeconds(0.6) @@ -306,7 +331,8 @@ namespace Ink_Canvas { sb.Children.Add(slideAnimation); - sb.Completed += (s, _) => { + sb.Completed += (s, _) => + { BorderSettings.Visibility = Visibility.Collapsed; isOpeningOrHidingSettingsPane = false; }; @@ -321,13 +347,16 @@ namespace Ink_Canvas { AnimationsHelper.HideWithSlideAndFade(TwoFingerGestureBorder); AnimationsHelper.HideWithSlideAndFade(EraserSizePanel); AnimationsHelper.HideWithSlideAndFade(BoardTwoFingerGestureBorder); - if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) { + if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) + { AnimationsHelper.HideWithSlideAndFade(BorderDrawShape); AnimationsHelper.HideWithSlideAndFade(BoardBorderDrawShape); } - if (mode != null) { - if (mode != "clear") { + if (mode != null) + { + if (mode != "clear") + { CursorIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(27, 27, 27)); CursorIconGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.LinedCursorIcon); PenIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(27, 27, 27)); @@ -358,70 +387,77 @@ namespace Ink_Canvas { System.Windows.Controls.Canvas.SetLeft(FloatingbarSelectionBG, 0); } - switch (mode) { + switch (mode) + { case "pen": - case "color": { - PenIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138)); - PenIconGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.SolidPenIcon); - BoardPen.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); - BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235)); - BoardPenGeometry.Brush = new SolidColorBrush(Colors.GhostWhite); - BoardPenLabel.Foreground = new SolidColorBrush(Colors.GhostWhite); + case "color": + { + PenIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138)); + PenIconGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.SolidPenIcon); + BoardPen.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); + BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235)); + BoardPenGeometry.Brush = new SolidColorBrush(Colors.GhostWhite); + BoardPenLabel.Foreground = new SolidColorBrush(Colors.GhostWhite); - FloatingbarSelectionBG.Visibility = Visibility.Visible; - System.Windows.Controls.Canvas.SetLeft(FloatingbarSelectionBG, 28); + FloatingbarSelectionBG.Visibility = Visibility.Visible; + System.Windows.Controls.Canvas.SetLeft(FloatingbarSelectionBG, 28); break; - } - case "eraser": { - CircleEraserIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138)); - CircleEraserIconGeometry.Geometry = - Geometry.Parse(XamlGraphicsIconGeometries.SolidEraserCircleIcon); - BoardEraser.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); - BoardEraser.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235)); - BoardEraserGeometry.Brush = new SolidColorBrush(Colors.GhostWhite); - BoardEraserLabel.Foreground = new SolidColorBrush(Colors.GhostWhite); + } + case "eraser": + { + CircleEraserIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138)); + CircleEraserIconGeometry.Geometry = + Geometry.Parse(XamlGraphicsIconGeometries.SolidEraserCircleIcon); + BoardEraser.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); + BoardEraser.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235)); + BoardEraserGeometry.Brush = new SolidColorBrush(Colors.GhostWhite); + BoardEraserLabel.Foreground = new SolidColorBrush(Colors.GhostWhite); - FloatingbarSelectionBG.Visibility = Visibility.Visible; - System.Windows.Controls.Canvas.SetLeft(FloatingbarSelectionBG, 28 * 3); + FloatingbarSelectionBG.Visibility = Visibility.Visible; + System.Windows.Controls.Canvas.SetLeft(FloatingbarSelectionBG, 28 * 3); break; - } - case "eraserByStrokes": { - StrokeEraserIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138)); - StrokeEraserIconGeometry.Geometry = - Geometry.Parse(XamlGraphicsIconGeometries.SolidEraserStrokeIcon); - BoardEraser.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); - BoardEraser.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235)); - BoardEraserGeometry.Brush = new SolidColorBrush(Colors.GhostWhite); - BoardEraserLabel.Foreground = new SolidColorBrush(Colors.GhostWhite); + } + case "eraserByStrokes": + { + StrokeEraserIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138)); + StrokeEraserIconGeometry.Geometry = + Geometry.Parse(XamlGraphicsIconGeometries.SolidEraserStrokeIcon); + BoardEraser.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); + BoardEraser.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235)); + BoardEraserGeometry.Brush = new SolidColorBrush(Colors.GhostWhite); + BoardEraserLabel.Foreground = new SolidColorBrush(Colors.GhostWhite); - FloatingbarSelectionBG.Visibility = Visibility.Visible; - System.Windows.Controls.Canvas.SetLeft(FloatingbarSelectionBG, 28 * 4); + FloatingbarSelectionBG.Visibility = Visibility.Visible; + System.Windows.Controls.Canvas.SetLeft(FloatingbarSelectionBG, 28 * 4); break; - } - case "select": { - LassoSelectIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138)); - LassoSelectIconGeometry.Geometry = - Geometry.Parse(XamlGraphicsIconGeometries.SolidLassoSelectIcon); - BoardSelect.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); - BoardSelect.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235)); - BoardSelectGeometry.Brush = new SolidColorBrush(Colors.GhostWhite); - BoardSelectLabel.Foreground = new SolidColorBrush(Colors.GhostWhite); + } + case "select": + { + LassoSelectIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138)); + LassoSelectIconGeometry.Geometry = + Geometry.Parse(XamlGraphicsIconGeometries.SolidLassoSelectIcon); + BoardSelect.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); + BoardSelect.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235)); + BoardSelectGeometry.Brush = new SolidColorBrush(Colors.GhostWhite); + BoardSelectLabel.Foreground = new SolidColorBrush(Colors.GhostWhite); - FloatingbarSelectionBG.Visibility = Visibility.Visible; - System.Windows.Controls.Canvas.SetLeft(FloatingbarSelectionBG, 28 * 5); + FloatingbarSelectionBG.Visibility = Visibility.Visible; + System.Windows.Controls.Canvas.SetLeft(FloatingbarSelectionBG, 28 * 5); break; - } - case "shape": { - // 对图形模式进行特殊处理,不修改按钮UI状态 - // 只隐藏相关面板,但保持图形绘制模式 - break; - } + } + case "shape": + { + // 对图形模式进行特殊处理,不修改按钮UI状态 + // 只隐藏相关面板,但保持图形绘制模式 + break; + } } if (autoAlignCenter) // 控制居中 { - if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) { + if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) + { await Task.Delay(50); ViewboxFloatingBarMarginAnimation(60); } @@ -445,7 +481,8 @@ namespace Ink_Canvas { #endregion #region 撤銷重做按鈕 - private void SymbolIconUndo_MouseUp(object sender, MouseButtonEventArgs e) { + private void SymbolIconUndo_MouseUp(object sender, MouseButtonEventArgs e) + { //if (lastBorderMouseDownObject != sender) return; if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel) @@ -457,7 +494,8 @@ namespace Ink_Canvas { HideSubPanels(); } - private void SymbolIconRedo_MouseUp(object sender, MouseButtonEventArgs e) { + private void SymbolIconRedo_MouseUp(object sender, MouseButtonEventArgs e) + { //if (lastBorderMouseDownObject != sender) return; if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel) @@ -509,11 +547,12 @@ namespace Ink_Canvas { Not_Enter_Blackboard_fir_Mouse_Click = false; } */ - new Thread(() => { + new Thread(() => + { Thread.Sleep(100); Application.Current.Dispatcher.Invoke(() => { ViewboxFloatingBarMarginAnimation(60); }); }).Start(); - + HideSubPanels(); if (GridTransparencyFakeBackground.Background == Brushes.Transparent) @@ -540,7 +579,9 @@ namespace Ink_Canvas { { WaterMarkTime.Visibility = Visibility.Visible; WaterMarkDate.Visibility = Visibility.Visible; - } else { + } + else + { WaterMarkTime.Visibility = Visibility.Collapsed; WaterMarkDate.Visibility = Visibility.Collapsed; } @@ -548,17 +589,24 @@ namespace Ink_Canvas { if (Settings.Appearance.EnableChickenSoupInWhiteboardMode) { BlackBoardWaterMark.Visibility = Visibility.Visible; - } else { + } + else + { BlackBoardWaterMark.Visibility = Visibility.Collapsed; } - if (Settings.Appearance.ChickenSoupSource == 0) { + if (Settings.Appearance.ChickenSoupSource == 0) + { int randChickenSoupIndex = new Random().Next(ChickenSoup.OSUPlayerYuLu.Length); BlackBoardWaterMark.Text = ChickenSoup.OSUPlayerYuLu[randChickenSoupIndex]; - } else if (Settings.Appearance.ChickenSoupSource == 1) { + } + else if (Settings.Appearance.ChickenSoupSource == 1) + { int randChickenSoupIndex = new Random().Next(ChickenSoup.MingYanJingJu.Length); BlackBoardWaterMark.Text = ChickenSoup.MingYanJingJu[randChickenSoupIndex]; - } else if (Settings.Appearance.ChickenSoupSource == 2) { + } + else if (Settings.Appearance.ChickenSoupSource == 2) + { int randChickenSoupIndex = new Random().Next(ChickenSoup.GaoKaoPhrases.Length); BlackBoardWaterMark.Text = ChickenSoup.GaoKaoPhrases[randChickenSoupIndex]; } @@ -602,17 +650,19 @@ namespace Ink_Canvas { inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) SaveScreenShot(true); if (BtnPPTSlideShowEnd.Visibility == Visibility.Collapsed) - new Thread(() => { + new Thread(() => + { Thread.Sleep(300); Application.Current.Dispatcher.Invoke(() => { ViewboxFloatingBarMarginAnimation(100, true); }); }).Start(); else - new Thread(() => { + new Thread(() => + { Thread.Sleep(300); Application.Current.Dispatcher.Invoke(() => { ViewboxFloatingBarMarginAnimation(60); }); }).Start(); - if (System.Windows.Controls.Canvas.GetLeft(FloatingbarSelectionBG)!=28) PenIcon_Click(null, null); + if (System.Windows.Controls.Canvas.GetLeft(FloatingbarSelectionBG) != 28) PenIcon_Click(null, null); if (Settings.Gesture.AutoSwitchTwoFingerGesture) // 自动启用多指书写 ToggleSwitchEnableTwoFingerTranslate.IsOn = false; @@ -633,7 +683,8 @@ namespace Ink_Canvas { BtnExit.Foreground = Brushes.White; ThemeManager.Current.ApplicationTheme = ApplicationTheme.Dark; - new Thread(() => { + new Thread(() => + { Thread.Sleep(200); Application.Current.Dispatcher.Invoke(() => { isDisplayingOrHidingBlackboard = false; }); }).Start(); @@ -643,14 +694,18 @@ namespace Ink_Canvas { } #endregion - private async void SymbolIconCursor_Click(object sender, RoutedEventArgs e) { - if (currentMode != 0) { + private async void SymbolIconCursor_Click(object sender, RoutedEventArgs e) + { + if (currentMode != 0) + { ImageBlackboard_MouseUp(null, null); } - else { + else + { BtnHideInkCanvas_Click(BtnHideInkCanvas, null); - if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) { + if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) + { await Task.Delay(100); ViewboxFloatingBarMarginAnimation(60); } @@ -659,19 +714,23 @@ namespace Ink_Canvas { #region 清空畫布按鈕 - private void SymbolIconDelete_MouseUp(object sender, MouseButtonEventArgs e) { + private void SymbolIconDelete_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel) ((Panel)lastBorderMouseDownObject).Background = new SolidColorBrush(Colors.Transparent); if (sender == SymbolIconDelete && lastBorderMouseDownObject != SymbolIconDelete) return; - if (inkCanvas.GetSelectedStrokes().Count > 0) { + if (inkCanvas.GetSelectedStrokes().Count > 0) + { inkCanvas.Strokes.Remove(inkCanvas.GetSelectedStrokes()); GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; } - else if (inkCanvas.Strokes.Count > 0) { + else if (inkCanvas.Strokes.Count > 0) + { if (Settings.Automation.IsAutoSaveStrokesAtClear && - inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) { + inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) + { if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) { var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0; @@ -710,27 +769,31 @@ namespace Ink_Canvas { #endregion - private void FloatingBarToolBtnMouseDownFeedback_Panel(object sender, MouseButtonEventArgs e) { + private void FloatingBarToolBtnMouseDownFeedback_Panel(object sender, MouseButtonEventArgs e) + { var s = (Panel)sender; lastBorderMouseDownObject = sender; if (s == SymbolIconDelete) s.Background = new SolidColorBrush(Color.FromArgb(28, 127, 29, 29)); else s.Background = new SolidColorBrush(Color.FromArgb(28, 24, 24, 27)); } - private void FloatingBarToolBtnMouseLeaveFeedback_Panel(object sender, MouseEventArgs e) { + private void FloatingBarToolBtnMouseLeaveFeedback_Panel(object sender, MouseEventArgs e) + { var s = (Panel)sender; lastBorderMouseDownObject = null; s.Background = new SolidColorBrush(Colors.Transparent); } - private void SymbolIconSettings_Click(object sender, RoutedEventArgs e) { + private void SymbolIconSettings_Click(object sender, RoutedEventArgs e) + { if (isOpeningOrHidingSettingsPane) return; HideSubPanels(); BtnSettings_Click(null, null); } - - private void ImageCountdownTimer_MouseUp(object sender, MouseButtonEventArgs e) { + + private void ImageCountdownTimer_MouseUp(object sender, MouseButtonEventArgs e) + { LeftUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed; RightUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed; AnimationsHelper.HideWithSlideAndFade(BorderTools); @@ -739,14 +802,16 @@ namespace Ink_Canvas { new CountdownTimerWindow().Show(); } - private void OperatingGuideWindowIcon_MouseUp(object sender, MouseButtonEventArgs e) { + private void OperatingGuideWindowIcon_MouseUp(object sender, MouseButtonEventArgs e) + { AnimationsHelper.HideWithSlideAndFade(BorderTools); AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); new OperatingGuideWindow().Show(); } - private void SymbolIconRand_MouseUp(object sender, MouseButtonEventArgs e) { + private void SymbolIconRand_MouseUp(object sender, MouseButtonEventArgs e) + { // 如果控件被隐藏,不处理事件 if (RandomDrawPanel.Visibility != Visibility.Visible) return; @@ -759,8 +824,10 @@ namespace Ink_Canvas { new RandWindow(Settings).Show(); } - public void CheckEraserTypeTab() { - if (Settings.Canvas.EraserShapeType == 0) { + public void CheckEraserTypeTab() + { + if (Settings.Canvas.EraserShapeType == 0) + { CircleEraserTabButton.Background = new SolidColorBrush(Color.FromArgb(85, 59, 130, 246)); CircleEraserTabButton.Opacity = 1; CircleEraserTabButtonText.FontWeight = FontWeights.Bold; @@ -787,7 +854,8 @@ namespace Ink_Canvas { BoardRectangleEraserTabButtonText.Margin = new Thickness(2, 1, 0, 0); BoardRectangleEraserTabButtonIndicator.Visibility = Visibility.Collapsed; } - else { + else + { RectangleEraserTabButton.Background = new SolidColorBrush(Color.FromArgb(85, 59, 130, 246)); RectangleEraserTabButton.Opacity = 1; RectangleEraserTabButtonText.FontWeight = FontWeights.Bold; @@ -816,7 +884,8 @@ namespace Ink_Canvas { } } - private void SymbolIconRandOne_MouseUp(object sender, MouseButtonEventArgs e) { + private void SymbolIconRandOne_MouseUp(object sender, MouseButtonEventArgs e) + { // 如果控件被隐藏,不处理事件 if (SingleDrawPanel.Visibility != Visibility.Visible) return; @@ -827,26 +896,33 @@ namespace Ink_Canvas { AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); // 检查是否启用了直接调用ClassIsland点名功能 - if (Settings.RandSettings.DirectCallCiRand) { - try { - Process.Start(new ProcessStartInfo { + if (Settings.RandSettings.DirectCallCiRand) + { + try + { + Process.Start(new ProcessStartInfo + { FileName = "classisland://plugins/IslandCaller/Run", UseShellExecute = true }); } - catch (Exception ex) { + catch (Exception ex) + { MessageBox.Show("无法调用ClassIsland点名:" + ex.Message); - + // 调用失败时回退到默认的随机点名窗口 new RandWindow(Settings, true).ShowDialog(); } - } else { + } + else + { // 使用默认的随机点名窗口 new RandWindow(Settings, true).ShowDialog(); } } - private void GridInkReplayButton_MouseUp(object sender, MouseButtonEventArgs e) { + private void GridInkReplayButton_MouseUp(object sender, MouseButtonEventArgs e) + { //if (lastBorderMouseDownObject != sender) return; AnimationsHelper.HideWithSlideAndFade(BorderTools); @@ -876,14 +952,18 @@ namespace Ink_Canvas { var strokes = inkCanvas.Strokes.Clone(); if (inkCanvas.GetSelectedStrokes().Count != 0) strokes = inkCanvas.GetSelectedStrokes().Clone(); int k = 1, i = 0; - new Thread(() => { + new Thread(() => + { isRestartInkReplay = true; - while (isRestartInkReplay) { + while (isRestartInkReplay) + { isRestartInkReplay = false; - Application.Current.Dispatcher.Invoke(() => { + Application.Current.Dispatcher.Invoke(() => + { InkCanvasForInkReplay.Strokes.Clear(); }); - foreach (var stroke in strokes) { + foreach (var stroke in strokes) + { if (isRestartInkReplay) break; @@ -891,22 +971,27 @@ namespace Ink_Canvas { if (stroke.StylusPoints.Count == 629) //圆或椭圆 { Stroke s = null; - foreach (var stylusPoint in stroke.StylusPoints) { + foreach (var stylusPoint in stroke.StylusPoints) + { if (isRestartInkReplay) break; - while (isPauseInkReplay) { + while (isPauseInkReplay) + { Thread.Sleep(10); } - if (i++ >= 50) { + if (i++ >= 50) + { i = 0; Thread.Sleep((int)(10 / inkReplaySpeed)); if (isStopInkReplay) return; } - Application.Current.Dispatcher.Invoke(() => { - try { + Application.Current.Dispatcher.Invoke(() => + { + try + { InkCanvasForInkReplay.Strokes.Remove(s); } catch { } @@ -917,24 +1002,31 @@ namespace Ink_Canvas { InkCanvasForInkReplay.Strokes.Add(s); }); } - } else { + } + else + { Stroke s = null; - foreach (var stylusPoint in stroke.StylusPoints) { + foreach (var stylusPoint in stroke.StylusPoints) + { if (isRestartInkReplay) break; - while (isPauseInkReplay) { + while (isPauseInkReplay) + { Thread.Sleep(10); } - if (i++ >= k) { + if (i++ >= k) + { i = 0; Thread.Sleep((int)(10 / inkReplaySpeed)); if (isStopInkReplay) return; } - Application.Current.Dispatcher.Invoke(() => { - try { + Application.Current.Dispatcher.Invoke(() => + { + try + { InkCanvasForInkReplay.Strokes.Remove(s); } catch { } @@ -950,7 +1042,8 @@ namespace Ink_Canvas { } Thread.Sleep(100); - Application.Current.Dispatcher.Invoke(() => { + Application.Current.Dispatcher.Invoke(() => + { InkCanvasForInkReplay.Visibility = Visibility.Collapsed; InkCanvasGridForInkReplay.Visibility = Visibility.Visible; InkCanvasGridForInkReplay.IsHitTestVisible = true; @@ -968,8 +1061,10 @@ namespace Ink_Canvas { private bool isRestartInkReplay; private double inkReplaySpeed = 1; - private void InkCanvasForInkReplay_MouseDown(object sender, MouseButtonEventArgs e) { - if (e.ClickCount == 2) { + private void InkCanvasForInkReplay_MouseDown(object sender, MouseButtonEventArgs e) + { + if (e.ClickCount == 2) + { InkCanvasForInkReplay.Visibility = Visibility.Collapsed; InkCanvasGridForInkReplay.Visibility = Visibility.Visible; InkCanvasGridForInkReplay.IsHitTestVisible = true; @@ -982,7 +1077,8 @@ namespace Ink_Canvas { } } - private void InkReplayPlayPauseBorder_OnMouseDown(object sender, MouseButtonEventArgs e) { + private void InkReplayPlayPauseBorder_OnMouseDown(object sender, MouseButtonEventArgs e) + { InkReplayPlayPauseBorder.Background = new SolidColorBrush(Color.FromArgb(34, 9, 9, 11)); } @@ -990,8 +1086,8 @@ namespace Ink_Canvas { { InkReplayPlayPauseBorder.Background = new SolidColorBrush(Colors.Transparent); isPauseInkReplay = !isPauseInkReplay; - InkReplayPanelStatusText.Text = isPauseInkReplay?"已暂停!":"正在重播墨迹..."; - InkReplayPlayButtonImage.Visibility = isPauseInkReplay ? Visibility.Visible: Visibility.Collapsed; + InkReplayPanelStatusText.Text = isPauseInkReplay ? "已暂停!" : "正在重播墨迹..."; + InkReplayPlayButtonImage.Visibility = isPauseInkReplay ? Visibility.Visible : Visibility.Collapsed; InkReplayPauseButtonImage.Visibility = !isPauseInkReplay ? Visibility.Visible : Visibility.Collapsed; } @@ -1044,13 +1140,15 @@ namespace Ink_Canvas { InkReplaySpeedTextBlock.Text = inkReplaySpeed + "x"; } - private void SymbolIconTools_MouseUp(object sender, MouseButtonEventArgs e) { + private void SymbolIconTools_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel) ((Panel)lastBorderMouseDownObject).Background = new SolidColorBrush(Colors.Transparent); if (sender == ToolsFloatingBarBtn && lastBorderMouseDownObject != ToolsFloatingBarBtn) return; - if (BorderTools.Visibility == Visibility.Visible) { + if (BorderTools.Visibility == Visibility.Visible) + { AnimationsHelper.HideWithSlideAndFade(EraserSizePanel); AnimationsHelper.HideWithSlideAndFade(BorderTools); AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); @@ -1064,7 +1162,8 @@ namespace Ink_Canvas { AnimationsHelper.HideWithSlideAndFade(TwoFingerGestureBorder); AnimationsHelper.HideWithSlideAndFade(BoardTwoFingerGestureBorder); } - else { + else + { AnimationsHelper.HideWithSlideAndFade(EraserSizePanel); AnimationsHelper.HideWithSlideAndFade(BorderTools); AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); @@ -1083,9 +1182,11 @@ namespace Ink_Canvas { private bool isViewboxFloatingBarMarginAnimationRunning; public async void ViewboxFloatingBarMarginAnimation(int MarginFromEdge, - bool PosXCaculatedWithTaskbarHeight = false) { + bool PosXCaculatedWithTaskbarHeight = false) + { if (MarginFromEdge == 60) MarginFromEdge = 55; - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { if (Topmost == false) MarginFromEdge = -60; else @@ -1094,7 +1195,8 @@ namespace Ink_Canvas { double dpiScaleX = 1, dpiScaleY = 1; var source = PresentationSource.FromVisual(this); - if (source != null) { + if (source != null) + { dpiScaleX = source.CompositionTarget.TransformToDevice.M11; dpiScaleY = source.CompositionTarget.TransformToDevice.M22; } @@ -1124,7 +1226,7 @@ namespace Ink_Canvas { // 如果任务栏高度为0(隐藏状态),则使用固定高度 if (toolbarHeight == 0) { - pos.Y = screenHeight - ViewboxFloatingBar.ActualHeight * ViewboxFloatingBarScaleTransform.ScaleY - + pos.Y = screenHeight - ViewboxFloatingBar.ActualHeight * ViewboxFloatingBarScaleTransform.ScaleY - 3 * ViewboxFloatingBarScaleTransform.ScaleY; LogHelper.WriteLogToFile($"任务栏隐藏,使用固定高度: {ViewboxFloatingBar.ActualHeight}"); } @@ -1135,17 +1237,22 @@ namespace Ink_Canvas { } } - if (MarginFromEdge != -60) { - if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) { - if (pointPPT.X != -1 || pointPPT.Y != -1) { + if (MarginFromEdge != -60) + { + if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) + { + if (pointPPT.X != -1 || pointPPT.Y != -1) + { if (Math.Abs(pointPPT.Y - pos.Y) > 50) pos = pointPPT; else pointPPT = pos; } } - else { - if (pointDesktop.X != -1 || pointDesktop.Y != -1) { + else + { + if (pointDesktop.X != -1 || pointDesktop.Y != -1) + { if (Math.Abs(pointDesktop.Y - pos.Y) > 50) pos = pointDesktop; else @@ -1154,7 +1261,8 @@ namespace Ink_Canvas { } } - var marginAnimation = new ThicknessAnimation { + var marginAnimation = new ThicknessAnimation + { Duration = TimeSpan.FromSeconds(0.35), From = ViewboxFloatingBar.Margin, To = new Thickness(pos.X, pos.Y, 0, -20) @@ -1165,7 +1273,8 @@ namespace Ink_Canvas { await Task.Delay(200); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { ViewboxFloatingBar.Margin = new Thickness(pos.X, pos.Y, -2000, -200); if (Topmost == false) ViewboxFloatingBar.Visibility = Visibility.Hidden; }); @@ -1173,7 +1282,8 @@ namespace Ink_Canvas { public async void PureViewboxFloatingBarMarginAnimationInDesktopMode() { - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { ViewboxFloatingBar.Visibility = Visibility.Visible; isViewboxFloatingBarMarginAnimationRunning = true; @@ -1195,7 +1305,7 @@ namespace Ink_Canvas { // 如果任务栏高度为0(隐藏状态),则使用固定边距 if (toolbarHeight == 0) { - pos.Y = screenHeight - ViewboxFloatingBar.ActualHeight * ViewboxFloatingBarScaleTransform.ScaleY - + pos.Y = screenHeight - ViewboxFloatingBar.ActualHeight * ViewboxFloatingBarScaleTransform.ScaleY - 3 * ViewboxFloatingBarScaleTransform.ScaleY; LogHelper.WriteLogToFile($"任务栏隐藏,使用固定高度: {ViewboxFloatingBar.ActualHeight}"); } @@ -1219,14 +1329,16 @@ namespace Ink_Canvas { await Task.Delay(349); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { ViewboxFloatingBar.Margin = new Thickness(pos.X, pos.Y, -2000, -200); }); } public async void PureViewboxFloatingBarMarginAnimationInPPTMode() { - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { ViewboxFloatingBar.Visibility = Visibility.Visible; isViewboxFloatingBarMarginAnimationRunning = true; @@ -1264,26 +1376,29 @@ namespace Ink_Canvas { await Task.Delay(349); - await Dispatcher.InvokeAsync(() => { + await Dispatcher.InvokeAsync(() => + { ViewboxFloatingBar.Margin = new Thickness(pos.X, pos.Y, -2000, -200); }); } - private async void CursorIcon_Click(object sender, RoutedEventArgs e) { + private async void CursorIcon_Click(object sender, RoutedEventArgs e) + { if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel) ((Panel)lastBorderMouseDownObject).Background = new SolidColorBrush(Colors.Transparent); - if (sender==Cursor_Icon && lastBorderMouseDownObject != Cursor_Icon) return; - + if (sender == Cursor_Icon && lastBorderMouseDownObject != Cursor_Icon) return; + // 禁用高级橡皮擦系统 DisableAdvancedEraserSystem(); - + // 隱藏高亮 FloatingbarSelectionBG.Visibility = Visibility.Hidden; System.Windows.Controls.Canvas.SetLeft(FloatingbarSelectionBG, 0); // 切换前自动截图保存墨迹 if (inkCanvas.Strokes.Count > 0 && - inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) { + inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) + { if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) { var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0; @@ -1293,25 +1408,33 @@ namespace Ink_Canvas { else SaveScreenShot(true); } - if (BtnPPTSlideShowEnd.Visibility != Visibility.Visible) { - if (Settings.Canvas.HideStrokeWhenSelecting) { + if (BtnPPTSlideShowEnd.Visibility != Visibility.Visible) + { + if (Settings.Canvas.HideStrokeWhenSelecting) + { inkCanvas.Visibility = Visibility.Collapsed; } - else { + else + { inkCanvas.IsHitTestVisible = false; inkCanvas.Visibility = Visibility.Visible; } } - else { - if (Settings.PowerPointSettings.IsShowStrokeOnSelectInPowerPoint) { + else + { + if (Settings.PowerPointSettings.IsShowStrokeOnSelectInPowerPoint) + { inkCanvas.Visibility = Visibility.Visible; inkCanvas.IsHitTestVisible = true; } - else { - if (Settings.Canvas.HideStrokeWhenSelecting) { + else + { + if (Settings.Canvas.HideStrokeWhenSelecting) + { inkCanvas.Visibility = Visibility.Collapsed; } - else { + else + { inkCanvas.IsHitTestVisible = false; inkCanvas.Visibility = Visibility.Visible; } @@ -1325,7 +1448,8 @@ namespace Ink_Canvas { inkCanvas.Select(new StrokeCollection()); GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; - if (currentMode != 0) { + if (currentMode != 0) + { SaveStrokes(); // 总是恢复备份墨迹,不管是否在PPT模式 // PPT墨迹和白板墨迹应该分别管理,不应该互相影响 @@ -1345,7 +1469,8 @@ namespace Ink_Canvas { StackPanelCanvasControls.Visibility = Visibility.Collapsed; - if (!isFloatingBarFolded) { + if (!isFloatingBarFolded) + { HideSubPanels("cursor", true); await Task.Delay(50); @@ -1356,7 +1481,8 @@ namespace Ink_Canvas { } } - private void PenIcon_Click(object sender, RoutedEventArgs e) { + private void PenIcon_Click(object sender, RoutedEventArgs e) + { if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel) ((Panel)lastBorderMouseDownObject).Background = new SolidColorBrush(Colors.Transparent); @@ -1376,7 +1502,8 @@ namespace Ink_Canvas { bool wasInInkMode = inkCanvas.EditingMode == InkCanvasEditingMode.Ink; bool wasHighlighter = drawingAttributes.IsHighlighter; - if (Pen_Icon.Background == null || StackPanelCanvasControls.Visibility == Visibility.Collapsed) { + if (Pen_Icon.Background == null || StackPanelCanvasControls.Visibility == Visibility.Collapsed) + { inkCanvas.EditingMode = InkCanvasEditingMode.Ink; GridTransparencyFakeBackground.Opacity = 1; @@ -1391,14 +1518,16 @@ namespace Ink_Canvas { /*if (forceEraser && currentMode == 0) BtnColorRed_Click(sender, null);*/ - if (GridBackgroundCover.Visibility == Visibility.Collapsed) { + if (GridBackgroundCover.Visibility == Visibility.Collapsed) + { if (BtnSwitchTheme.Content.ToString() == "浅色") BtnSwitch.Content = "黑板"; else BtnSwitch.Content = "白板"; StackPanelPPTButtons.Visibility = Visibility.Visible; } - else { + else + { BtnSwitch.Content = "屏幕"; StackPanelPPTButtons.Visibility = Visibility.Collapsed; } @@ -1421,10 +1550,13 @@ namespace Ink_Canvas { ColorSwitchCheck(); HideSubPanels("pen", true); } - else { - if (wasInInkMode) { + else + { + if (wasInInkMode) + { // 修复:从线擦切换到批注时,确保正确重置状态 - if (forceEraser) { + if (forceEraser) + { // 从橡皮擦模式切换过来,重置为默认笔模式 forceEraser = false; forcePointEraser = false; @@ -1434,13 +1566,15 @@ namespace Ink_Canvas { drawingAttributes.StylusTip = StylusTip.Ellipse; // 在非白板模式下,从线擦切换到批注时不直接弹出子面板 - if (currentMode != 1) { + if (currentMode != 1) + { HideSubPanels("pen", true); return; } } - if (PenPalette.Visibility == Visibility.Visible) { + if (PenPalette.Visibility == Visibility.Visible) + { AnimationsHelper.HideWithSlideAndFade(EraserSizePanel); AnimationsHelper.HideWithSlideAndFade(BorderTools); AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); @@ -1454,7 +1588,8 @@ namespace Ink_Canvas { AnimationsHelper.HideWithSlideAndFade(TwoFingerGestureBorder); AnimationsHelper.HideWithSlideAndFade(BoardTwoFingerGestureBorder); } - else { + else + { AnimationsHelper.HideWithSlideAndFade(EraserSizePanel); AnimationsHelper.HideWithSlideAndFade(BorderTools); AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); @@ -1469,9 +1604,11 @@ namespace Ink_Canvas { AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardPenPalette); } } - else { + else + { // 切换到批注模式时,确保保存当前图片信息 - if (currentMode != 0) { + if (currentMode != 0) + { SaveStrokes(); } inkCanvas.EditingMode = InkCanvasEditingMode.Ink; @@ -1490,13 +1627,15 @@ namespace Ink_Canvas { } } - private void ColorThemeSwitch_MouseUp(object sender, RoutedEventArgs e) { + private void ColorThemeSwitch_MouseUp(object sender, RoutedEventArgs e) + { isUselightThemeColor = !isUselightThemeColor; if (currentMode == 0) isDesktopUselightThemeColor = isUselightThemeColor; CheckColorTheme(); } - private void EraserIcon_Click(object sender, RoutedEventArgs e) { + private void EraserIcon_Click(object sender, RoutedEventArgs e) + { EnterMultiTouchModeIfNeeded(); bool isAlreadyEraser = inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint; forceEraser = false; @@ -1504,7 +1643,8 @@ namespace Ink_Canvas { drawingShapeMode = 0; // 切换到橡皮擦模式时,确保保存当前图片信息 - if (!isAlreadyEraser && currentMode != 0) { + if (!isAlreadyEraser && currentMode != 0) + { SaveStrokes(); } @@ -1521,13 +1661,17 @@ namespace Ink_Canvas { // 注意:eraserVisualBorder在MW_Eraser.cs中定义,这里无法直接访问 Trace.WriteLine($"Advanced Eraser: Eraser button clicked, current size: {currentEraserSize}, circle: {isCurrentEraserCircle}"); - if (isAlreadyEraser) { + if (isAlreadyEraser) + { // 已是橡皮状态,再次点击才弹出/收起面板 - if (EraserSizePanel.Visibility == Visibility.Collapsed) { + if (EraserSizePanel.Visibility == Visibility.Collapsed) + { AnimationsHelper.ShowWithSlideFromBottomAndFade(EraserSizePanel); if (BoardEraserSizePanel != null) AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardEraserSizePanel); - } else { + } + else + { AnimationsHelper.HideWithSlideAndFade(EraserSizePanel); if (BoardEraserSizePanel != null) AnimationsHelper.HideWithSlideAndFade(BoardEraserSizePanel); @@ -1535,7 +1679,8 @@ namespace Ink_Canvas { } } - private void BoardEraserIcon_Click(object sender, RoutedEventArgs e) { + private void BoardEraserIcon_Click(object sender, RoutedEventArgs e) + { EnterMultiTouchModeIfNeeded(); bool isAlreadyEraser = inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint; forceEraser = false; @@ -1544,19 +1689,23 @@ namespace Ink_Canvas { // 启用新的高级橡皮擦系统 EnableAdvancedEraserSystem(); - + // 使用新的高级橡皮擦系统 inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint; ApplyAdvancedEraserShape(); // 使用新的橡皮擦形状应用方法 SetCursorBasedOnEditingMode(inkCanvas); HideSubPanels("eraser"); // 高亮橡皮按钮 - if (isAlreadyEraser) { + if (isAlreadyEraser) + { // 已是橡皮状态,再次点击才弹出/收起面板 - if (BoardEraserSizePanel != null && BoardEraserSizePanel.Visibility == Visibility.Collapsed) { + if (BoardEraserSizePanel != null && BoardEraserSizePanel.Visibility == Visibility.Collapsed) + { AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardEraserSizePanel); AnimationsHelper.ShowWithSlideFromBottomAndFade(EraserSizePanel); - } else { + } + else + { if (BoardEraserSizePanel != null) AnimationsHelper.HideWithSlideAndFade(BoardEraserSizePanel); AnimationsHelper.HideWithSlideAndFade(EraserSizePanel); @@ -1564,7 +1713,8 @@ namespace Ink_Canvas { } } - private void EraserIconByStrokes_Click(object sender, RoutedEventArgs e) { + private void EraserIconByStrokes_Click(object sender, RoutedEventArgs e) + { EnterMultiTouchModeIfNeeded(); if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel) @@ -1595,7 +1745,8 @@ namespace Ink_Canvas { HideSubPanels("eraserByStrokes"); } - private void CursorWithDelIcon_Click(object sender, RoutedEventArgs e) { + private void CursorWithDelIcon_Click(object sender, RoutedEventArgs e) + { if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel) ((Panel)lastBorderMouseDownObject).Background = new SolidColorBrush(Colors.Transparent); @@ -1605,31 +1756,37 @@ namespace Ink_Canvas { CursorIcon_Click(null, null); } - private void SelectIcon_MouseUp(object sender, RoutedEvent e) { + private void SelectIcon_MouseUp(object sender, RoutedEvent e) + { // 禁用高级橡皮擦系统 DisableAdvancedEraserSystem(); - + forceEraser = true; drawingShapeMode = 0; inkCanvas.IsManipulationEnabled = false; - if (inkCanvas.EditingMode == InkCanvasEditingMode.Select) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.Select) + { var selectedStrokes = new StrokeCollection(); foreach (var stroke in inkCanvas.Strokes) if (stroke.GetBounds().Width > 0 && stroke.GetBounds().Height > 0) selectedStrokes.Add(stroke); inkCanvas.Select(selectedStrokes); } - else { + else + { inkCanvas.EditingMode = InkCanvasEditingMode.Select; } } - private void DrawShapePromptToPen() { - if (isLongPressSelected) { + private void DrawShapePromptToPen() + { + if (isLongPressSelected) + { // 如果是长按选中的状态,只隐藏面板,不切换到笔模式 HideSubPanels("shape"); } - else { + else + { if (StackPanelCanvasControls.Visibility == Visibility.Visible) HideSubPanels("pen"); else @@ -1637,25 +1794,31 @@ namespace Ink_Canvas { } } - private void CloseBordertools_MouseUp(object sender, MouseButtonEventArgs e) { + private void CloseBordertools_MouseUp(object sender, MouseButtonEventArgs e) + { HideSubPanels(); } #region Left Side Panel - private void BtnFingerDragMode_Click(object sender, RoutedEventArgs e) { - if (isSingleFingerDragMode) { + private void BtnFingerDragMode_Click(object sender, RoutedEventArgs e) + { + if (isSingleFingerDragMode) + { isSingleFingerDragMode = false; BtnFingerDragMode.Content = "单指\n拖动"; } - else { + else + { isSingleFingerDragMode = true; BtnFingerDragMode.Content = "多指\n拖动"; } } - private void BtnUndo_Click(object sender, RoutedEventArgs e) { - if (inkCanvas.GetSelectedStrokes().Count != 0) { + private void BtnUndo_Click(object sender, RoutedEventArgs e) + { + if (inkCanvas.GetSelectedStrokes().Count != 0) + { GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; inkCanvas.Select(new StrokeCollection()); } @@ -1664,8 +1827,10 @@ namespace Ink_Canvas { ApplyHistoryToCanvas(item); } - private void BtnRedo_Click(object sender, RoutedEventArgs e) { - if (inkCanvas.GetSelectedStrokes().Count != 0) { + private void BtnRedo_Click(object sender, RoutedEventArgs e) + { + if (inkCanvas.GetSelectedStrokes().Count != 0) + { GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; inkCanvas.Select(new StrokeCollection()); } @@ -1674,9 +1839,11 @@ namespace Ink_Canvas { ApplyHistoryToCanvas(item); } - private void Btn_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e) { + private void Btn_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e) + { if (!isLoaded) return; - try { + try + { if (((Button)sender).IsEnabled) ((UIElement)((Button)sender).Content).Opacity = 1; else @@ -1691,25 +1858,28 @@ namespace Ink_Canvas { public static bool CloseIsFromButton; - public void BtnExit_Click(object sender, RoutedEventArgs e) { + public void BtnExit_Click(object sender, RoutedEventArgs e) + { App.IsAppExitByUser = true; // 不设置 CloseIsFromButton = true,让它也经过确认流程 Close(); } - public void BtnRestart_Click(object sender, RoutedEventArgs e) { + public void BtnRestart_Click(object sender, RoutedEventArgs e) + { Process.Start(System.Windows.Forms.Application.ExecutablePath, "-m"); App.IsAppExitByUser = true; // 不设置 CloseIsFromButton = true,让它也经过确认流程 Close(); } - private void SettingsOverlayClick(object sender, MouseButtonEventArgs e) { + private void SettingsOverlayClick(object sender, MouseButtonEventArgs e) + { if (isOpeningOrHidingSettingsPane) return; - + // 获取点击的位置 Point clickPoint = e.GetPosition(BorderSettingsMask); - + // 获取BorderSettings的位置和大小 Point settingsPosition = BorderSettings.TranslatePoint(new Point(0, 0), BorderSettingsMask); Rect settingsRect = new Rect( @@ -1718,20 +1888,24 @@ namespace Ink_Canvas { BorderSettings.ActualWidth, BorderSettings.ActualHeight ); - + // 如果点击位置不在设置界面内部,才关闭设置界面 - if (!settingsRect.Contains(clickPoint)) { + if (!settingsRect.Contains(clickPoint)) + { BtnSettings_Click(null, null); } } private bool isOpeningOrHidingSettingsPane; - private void BtnSettings_Click(object sender, RoutedEventArgs e) { - if (BorderSettings.Visibility == Visibility.Visible) { + private void BtnSettings_Click(object sender, RoutedEventArgs e) + { + if (BorderSettings.Visibility == Visibility.Visible) + { HideSubPanels(); } - else { + else + { // 设置蒙版为可点击,并添加半透明背景 BorderSettingsMask.IsHitTestVisible = true; BorderSettingsMask.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0)); @@ -1739,7 +1913,8 @@ namespace Ink_Canvas { var sb = new Storyboard(); // 滑动动画 - var slideAnimation = new DoubleAnimation { + var slideAnimation = new DoubleAnimation + { From = BorderSettings.RenderTransform.Value.OffsetX - 440, // 滑动距离 To = 0, Duration = TimeSpan.FromSeconds(0.6) @@ -1765,20 +1940,24 @@ namespace Ink_Canvas { private bool forceEraser; - private void BtnClear_Click(object sender, RoutedEventArgs e) { + private void BtnClear_Click(object sender, RoutedEventArgs e) + { forceEraser = false; //BorderClearInDelete.Visibility = Visibility.Collapsed; - if (currentMode == 0) { + if (currentMode == 0) + { // 先回到画笔再清屏,避免 TimeMachine 的相关 bug 影响 if (Pen_Icon.Background == null && StackPanelCanvasControls.Visibility == Visibility.Visible) PenIcon_Click(null, null); } - else { + else + { if (Pen_Icon.Background == null) PenIcon_Click(null, null); } - if (inkCanvas.Strokes.Count != 0) { + if (inkCanvas.Strokes.Count != 0) + { var whiteboardIndex = CurrentWhiteboardIndex; if (currentMode == 0) whiteboardIndex = 0; strokeCollections[whiteboardIndex] = inkCanvas.Strokes.Clone(); @@ -1798,7 +1977,8 @@ namespace Ink_Canvas { private bool lastIsInMultiTouchMode; - private void CancelSingleFingerDragMode() { + private void CancelSingleFingerDragMode() + { if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape(); GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; @@ -1807,7 +1987,8 @@ namespace Ink_Canvas { isLongPressSelected = false; } - private void BtnHideControl_Click(object sender, RoutedEventArgs e) { + private void BtnHideControl_Click(object sender, RoutedEventArgs e) + { if (StackPanelControl.Visibility == Visibility.Visible) StackPanelControl.Visibility = Visibility.Hidden; else @@ -1816,33 +1997,40 @@ namespace Ink_Canvas { private int currentMode; - private void BtnSwitch_Click(object sender, RoutedEventArgs e) { - if (GridTransparencyFakeBackground.Background == Brushes.Transparent) { - if (currentMode == 0) { + private void BtnSwitch_Click(object sender, RoutedEventArgs e) + { + if (GridTransparencyFakeBackground.Background == Brushes.Transparent) + { + if (currentMode == 0) + { currentMode++; GridBackgroundCover.Visibility = Visibility.Collapsed; AnimationsHelper.HideWithSlideAndFade(BlackboardLeftSide); AnimationsHelper.HideWithSlideAndFade(BlackboardCenterSide); AnimationsHelper.HideWithSlideAndFade(BlackboardRightSide); - + DeselectUIElement(); SaveStrokes(true); ClearStrokes(true); RestoreStrokes(true); - - if (BtnSwitchTheme.Content.ToString() == "浅色") { + + if (BtnSwitchTheme.Content.ToString() == "浅色") + { BtnSwitch.Content = "黑板"; BtnExit.Foreground = Brushes.White; } - else { + else + { BtnSwitch.Content = "白板"; - if (isPresentationHaveBlackSpace) { + if (isPresentationHaveBlackSpace) + { BtnExit.Foreground = Brushes.White; ThemeManager.Current.ApplicationTheme = ApplicationTheme.Dark; } - else { + else + { BtnExit.Foreground = Brushes.Black; ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light; } @@ -1854,8 +2042,10 @@ namespace Ink_Canvas { Topmost = true; BtnHideInkCanvas_Click(BtnHideInkCanvas, e); } - else { - switch (++currentMode % 2) { + else + { + switch (++currentMode % 2) + { case 0: //屏幕模式 currentMode = 0; GridBackgroundCover.Visibility = Visibility.Collapsed; @@ -1870,18 +2060,22 @@ namespace Ink_Canvas { ClearStrokes(true); RestoreStrokes(true); - if (BtnSwitchTheme.Content.ToString() == "浅色") { + if (BtnSwitchTheme.Content.ToString() == "浅色") + { BtnSwitch.Content = "黑板"; BtnExit.Foreground = Brushes.White; ThemeManager.Current.ApplicationTheme = ApplicationTheme.Dark; } - else { + else + { BtnSwitch.Content = "白板"; - if (isPresentationHaveBlackSpace) { + if (isPresentationHaveBlackSpace) + { BtnExit.Foreground = Brushes.White; ThemeManager.Current.ApplicationTheme = ApplicationTheme.Dark; } - else { + else + { BtnExit.Foreground = Brushes.Black; ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light; } @@ -1908,11 +2102,13 @@ namespace Ink_Canvas { RestoreStrokes(); BtnSwitch.Content = "屏幕"; - if (BtnSwitchTheme.Content.ToString() == "浅色") { + if (BtnSwitchTheme.Content.ToString() == "浅色") + { BtnExit.Foreground = Brushes.White; ThemeManager.Current.ApplicationTheme = ApplicationTheme.Dark; } - else { + else + { BtnExit.Foreground = Brushes.Black; ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light; } @@ -1946,8 +2142,10 @@ namespace Ink_Canvas { private int BoundsWidth = 5; - private void BtnHideInkCanvas_Click(object sender, RoutedEventArgs e) { - if (GridTransparencyFakeBackground.Background == Brushes.Transparent) { + private void BtnHideInkCanvas_Click(object sender, RoutedEventArgs e) + { + if (GridTransparencyFakeBackground.Background == Brushes.Transparent) + { GridTransparencyFakeBackground.Opacity = 1; GridTransparencyFakeBackground.Background = new SolidColorBrush(StringToColor("#01FFFFFF")); inkCanvas.IsHitTestVisible = true; @@ -1957,25 +2155,30 @@ namespace Ink_Canvas { GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; - if (GridBackgroundCover.Visibility == Visibility.Collapsed) { + if (GridBackgroundCover.Visibility == Visibility.Collapsed) + { if (BtnSwitchTheme.Content.ToString() == "浅色") BtnSwitch.Content = "黑板"; else BtnSwitch.Content = "白板"; StackPanelPPTButtons.Visibility = Visibility.Visible; } - else { + else + { BtnSwitch.Content = "屏幕"; StackPanelPPTButtons.Visibility = Visibility.Collapsed; } BtnHideInkCanvas.Content = "隐藏\n画板"; } - else { + else + { // Auto-clear Strokes 要等待截图完成再清理笔记 - if (BtnPPTSlideShowEnd.Visibility != Visibility.Visible) { + if (BtnPPTSlideShowEnd.Visibility != Visibility.Visible) + { if (isLoaded && Settings.Automation.IsAutoClearWhenExitingWritingMode) - if (inkCanvas.Strokes.Count > 0) { + if (inkCanvas.Strokes.Count > 0) + { if (Settings.Automation.IsAutoSaveStrokesAtClear && inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) SaveScreenShot(true); @@ -1986,10 +2189,12 @@ namespace Ink_Canvas { inkCanvas.IsHitTestVisible = true; inkCanvas.Visibility = Visibility.Visible; } - else { + else + { if (isLoaded && Settings.Automation.IsAutoClearWhenExitingWritingMode && !Settings.PowerPointSettings.IsNoClearStrokeOnSelectWhenInPowerPoint) - if (inkCanvas.Strokes.Count > 0) { + if (inkCanvas.Strokes.Count > 0) + { if (Settings.Automation.IsAutoSaveStrokesAtClear && inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) SaveScreenShot(true); @@ -1998,11 +2203,13 @@ namespace Ink_Canvas { } - if (Settings.PowerPointSettings.IsShowStrokeOnSelectInPowerPoint) { + if (Settings.PowerPointSettings.IsShowStrokeOnSelectInPowerPoint) + { inkCanvas.Visibility = Visibility.Visible; inkCanvas.IsHitTestVisible = true; } - else { + else + { inkCanvas.IsHitTestVisible = true; inkCanvas.Visibility = Visibility.Visible; } @@ -2013,7 +2220,8 @@ namespace Ink_Canvas { GridBackgroundCoverHolder.Visibility = Visibility.Collapsed; - if (currentMode != 0) { + if (currentMode != 0) + { SaveStrokes(); RestoreStrokes(true); } @@ -2027,29 +2235,35 @@ namespace Ink_Canvas { BtnHideInkCanvas.Content = "显示\n画板"; } - if (GridTransparencyFakeBackground.Background == Brushes.Transparent) { + if (GridTransparencyFakeBackground.Background == Brushes.Transparent) + { StackPanelCanvasControls.Visibility = Visibility.Collapsed; CheckEnableTwoFingerGestureBtnVisibility(false); HideSubPanels("cursor"); } - else { + else + { AnimationsHelper.ShowWithSlideFromLeftAndFade(StackPanelCanvasControls); CheckEnableTwoFingerGestureBtnVisibility(true); } } - private void BtnSwitchSide_Click(object sender, RoutedEventArgs e) { - if (ViewBoxStackPanelMain.HorizontalAlignment == HorizontalAlignment.Right) { + private void BtnSwitchSide_Click(object sender, RoutedEventArgs e) + { + if (ViewBoxStackPanelMain.HorizontalAlignment == HorizontalAlignment.Right) + { ViewBoxStackPanelMain.HorizontalAlignment = HorizontalAlignment.Left; ViewBoxStackPanelShapes.HorizontalAlignment = HorizontalAlignment.Right; } - else { + else + { ViewBoxStackPanelMain.HorizontalAlignment = HorizontalAlignment.Right; ViewBoxStackPanelShapes.HorizontalAlignment = HorizontalAlignment.Left; } } - private void StackPanel_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) { + private void StackPanel_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) + { if (((StackPanel)sender).Visibility == Visibility.Visible) GridForLeftSideReservedSpace.Visibility = Visibility.Collapsed; else diff --git a/Ink Canvas/MainWindow_cs/MW_Hotkeys.cs b/Ink Canvas/MainWindow_cs/MW_Hotkeys.cs index 5f7660bb..594d3a21 100644 --- a/Ink Canvas/MainWindow_cs/MW_Hotkeys.cs +++ b/Ink Canvas/MainWindow_cs/MW_Hotkeys.cs @@ -1,16 +1,20 @@ using System.Windows; using System.Windows.Input; -namespace Ink_Canvas { - public partial class MainWindow : Window { - private void Window_MouseWheel(object sender, MouseWheelEventArgs e) { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { + private void Window_MouseWheel(object sender, MouseWheelEventArgs e) + { if (StackPanelPPTControls.Visibility != Visibility.Visible || currentMode != 0) return; if (e.Delta >= 120) BtnPPTSlidesUp_Click(BtnPPTSlidesUp, null); else if (e.Delta <= -120) BtnPPTSlidesDown_Click(BtnPPTSlidesDown, null); } - private void Main_Grid_PreviewKeyDown(object sender, KeyEventArgs e) { + private void Main_Grid_PreviewKeyDown(object sender, KeyEventArgs e) + { if (StackPanelPPTControls.Visibility != Visibility.Visible || currentMode != 0) return; if (e.Key == Key.Down || e.Key == Key.PageDown || e.Key == Key.Right || e.Key == Key.N || @@ -19,53 +23,66 @@ namespace Ink_Canvas { BtnPPTSlidesUp_Click(BtnPPTSlidesUp, null); } - private void Window_KeyDown(object sender, KeyEventArgs e) { + private void Window_KeyDown(object sender, KeyEventArgs e) + { if (e.Key == Key.Escape) KeyExit(null, null); } - private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) { + private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) + { e.CanExecute = true; } - private void HotKey_Undo(object sender, ExecutedRoutedEventArgs e) { - try { + private void HotKey_Undo(object sender, ExecutedRoutedEventArgs e) + { + try + { SymbolIconUndo_MouseUp(lastBorderMouseDownObject, null); } catch { } } - private void HotKey_Redo(object sender, ExecutedRoutedEventArgs e) { - try { + private void HotKey_Redo(object sender, ExecutedRoutedEventArgs e) + { + try + { SymbolIconRedo_MouseUp(lastBorderMouseDownObject, null); } catch { } } - private void HotKey_Clear(object sender, ExecutedRoutedEventArgs e) { + private void HotKey_Clear(object sender, ExecutedRoutedEventArgs e) + { SymbolIconDelete_MouseUp(lastBorderMouseDownObject, null); } - private void KeyExit(object sender, ExecutedRoutedEventArgs e) { + private void KeyExit(object sender, ExecutedRoutedEventArgs e) + { if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) BtnPPTSlideShowEnd_Click(BtnPPTSlideShowEnd, null); } - private void KeyChangeToDrawTool(object sender, ExecutedRoutedEventArgs e) { + private void KeyChangeToDrawTool(object sender, ExecutedRoutedEventArgs e) + { PenIcon_Click(lastBorderMouseDownObject, null); } - private void KeyChangeToQuitDrawTool(object sender, ExecutedRoutedEventArgs e) { + private void KeyChangeToQuitDrawTool(object sender, ExecutedRoutedEventArgs e) + { if (currentMode != 0) ImageBlackboard_MouseUp(lastBorderMouseDownObject, null); CursorIcon_Click(lastBorderMouseDownObject, null); } - private void KeyChangeToSelect(object sender, ExecutedRoutedEventArgs e) { + private void KeyChangeToSelect(object sender, ExecutedRoutedEventArgs e) + { if (StackPanelCanvasControls.Visibility == Visibility.Visible) SymbolIconSelect_MouseUp(lastBorderMouseDownObject, null); } - private void KeyChangeToEraser(object sender, ExecutedRoutedEventArgs e) { - if (StackPanelCanvasControls.Visibility == Visibility.Visible) { + private void KeyChangeToEraser(object sender, ExecutedRoutedEventArgs e) + { + if (StackPanelCanvasControls.Visibility == Visibility.Visible) + { if (Eraser_Icon.Background != null) EraserIconByStrokes_Click(lastBorderMouseDownObject, null); else @@ -73,19 +90,23 @@ namespace Ink_Canvas { } } - private void KeyChangeToBoard(object sender, ExecutedRoutedEventArgs e) { + private void KeyChangeToBoard(object sender, ExecutedRoutedEventArgs e) + { ImageBlackboard_MouseUp(lastBorderMouseDownObject, null); } - private void KeyCapture(object sender, ExecutedRoutedEventArgs e) { + private void KeyCapture(object sender, ExecutedRoutedEventArgs e) + { SaveScreenShotToDesktop(); } - private void KeyDrawLine(object sender, ExecutedRoutedEventArgs e) { + private void KeyDrawLine(object sender, ExecutedRoutedEventArgs e) + { if (StackPanelCanvasControls.Visibility == Visibility.Visible) BtnDrawLine_Click(lastMouseDownSender, null); } - private void KeyHide(object sender, ExecutedRoutedEventArgs e) { + private void KeyHide(object sender, ExecutedRoutedEventArgs e) + { SymbolIconEmoji_MouseUp(null, null); } } diff --git a/Ink Canvas/MainWindow_cs/MW_Icons.cs b/Ink Canvas/MainWindow_cs/MW_Icons.cs index 71cb076d..72ccca77 100644 --- a/Ink Canvas/MainWindow_cs/MW_Icons.cs +++ b/Ink Canvas/MainWindow_cs/MW_Icons.cs @@ -1,5 +1,7 @@ -namespace Ink_Canvas { - public static class XamlGraphicsIconGeometries { +namespace Ink_Canvas +{ + public static class XamlGraphicsIconGeometries + { public static string LinedCursorIcon = "F1 M24,24z M0,0z M5.72106,15.9716L3.71327,3.00395C3.6389,2.6693 3.65747,2.41831 3.76902,2.25099 3.88057,2.08366 4.0479,2 4.271,2 4.4941,2 4.71711,2.07437 4.94021,2.2231 6.72502,3.39438 9.28149,5.10481 12.6094,7.3544 15.677,9.45526 18.1125,11.1285 19.9159,12.3742 20.1204,12.5229 20.2505,12.6995 20.3062,12.904 20.362,13.1085 20.3249,13.2944 20.1947,13.4618 20.0832,13.6105 19.8973,13.6849 19.637,13.6849L13.3902,13.6849 17.6291,19.7365C17.722,19.8666 17.75,20.0153 17.7128,20.1827 17.6942,20.3314 17.6198,20.4522 17.4897,20.5452L15.5654,21.8838C15.4353,21.9768 15.2865,22.0139 15.1192,21.9953 14.9704,21.9582 14.8496,21.8745 14.7566,21.7444L10.2389,15.2745 7.58956,19.9038C7.45942,20.1269 7.30144,20.2756 7.11552,20.35 6.92961,20.4058 6.75292,20.3872 6.5856,20.2942 6.43686,20.2013 6.34392,20.0339 6.30673,19.7922L6.00007,17.8959C5.88852,17.0779,5.79543,16.4364,5.72106,15.9716z"; diff --git a/Ink Canvas/MainWindow_cs/MW_Notification.cs b/Ink Canvas/MainWindow_cs/MW_Notification.cs index aa375b82..e1e69945 100644 --- a/Ink Canvas/MainWindow_cs/MW_Notification.cs +++ b/Ink Canvas/MainWindow_cs/MW_Notification.cs @@ -1,30 +1,37 @@ -using System; +using Ink_Canvas.Helpers; +using System; using System.Linq; using System.Threading; using System.Windows; -using Ink_Canvas.Helpers; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { private int lastNotificationShowTime; private int notificationShowTime = 2500; - public static void ShowNewMessage(string notice, bool isShowImmediately = true) { + public static void ShowNewMessage(string notice, bool isShowImmediately = true) + { (Application.Current?.Windows.Cast().FirstOrDefault(window => window is MainWindow) as MainWindow) ?.ShowNotification(notice, isShowImmediately); } - public void ShowNotification(string notice, bool isShowImmediately = true) { - try { + public void ShowNotification(string notice, bool isShowImmediately = true) + { + try + { lastNotificationShowTime = Environment.TickCount; TextBlockNotice.Text = notice; AnimationsHelper.ShowWithSlideFromBottomAndFade(GridNotifications); - new Thread(() => { + new Thread(() => + { Thread.Sleep(notificationShowTime + 300); if (Environment.TickCount - lastNotificationShowTime >= notificationShowTime) - Application.Current.Dispatcher.Invoke(() => { + Application.Current.Dispatcher.Invoke(() => + { AnimationsHelper.HideWithSlideAndFade(GridNotifications); }); }).Start(); diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs index 85e658aa..452f3f8b 100644 --- a/Ink Canvas/MainWindow_cs/MW_PPT.cs +++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs @@ -1,4 +1,8 @@ -using System; +using Ink_Canvas.Helpers; +using iNKORE.UI.WPF.Modern; +using Microsoft.Office.Core; +using Microsoft.Office.Interop.PowerPoint; +using System; using System.IO; using System.Runtime.InteropServices; using System.Security.Cryptography; @@ -6,22 +10,17 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; -using System.Windows.Ink; -using System.Windows.Input; using System.Windows.Media; -using System.Windows.Threading; -using Ink_Canvas.Helpers; -using iNKORE.UI.WPF.Modern; -using Microsoft.Office.Core; -using Microsoft.Office.Interop.PowerPoint; using Application = System.Windows.Application; using File = System.IO.File; using MessageBox = System.Windows.MessageBox; using MouseButtonEventArgs = System.Windows.Input.MouseButtonEventArgs; using MouseEventArgs = System.Windows.Input.MouseEventArgs; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { #region Win32 API Declarations [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); @@ -627,8 +626,10 @@ namespace Ink_Canvas { } #endregion - private void BtnCheckPPT_Click(object sender, RoutedEventArgs e) { - try { + private void BtnCheckPPT_Click(object sender, RoutedEventArgs e) + { + try + { // 使用新的PPT管理器进行连接检查 if (_pptManager == null) { @@ -655,14 +656,16 @@ namespace Ink_Canvas { }); }); } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"手动检查PPT应用程序失败: {ex}", LogHelper.LogType.Error); _pptUIManager?.UpdateConnectionStatus(false); MessageBox.Show("未找到幻灯片"); } } - private void ToggleSwitchSupportWPS_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchSupportWPS_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.IsSupportWPS = ToggleSwitchSupportWPS.IsOn; @@ -699,8 +702,10 @@ namespace Ink_Canvas { - private void BtnPPTSlidesUp_Click(object sender, RoutedEventArgs e) { - Application.Current.Dispatcher.Invoke(() => { + private void BtnPPTSlidesUp_Click(object sender, RoutedEventArgs e) + { + Application.Current.Dispatcher.Invoke(() => + { try { _isPptClickingBtnTurned = true; @@ -732,15 +737,18 @@ namespace Ink_Canvas { _pptUIManager?.UpdateConnectionStatus(false); } } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"PPT上一页操作异常: {ex}", LogHelper.LogType.Error); _pptUIManager?.UpdateConnectionStatus(false); } }); } - private void BtnPPTSlidesDown_Click(object sender, RoutedEventArgs e) { - Application.Current.Dispatcher.Invoke(() => { + private void BtnPPTSlidesDown_Click(object sender, RoutedEventArgs e) + { + Application.Current.Dispatcher.Invoke(() => + { try { _isPptClickingBtnTurned = true; @@ -772,7 +780,8 @@ namespace Ink_Canvas { _pptUIManager?.UpdateConnectionStatus(false); } } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"PPT下一页操作异常: {ex}", LogHelper.LogType.Error); _pptUIManager?.UpdateConnectionStatus(false); } @@ -822,7 +831,8 @@ namespace Ink_Canvas { } } - private async void PPTNavigationBtn_MouseUp(object sender, MouseButtonEventArgs e) { + private async void PPTNavigationBtn_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; if (sender == PPTLSPageButton) @@ -868,7 +878,8 @@ namespace Ink_Canvas { } // 控制居中 - if (!isFloatingBarFolded) { + if (!isFloatingBarFolded) + { await Task.Delay(100); ViewboxFloatingBarMarginAnimation(60); } @@ -879,28 +890,34 @@ namespace Ink_Canvas { } } - private void BtnPPTSlideShow_Click(object sender, RoutedEventArgs e) { - new Thread(() => { - try { + private void BtnPPTSlideShow_Click(object sender, RoutedEventArgs e) + { + new Thread(() => + { + try + { if (_pptManager?.TryStartSlideShow() != true) { LogHelper.WriteLogToFile("启动幻灯片放映失败", LogHelper.LogType.Warning); } } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"启动幻灯片放映异常: {ex}", LogHelper.LogType.Error); } }).Start(); } - private async void BtnPPTSlideShowEnd_Click(object sender, RoutedEventArgs e) { + private async void BtnPPTSlideShowEnd_Click(object sender, RoutedEventArgs e) + { try { // 保存当前页墨迹 var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0; if (currentSlide > 0) { - Application.Current.Dispatcher.Invoke(() => { + Application.Current.Dispatcher.Invoke(() => + { _pptInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes); timeMachine.ClearStrokeHistory(); }); @@ -916,7 +933,8 @@ namespace Ink_Canvas { LogHelper.WriteLogToFile("结束幻灯片放映失败", LogHelper.LogType.Warning); // 手动更新UI状态,防止事件未触发 - await Application.Current.Dispatcher.InvokeAsync(() => { + await Application.Current.Dispatcher.InvokeAsync(() => + { _pptUIManager?.UpdateSlideShowStatus(false); _pptUIManager?.UpdateSidebarExitButtons(false); LogHelper.WriteLogToFile("手动更新放映结束UI状态", LogHelper.LogType.Trace); @@ -932,7 +950,8 @@ namespace Ink_Canvas { LogHelper.WriteLogToFile($"结束PPT放映操作异常: {ex}", LogHelper.LogType.Error); // 确保UI状态正确 - await Application.Current.Dispatcher.InvokeAsync(() => { + await Application.Current.Dispatcher.InvokeAsync(() => + { _pptUIManager?.UpdateSlideShowStatus(false); _pptUIManager?.UpdateSidebarExitButtons(false); }); @@ -942,11 +961,15 @@ namespace Ink_Canvas { private void GridPPTControlPrevious_MouseDown(object sender, MouseButtonEventArgs e) { lastBorderMouseDownObject = sender; - if (sender == PPTLSPreviousButtonBorder) { + if (sender == PPTLSPreviousButtonBorder) + { PPTLSPreviousButtonFeedbackBorder.Opacity = 0.15; - } else if (sender == PPTRSPreviousButtonBorder) { + } + else if (sender == PPTRSPreviousButtonBorder) + { PPTRSPreviousButtonFeedbackBorder.Opacity = 0.15; - } else if (sender == PPTLBPreviousButtonBorder) + } + else if (sender == PPTLBPreviousButtonBorder) { PPTLBPreviousButtonFeedbackBorder.Opacity = 0.15; } @@ -958,11 +981,15 @@ namespace Ink_Canvas { private void GridPPTControlPrevious_MouseLeave(object sender, MouseEventArgs e) { lastBorderMouseDownObject = null; - if (sender == PPTLSPreviousButtonBorder) { + if (sender == PPTLSPreviousButtonBorder) + { PPTLSPreviousButtonFeedbackBorder.Opacity = 0; - } else if (sender == PPTRSPreviousButtonBorder) { + } + else if (sender == PPTRSPreviousButtonBorder) + { PPTRSPreviousButtonFeedbackBorder.Opacity = 0; - } else if (sender == PPTLBPreviousButtonBorder) + } + else if (sender == PPTLBPreviousButtonBorder) { PPTLBPreviousButtonFeedbackBorder.Opacity = 0; } @@ -971,13 +998,18 @@ namespace Ink_Canvas { PPTRBPreviousButtonFeedbackBorder.Opacity = 0; } } - private void GridPPTControlPrevious_MouseUp(object sender, MouseButtonEventArgs e) { + private void GridPPTControlPrevious_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; - if (sender == PPTLSPreviousButtonBorder) { + if (sender == PPTLSPreviousButtonBorder) + { PPTLSPreviousButtonFeedbackBorder.Opacity = 0; - } else if (sender == PPTRSPreviousButtonBorder) { + } + else if (sender == PPTRSPreviousButtonBorder) + { PPTRSPreviousButtonFeedbackBorder.Opacity = 0; - } else if (sender == PPTLBPreviousButtonBorder) + } + else if (sender == PPTLBPreviousButtonBorder) { PPTLBPreviousButtonFeedbackBorder.Opacity = 0; } @@ -989,13 +1021,18 @@ namespace Ink_Canvas { } - private void GridPPTControlNext_MouseDown(object sender, MouseButtonEventArgs e) { + private void GridPPTControlNext_MouseDown(object sender, MouseButtonEventArgs e) + { lastBorderMouseDownObject = sender; - if (sender == PPTLSNextButtonBorder) { + if (sender == PPTLSNextButtonBorder) + { PPTLSNextButtonFeedbackBorder.Opacity = 0.15; - } else if (sender == PPTRSNextButtonBorder) { + } + else if (sender == PPTRSNextButtonBorder) + { PPTRSNextButtonFeedbackBorder.Opacity = 0.15; - } else if (sender == PPTLBNextButtonBorder) + } + else if (sender == PPTLBNextButtonBorder) { PPTLBNextButtonFeedbackBorder.Opacity = 0.15; } @@ -1007,11 +1044,15 @@ namespace Ink_Canvas { private void GridPPTControlNext_MouseLeave(object sender, MouseEventArgs e) { lastBorderMouseDownObject = null; - if (sender == PPTLSNextButtonBorder) { + if (sender == PPTLSNextButtonBorder) + { PPTLSNextButtonFeedbackBorder.Opacity = 0; - } else if (sender == PPTRSNextButtonBorder) { + } + else if (sender == PPTRSNextButtonBorder) + { PPTRSNextButtonFeedbackBorder.Opacity = 0; - } else if (sender == PPTLBNextButtonBorder) + } + else if (sender == PPTLBNextButtonBorder) { PPTLBNextButtonFeedbackBorder.Opacity = 0; } @@ -1020,13 +1061,18 @@ namespace Ink_Canvas { PPTRBNextButtonFeedbackBorder.Opacity = 0; } } - private void GridPPTControlNext_MouseUp(object sender, MouseButtonEventArgs e) { + private void GridPPTControlNext_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; - if (sender == PPTLSNextButtonBorder) { + if (sender == PPTLSNextButtonBorder) + { PPTLSNextButtonFeedbackBorder.Opacity = 0; - } else if (sender == PPTRSNextButtonBorder) { + } + else if (sender == PPTRSNextButtonBorder) + { PPTRSNextButtonFeedbackBorder.Opacity = 0; - } else if (sender == PPTLBNextButtonBorder) + } + else if (sender == PPTLBNextButtonBorder) { PPTLBNextButtonFeedbackBorder.Opacity = 0; } @@ -1037,7 +1083,8 @@ namespace Ink_Canvas { BtnPPTSlidesDown_Click(BtnPPTSlidesDown, null); } - private void ImagePPTControlEnd_MouseUp(object sender, MouseButtonEventArgs e) { + private void ImagePPTControlEnd_MouseUp(object sender, MouseButtonEventArgs e) + { BtnPPTSlideShowEnd_Click(BtnPPTSlideShowEnd, null); } diff --git a/Ink Canvas/MainWindow_cs/MW_PageListView.cs b/Ink Canvas/MainWindow_cs/MW_PageListView.cs index 4944498a..70521c1d 100644 --- a/Ink Canvas/MainWindow_cs/MW_PageListView.cs +++ b/Ink Canvas/MainWindow_cs/MW_PageListView.cs @@ -1,10 +1,10 @@ -using System.Collections.ObjectModel; +using Ink_Canvas.Helpers; +using System.Collections.ObjectModel; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Input; -using Ink_Canvas.Helpers; namespace Ink_Canvas { @@ -23,7 +23,8 @@ namespace Ink_Canvas /// private void RefreshBlackBoardSidePageListView() { - if (blackBoardSidePageListViewObservableCollection.Count == WhiteboardTotalCount) { + if (blackBoardSidePageListViewObservableCollection.Count == WhiteboardTotalCount) + { foreach (int index in Enumerable.Range(1, WhiteboardTotalCount)) { var st = ApplyHistoriesToNewStrokeCollection(TimeMachineHistories[index]); @@ -33,13 +34,16 @@ namespace Ink_Canvas Index = index, Strokes = st, }; - blackBoardSidePageListViewObservableCollection[index-1] = pitem; + blackBoardSidePageListViewObservableCollection[index - 1] = pitem; } - } else { + } + else + { blackBoardSidePageListViewObservableCollection.Clear(); - foreach (int index in Enumerable.Range(1, WhiteboardTotalCount)) { + foreach (int index in Enumerable.Range(1, WhiteboardTotalCount)) + { var st = ApplyHistoriesToNewStrokeCollection(TimeMachineHistories[index]); - st.Clip(new Rect(0,0, (int)inkCanvas.ActualWidth, (int)inkCanvas.ActualHeight)); + st.Clip(new Rect(0, 0, (int)inkCanvas.ActualWidth, (int)inkCanvas.ActualHeight)); var pitem = new PageListViewItem { Index = index, @@ -58,8 +62,8 @@ namespace Ink_Canvas }; blackBoardSidePageListViewObservableCollection[CurrentWhiteboardIndex - 1] = _pitem; - BlackBoardLeftSidePageListView.SelectedIndex = CurrentWhiteboardIndex -1; - BlackBoardRightSidePageListView.SelectedIndex = CurrentWhiteboardIndex -1; + BlackBoardLeftSidePageListView.SelectedIndex = CurrentWhiteboardIndex - 1; + BlackBoardRightSidePageListView.SelectedIndex = CurrentWhiteboardIndex - 1; } public static void ScrollViewToVerticalTop(FrameworkElement element, ScrollViewer scrollViewer) @@ -71,7 +75,8 @@ namespace Ink_Canvas } - private void BlackBoardLeftSidePageListView_OnMouseUp(object sender, MouseButtonEventArgs e) { + private void BlackBoardLeftSidePageListView_OnMouseUp(object sender, MouseButtonEventArgs e) + { AnimationsHelper.HideWithSlideAndFade(BoardBorderLeftPageListView); AnimationsHelper.HideWithSlideAndFade(BoardBorderRightPageListView); var item = BlackBoardLeftSidePageListView.SelectedItem; diff --git a/Ink Canvas/MainWindow_cs/MW_Save&OpenStrokes.cs b/Ink Canvas/MainWindow_cs/MW_Save&OpenStrokes.cs index 16809605..bf233c24 100644 --- a/Ink Canvas/MainWindow_cs/MW_Save&OpenStrokes.cs +++ b/Ink Canvas/MainWindow_cs/MW_Save&OpenStrokes.cs @@ -1,18 +1,19 @@ using Ink_Canvas.Helpers; +using Newtonsoft.Json; using System; +using System.Collections.Generic; using System.IO; using System.Windows; +using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Input; -using File = System.IO.File; using System.Windows.Media; using System.Windows.Media.Imaging; +using File = System.IO.File; using OpenFileDialog = Microsoft.Win32.OpenFileDialog; -using System.Collections.Generic; -using System.Windows.Controls; -using Newtonsoft.Json; -namespace Ink_Canvas { +namespace Ink_Canvas +{ // 1. 定义元素信息结构 public class CanvasElementInfo { @@ -24,8 +25,10 @@ namespace Ink_Canvas { public double Height { get; set; } public string Stretch { get; set; } = "Fill"; // 默认为Fill } - public partial class MainWindow : Window { - private void SymbolIconSaveStrokes_MouseUp(object sender, MouseButtonEventArgs e) { + public partial class MainWindow : Window + { + private void SymbolIconSaveStrokes_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender || inkCanvas.Visibility != Visibility.Visible) return; AnimationsHelper.HideWithSlideAndFade(BorderTools); @@ -36,8 +39,10 @@ namespace Ink_Canvas { SaveInkCanvasStrokes(true, true); } - private void SaveInkCanvasStrokes(bool newNotice = true, bool saveByUser = false) { - try { + private void SaveInkCanvasStrokes(bool newNotice = true, bool saveByUser = false) + { + try + { var savePath = Settings.Automation.AutoSavedStrokesLocation + (saveByUser ? @"\User Saved - " : @"\Auto Saved - ") + (currentMode == 0 ? "Annotation Strokes" : "BlackBoard Strokes"); @@ -49,13 +54,13 @@ namespace Ink_Canvas { else //savePathWithName = savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".icstk"; savePathWithName = savePath + @"\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff") + ".icstk"; - + if (Settings.Automation.IsSaveFullPageStrokes) { // 全页面保存模式 - 检查是否存在多页面墨迹 bool hasMultiplePages = false; List allPageStrokes = new List(); - + // 检查PPT放映模式下的多页面墨迹 if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible && _pptManager?.IsConnected == true) { @@ -101,7 +106,7 @@ namespace Ink_Canvas { } } } - + if (hasMultiplePages && allPageStrokes.Count > 0) { // 多页面墨迹保存为压缩包 @@ -142,7 +147,8 @@ namespace Ink_Canvas { if (newNotice) ShowNotification("墨迹成功保存至 " + savePathWithName); } } - catch (Exception ex) { + catch (Exception ex) + { ShowNotification("墨迹保存失败"); LogHelper.WriteLogToFile("墨迹保存失败 | " + ex.ToString(), LogHelper.LogType.Error); } @@ -158,7 +164,7 @@ namespace Ink_Canvas { // 创建临时目录来存放文件 string tempDir = Path.Combine(Path.GetTempPath(), $"InkCanvas_MultiPage_{DateTime.Now:yyyyMMdd_HHmmss}"); Directory.CreateDirectory(tempDir); - + try { // 保存所有页面的文件到临时目录 @@ -173,7 +179,7 @@ namespace Ink_Canvas { { strokes.Save(fs); } - + // 保存页面图像 string imageFileName = Path.Combine(tempDir, $"page_{i + 1:D4}.png"); using (var fs = new FileStream(imageFileName, FileMode.Create)) @@ -182,7 +188,7 @@ namespace Ink_Canvas { } } } - + // 保存元数据信息 string metadataFile = Path.Combine(tempDir, "metadata.txt"); using (var writer = new StreamWriter(metadataFile, false, System.Text.Encoding.UTF8)) @@ -201,20 +207,20 @@ namespace Ink_Canvas { writer.WriteLine($"PPT总页数: {pptApplication.SlideShowWindows[1].Presentation.Slides.Count}"); writer.WriteLine($"PPT文件路径: {pptApplication.SlideShowWindows[1].Presentation.FullName}"); } - + for (int i = 0; i < allPageStrokes.Count; i++) { writer.WriteLine($"页面 {i + 1}: {allPageStrokes[i].Count} 条墨迹"); } } - + // 使用.NET Framework内置的压缩功能创建ZIP文件 if (File.Exists(zipFileName)) File.Delete(zipFileName); - + // 使用System.IO.Compression.FileSystem来创建ZIP System.IO.Compression.ZipFile.CreateFromDirectory(tempDir, zipFileName); - + if (newNotice) ShowNotification($"多页面墨迹成功保存至压缩包 {zipFileName}"); } finally @@ -245,17 +251,17 @@ namespace Ink_Canvas { { // 全页面保存模式 - 保存整个墨迹页面的图像 var bitmap = new System.Drawing.Bitmap( - (int)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, + (int)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, (int)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height); - + using (var g = System.Drawing.Graphics.FromImage(bitmap)) { // 创建黑色或透明背景 - System.Drawing.Color bgColor = Settings.Canvas.UsingWhiteboard - ? System.Drawing.Color.White + System.Drawing.Color bgColor = Settings.Canvas.UsingWhiteboard + ? System.Drawing.Color.White : System.Drawing.Color.FromArgb(22, 41, 36); // 黑板背景色 g.Clear(bgColor); - + // 将InkCanvas墨迹渲染到Visual var visual = new DrawingVisual(); using (var dc = visual.RenderOpen()) @@ -265,41 +271,41 @@ namespace Ink_Canvas { // 绘制矩形并填充为inkCanvas的内容 dc.DrawRectangle(visualBrush, null, new Rect(0, 0, inkCanvas.ActualWidth, inkCanvas.ActualHeight)); } - + // 创建适合墨迹画布尺寸的渲染位图 var rtb = new RenderTargetBitmap( - (int)inkCanvas.ActualWidth, (int)inkCanvas.ActualHeight, - 96, 96, + (int)inkCanvas.ActualWidth, (int)inkCanvas.ActualHeight, + 96, 96, PixelFormats.Pbgra32); rtb.Render(visual); - + // 转换为GDI+ Bitmap并保存 var encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(rtb)); - + using (var ms = new MemoryStream()) { encoder.Save(ms); ms.Seek(0, SeekOrigin.Begin); var imgBitmap = new System.Drawing.Bitmap(ms); - + // 将生成的墨迹图像绘制到屏幕截图上 // 居中绘制,确保墨迹位于屏幕中央 int x = (bitmap.Width - imgBitmap.Width) / 2; int y = (bitmap.Height - imgBitmap.Height) / 2; g.DrawImage(imgBitmap, x, y); - + // 保存为PNG string imagePathWithName = Path.ChangeExtension(savePathWithName, "png"); bitmap.Save(imagePathWithName, System.Drawing.Imaging.ImageFormat.Png); - + // 仍然保存墨迹文件以兼容旧版本 var fs = new FileStream(savePathWithName, FileMode.Create); inkCanvas.Strokes.Save(fs); fs.Close(); } } - + // 显示提示 if (newNotice) ShowNotification("墨迹成功全页面保存至 " + Path.ChangeExtension(savePathWithName, "png")); } @@ -316,14 +322,14 @@ namespace Ink_Canvas { tempCanvas.Strokes = strokes; tempCanvas.Width = inkCanvas.ActualWidth; tempCanvas.Height = inkCanvas.ActualHeight; - + // 创建渲染位图 var rtb = new RenderTargetBitmap( - (int)tempCanvas.Width, (int)tempCanvas.Height, - 96, 96, + (int)tempCanvas.Width, (int)tempCanvas.Height, + 96, 96, PixelFormats.Pbgra32); rtb.Render(tempCanvas); - + // 保存为PNG var encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(rtb)); @@ -336,7 +342,8 @@ namespace Ink_Canvas { } } - private void SymbolIconOpenStrokes_MouseUp(object sender, MouseButtonEventArgs e) { + private void SymbolIconOpenStrokes_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; AnimationsHelper.HideWithSlideAndFade(BorderTools); AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); @@ -348,21 +355,26 @@ namespace Ink_Canvas { if (openFileDialog.ShowDialog() != true) return; LogHelper.WriteLogToFile($"Strokes Insert: Name: {openFileDialog.FileName}", LogHelper.LogType.Event); - - try { + + try + { string fileExtension = Path.GetExtension(openFileDialog.FileName).ToLower(); - - if (fileExtension == ".zip") { + + if (fileExtension == ".zip") + { // 处理ICC压缩包 OpenICCZipFile(openFileDialog.FileName); - } else { + } + else + { // 处理单个墨迹文件 OpenSingleStrokeFile(openFileDialog.FileName); } if (inkCanvas.Visibility != Visibility.Visible) SymbolIconCursor_Click(sender, null); } - catch (Exception ex) { + catch (Exception ex) + { ShowNotification("墨迹打开失败"); LogHelper.WriteLogToFile($"墨迹打开失败: {ex.ToString()}", LogHelper.LogType.Error); } @@ -371,63 +383,76 @@ namespace Ink_Canvas { /// /// 打开ICC创建的.zip压缩包 /// - private void OpenICCZipFile(string zipFilePath) { - try { + private void OpenICCZipFile(string zipFilePath) + { + try + { // 创建临时目录来解压文件 string tempDir = Path.Combine(Path.GetTempPath(), $"InkCanvas_Open_{DateTime.Now:yyyyMMdd_HHmmss}"); Directory.CreateDirectory(tempDir); - - try { + + try + { // 解压ZIP文件 System.IO.Compression.ZipFile.ExtractToDirectory(zipFilePath, tempDir); - + // 读取元数据文件 string metadataFile = Path.Combine(tempDir, "metadata.txt"); - if (!File.Exists(metadataFile)) { + if (!File.Exists(metadataFile)) + { throw new Exception("压缩包中未找到元数据文件"); } - + var metadata = ReadMetadataFile(metadataFile); - + // 根据元数据信息决定恢复模式 bool isPPTMode = metadata.ContainsKey("模式") && metadata["模式"].Contains("PPT放映"); bool isWhiteboardMode = metadata.ContainsKey("模式") && metadata["模式"].Contains("白板"); - + // 检查当前是否处于PPT模式 bool isCurrentlyInPPTMode = BtnPPTSlideShowEnd.Visibility == Visibility.Visible && pptApplication != null; - + // 检查当前是否处于白板模式 bool isCurrentlyInWhiteboardMode = currentMode != 0; - + // 严格模式隔离:只在对应模式下恢复对应墨迹 - if (isPPTMode && isCurrentlyInPPTMode) { + if (isPPTMode && isCurrentlyInPPTMode) + { // 只在PPT放映模式下恢复PPT墨迹 RestorePPTStrokesFromZip(tempDir, metadata); - } else if (isWhiteboardMode && isCurrentlyInWhiteboardMode) { + } + else if (isWhiteboardMode && isCurrentlyInWhiteboardMode) + { // 只在白板模式下恢复白板墨迹 RestoreWhiteboardStrokesFromZip(tempDir, metadata); - } else { + } + else + { // 模式不匹配时,显示提示信息 string savedMode = isPPTMode ? "PPT放映" : (isWhiteboardMode ? "白板" : "未知"); string currentMode = isCurrentlyInPPTMode ? "PPT放映" : (isCurrentlyInWhiteboardMode ? "白板" : "桌面"); ShowNotification($"墨迹保存模式({savedMode})与当前模式({currentMode})不匹配,无法恢复墨迹"); LogHelper.WriteLogToFile($"模式不匹配:保存模式={savedMode},当前模式={currentMode}", LogHelper.LogType.Warning); } - + ShowNotification($"成功打开ICC压缩包,共{(metadata.ContainsKey("总页数") ? metadata["总页数"] : "0")}页"); } - finally { + finally + { // 清理临时目录 - try { + try + { if (Directory.Exists(tempDir)) Directory.Delete(tempDir, true); } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"清理临时目录失败: {ex.ToString()}", LogHelper.LogType.Warning); } } } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"打开ICC压缩包失败: {ex.ToString()}", LogHelper.LogType.Error); throw; } @@ -436,68 +461,80 @@ namespace Ink_Canvas { /// /// 读取元数据文件 /// - private Dictionary ReadMetadataFile(string metadataPath) { + private Dictionary ReadMetadataFile(string metadataPath) + { var metadata = new Dictionary(); - - using (var reader = new StreamReader(metadataPath, System.Text.Encoding.UTF8)) { + + using (var reader = new StreamReader(metadataPath, System.Text.Encoding.UTF8)) + { string line; - while ((line = reader.ReadLine()) != null) { - if (line.Contains(":")) { + while ((line = reader.ReadLine()) != null) + { + if (line.Contains(":")) + { var parts = line.Split(new[] { ':' }, 2); - if (parts.Length == 2) { + if (parts.Length == 2) + { metadata[parts[0].Trim()] = parts[1].Trim(); } } } } - + return metadata; } /// /// 从ZIP文件恢复PPT墨迹 /// - private void RestorePPTStrokesFromZip(string tempDir, Dictionary metadata) { - try { + private void RestorePPTStrokesFromZip(string tempDir, Dictionary metadata) + { + try + { // 确保当前处于PPT放映模式 - if (BtnPPTSlideShowEnd.Visibility != Visibility.Visible || pptApplication == null) { + if (BtnPPTSlideShowEnd.Visibility != Visibility.Visible || pptApplication == null) + { throw new InvalidOperationException("当前不在PPT放映模式,无法恢复PPT墨迹"); } - + // 检查PPT文件路径是否匹配 if (metadata.ContainsKey("PPT文件路径")) { string savedPptPath = metadata["PPT文件路径"]; string currentPptPath = pptApplication.SlideShowWindows[1].Presentation.FullName; - + if (!string.IsNullOrEmpty(savedPptPath) && !string.IsNullOrEmpty(currentPptPath)) { // 使用文件路径哈希值进行比较,避免路径格式差异 string savedHash = GetFileHash(savedPptPath); string currentHash = GetFileHash(currentPptPath); - + if (savedHash != currentHash) { throw new InvalidOperationException($"墨迹文件与当前PPT文件不匹配。保存的PPT: {savedPptPath},当前PPT: {currentPptPath}"); } } } - + // 清空当前墨迹 ClearStrokes(true); timeMachine.ClearStrokeHistory(); - + // 重置PPT墨迹存储 _pptInkManager?.ClearAllStrokes(); // 读取所有页面的墨迹文件 var files = Directory.GetFiles(tempDir, "page_*.icstk"); - foreach (var file in files) { + foreach (var file in files) + { var fileName = Path.GetFileNameWithoutExtension(file); - if (fileName.StartsWith("page_") && int.TryParse(fileName.Substring(5), out int pageNumber)) { - using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read)) { + if (fileName.StartsWith("page_") && int.TryParse(fileName.Substring(5), out int pageNumber)) + { + using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read)) + { var strokes = new StrokeCollection(fs); - if (strokes.Count > 0) { + if (strokes.Count > 0) + { _pptInkManager?.SaveCurrentSlideStrokes(pageNumber, strokes); } } @@ -505,17 +542,20 @@ namespace Ink_Canvas { } // 恢复当前页面的墨迹 - if (_pptManager?.IsInSlideShow == true) { + if (_pptManager?.IsInSlideShow == true) + { int currentSlide = _pptManager.GetCurrentSlideNumber(); var currentStrokes = _pptInkManager?.LoadSlideStrokes(currentSlide); - if (currentStrokes != null && currentStrokes.Count > 0) { + if (currentStrokes != null && currentStrokes.Count > 0) + { inkCanvas.Strokes.Add(currentStrokes); } } - + LogHelper.WriteLogToFile($"成功恢复PPT墨迹,共{files.Length}页"); } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"恢复PPT墨迹失败: {ex.ToString()}", LogHelper.LogType.Error); throw; } @@ -524,40 +564,49 @@ namespace Ink_Canvas { /// /// 从ZIP文件恢复白板墨迹 /// - private void RestoreWhiteboardStrokesFromZip(string tempDir, Dictionary metadata) { - try { + private void RestoreWhiteboardStrokesFromZip(string tempDir, Dictionary metadata) + { + try + { // 确保当前处于白板模式 - if (currentMode == 0) { + if (currentMode == 0) + { throw new InvalidOperationException("当前不在白板模式,无法恢复白板墨迹"); } - + // 清空当前墨迹 ClearStrokes(true); timeMachine.ClearStrokeHistory(); - + // 读取总页数 int totalPages = 1; - if (metadata.ContainsKey("总页数") && int.TryParse(metadata["总页数"], out int parsedPages)) { + if (metadata.ContainsKey("总页数") && int.TryParse(metadata["总页数"], out int parsedPages)) + { totalPages = parsedPages; } - + // 重置白板状态 WhiteboardTotalCount = totalPages; CurrentWhiteboardIndex = 1; - + // 清空历史记录 - for (int i = 0; i < TimeMachineHistories.Length; i++) { + for (int i = 0; i < TimeMachineHistories.Length; i++) + { TimeMachineHistories[i] = null; } - + // 读取所有页面的墨迹文件 var files = Directory.GetFiles(tempDir, "page_*.icstk"); - foreach (var file in files) { + foreach (var file in files) + { var fileName = Path.GetFileNameWithoutExtension(file); - if (fileName.StartsWith("page_") && int.TryParse(fileName.Substring(5), out int pageNumber)) { - using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read)) { + if (fileName.StartsWith("page_") && int.TryParse(fileName.Substring(5), out int pageNumber)) + { + using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read)) + { var strokes = new StrokeCollection(fs); - if (strokes.Count > 0) { + if (strokes.Count > 0) + { // 创建历史记录 var history = new TimeMachineHistory(strokes, TimeMachineHistoryType.UserInput, false); TimeMachineHistories[pageNumber] = new TimeMachineHistory[] { history }; @@ -565,18 +614,20 @@ namespace Ink_Canvas { } } } - + // 恢复第一页的墨迹 - if (TimeMachineHistories[1] != null) { + if (TimeMachineHistories[1] != null) + { RestoreStrokes(); } - + // 更新UI显示 UpdateIndexInfoDisplay(); - + LogHelper.WriteLogToFile($"成功恢复白板墨迹,共{totalPages}页"); } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"恢复白板墨迹失败: {ex.ToString()}", LogHelper.LogType.Error); throw; } @@ -585,51 +636,55 @@ namespace Ink_Canvas { /// /// 打开单个墨迹文件 /// - private void OpenSingleStrokeFile(string filePath) { - var fileStreamHasNoStroke = false; - using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { - var strokes = new StrokeCollection(fs); - fileStreamHasNoStroke = strokes.Count == 0; - if (!fileStreamHasNoStroke) { - ClearStrokes(true); - timeMachine.ClearStrokeHistory(); - inkCanvas.Strokes.Add(strokes); - LogHelper.NewLog($"Strokes Insert: Strokes Count: {inkCanvas.Strokes.Count.ToString()}"); - } - } - - // 恢复元素信息 - var elementsFile = Path.ChangeExtension(filePath, ".elements.json"); - if (File.Exists(elementsFile)) + private void OpenSingleStrokeFile(string filePath) + { + var fileStreamHasNoStroke = false; + using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) + { + var strokes = new StrokeCollection(fs); + fileStreamHasNoStroke = strokes.Count == 0; + if (!fileStreamHasNoStroke) { - var elementInfos = JsonConvert.DeserializeObject>(File.ReadAllText(elementsFile)); - foreach (var info in elementInfos) + ClearStrokes(true); + timeMachine.ClearStrokeHistory(); + inkCanvas.Strokes.Add(strokes); + LogHelper.NewLog($"Strokes Insert: Strokes Count: {inkCanvas.Strokes.Count.ToString()}"); + } + } + + // 恢复元素信息 + var elementsFile = Path.ChangeExtension(filePath, ".elements.json"); + if (File.Exists(elementsFile)) + { + var elementInfos = JsonConvert.DeserializeObject>(File.ReadAllText(elementsFile)); + foreach (var info in elementInfos) + { + if (info.Type == "Image" && File.Exists(info.SourcePath)) { - if (info.Type == "Image" && File.Exists(info.SourcePath)) + var img = new Image { - var img = new Image - { - Source = new BitmapImage(new Uri(info.SourcePath)), - Width = info.Width, - Height = info.Height, - Stretch = Enum.TryParse(info.Stretch, out var stretch) ? stretch : Stretch.Fill - }; - InkCanvas.SetLeft(img, info.Left); - InkCanvas.SetTop(img, info.Top); - inkCanvas.Children.Add(img); - } + Source = new BitmapImage(new Uri(info.SourcePath)), + Width = info.Width, + Height = info.Height, + Stretch = Enum.TryParse(info.Stretch, out var stretch) ? stretch : Stretch.Fill + }; + InkCanvas.SetLeft(img, info.Left); + InkCanvas.SetTop(img, info.Top); + inkCanvas.Children.Add(img); } } - - if (fileStreamHasNoStroke) - using (var ms = new MemoryStream(File.ReadAllBytes(filePath))) { - ms.Seek(0, SeekOrigin.Begin); - var strokes = new StrokeCollection(ms); - ClearStrokes(true); - timeMachine.ClearStrokeHistory(); - inkCanvas.Strokes.Add(strokes); - LogHelper.NewLog($"Strokes Insert (2): Strokes Count: {strokes.Count.ToString()}"); } + + if (fileStreamHasNoStroke) + using (var ms = new MemoryStream(File.ReadAllBytes(filePath))) + { + ms.Seek(0, SeekOrigin.Begin); + var strokes = new StrokeCollection(ms); + ClearStrokes(true); + timeMachine.ClearStrokeHistory(); + inkCanvas.Strokes.Add(strokes); + LogHelper.NewLog($"Strokes Insert (2): Strokes Count: {strokes.Count.ToString()}"); + } } } } diff --git a/Ink Canvas/MainWindow_cs/MW_Screenshot.cs b/Ink Canvas/MainWindow_cs/MW_Screenshot.cs index d33e88de..495c1aad 100644 --- a/Ink Canvas/MainWindow_cs/MW_Screenshot.cs +++ b/Ink Canvas/MainWindow_cs/MW_Screenshot.cs @@ -1,3 +1,4 @@ +using Ink_Canvas.Helpers; using System; using System.Collections.Generic; using System.Drawing; @@ -8,93 +9,103 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Forms; using System.Windows.Media.Imaging; -using Ink_Canvas.Helpers; -using Ink_Canvas.Helpers; using Application = System.Windows.Application; using Clipboard = System.Windows.Clipboard; using Size = System.Drawing.Size; -namespace Ink_Canvas { +namespace Ink_Canvas +{ // 截图结果结构体 public struct ScreenshotResult { public System.Drawing.Rectangle Area; public List Path; - + public ScreenshotResult(System.Drawing.Rectangle area, List path = null) { Area = area; Path = path; } } - - public partial class MainWindow : Window { - private void SaveScreenShot(bool isHideNotification, string fileName = null) { + + public partial class MainWindow : Window + { + private void SaveScreenShot(bool isHideNotification, string fileName = null) + { var savePath = Settings.Automation.IsSaveScreenshotsInDateFolders ? GetDateFolderPath(fileName) : GetDefaultFolderPath(); CaptureAndSaveScreenshot(savePath, isHideNotification); - - if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) + + if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) SaveInkCanvasStrokes(false); } - private void SaveScreenShotToDesktop() { + private void SaveScreenShotToDesktop() + { var desktopPath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.png"); CaptureAndSaveScreenshot(desktopPath, false); - - if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) + + if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) SaveInkCanvasStrokes(false); } // 提取公共的截图和保存逻辑 - private void CaptureAndSaveScreenshot(string savePath, bool isHideNotification) { + private void CaptureAndSaveScreenshot(string savePath, bool isHideNotification) + { var rc = SystemInformation.VirtualScreen; - + using (var bitmap = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb)) - using (var memoryGraphics = Graphics.FromImage(bitmap)) { + using (var memoryGraphics = Graphics.FromImage(bitmap)) + { memoryGraphics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy); - + // 确保目录存在 var directory = Path.GetDirectoryName(savePath); - if (!Directory.Exists(directory)) { + if (!Directory.Exists(directory)) + { Directory.CreateDirectory(directory); } - + bitmap.Save(savePath, ImageFormat.Png); } - - if (!isHideNotification) { + + if (!isHideNotification) + { ShowNotification($"截图成功保存至 {savePath}"); } } // 获取日期文件夹路径 - private string GetDateFolderPath(string fileName) { - if (string.IsNullOrWhiteSpace(fileName)) { + private string GetDateFolderPath(string fileName) + { + if (string.IsNullOrWhiteSpace(fileName)) + { fileName = DateTime.Now.ToString("HH-mm-ss"); } - + var basePath = Settings.Automation.AutoSavedStrokesLocation; var dateFolder = DateTime.Now.ToString("yyyyMMdd"); - + return Path.Combine( - basePath, - "Auto Saved - Screenshots", - dateFolder, + basePath, + "Auto Saved - Screenshots", + dateFolder, $"{fileName}.png"); } // 获取默认文件夹路径 - private string GetDefaultFolderPath() { + private string GetDefaultFolderPath() + { var basePath = Settings.Automation.AutoSavedStrokesLocation; var screenshotsFolder = Path.Combine(basePath, "Auto Saved - Screenshots"); - if (!Directory.Exists(screenshotsFolder)) { + if (!Directory.Exists(screenshotsFolder)) + { Directory.CreateDirectory(screenshotsFolder); } @@ -104,8 +115,10 @@ namespace Ink_Canvas { } // 截图并复制到剪贴板 - private async Task CaptureScreenshotToClipboard() { - try { + private async Task CaptureScreenshotToClipboard() + { + try + { // 隐藏主窗口以避免截图包含窗口本身 var originalVisibility = this.Visibility; this.Visibility = Visibility.Hidden; @@ -127,13 +140,13 @@ namespace Ink_Canvas { if (originalBitmap != null) { Bitmap finalBitmap = originalBitmap; - + // 如果有路径信息,应用形状遮罩 if (screenshotResult.Value.Path != null && screenshotResult.Value.Path.Count > 0) { finalBitmap = ApplyShapeMask(originalBitmap, screenshotResult.Value.Path, screenshotResult.Value.Area); } - + // 将截图复制到剪贴板 CopyBitmapToClipboard(finalBitmap); @@ -148,7 +161,8 @@ namespace Ink_Canvas { ShowNotification("截图已取消"); } } - catch (Exception ex) { + catch (Exception ex) + { ShowNotification($"截图失败: {ex.Message}"); this.Visibility = Visibility.Visible; } @@ -221,32 +235,41 @@ namespace Ink_Canvas { } // 自动粘贴截图到画布 - private async Task AutoPasteScreenshot() { - try { + private async Task AutoPasteScreenshot() + { + try + { // 只在白板模式下自动粘贴 - if (currentMode == 1) { + if (currentMode == 1) + { await PasteImageFromClipboard(); ShowNotification("截图已自动插入到画布"); - } else { + } + else + { ShowNotification("截图已复制到剪贴板,可在白板模式下粘贴"); } } - catch (Exception ex) { + catch (Exception ex) + { ShowNotification($"自动粘贴截图失败: {ex.Message}"); LogHelper.WriteLogToFile($"自动粘贴截图失败: {ex.Message}", LogHelper.LogType.Error); } } // 将Bitmap复制到剪贴板 - private void CopyBitmapToClipboard(Bitmap bitmap) { - try { + private void CopyBitmapToClipboard(Bitmap bitmap) + { + try + { // 将System.Drawing.Bitmap转换为WPF BitmapSource var bitmapSource = ConvertBitmapToBitmapSource(bitmap); // 复制到剪贴板 Clipboard.SetImage(bitmapSource); } - catch (Exception ex) { + catch (Exception ex) + { ShowNotification($"复制到剪贴板失败: {ex.Message}"); } } @@ -259,7 +282,7 @@ namespace Ink_Canvas { // 获取DPI缩放比例 var dpiScale = GetDpiScale(); var virtualScreen = SystemInformation.VirtualScreen; - + // 创建结果位图 var resultBitmap = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format32bppArgb); using (var resultGraphics = Graphics.FromImage(resultBitmap)) @@ -278,11 +301,11 @@ namespace Ink_Canvas { // 将WPF坐标转换为实际屏幕坐标,然后相对于截图区域计算偏移 double screenX = (path[i].X * dpiScale) + virtualScreen.Left; double screenY = (path[i].Y * dpiScale) + virtualScreen.Top; - + // 计算相对于截图区域的坐标 float relativeX = (float)(screenX - area.X); float relativeY = (float)(screenY - area.Y); - + points[i] = new PointF(relativeX, relativeY); } @@ -291,7 +314,7 @@ namespace Ink_Canvas { // 设置裁剪区域为路径内部 resultGraphics.SetClip(pathGraphics); - + // 在裁剪区域内绘制原始图像 resultGraphics.DrawImage(bitmap, 0, 0); } @@ -318,8 +341,10 @@ namespace Ink_Canvas { } // 将System.Drawing.Bitmap转换为WPF BitmapSource - private BitmapSource ConvertBitmapToBitmapSource(Bitmap bitmap) { - using (var memory = new MemoryStream()) { + private BitmapSource ConvertBitmapToBitmapSource(Bitmap bitmap) + { + using (var memory = new MemoryStream()) + { bitmap.Save(memory, ImageFormat.Png); memory.Position = 0; diff --git a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs index d9b86693..c302795f 100644 --- a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs +++ b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs @@ -1,3 +1,4 @@ +using iNKORE.UI.WPF.Modern.Controls; using System; using System.Collections.Generic; using System.Windows; @@ -7,21 +8,24 @@ using System.Windows.Input; using System.Windows.Media; using System.Windows.Shapes; using System.Windows.Threading; -using Ink_Canvas.Helpers; -using iNKORE.UI.WPF.Modern.Controls; using Point = System.Windows.Point; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { #region Floating Control private object lastBorderMouseDownObject; - private void Border_MouseDown(object sender, MouseButtonEventArgs e) { + private void Border_MouseDown(object sender, MouseButtonEventArgs e) + { // 如果发送者是 RandomDrawPanel 或 SingleDrawPanel,且它们被隐藏,则不处理事件 - if (sender is SimpleStackPanel panel) { - if ((panel == RandomDrawPanel || panel == SingleDrawPanel) && - panel.Visibility != Visibility.Visible) { + if (sender is SimpleStackPanel panel) + { + if ((panel == RandomDrawPanel || panel == SingleDrawPanel) && + panel.Visibility != Visibility.Visible) + { return; } } @@ -30,22 +34,26 @@ namespace Ink_Canvas { private bool isStrokeSelectionCloneOn; - private void BorderStrokeSelectionClone_MouseUp(object sender, MouseButtonEventArgs e) { + private void BorderStrokeSelectionClone_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; - if (isStrokeSelectionCloneOn) { + if (isStrokeSelectionCloneOn) + { BorderStrokeSelectionClone.Background = Brushes.Transparent; isStrokeSelectionCloneOn = false; } - else { + else + { BorderStrokeSelectionClone.Background = new SolidColorBrush(StringToColor("#FF1ED760")); isStrokeSelectionCloneOn = true; } } - private void BorderStrokeSelectionCloneToNewBoard_MouseUp(object sender, MouseButtonEventArgs e) { + private void BorderStrokeSelectionCloneToNewBoard_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; var strokes = inkCanvas.GetSelectedStrokes(); @@ -55,23 +63,28 @@ namespace Ink_Canvas { inkCanvas.Strokes.Add(strokes); } - private void BorderStrokeSelectionDelete_MouseUp(object sender, MouseButtonEventArgs e) { + private void BorderStrokeSelectionDelete_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; SymbolIconDelete_MouseUp(sender, e); } - private void GridPenWidthDecrease_MouseUp(object sender, MouseButtonEventArgs e) { + private void GridPenWidthDecrease_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; ChangeStrokeThickness(0.8); } - private void GridPenWidthIncrease_MouseUp(object sender, MouseButtonEventArgs e) { + private void GridPenWidthIncrease_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; ChangeStrokeThickness(1.25); } - private void ChangeStrokeThickness(double multipler) { - foreach (var stroke in inkCanvas.GetSelectedStrokes()) { + private void ChangeStrokeThickness(double multipler) + { + foreach (var stroke in inkCanvas.GetSelectedStrokes()) + { var newWidth = stroke.DrawingAttributes.Width * multipler; var newHeight = stroke.DrawingAttributes.Height * multipler; if (!(newWidth >= DrawingAttributes.MinWidth) || !(newWidth <= DrawingAttributes.MaxWidth) @@ -92,16 +105,19 @@ namespace Ink_Canvas { } } - private void GridPenWidthRestore_MouseUp(object sender, MouseButtonEventArgs e) { + private void GridPenWidthRestore_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; - foreach (var stroke in inkCanvas.GetSelectedStrokes()) { + foreach (var stroke in inkCanvas.GetSelectedStrokes()) + { stroke.DrawingAttributes.Width = inkCanvas.DefaultDrawingAttributes.Width; stroke.DrawingAttributes.Height = inkCanvas.DefaultDrawingAttributes.Height; } } - private void ImageFlipHorizontal_MouseUp(object sender, MouseButtonEventArgs e) { + private void ImageFlipHorizontal_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; var m = new Matrix(); @@ -137,7 +153,8 @@ namespace Ink_Canvas { //updateBorderStrokeSelectionControlLocation(); } - private void ImageFlipVertical_MouseUp(object sender, MouseButtonEventArgs e) { + private void ImageFlipVertical_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; var m = new Matrix(); @@ -166,8 +183,9 @@ namespace Ink_Canvas { } } -// ... existing code ... - private void ImageRotate45_MouseUp(object sender, MouseButtonEventArgs e) { + // ... existing code ... + private void ImageRotate45_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; var m = new Matrix(); @@ -196,7 +214,8 @@ namespace Ink_Canvas { } } - private void ImageRotate90_MouseUp(object sender, MouseButtonEventArgs e) { + private void ImageRotate90_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; var m = new Matrix(); @@ -235,27 +254,33 @@ namespace Ink_Canvas { private bool isGridInkCanvasSelectionCoverMouseDown; private StrokeCollection StrokesSelectionClone = new StrokeCollection(); - private void GridInkCanvasSelectionCover_MouseDown(object sender, MouseButtonEventArgs e) { + private void GridInkCanvasSelectionCover_MouseDown(object sender, MouseButtonEventArgs e) + { isGridInkCanvasSelectionCoverMouseDown = true; } - private void GridInkCanvasSelectionCover_MouseUp(object sender, MouseButtonEventArgs e) { + private void GridInkCanvasSelectionCover_MouseUp(object sender, MouseButtonEventArgs e) + { if (!isGridInkCanvasSelectionCoverMouseDown) return; isGridInkCanvasSelectionCoverMouseDown = false; GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; } - private void BtnSelect_Click(object sender, RoutedEventArgs e) { + private void BtnSelect_Click(object sender, RoutedEventArgs e) + { ExitMultiTouchModeIfNeeded(); forceEraser = true; drawingShapeMode = 0; inkCanvas.IsManipulationEnabled = false; - if (inkCanvas.EditingMode == InkCanvasEditingMode.Select) { - if (inkCanvas.GetSelectedStrokes().Count == inkCanvas.Strokes.Count) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.Select) + { + if (inkCanvas.GetSelectedStrokes().Count == inkCanvas.Strokes.Count) + { inkCanvas.EditingMode = InkCanvasEditingMode.Ink; inkCanvas.EditingMode = InkCanvasEditingMode.Select; } - else { + else + { var selectedStrokes = new StrokeCollection(); foreach (var stroke in inkCanvas.Strokes) if (stroke.GetBounds().Width > 0 && stroke.GetBounds().Height > 0) @@ -263,7 +288,8 @@ namespace Ink_Canvas { inkCanvas.Select(selectedStrokes); } } - else { + else + { inkCanvas.EditingMode = InkCanvasEditingMode.Select; } } @@ -272,14 +298,17 @@ namespace Ink_Canvas { private double BorderStrokeSelectionControlHeight = 80.0; private bool isProgramChangeStrokeSelection; - private void inkCanvas_SelectionChanged(object sender, EventArgs e) { + private void inkCanvas_SelectionChanged(object sender, EventArgs e) + { if (isProgramChangeStrokeSelection) return; - if (inkCanvas.GetSelectedStrokes().Count == 0) { + if (inkCanvas.GetSelectedStrokes().Count == 0) + { GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; // 当没有选中笔画时,检查是否有选中的UIElement CheckUIElementSelection(); } - else { + else + { GridInkCanvasSelectionCover.Visibility = Visibility.Visible; BorderStrokeSelectionClone.Background = Brushes.Transparent; isStrokeSelectionCloneOn = false; @@ -304,7 +333,8 @@ namespace Ink_Canvas { } } - private void updateBorderStrokeSelectionControlLocation() { + private void updateBorderStrokeSelectionControlLocation() + { var borderLeft = (inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Right - BorderStrokeSelectionControlWidth) / 2; var borderTop = inkCanvas.GetSelectionBounds().Bottom + 1; @@ -319,11 +349,13 @@ namespace Ink_Canvas { BorderStrokeSelectionControl.Margin = new Thickness(borderLeft, borderTop, 0, 0); } - private void GridInkCanvasSelectionCover_ManipulationStarting(object sender, ManipulationStartingEventArgs e) { + private void GridInkCanvasSelectionCover_ManipulationStarting(object sender, ManipulationStartingEventArgs e) + { e.Mode = ManipulationModes.All; } - private void GridInkCanvasSelectionCover_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) { + private void GridInkCanvasSelectionCover_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) + { if (StrokeManipulationHistory?.Count > 0) { timeMachine.CommitStrokeManipulationHistory(StrokeManipulationHistory); @@ -344,9 +376,12 @@ namespace Ink_Canvas { } } - private void GridInkCanvasSelectionCover_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) { - try { - if (dec.Count >= 1) { + private void GridInkCanvasSelectionCover_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) + { + try + { + if (dec.Count >= 1) + { bool disableScale = dec.Count >= 3; var md = e.DeltaManipulation; var trans = md.Translation; // 获得位移矢量 @@ -372,10 +407,12 @@ namespace Ink_Canvas { strokes = StrokesSelectionClone; else if (Settings.Gesture.IsEnableTwoFingerRotationOnSelection) m.RotateAt(rotate, center.X, center.Y); // 旋转 - foreach (var stroke in strokes) { + foreach (var stroke in strokes) + { stroke.Transform(m, false); - try { + try + { stroke.DrawingAttributes.Width *= md.Scale.X; stroke.DrawingAttributes.Height *= md.Scale.Y; } @@ -394,15 +431,18 @@ namespace Ink_Canvas { private Point lastTouchPointOnGridInkCanvasCover = new Point(0, 0); - private void GridInkCanvasSelectionCover_PreviewTouchDown(object sender, TouchEventArgs e) { + private void GridInkCanvasSelectionCover_PreviewTouchDown(object sender, TouchEventArgs e) + { dec.Add(e.TouchDevice.Id); //设备1个的时候,记录中心点 - if (dec.Count == 1) { + if (dec.Count == 1) + { var touchPoint = e.GetTouchPoint(null); centerPoint = touchPoint.Position; lastTouchPointOnGridInkCanvasCover = touchPoint.Position; - if (isStrokeSelectionCloneOn) { + if (isStrokeSelectionCloneOn) + { var strokes = inkCanvas.GetSelectedStrokes(); isProgramChangeStrokeSelection = true; inkCanvas.Select(new StrokeCollection()); @@ -411,7 +451,8 @@ namespace Ink_Canvas { isProgramChangeStrokeSelection = false; inkCanvas.Strokes.Add(StrokesSelectionClone); } - else { + else + { // 新增:启动套索选择模式 inkCanvas.EditingMode = InkCanvasEditingMode.Select; inkCanvas.Select(new StrokeCollection()); @@ -419,11 +460,13 @@ namespace Ink_Canvas { } } - private void GridInkCanvasSelectionCover_PreviewTouchUp(object sender, TouchEventArgs e) { + private void GridInkCanvasSelectionCover_PreviewTouchUp(object sender, TouchEventArgs e) + { dec.Remove(e.TouchDevice.Id); if (dec.Count >= 1) return; isProgramChangeStrokeSelection = false; - if (lastTouchPointOnGridInkCanvasCover == e.GetTouchPoint(null).Position) { + if (lastTouchPointOnGridInkCanvasCover == e.GetTouchPoint(null).Position) + { if (!(lastTouchPointOnGridInkCanvasCover.X < inkCanvas.GetSelectionBounds().Left) && !(lastTouchPointOnGridInkCanvasCover.Y < inkCanvas.GetSelectionBounds().Top) && !(lastTouchPointOnGridInkCanvasCover.X > inkCanvas.GetSelectionBounds().Right) && @@ -431,17 +474,20 @@ namespace Ink_Canvas { inkCanvas.Select(new StrokeCollection()); StrokesSelectionClone = new StrokeCollection(); } - else if (inkCanvas.GetSelectedStrokes().Count == 0) { + else if (inkCanvas.GetSelectedStrokes().Count == 0) + { GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; StrokesSelectionClone = new StrokeCollection(); } - else { + else + { GridInkCanvasSelectionCover.Visibility = Visibility.Visible; StrokesSelectionClone = new StrokeCollection(); } } - private void LassoSelect_Click(object sender, RoutedEventArgs e) { + private void LassoSelect_Click(object sender, RoutedEventArgs e) + { ExitMultiTouchModeIfNeeded(); forceEraser = false; forcePointEraser = false; @@ -450,7 +496,8 @@ namespace Ink_Canvas { SetCursorBasedOnEditingMode(inkCanvas); } - private void BtnLassoSelect_Click(object sender, RoutedEventArgs e) { + private void BtnLassoSelect_Click(object sender, RoutedEventArgs e) + { ExitMultiTouchModeIfNeeded(); forceEraser = false; forcePointEraser = false; diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs index 527cc08b..1dac611c 100644 --- a/Ink Canvas/MainWindow_cs/MW_Settings.cs +++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs @@ -1,3 +1,7 @@ +using Hardcodet.Wpf.TaskbarNotification; +using Ink_Canvas.Helpers; +using Newtonsoft.Json; +using OSVersionExtension; using System; using System.Diagnostics; using System.IO; @@ -9,10 +13,6 @@ using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; -using Hardcodet.Wpf.TaskbarNotification; -using Ink_Canvas.Helpers; -using Newtonsoft.Json; -using OSVersionExtension; using Application = System.Windows.Application; using CheckBox = System.Windows.Controls.CheckBox; using ComboBox = System.Windows.Controls.ComboBox; @@ -22,74 +22,87 @@ using OpenFileDialog = Microsoft.Win32.OpenFileDialog; using OperatingSystem = OSVersionExtension.OperatingSystem; using RadioButton = System.Windows.Controls.RadioButton; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { #region Behavior - private void ToggleSwitchIsAutoUpdate_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchIsAutoUpdate_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Startup.IsAutoUpdate = ToggleSwitchIsAutoUpdate.IsOn; - + // 自动更新关闭时隐藏静默更新选项 - ToggleSwitchIsAutoUpdateWithSilence.Visibility = + ToggleSwitchIsAutoUpdateWithSilence.Visibility = ToggleSwitchIsAutoUpdate.IsOn ? Visibility.Visible : Visibility.Collapsed; - + // 如果关闭了自动更新,同时也关闭静默更新 - if (!ToggleSwitchIsAutoUpdate.IsOn) { + if (!ToggleSwitchIsAutoUpdate.IsOn) + { Settings.Startup.IsAutoUpdateWithSilence = false; ToggleSwitchIsAutoUpdateWithSilence.IsOn = false; } - + // 无论如何,静默更新时间区域的显示都要跟随静默更新设置 AutoUpdateTimePeriodBlock.Visibility = - (Settings.Startup.IsAutoUpdateWithSilence && Settings.Startup.IsAutoUpdate) ? + (Settings.Startup.IsAutoUpdateWithSilence && Settings.Startup.IsAutoUpdate) ? Visibility.Visible : Visibility.Collapsed; - + SaveSettingsToFile(); } - private void ToggleSwitchIsAutoUpdateWithSilence_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchIsAutoUpdateWithSilence_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Startup.IsAutoUpdateWithSilence = ToggleSwitchIsAutoUpdateWithSilence.IsOn; - + // 静默更新的时间设置区域只在静默更新开启时显示 AutoUpdateTimePeriodBlock.Visibility = Settings.Startup.IsAutoUpdateWithSilence ? Visibility.Visible : Visibility.Collapsed; - + SaveSettingsToFile(); } - private void AutoUpdateWithSilenceStartTimeComboBox_SelectionChanged(object sender, RoutedEventArgs e) { + private void AutoUpdateWithSilenceStartTimeComboBox_SelectionChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Startup.AutoUpdateWithSilenceStartTime = (string)AutoUpdateWithSilenceStartTimeComboBox.SelectedItem; SaveSettingsToFile(); } - private void AutoUpdateWithSilenceEndTimeComboBox_SelectionChanged(object sender, RoutedEventArgs e) { + private void AutoUpdateWithSilenceEndTimeComboBox_SelectionChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Startup.AutoUpdateWithSilenceEndTime = (string)AutoUpdateWithSilenceEndTimeComboBox.SelectedItem; SaveSettingsToFile(); } - private void ToggleSwitchRunAtStartup_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchRunAtStartup_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; - if (ToggleSwitchRunAtStartup.IsOn) { + if (ToggleSwitchRunAtStartup.IsOn) + { StartAutomaticallyDel("InkCanvas"); StartAutomaticallyCreate("Ink Canvas Annotation"); - } else { + } + else + { StartAutomaticallyDel("InkCanvas"); StartAutomaticallyDel("Ink Canvas Annotation"); } } - private void ToggleSwitchFoldAtStartup_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchFoldAtStartup_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Startup.IsFoldAtStartup = ToggleSwitchFoldAtStartup.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchSupportPowerPoint_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchSupportPowerPoint_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.PowerPointSupport = ToggleSwitchSupportPowerPoint.IsOn; @@ -110,7 +123,8 @@ namespace Ink_Canvas { } } - private void ToggleSwitchShowCanvasAtNewSlideShow_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchShowCanvasAtNewSlideShow_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.IsShowCanvasAtNewSlideShow = ToggleSwitchShowCanvasAtNewSlideShow.IsOn; @@ -121,7 +135,8 @@ namespace Ink_Canvas { #region Startup - private void ToggleSwitchEnableNibMode_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableNibMode_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; if (sender == ToggleSwitchEnableNibMode) BoardToggleSwitchEnableNibMode.IsOn = ToggleSwitchEnableNibMode.IsOn; @@ -140,14 +155,18 @@ namespace Ink_Canvas { #region Appearance - private void ToggleSwitchEnableDisPlayNibModeToggle_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableDisPlayNibModeToggle_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Appearance.IsEnableDisPlayNibModeToggler = ToggleSwitchEnableDisPlayNibModeToggle.IsOn; SaveSettingsToFile(); - if (!ToggleSwitchEnableDisPlayNibModeToggle.IsOn) { + if (!ToggleSwitchEnableDisPlayNibModeToggle.IsOn) + { NibModeSimpleStackPanel.Visibility = Visibility.Collapsed; BoardNibModeSimpleStackPanel.Visibility = Visibility.Collapsed; - } else { + } + else + { NibModeSimpleStackPanel.Visibility = Visibility.Visible; BoardNibModeSimpleStackPanel.Visibility = Visibility.Visible; } @@ -159,13 +178,15 @@ namespace Ink_Canvas { // SaveSettingsToFile(); //} - private void ToggleSwitchEnableQuickPanel_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableQuickPanel_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Appearance.IsShowQuickPanel = ToggleSwitchEnableQuickPanel.IsOn; SaveSettingsToFile(); } - private void ViewboxFloatingBarScaleTransformValueSlider_ValueChanged(object sender, RoutedEventArgs e) { + private void ViewboxFloatingBarScaleTransformValueSlider_ValueChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Appearance.ViewboxFloatingBarScaleTransformValue = ViewboxFloatingBarScaleTransformValueSlider.Value; @@ -182,33 +203,38 @@ namespace Ink_Canvas { ViewboxFloatingBarMarginAnimation(100, true); } - private void ViewboxFloatingBarOpacityValueSlider_ValueChanged(object sender, RoutedEventArgs e) { + private void ViewboxFloatingBarOpacityValueSlider_ValueChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Appearance.ViewboxFloatingBarOpacityValue = ViewboxFloatingBarOpacityValueSlider.Value; SaveSettingsToFile(); ViewboxFloatingBar.Opacity = Settings.Appearance.ViewboxFloatingBarOpacityValue; } - private void ViewboxFloatingBarOpacityInPPTValueSlider_ValueChanged(object sender, RoutedEventArgs e) { + private void ViewboxFloatingBarOpacityInPPTValueSlider_ValueChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Appearance.ViewboxFloatingBarOpacityInPPTValue = ViewboxFloatingBarOpacityInPPTValueSlider.Value; SaveSettingsToFile(); } - private void ToggleSwitchEnableTrayIcon_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableTrayIcon_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Appearance.EnableTrayIcon = ToggleSwitchEnableTrayIcon.IsOn; ICCTrayIconExampleImage.Visibility = Settings.Appearance.EnableTrayIcon ? Visibility.Visible : Visibility.Collapsed; var _taskbar = (TaskbarIcon)Application.Current.Resources["TaskbarTrayIcon"]; - _taskbar.Visibility = ToggleSwitchEnableTrayIcon.IsOn? Visibility.Visible : Visibility.Collapsed; + _taskbar.Visibility = ToggleSwitchEnableTrayIcon.IsOn ? Visibility.Visible : Visibility.Collapsed; SaveSettingsToFile(); } - private void ComboBoxUnFoldBtnImg_SelectionChanged(object sender, RoutedEventArgs e) { + private void ComboBoxUnFoldBtnImg_SelectionChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Appearance.UnFoldButtonImageType = ComboBoxUnFoldBtnImg.SelectedIndex; SaveSettingsToFile(); - if (ComboBoxUnFoldBtnImg.SelectedIndex == 0) { + if (ComboBoxUnFoldBtnImg.SelectedIndex == 0) + { RightUnFoldBtnImgChevron.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/new-icons/unfold-chevron.png")); RightUnFoldBtnImgChevron.Width = 14; @@ -219,7 +245,9 @@ namespace Ink_Canvas { LeftUnFoldBtnImgChevron.Width = 14; LeftUnFoldBtnImgChevron.Height = 14; LeftUnFoldBtnImgChevron.RenderTransform = null; - } else if (ComboBoxUnFoldBtnImg.SelectedIndex == 1) { + } + else if (ComboBoxUnFoldBtnImg.SelectedIndex == 1) + { RightUnFoldBtnImgChevron.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/new-icons/pen-white.png")); RightUnFoldBtnImgChevron.Width = 18; @@ -233,23 +261,30 @@ namespace Ink_Canvas { } } - private void ComboBoxChickenSoupSource_SelectionChanged(object sender, RoutedEventArgs e) { + private void ComboBoxChickenSoupSource_SelectionChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Appearance.ChickenSoupSource = ComboBoxChickenSoupSource.SelectedIndex; SaveSettingsToFile(); - if (Settings.Appearance.ChickenSoupSource == 0) { + if (Settings.Appearance.ChickenSoupSource == 0) + { int randChickenSoupIndex = new Random().Next(ChickenSoup.OSUPlayerYuLu.Length); BlackBoardWaterMark.Text = ChickenSoup.OSUPlayerYuLu[randChickenSoupIndex]; - } else if (Settings.Appearance.ChickenSoupSource == 1) { + } + else if (Settings.Appearance.ChickenSoupSource == 1) + { int randChickenSoupIndex = new Random().Next(ChickenSoup.MingYanJingJu.Length); BlackBoardWaterMark.Text = ChickenSoup.MingYanJingJu[randChickenSoupIndex]; - } else if (Settings.Appearance.ChickenSoupSource == 2) { + } + else if (Settings.Appearance.ChickenSoupSource == 2) + { int randChickenSoupIndex = new Random().Next(ChickenSoup.GaoKaoPhrases.Length); BlackBoardWaterMark.Text = ChickenSoup.GaoKaoPhrases[randChickenSoupIndex]; } } - private void ToggleSwitchEnableViewboxBlackBoardScaleTransform_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableViewboxBlackBoardScaleTransform_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Appearance.EnableViewboxBlackBoardScaleTransform = ToggleSwitchEnableViewboxBlackBoardScaleTransform.IsOn; @@ -257,64 +292,85 @@ namespace Ink_Canvas { LoadSettings(); } - public void ComboBoxFloatingBarImg_SelectionChanged(object sender, RoutedEventArgs e) { + public void ComboBoxFloatingBarImg_SelectionChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Appearance.FloatingBarImg = ComboBoxFloatingBarImg.SelectedIndex; UpdateFloatingBarIcon(); SaveSettingsToFile(); } - + public void UpdateFloatingBarIcon() { int index = Settings.Appearance.FloatingBarImg; - - if (index == 0) { + + if (index == 0) + { FloatingbarHeadIconImg.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/icc.png")); FloatingbarHeadIconImg.Margin = new Thickness(0.5); - } else if (index == 1) { + } + else if (index == 1) + { FloatingbarHeadIconImg.Source = new BitmapImage( new Uri("pack://application:,,,/Resources/Icons-png/icc-transparent-dark-small.png")); FloatingbarHeadIconImg.Margin = new Thickness(1.2); - } else if (index == 2) { + } + else if (index == 2) + { FloatingbarHeadIconImg.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/kuandoujiyanhuaji.png")); FloatingbarHeadIconImg.Margin = new Thickness(2, 2, 2, 1.5); - } else if (index == 3) { + } + else if (index == 3) + { FloatingbarHeadIconImg.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/kuanshounvhuaji.png")); FloatingbarHeadIconImg.Margin = new Thickness(2, 2, 2, 1.5); - } else if (index == 4) { + } + else if (index == 4) + { FloatingbarHeadIconImg.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/kuanciya.png")); FloatingbarHeadIconImg.Margin = new Thickness(2, 2, 2, 1.5); - } else if (index == 5) { + } + else if (index == 5) + { FloatingbarHeadIconImg.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/kuanneikuhuaji.png")); FloatingbarHeadIconImg.Margin = new Thickness(2, 2, 2, 1.5); - } else if (index == 6) { + } + else if (index == 6) + { FloatingbarHeadIconImg.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/kuandogeyuanliangwo.png")); FloatingbarHeadIconImg.Margin = new Thickness(2, 2, 2, 1.5); - } else if (index == 7) { + } + else if (index == 7) + { FloatingbarHeadIconImg.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/tiebahuaji.png")); FloatingbarHeadIconImg.Margin = new Thickness(2, 2, 2, 1); - } else if (index >= 8 && index - 8 < Settings.Appearance.CustomFloatingBarImgs.Count) { + } + else if (index >= 8 && index - 8 < Settings.Appearance.CustomFloatingBarImgs.Count) + { // 使用自定义图标 var customIcon = Settings.Appearance.CustomFloatingBarImgs[index - 8]; - try { + try + { FloatingbarHeadIconImg.Source = new BitmapImage(new Uri(customIcon.FilePath)); FloatingbarHeadIconImg.Margin = new Thickness(2); - } catch { + } + catch + { // 如果加载失败,使用默认图标 FloatingbarHeadIconImg.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/icc.png")); FloatingbarHeadIconImg.Margin = new Thickness(0.5); } } } - + public void UpdateCustomIconsInComboBox() { // 保留前8个内置图标选项 @@ -322,7 +378,7 @@ namespace Ink_Canvas { { ComboBoxFloatingBarImg.Items.RemoveAt(ComboBoxFloatingBarImg.Items.Count - 1); } - + // 添加自定义图标选项 foreach (var customIcon in Settings.Appearance.CustomFloatingBarImgs) { @@ -332,20 +388,20 @@ namespace Ink_Canvas { ComboBoxFloatingBarImg.Items.Add(item); } } - + private void ButtonAddCustomIcon_Click(object sender, RoutedEventArgs e) { AddCustomIconWindow dialog = new AddCustomIconWindow(this); dialog.Owner = this; dialog.ShowDialog(); - + if (dialog.IsSuccess) { // 自动选中新添加的图标 ComboBoxFloatingBarImg.SelectedIndex = ComboBoxFloatingBarImg.Items.Count - 1; } } - + private void ButtonManageCustomIcons_Click(object sender, RoutedEventArgs e) { CustomIconWindow dialog = new CustomIconWindow(this); @@ -353,14 +409,19 @@ namespace Ink_Canvas { dialog.ShowDialog(); } - private void ToggleSwitchEnableTimeDisplayInWhiteboardMode_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableTimeDisplayInWhiteboardMode_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Appearance.EnableTimeDisplayInWhiteboardMode = ToggleSwitchEnableTimeDisplayInWhiteboardMode.IsOn; - if (currentMode == 1) { - if (ToggleSwitchEnableTimeDisplayInWhiteboardMode.IsOn) { + if (currentMode == 1) + { + if (ToggleSwitchEnableTimeDisplayInWhiteboardMode.IsOn) + { WaterMarkTime.Visibility = Visibility.Visible; WaterMarkDate.Visibility = Visibility.Visible; - } else { + } + else + { WaterMarkTime.Visibility = Visibility.Collapsed; WaterMarkDate.Visibility = Visibility.Collapsed; } @@ -370,13 +431,18 @@ namespace Ink_Canvas { LoadSettings(); } - private void ToggleSwitchEnableChickenSoupInWhiteboardMode_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableChickenSoupInWhiteboardMode_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Appearance.EnableChickenSoupInWhiteboardMode = ToggleSwitchEnableChickenSoupInWhiteboardMode.IsOn; - if (currentMode == 1) { - if (ToggleSwitchEnableTimeDisplayInWhiteboardMode.IsOn) { + if (currentMode == 1) + { + if (ToggleSwitchEnableTimeDisplayInWhiteboardMode.IsOn) + { BlackBoardWaterMark.Visibility = Visibility.Visible; - } else { + } + else + { BlackBoardWaterMark.Visibility = Visibility.Collapsed; } } @@ -424,7 +490,8 @@ namespace Ink_Canvas { // SaveSettingsToFile(); //} - private void ToggleSwitchShowPPTButton_OnToggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchShowPPTButton_OnToggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.ShowPPTButton = ToggleSwitchShowPPTButton.IsOn; SaveSettingsToFile(); @@ -437,13 +504,15 @@ namespace Ink_Canvas { UpdatePPTBtnPreview(); } - private void ToggleSwitchEnablePPTButtonPageClickable_OnToggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnablePPTButtonPageClickable_OnToggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.EnablePPTButtonPageClickable = ToggleSwitchEnablePPTButtonPageClickable.IsOn; SaveSettingsToFile(); } - private void CheckboxEnableLBPPTButton_IsCheckChanged(object sender, RoutedEventArgs e) { + private void CheckboxEnableLBPPTButton_IsCheckChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; var str = Settings.PowerPointSettings.PPTButtonsDisplayOption.ToString(); char[] c = str.ToCharArray(); @@ -602,7 +671,8 @@ namespace Ink_Canvas { UpdatePPTBtnPreview(); } - private void PPTButtonLeftPositionValueSlider_ValueChanged(object sender, RoutedEventArgs e) { + private void PPTButtonLeftPositionValueSlider_ValueChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.PPTLSButtonPosition = (int)PPTButtonLeftPositionValueSlider.Value; UpdatePPTBtnSlidersStatus(); @@ -611,13 +681,18 @@ namespace Ink_Canvas { UpdatePPTBtnPreview(); } - private void UpdatePPTBtnSlidersStatus() { - if (PPTButtonLeftPositionValueSlider.Value <= -500 || PPTButtonLeftPositionValueSlider.Value >= 500) { - if (PPTButtonLeftPositionValueSlider.Value >= 500) { + private void UpdatePPTBtnSlidersStatus() + { + if (PPTButtonLeftPositionValueSlider.Value <= -500 || PPTButtonLeftPositionValueSlider.Value >= 500) + { + if (PPTButtonLeftPositionValueSlider.Value >= 500) + { PPTBtnLSPlusBtn.IsEnabled = false; PPTBtnLSPlusBtn.Opacity = 0.5; PPTButtonLeftPositionValueSlider.Value = 500; - } else if (PPTButtonLeftPositionValueSlider.Value <= -500) { + } + else if (PPTButtonLeftPositionValueSlider.Value <= -500) + { PPTBtnLSMinusBtn.IsEnabled = false; PPTBtnLSMinusBtn.Opacity = 0.5; PPTButtonLeftPositionValueSlider.Value = -500; @@ -655,7 +730,8 @@ namespace Ink_Canvas { } } - private void PPTBtnLSPlusBtn_Clicked(object sender, RoutedEventArgs e) { + private void PPTBtnLSPlusBtn_Clicked(object sender, RoutedEventArgs e) + { if (!isLoaded) return; PPTButtonLeftPositionValueSlider.Value++; UpdatePPTBtnSlidersStatus(); @@ -684,7 +760,8 @@ namespace Ink_Canvas { UpdatePPTBtnPreview(); } - private void PPTBtnLSResetBtn_Clicked(object sender, RoutedEventArgs e) { + private void PPTBtnLSResetBtn_Clicked(object sender, RoutedEventArgs e) + { if (!isLoaded) return; PPTButtonLeftPositionValueSlider.Value = 0; UpdatePPTBtnSlidersStatus(); @@ -741,7 +818,7 @@ namespace Ink_Canvas { Settings.PowerPointSettings.PPTRSButtonPosition = (int)PPTButtonRightPositionValueSlider.Value; UpdatePPTBtnSlidersStatus(); UpdatePPTUIManagerSettings(); - SliderDelayAction.DebounceAction(2000,null, SaveSettingsToFile); + SliderDelayAction.DebounceAction(2000, null, SaveSettingsToFile); UpdatePPTBtnPreview(); } @@ -762,25 +839,32 @@ namespace Ink_Canvas { } } - private void UpdatePPTBtnPreview() { + private void UpdatePPTBtnPreview() + { //new BitmapImage(new Uri("pack://application:,,,/Resources/new-icons/unfold-chevron.png")); var bopt = Settings.PowerPointSettings.PPTBButtonsOption.ToString(); char[] boptc = bopt.ToCharArray(); - if (boptc[1] == '2') { + if (boptc[1] == '2') + { PPTBtnPreviewLB.Opacity = 0.5; PPTBtnPreviewRB.Opacity = 0.5; - } else { + } + else + { PPTBtnPreviewLB.Opacity = 1; PPTBtnPreviewRB.Opacity = 1; } - if (boptc[2] == '2') { + if (boptc[2] == '2') + { PPTBtnPreviewLB.Source = new BitmapImage( new Uri("pack://application:,,,/Resources/PresentationExample/bottombar-dark.png")); PPTBtnPreviewRB.Source = new BitmapImage( new Uri("pack://application:,,,/Resources/PresentationExample/bottombar-dark.png")); - } else { + } + else + { PPTBtnPreviewLB.Source = new BitmapImage( new Uri("pack://application:,,,/Resources/PresentationExample/bottombar-white.png")); @@ -821,23 +905,27 @@ namespace Ink_Canvas { var dopt = Settings.PowerPointSettings.PPTButtonsDisplayOption.ToString(); char[] doptc = dopt.ToCharArray(); - if (Settings.PowerPointSettings.ShowPPTButton) { + if (Settings.PowerPointSettings.ShowPPTButton) + { PPTBtnPreviewLB.Visibility = doptc[0] == '2' ? Visibility.Visible : Visibility.Collapsed; PPTBtnPreviewRB.Visibility = doptc[1] == '2' ? Visibility.Visible : Visibility.Collapsed; PPTBtnPreviewLS.Visibility = doptc[2] == '2' ? Visibility.Visible : Visibility.Collapsed; PPTBtnPreviewRS.Visibility = doptc[3] == '2' ? Visibility.Visible : Visibility.Collapsed; - } else { + } + else + { PPTBtnPreviewLB.Visibility = Visibility.Collapsed; PPTBtnPreviewRB.Visibility = Visibility.Collapsed; PPTBtnPreviewLS.Visibility = Visibility.Collapsed; PPTBtnPreviewRS.Visibility = Visibility.Collapsed; } - + PPTBtnPreviewRSTransform.Y = -(Settings.PowerPointSettings.PPTRSButtonPosition * 0.5); PPTBtnPreviewLSTransform.Y = -(Settings.PowerPointSettings.PPTLSButtonPosition * 0.5); } - private void ToggleSwitchShowCursor_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchShowCursor_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Canvas.IsShowCursor = ToggleSwitchShowCursor.IsOn; @@ -846,81 +934,91 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void ToggleSwitchEnablePressureTouchMode_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnablePressureTouchMode_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Canvas.EnablePressureTouchMode = ToggleSwitchEnablePressureTouchMode.IsOn; - + // 如果启用了压感触屏模式,则自动关闭屏蔽压感 - if (Settings.Canvas.EnablePressureTouchMode && Settings.Canvas.DisablePressure) { + if (Settings.Canvas.EnablePressureTouchMode && Settings.Canvas.DisablePressure) + { Settings.Canvas.DisablePressure = false; ToggleSwitchDisablePressure.IsOn = false; } - + SaveSettingsToFile(); } - private void ToggleSwitchDisablePressure_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchDisablePressure_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Canvas.DisablePressure = ToggleSwitchDisablePressure.IsOn; - + // 如果启用了屏蔽压感,则自动关闭压感触屏模式 - if (Settings.Canvas.DisablePressure && Settings.Canvas.EnablePressureTouchMode) { + if (Settings.Canvas.DisablePressure && Settings.Canvas.EnablePressureTouchMode) + { Settings.Canvas.EnablePressureTouchMode = false; ToggleSwitchEnablePressureTouchMode.IsOn = false; } - + SaveSettingsToFile(); } - private void ToggleSwitchAutoStraightenLine_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoStraightenLine_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; - + Settings.Canvas.AutoStraightenLine = ToggleSwitchAutoStraightenLine.IsOn; SaveSettingsToFile(); } - - private void AutoStraightenLineThresholdSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) { + + private void AutoStraightenLineThresholdSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { if (!isLoaded) return; - + Settings.Canvas.AutoStraightenLineThreshold = (int)e.NewValue; SaveSettingsToFile(); } - - private void ToggleSwitchLineEndpointSnapping_Toggled(object sender, RoutedEventArgs e) { + + private void ToggleSwitchLineEndpointSnapping_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; - + Settings.Canvas.LineEndpointSnapping = ToggleSwitchLineEndpointSnapping.IsOn; SaveSettingsToFile(); } - - private void LineEndpointSnappingThresholdSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) { + + private void LineEndpointSnappingThresholdSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { if (!isLoaded) return; - + Settings.Canvas.LineEndpointSnappingThreshold = (int)e.NewValue; SaveSettingsToFile(); } - - private void LineStraightenSensitivitySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) { + + private void LineStraightenSensitivitySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { if (!isLoaded) return; - + // 记录旧值用于调试 double oldValue = Settings.InkToShape.LineStraightenSensitivity; - + // 确保灵敏度值被正确保存到设置中 Settings.InkToShape.LineStraightenSensitivity = e.NewValue; - + // 输出调试信息,观察值变化 Debug.WriteLine($"LineStraightenSensitivity changed: {oldValue} -> {e.NewValue}"); - + // 立即保存设置到文件,确保设置不会丢失 SaveSettingsToFile(); } - - private void ToggleSwitchHighPrecisionLineStraighten_Toggled(object sender, RoutedEventArgs e) { + + private void ToggleSwitchHighPrecisionLineStraighten_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; - + Settings.Canvas.HighPrecisionLineStraighten = ToggleSwitchHighPrecisionLineStraighten.IsOn; Debug.WriteLine($"HighPrecisionLineStraighten changed: {Settings.Canvas.HighPrecisionLineStraighten}"); SaveSettingsToFile(); @@ -930,12 +1028,16 @@ namespace Ink_Canvas { #region Canvas - private void ComboBoxPenStyle_SelectionChanged(object sender, SelectionChangedEventArgs e) { + private void ComboBoxPenStyle_SelectionChanged(object sender, SelectionChangedEventArgs e) + { if (!isLoaded) return; - if (sender == ComboBoxPenStyle) { + if (sender == ComboBoxPenStyle) + { Settings.Canvas.InkStyle = ComboBoxPenStyle.SelectedIndex; BoardComboBoxPenStyle.SelectedIndex = ComboBoxPenStyle.SelectedIndex; - } else { + } + else + { Settings.Canvas.InkStyle = BoardComboBoxPenStyle.SelectedIndex; ComboBoxPenStyle.SelectedIndex = BoardComboBoxPenStyle.SelectedIndex; } @@ -943,28 +1045,34 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void ComboBoxEraserSize_SelectionChanged(object sender, SelectionChangedEventArgs e) { + private void ComboBoxEraserSize_SelectionChanged(object sender, SelectionChangedEventArgs e) + { if (!isLoaded) return; Settings.Canvas.EraserSize = ComboBoxEraserSize.SelectedIndex; // 使用新的高级橡皮擦形状应用方法 ApplyAdvancedEraserShape(); - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { inkCanvas.EditingMode = InkCanvasEditingMode.Ink; inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint; } SaveSettingsToFile(); } - private void ComboBoxEraserSizeFloatingBar_SelectionChanged(object sender, SelectionChangedEventArgs e) { + private void ComboBoxEraserSizeFloatingBar_SelectionChanged(object sender, SelectionChangedEventArgs e) + { if (!isLoaded) return; ComboBox s = (ComboBox)sender; Settings.Canvas.EraserSize = s.SelectedIndex; - if (s == ComboBoxEraserSizeFloatingBar) { + if (s == ComboBoxEraserSizeFloatingBar) + { BoardComboBoxEraserSize.SelectedIndex = s.SelectedIndex; ComboBoxEraserSize.SelectedIndex = s.SelectedIndex; - } else if (s == BoardComboBoxEraserSize) { + } + else if (s == BoardComboBoxEraserSize) + { ComboBoxEraserSizeFloatingBar.SelectedIndex = s.SelectedIndex; ComboBoxEraserSize.SelectedIndex = s.SelectedIndex; } @@ -972,14 +1080,16 @@ namespace Ink_Canvas { // 使用新的高级橡皮擦形状应用方法 ApplyAdvancedEraserShape(); - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { inkCanvas.EditingMode = InkCanvasEditingMode.Ink; inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint; } SaveSettingsToFile(); } - private void SwitchToCircleEraser(object sender, MouseButtonEventArgs e) { + private void SwitchToCircleEraser(object sender, MouseButtonEventArgs e) + { if (!isLoaded) return; Settings.Canvas.EraserShapeType = 0; SaveSettingsToFile(); @@ -993,7 +1103,8 @@ namespace Ink_Canvas { inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint; } - private void SwitchToRectangleEraser(object sender, MouseButtonEventArgs e) { + private void SwitchToRectangleEraser(object sender, MouseButtonEventArgs e) + { if (!isLoaded) return; Settings.Canvas.EraserShapeType = 1; SaveSettingsToFile(); @@ -1008,7 +1119,8 @@ namespace Ink_Canvas { } - private void InkWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) { + private void InkWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { if (!isLoaded) return; if (sender == BoardInkWidthSlider) InkWidthSlider.Value = ((Slider)sender).Value; if (sender == InkWidthSlider) BoardInkWidthSlider.Value = ((Slider)sender).Value; @@ -1018,7 +1130,8 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void HighlighterWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) { + private void HighlighterWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { if (!isLoaded) return; // if (sender == BoardInkWidthSlider) InkWidthSlider.Value = ((Slider)sender).Value; // if (sender == InkWidthSlider) BoardInkWidthSlider.Value = ((Slider)sender).Value; @@ -1028,7 +1141,8 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void InkAlphaSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) { + private void InkAlphaSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { if (!isLoaded) return; // if (sender == BoardInkWidthSlider) InkWidthSlider.Value = ((Slider)sender).Value; // if (sender == InkWidthSlider) BoardInkWidthSlider.Value = ((Slider)sender).Value; @@ -1042,7 +1156,8 @@ namespace Ink_Canvas { // SaveSettingsToFile(); } - private void ComboBoxHyperbolaAsymptoteOption_SelectionChanged(object sender, SelectionChangedEventArgs e) { + private void ComboBoxHyperbolaAsymptoteOption_SelectionChanged(object sender, SelectionChangedEventArgs e) + { if (!isLoaded) return; Settings.Canvas.HyperbolaAsymptoteOption = (OptionalOperation)ComboBoxHyperbolaAsymptoteOption.SelectedIndex; @@ -1053,35 +1168,40 @@ namespace Ink_Canvas { #region Automation - private void StartOrStoptimerCheckAutoFold() { + private void StartOrStoptimerCheckAutoFold() + { if (Settings.Automation.IsEnableAutoFold) timerCheckAutoFold.Start(); else timerCheckAutoFold.Stop(); } - private void ToggleSwitchAutoFoldInEasiNote_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldInEasiNote_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldInEasiNote = ToggleSwitchAutoFoldInEasiNote.IsOn; SaveSettingsToFile(); StartOrStoptimerCheckAutoFold(); } - private void ToggleSwitchAutoFoldInEasiNoteIgnoreDesktopAnno_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldInEasiNoteIgnoreDesktopAnno_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldInEasiNoteIgnoreDesktopAnno = ToggleSwitchAutoFoldInEasiNoteIgnoreDesktopAnno.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchAutoFoldInEasiCamera_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldInEasiCamera_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldInEasiCamera = ToggleSwitchAutoFoldInEasiCamera.IsOn; SaveSettingsToFile(); StartOrStoptimerCheckAutoFold(); } - private void ToggleSwitchAutoFoldInEasiNote3_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldInEasiNote3_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldInEasiNote3 = ToggleSwitchAutoFoldInEasiNote3.IsOn; SaveSettingsToFile(); @@ -1096,56 +1216,64 @@ namespace Ink_Canvas { StartOrStoptimerCheckAutoFold(); } - private void ToggleSwitchAutoFoldInEasiNote5C_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldInEasiNote5C_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldInEasiNote5C = ToggleSwitchAutoFoldInEasiNote5C.IsOn; SaveSettingsToFile(); StartOrStoptimerCheckAutoFold(); } - private void ToggleSwitchAutoFoldInSeewoPincoTeacher_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldInSeewoPincoTeacher_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldInSeewoPincoTeacher = ToggleSwitchAutoFoldInSeewoPincoTeacher.IsOn; SaveSettingsToFile(); StartOrStoptimerCheckAutoFold(); } - private void ToggleSwitchAutoFoldInHiteTouchPro_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldInHiteTouchPro_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldInHiteTouchPro = ToggleSwitchAutoFoldInHiteTouchPro.IsOn; SaveSettingsToFile(); StartOrStoptimerCheckAutoFold(); } - private void ToggleSwitchAutoFoldInHiteLightBoard_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldInHiteLightBoard_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldInHiteLightBoard = ToggleSwitchAutoFoldInHiteLightBoard.IsOn; SaveSettingsToFile(); StartOrStoptimerCheckAutoFold(); } - private void ToggleSwitchAutoFoldInHiteCamera_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldInHiteCamera_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldInHiteCamera = ToggleSwitchAutoFoldInHiteCamera.IsOn; SaveSettingsToFile(); StartOrStoptimerCheckAutoFold(); } - private void ToggleSwitchAutoFoldInWxBoardMain_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldInWxBoardMain_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldInWxBoardMain = ToggleSwitchAutoFoldInWxBoardMain.IsOn; SaveSettingsToFile(); StartOrStoptimerCheckAutoFold(); } - private void ToggleSwitchAutoFoldInOldZyBoard_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldInOldZyBoard_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldInOldZyBoard = ToggleSwitchAutoFoldInOldZyBoard.IsOn; SaveSettingsToFile(); StartOrStoptimerCheckAutoFold(); } - private void ToggleSwitchAutoFoldInMSWhiteboard_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldInMSWhiteboard_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldInMSWhiteboard = ToggleSwitchAutoFoldInMSWhiteboard.IsOn; SaveSettingsToFile(); @@ -1192,7 +1320,8 @@ namespace Ink_Canvas { StartOrStoptimerCheckAutoFold(); } - private void ToggleSwitchAutoFoldInPPTSlideShow_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldInPPTSlideShow_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldInPPTSlideShow = ToggleSwitchAutoFoldInPPTSlideShow.IsOn; if (Settings.Automation.IsAutoFoldInPPTSlideShow) @@ -1200,7 +1329,9 @@ namespace Ink_Canvas { SettingsPPTInkingAndAutoFoldExplictBorder.Visibility = Visibility.Visible; SettingsShowCanvasAtNewSlideShowStackPanel.Opacity = 0.5; SettingsShowCanvasAtNewSlideShowStackPanel.IsHitTestVisible = false; - } else { + } + else + { SettingsPPTInkingAndAutoFoldExplictBorder.Visibility = Visibility.Collapsed; SettingsShowCanvasAtNewSlideShowStackPanel.Opacity = 1; SettingsShowCanvasAtNewSlideShowStackPanel.IsHitTestVisible = true; @@ -1209,7 +1340,8 @@ namespace Ink_Canvas { StartOrStoptimerCheckAutoFold(); } - private void ToggleSwitchAutoKillPptService_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoKillPptService_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoKillPptService = ToggleSwitchAutoKillPptService.IsOn; SaveSettingsToFile(); @@ -1223,7 +1355,8 @@ namespace Ink_Canvas { timerKillProcess.Stop(); } - private void ToggleSwitchAutoKillEasiNote_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoKillEasiNote_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoKillEasiNote = ToggleSwitchAutoKillEasiNote.IsOn; SaveSettingsToFile(); @@ -1236,7 +1369,8 @@ namespace Ink_Canvas { timerKillProcess.Stop(); } - private void ToggleSwitchAutoKillHiteAnnotation_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoKillHiteAnnotation_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoKillHiteAnnotation = ToggleSwitchAutoKillHiteAnnotation.IsOn; SaveSettingsToFile(); @@ -1318,7 +1452,7 @@ namespace Ink_Canvas { else timerKillProcess.Stop(); } - + private void ToggleSwitchAutoEnterAnnotationModeWhenExitFoldMode_Toggled(object sender, RoutedEventArgs e) { if (!isLoaded) return; @@ -1326,13 +1460,15 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void ToggleSwitchSaveScreenshotsInDateFolders_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchSaveScreenshotsInDateFolders_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsSaveScreenshotsInDateFolders = ToggleSwitchSaveScreenshotsInDateFolders.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchAutoSaveStrokesAtScreenshot_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoSaveStrokesAtScreenshot_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoSaveStrokesAtScreenshot = ToggleSwitchAutoSaveStrokesAtScreenshot.IsOn; ToggleSwitchAutoSaveStrokesAtClear.Header = @@ -1340,40 +1476,45 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void ToggleSwitchAutoSaveStrokesAtClear_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoSaveStrokesAtClear_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoSaveStrokesAtClear = ToggleSwitchAutoSaveStrokesAtClear.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchHideStrokeWhenSelecting_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchHideStrokeWhenSelecting_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Canvas.HideStrokeWhenSelecting = ToggleSwitchHideStrokeWhenSelecting.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchClearCanvasAndClearTimeMachine_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchClearCanvasAndClearTimeMachine_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Canvas.ClearCanvasAndClearTimeMachine = ToggleSwitchClearCanvasAndClearTimeMachine.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchFitToCurve_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchFitToCurve_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; drawingAttributes.FitToCurve = ToggleSwitchFitToCurve.IsOn; Settings.Canvas.FitToCurve = ToggleSwitchFitToCurve.IsOn; - + // 启用原来的FitToCurve时自动禁用高级贝塞尔平滑 if (ToggleSwitchFitToCurve.IsOn) { ToggleSwitchAdvancedBezierSmoothing.IsOn = false; Settings.Canvas.UseAdvancedBezierSmoothing = false; } - + SaveSettingsToFile(); } - private void ToggleSwitchAdvancedBezierSmoothing_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAdvancedBezierSmoothing_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Canvas.UseAdvancedBezierSmoothing = ToggleSwitchAdvancedBezierSmoothing.IsOn; @@ -1439,83 +1580,96 @@ namespace Ink_Canvas { } } */ - - private void ToggleSwitchAutoSaveStrokesInPowerPoint_Toggled(object sender, RoutedEventArgs e) { + + private void ToggleSwitchAutoSaveStrokesInPowerPoint_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint = ToggleSwitchAutoSaveStrokesInPowerPoint.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchNotifyPreviousPage_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchNotifyPreviousPage_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.IsNotifyPreviousPage = ToggleSwitchNotifyPreviousPage.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchNotifyHiddenPage_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchNotifyHiddenPage_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.IsNotifyHiddenPage = ToggleSwitchNotifyHiddenPage.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchNotifyAutoPlayPresentation_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchNotifyAutoPlayPresentation_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.IsNotifyAutoPlayPresentation = ToggleSwitchNotifyAutoPlayPresentation.IsOn; SaveSettingsToFile(); } - private void SideControlMinimumAutomationSlider_ValueChanged(object sender, RoutedEventArgs e) { + private void SideControlMinimumAutomationSlider_ValueChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.MinimumAutomationStrokeNumber = (int)SideControlMinimumAutomationSlider.Value; SaveSettingsToFile(); } - private void AutoSavedStrokesLocationTextBox_TextChanged(object sender, RoutedEventArgs e) { + private void AutoSavedStrokesLocationTextBox_TextChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.AutoSavedStrokesLocation = AutoSavedStrokesLocation.Text; SaveSettingsToFile(); } - private void AutoSavedStrokesLocationButton_Click(object sender, RoutedEventArgs e) { + private void AutoSavedStrokesLocationButton_Click(object sender, RoutedEventArgs e) + { var folderBrowser = new FolderBrowserDialog(); folderBrowser.ShowDialog(); if (folderBrowser.SelectedPath.Length > 0) AutoSavedStrokesLocation.Text = folderBrowser.SelectedPath; SaveSettingsToFile(); } - private void SetAutoSavedStrokesLocationToDiskDButton_Click(object sender, RoutedEventArgs e) { + private void SetAutoSavedStrokesLocationToDiskDButton_Click(object sender, RoutedEventArgs e) + { AutoSavedStrokesLocation.Text = @"D:\Ink Canvas"; SaveSettingsToFile(); } - private void SetAutoSavedStrokesLocationToDocumentFolderButton_Click(object sender, RoutedEventArgs e) { + private void SetAutoSavedStrokesLocationToDocumentFolderButton_Click(object sender, RoutedEventArgs e) + { AutoSavedStrokesLocation.Text = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Ink Canvas"; SaveSettingsToFile(); } - private void ToggleSwitchAutoDelSavedFiles_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoDelSavedFiles_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.AutoDelSavedFiles = ToggleSwitchAutoDelSavedFiles.IsOn; SaveSettingsToFile(); } private void - ComboBoxAutoDelSavedFilesDaysThreshold_SelectionChanged(object sender, SelectionChangedEventArgs e) { + ComboBoxAutoDelSavedFilesDaysThreshold_SelectionChanged(object sender, SelectionChangedEventArgs e) + { if (!isLoaded) return; Settings.Automation.AutoDelSavedFilesDaysThreshold = int.Parse(((ComboBoxItem)ComboBoxAutoDelSavedFilesDaysThreshold.SelectedItem).Content.ToString()); SaveSettingsToFile(); } - private void ToggleSwitchAutoSaveScreenShotInPowerPoint_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoSaveScreenShotInPowerPoint_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint = ToggleSwitchAutoSaveScreenShotInPowerPoint.IsOn; SaveSettingsToFile(); } - - private void ToggleSwitchSaveFullPageStrokes_Toggled(object sender, RoutedEventArgs e) { + + private void ToggleSwitchSaveFullPageStrokes_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsSaveFullPageStrokes = ToggleSwitchSaveFullPageStrokes.IsOn; SaveSettingsToFile(); @@ -1525,20 +1679,23 @@ namespace Ink_Canvas { #region Gesture - private void ToggleSwitchEnableFingerGestureSlideShowControl_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableFingerGestureSlideShowControl_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.IsEnableFingerGestureSlideShowControl = ToggleSwitchEnableFingerGestureSlideShowControl.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchAutoSwitchTwoFingerGesture_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoSwitchTwoFingerGesture_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Gesture.AutoSwitchTwoFingerGesture = ToggleSwitchAutoSwitchTwoFingerGesture.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchEnableTwoFingerZoom_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableTwoFingerZoom_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; if (sender == ToggleSwitchEnableTwoFingerZoom) BoardToggleSwitchEnableTwoFingerZoom.IsOn = ToggleSwitchEnableTwoFingerZoom.IsOn; @@ -1549,38 +1706,44 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void ToggleSwitchEnableMultiTouchMode_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableMultiTouchMode_Toggled(object sender, RoutedEventArgs e) + { //if (!isLoaded) return; if (sender == ToggleSwitchEnableMultiTouchMode) BoardToggleSwitchEnableMultiTouchMode.IsOn = ToggleSwitchEnableMultiTouchMode.IsOn; else ToggleSwitchEnableMultiTouchMode.IsOn = BoardToggleSwitchEnableMultiTouchMode.IsOn; - - if (ToggleSwitchEnableMultiTouchMode.IsOn) { - if (!isInMultiTouchMode) { + + if (ToggleSwitchEnableMultiTouchMode.IsOn) + { + if (!isInMultiTouchMode) + { // 保存当前编辑模式和绘图工具状态 InkCanvasEditingMode currentEditingMode = inkCanvas.EditingMode; int currentDrawingShapeMode = drawingShapeMode; bool currentForceEraser = forceEraser; - + inkCanvas.StylusDown += MainWindow_StylusDown; inkCanvas.StylusMove += MainWindow_StylusMove; inkCanvas.StylusUp += MainWindow_StylusUp; inkCanvas.TouchDown += MainWindow_TouchDown; inkCanvas.TouchDown -= Main_Grid_TouchDown; - + // 先设为None再设回原来的模式,避免可能的事件冲突 inkCanvas.EditingMode = InkCanvasEditingMode.None; inkCanvas.Children.Clear(); isInMultiTouchMode = true; - + // 恢复到之前的编辑状态 inkCanvas.EditingMode = currentEditingMode; drawingShapeMode = currentDrawingShapeMode; forceEraser = currentForceEraser; } - } else { - if (isInMultiTouchMode) { + } + else + { + if (isInMultiTouchMode) + { // 保存当前编辑模式和绘图工具状态 InkCanvasEditingMode currentEditingMode = inkCanvas.EditingMode; int currentDrawingShapeMode = drawingShapeMode; @@ -1613,7 +1776,8 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void ToggleSwitchEnableTwoFingerTranslate_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableTwoFingerTranslate_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; if (sender == ToggleSwitchEnableTwoFingerTranslate) BoardToggleSwitchEnableTwoFingerTranslate.IsOn = ToggleSwitchEnableTwoFingerTranslate.IsOn; @@ -1624,7 +1788,8 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void ToggleSwitchEnableTwoFingerRotation_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableTwoFingerRotation_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; if (sender == ToggleSwitchEnableTwoFingerRotation) @@ -1637,7 +1802,8 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void ToggleSwitchEnableTwoFingerGestureInPresentationMode_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableTwoFingerGestureInPresentationMode_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.IsEnableTwoFingerGestureInPresentationMode = ToggleSwitchEnableTwoFingerGestureInPresentationMode.IsOn; @@ -1648,7 +1814,8 @@ namespace Ink_Canvas { #region Reset - public static void SetSettingsToRecommendation() { + public static void SetSettingsToRecommendation() + { var AutoDelSavedFilesDays = Settings.Automation.AutoDelSavedFiles; var AutoDelSavedFilesDaysThreshold = Settings.Automation.AutoDelSavedFilesDaysThreshold; Settings = new Settings(); @@ -1663,7 +1830,7 @@ namespace Ink_Canvas { Settings.Advanced.IsEnableEdgeGestureUtil = false; Settings.Advanced.EdgeGestureUtilOnlyAffectBlackboardMode = false; Settings.Advanced.IsEnableFullScreenHelper = false; - Settings.Advanced.IsEnableAvoidFullScreenHelper = false; + Settings.Advanced.IsEnableAvoidFullScreenHelper = false; Settings.Advanced.IsEnableForceFullScreen = false; Settings.Advanced.IsEnableDPIChangeDetection = false; Settings.Advanced.IsEnableResolutionChangeDetection = false; @@ -1777,8 +1944,10 @@ namespace Ink_Canvas { Settings.Startup.IsFoldAtStartup = false; } - private void BtnResetToSuggestion_Click(object sender, RoutedEventArgs e) { - try { + private void BtnResetToSuggestion_Click(object sender, RoutedEventArgs e) + { + try + { isLoaded = false; SetSettingsToRecommendation(); SaveSettingsToFile(); @@ -1792,9 +1961,11 @@ namespace Ink_Canvas { ShowNotification("设置已重置为默认推荐设置~"); } - private async void SpecialVersionResetToSuggestion_Click() { + private async void SpecialVersionResetToSuggestion_Click() + { await Task.Delay(1000); - try { + try + { isLoaded = false; SetSettingsToRecommendation(); Settings.Automation.AutoDelSavedFiles = true; @@ -1811,39 +1982,45 @@ namespace Ink_Canvas { #region Ink To Shape - private void ToggleSwitchEnableInkToShape_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableInkToShape_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.InkToShape.IsInkToShapeEnabled = ToggleSwitchEnableInkToShape.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchEnableInkToShapeNoFakePressureTriangle_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableInkToShapeNoFakePressureTriangle_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.InkToShape.IsInkToShapeNoFakePressureTriangle = ToggleSwitchEnableInkToShapeNoFakePressureTriangle.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchEnableInkToShapeNoFakePressureRectangle_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableInkToShapeNoFakePressureRectangle_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.InkToShape.IsInkToShapeNoFakePressureRectangle = ToggleSwitchEnableInkToShapeNoFakePressureRectangle.IsOn; SaveSettingsToFile(); } - private void ToggleCheckboxEnableInkToShapeTriangle_CheckedChanged(object sender, RoutedEventArgs e) { + private void ToggleCheckboxEnableInkToShapeTriangle_CheckedChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.InkToShape.IsInkToShapeTriangle = (bool)ToggleCheckboxEnableInkToShapeTriangle.IsChecked; SaveSettingsToFile(); } - private void ToggleCheckboxEnableInkToShapeRectangle_CheckedChanged(object sender, RoutedEventArgs e) { + private void ToggleCheckboxEnableInkToShapeRectangle_CheckedChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.InkToShape.IsInkToShapeRectangle = (bool)ToggleCheckboxEnableInkToShapeRectangle.IsChecked; SaveSettingsToFile(); } - private void ToggleCheckboxEnableInkToShapeRounded_CheckedChanged(object sender, RoutedEventArgs e) { + private void ToggleCheckboxEnableInkToShapeRounded_CheckedChanged(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.InkToShape.IsInkToShapeRounded = (bool)ToggleCheckboxEnableInkToShapeRounded.IsChecked; SaveSettingsToFile(); @@ -1853,7 +2030,8 @@ namespace Ink_Canvas { #region Advanced - private void ToggleSwitchIsSpecialScreen_OnToggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchIsSpecialScreen_OnToggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Advanced.IsSpecialScreen = ToggleSwitchIsSpecialScreen.IsOn; TouchMultiplierSlider.Visibility = @@ -1861,13 +2039,15 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void TouchMultiplierSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) { + private void TouchMultiplierSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { if (!isLoaded) return; Settings.Advanced.TouchMultiplier = e.NewValue; SaveSettingsToFile(); } - private void BorderCalculateMultiplier_TouchDown(object sender, TouchEventArgs e) { + private void BorderCalculateMultiplier_TouchDown(object sender, TouchEventArgs e) + { var args = e.GetTouchPoint(null).Bounds; double value; if (!Settings.Advanced.IsQuadIR) value = args.Width; @@ -1876,13 +2056,15 @@ namespace Ink_Canvas { TextBlockShowCalculatedMultiplier.Text = (5 / (value * 1.1)).ToString(); } - private void ToggleSwitchIsEnableFullScreenHelper_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchIsEnableFullScreenHelper_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Advanced.IsEnableFullScreenHelper = ToggleSwitchIsEnableFullScreenHelper.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchIsEnableAvoidFullScreenHelper_OnToggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchIsEnableAvoidFullScreenHelper_OnToggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Advanced.IsEnableAvoidFullScreenHelper = ToggleSwitchIsEnableAvoidFullScreenHelper.IsOn; SaveSettingsToFile(); @@ -1896,14 +2078,16 @@ namespace Ink_Canvas { } } - private void ToggleSwitchIsEnableEdgeGestureUtil_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchIsEnableEdgeGestureUtil_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Advanced.IsEnableEdgeGestureUtil = ToggleSwitchIsEnableEdgeGestureUtil.IsOn; if (OSVersion.GetOperatingSystem() >= OperatingSystem.Windows10) EdgeGestureUtil.DisableEdgeGestures(new WindowInteropHelper(this).Handle, ToggleSwitchIsEnableEdgeGestureUtil.IsOn); SaveSettingsToFile(); } - private void ToggleSwitchIsEnableForceFullScreen_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchIsEnableForceFullScreen_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Advanced.IsEnableForceFullScreen = ToggleSwitchIsEnableForceFullScreen.IsOn; SaveSettingsToFile(); @@ -1923,13 +2107,15 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void ToggleSwitchEraserBindTouchMultiplier_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEraserBindTouchMultiplier_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Advanced.EraserBindTouchMultiplier = ToggleSwitchEraserBindTouchMultiplier.IsOn; SaveSettingsToFile(); } - private void NibModeBoundsWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) { + private void NibModeBoundsWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { if (!isLoaded) return; Settings.Advanced.NibModeBoundsWidth = (int)e.NewValue; @@ -1941,7 +2127,8 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void FingerModeBoundsWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) { + private void FingerModeBoundsWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { if (!isLoaded) return; Settings.Advanced.FingerModeBoundsWidth = (int)e.NewValue; @@ -1953,119 +2140,136 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void ToggleSwitchIsQuadIR_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchIsQuadIR_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Advanced.IsQuadIR = ToggleSwitchIsQuadIR.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchIsLogEnabled_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchIsLogEnabled_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Advanced.IsLogEnabled = ToggleSwitchIsLogEnabled.IsOn; SaveSettingsToFile(); } - - private void ToggleSwitchIsSaveLogByDate_Toggled(object sender, RoutedEventArgs e) { + + 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; Settings.Advanced.IsSecondConfirmWhenShutdownApp = ToggleSwitchIsSecondConfimeWhenShutdownApp.IsOn; SaveSettingsToFile(); } - - private void ToggleSwitchIsAutoBackupBeforeUpdate_Toggled(object sender, RoutedEventArgs e) { + + private void ToggleSwitchIsAutoBackupBeforeUpdate_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Advanced.IsAutoBackupBeforeUpdate = ToggleSwitchIsAutoBackupBeforeUpdate.IsOn; SaveSettingsToFile(); } - - private void BtnManualBackup_Click(object sender, RoutedEventArgs e) { + + private void BtnManualBackup_Click(object sender, RoutedEventArgs e) + { if (!isLoaded) return; - - try { + + try + { // 确保Backups目录存在 string backupDir = Path.Combine(App.RootPath, "Backups"); - if (!Directory.Exists(backupDir)) { + if (!Directory.Exists(backupDir)) + { Directory.CreateDirectory(backupDir); LogHelper.WriteLogToFile($"创建备份目录: {backupDir}"); } - + // 创建备份文件名(使用当前日期时间) string backupFileName = $"Settings_Backup_{DateTime.Now:yyyyMMdd_HHmmss}.json"; string backupPath = Path.Combine(backupDir, backupFileName); - + // 序列化当前设置并保存到备份文件 string settingsJson = JsonConvert.SerializeObject(Settings, Formatting.Indented); File.WriteAllText(backupPath, settingsJson); - + LogHelper.WriteLogToFile($"成功创建设置备份: {backupPath}"); MessageBox.Show($"设置已成功备份到:\n{backupPath}", "备份成功", MessageBoxButton.OK, MessageBoxImage.Information); } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"创建设置备份时出错: {ex.Message}", LogHelper.LogType.Error); MessageBox.Show($"创建备份失败: {ex.Message}", "备份失败", MessageBoxButton.OK, MessageBoxImage.Error); } } - - private void BtnRestoreBackup_Click(object sender, RoutedEventArgs e) { + + private void BtnRestoreBackup_Click(object sender, RoutedEventArgs e) + { if (!isLoaded) return; - - try { + + try + { // 确保Backups目录存在 string backupDir = Path.Combine(App.RootPath, "Backups"); - if (!Directory.Exists(backupDir)) { + if (!Directory.Exists(backupDir)) + { Directory.CreateDirectory(backupDir); LogHelper.WriteLogToFile($"创建备份目录: {backupDir}"); MessageBox.Show("没有找到备份文件,请先创建备份", "还原失败", MessageBoxButton.OK, MessageBoxImage.Warning); return; } - + // 打开文件选择对话框 OpenFileDialog dlg = new OpenFileDialog(); dlg.InitialDirectory = backupDir; dlg.Filter = "设置备份文件|Settings_Backup_*.json|所有JSON文件|*.json"; dlg.Title = "选择要还原的备份文件"; - - if (dlg.ShowDialog() == true) { + + if (dlg.ShowDialog() == true) + { // 读取备份文件 string backupJson = File.ReadAllText(dlg.FileName); - + // 反序列化备份数据 Settings backupSettings = JsonConvert.DeserializeObject(backupJson); - - if (backupSettings != null) { + + if (backupSettings != null) + { // 确认是否要还原 - if (MessageBox.Show("确定要还原选择的备份文件吗?当前设置将被覆盖。", "确认还原", - MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) { - + if (MessageBox.Show("确定要还原选择的备份文件吗?当前设置将被覆盖。", "确认还原", + MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) + { + // 备份当前设置,以防出错 string currentSettingsJson = JsonConvert.SerializeObject(Settings, Formatting.Indented); string tempBackupPath = Path.Combine(backupDir, $"Settings_Before_Restore_{DateTime.Now:yyyyMMdd_HHmmss}.json"); File.WriteAllText(tempBackupPath, currentSettingsJson); - + // 还原设置 Settings = backupSettings; - + // 保存还原后的设置到文件 SaveSettingsToFile(); - + // 重新加载设置到UI LoadSettings(); - + LogHelper.WriteLogToFile($"成功从备份还原设置: {dlg.FileName}"); MessageBox.Show("设置已成功还原,部分设置可能需要重启软件后生效。", "还原成功", MessageBoxButton.OK, MessageBoxImage.Information); } } - else { + else + { MessageBox.Show("无法解析备份文件,文件可能已损坏", "还原失败", MessageBoxButton.OK, MessageBoxImage.Error); } } } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"还原设置备份时出错: {ex.Message}", LogHelper.LogType.Error); MessageBox.Show($"还原备份失败: {ex.Message}", "还原失败", MessageBoxButton.OK, MessageBoxImage.Error); } @@ -2075,7 +2279,8 @@ namespace Ink_Canvas { #region RandSettings - private void ToggleSwitchDisplayRandWindowNamesInputBtn_OnToggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchDisplayRandWindowNamesInputBtn_OnToggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.RandSettings.DisplayRandWindowNamesInputBtn = ToggleSwitchDisplayRandWindowNamesInputBtn.IsOn; SaveSettingsToFile(); @@ -2095,7 +2300,8 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void ToggleSwitchShowRandomAndSingleDraw_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchShowRandomAndSingleDraw_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; // 获取开关状态并保存到设置中 @@ -2109,123 +2315,144 @@ namespace Ink_Canvas { // 保存设置到文件 SaveSettingsToFile(); } - - private void ToggleSwitchDirectCallCiRand_Toggled(object sender, RoutedEventArgs e) { + + private void ToggleSwitchDirectCallCiRand_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; - + // 获取开关状态并保存到设置中 Settings.RandSettings.DirectCallCiRand = ToggleSwitchDirectCallCiRand.IsOn; - + // 保存设置到文件 SaveSettingsToFile(); } #endregion - public static void SaveSettingsToFile() { + public static void SaveSettingsToFile() + { var text = JsonConvert.SerializeObject(Settings, Formatting.Indented); - try { + try + { File.WriteAllText(App.RootPath + settingsFileName, text); } catch { } } - private void SCManipulationBoundaryFeedback(object sender, ManipulationBoundaryFeedbackEventArgs e) { + private void SCManipulationBoundaryFeedback(object sender, ManipulationBoundaryFeedbackEventArgs e) + { e.Handled = true; } - private void HyperlinkSourceToICCRepository_Click(object sender, RoutedEventArgs e) { + private void HyperlinkSourceToICCRepository_Click(object sender, RoutedEventArgs e) + { Process.Start("https://gitea.bliemhax.com/kriastans/InkCanvasForClass"); HideSubPanels(); } - private void HyperlinkSourceToPresentRepository_Click(object sender, RoutedEventArgs e) { + private void HyperlinkSourceToPresentRepository_Click(object sender, RoutedEventArgs e) + { Process.Start("https://bgithub.xyz/ChangSakura/Ink-Canvas"); HideSubPanels(); } - private void HyperlinkSourceToOringinalRepository_Click(object sender, RoutedEventArgs e) { + private void HyperlinkSourceToOringinalRepository_Click(object sender, RoutedEventArgs e) + { Process.Start("https://bgithub.xyz/WXRIW/Ink-Canvas"); HideSubPanels(); } - private async void UpdateChannelSelector_Checked(object sender, RoutedEventArgs e) { + private async void UpdateChannelSelector_Checked(object sender, RoutedEventArgs e) + { if (!isLoaded) return; var radioButton = sender as RadioButton; - if (radioButton != null) { + if (radioButton != null) + { string channel = radioButton.Tag.ToString(); UpdateChannel newChannel = channel == "Beta" ? UpdateChannel.Beta : UpdateChannel.Release; - + // 如果通道没有变化,不需要执行更新检查 - if (Settings.Startup.UpdateChannel == newChannel) { + if (Settings.Startup.UpdateChannel == newChannel) + { return; } - + Settings.Startup.UpdateChannel = newChannel; LogHelper.WriteLogToFile($"Settings | Update channel changed to {Settings.Startup.UpdateChannel}"); SaveSettingsToFile(); - + // 如果启用了自动更新,立即执行完整的检查更新操作 - if (Settings.Startup.IsAutoUpdate) { + if (Settings.Startup.IsAutoUpdate) + { LogHelper.WriteLogToFile($"AutoUpdate | Channel changed to {newChannel}, performing immediate update check"); - + // 执行完整的更新检查 - await Task.Run(async () => { - try { + await Task.Run(async () => + { + try + { // 调用主窗口的AutoUpdate方法,它会自动清除之前的更新状态并使用新通道重新检查 - Dispatcher.Invoke(() => { + Dispatcher.Invoke(() => + { AutoUpdate(); }); } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"AutoUpdate | Error during channel switch update check: {ex.Message}", LogHelper.LogType.Error); } }); } - else { + else + { LogHelper.WriteLogToFile($"AutoUpdate | Channel changed to {newChannel}, but auto-update is disabled"); } } } - - private async void FixVersionButton_Click(object sender, RoutedEventArgs e) { + + private async void FixVersionButton_Click(object sender, RoutedEventArgs e) + { // 显示确认对话框 var confirm = MessageBox.Show( "此操作将下载当前选择通道的最新版本并安装,软件将自动关闭并更新。\n\n确定要执行版本修复吗?", "版本修复确认", MessageBoxButton.YesNo, MessageBoxImage.Question); - - if (confirm == MessageBoxResult.Yes) { + + if (confirm == MessageBoxResult.Yes) + { // 禁用按钮,避免重复点击 FixVersionButton.IsEnabled = false; FixVersionButton.Content = "正在修复..."; - - try { + + try + { // 执行版本修复 bool result = await AutoUpdateHelper.FixVersion(Settings.Startup.UpdateChannel); - - if (!result) { + + if (!result) + { MessageBox.Show( "版本修复失败,可能是网络问题或当前已是最新版本。", "修复失败", MessageBoxButton.OK, MessageBoxImage.Error); - + // 恢复按钮状态 FixVersionButton.IsEnabled = true; FixVersionButton.Content = "版本修复"; } // 成功则会自动关闭应用程序并安装 } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"Error in FixVersionButton_Click: {ex.Message}", LogHelper.LogType.Error); MessageBox.Show( $"版本修复过程中发生错误: {ex.Message}", "修复错误", MessageBoxButton.OK, MessageBoxImage.Error); - + // 恢复按钮状态 FixVersionButton.IsEnabled = true; FixVersionButton.Content = "版本修复"; @@ -2237,14 +2464,14 @@ namespace Ink_Canvas { public void UpdatePickNameBackgroundsInComboBox() { // 清除现有的自定义背景选项 - if (ComboBoxPickNameBackground != null) + if (ComboBoxPickNameBackground != null) { // 保留第一个默认选项 while (ComboBoxPickNameBackground.Items.Count > 1) { ComboBoxPickNameBackground.Items.RemoveAt(ComboBoxPickNameBackground.Items.Count - 1); } - + // 添加自定义背景选项 foreach (var background in Settings.RandSettings.CustomPickNameBackgrounds) { @@ -2264,28 +2491,28 @@ namespace Ink_Canvas { ComboBoxPickNameBackground.SelectedIndex = Settings.RandSettings.SelectedBackgroundIndex; } } - + private void ComboBoxPickNameBackground_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (!isLoaded) return; - + Settings.RandSettings.SelectedBackgroundIndex = ComboBoxPickNameBackground.SelectedIndex; SaveSettingsToFile(); } - + private void ButtonAddCustomBackground_Click(object sender, RoutedEventArgs e) { AddPickNameBackgroundWindow dialog = new AddPickNameBackgroundWindow(this); dialog.Owner = this; dialog.ShowDialog(); - + if (dialog.IsSuccess) { // 自动选中新添加的背景 ComboBoxPickNameBackground.SelectedIndex = ComboBoxPickNameBackground.Items.Count - 1; } } - + private void ButtonManageBackgrounds_Click(object sender, RoutedEventArgs e) { ManagePickNameBackgroundsWindow dialog = new ManagePickNameBackgroundsWindow(this); @@ -2293,7 +2520,8 @@ namespace Ink_Canvas { dialog.ShowDialog(); } - private void ToggleSwitchEnableWppProcessKill_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnableWppProcessKill_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.EnableWppProcessKill = ToggleSwitchEnableWppProcessKill.IsOn; SaveSettingsToFile(); @@ -2313,25 +2541,29 @@ namespace Ink_Canvas { SaveSettingsToFile(); } - private void ToggleSwitchAutoFoldAfterPPTSlideShow_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoFoldAfterPPTSlideShow_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoFoldAfterPPTSlideShow = ToggleSwitchAutoFoldAfterPPTSlideShow.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchAlwaysGoToFirstPageOnReenter_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAlwaysGoToFirstPageOnReenter_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.PowerPointSettings.IsAlwaysGoToFirstPageOnReenter = ToggleSwitchAlwaysGoToFirstPageOnReenter.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchAutoEnterAnnotationAfterKillHite_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchAutoEnterAnnotationAfterKillHite_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Automation.IsAutoEnterAnnotationAfterKillHite = ToggleSwitchAutoEnterAnnotationAfterKillHite.IsOn; SaveSettingsToFile(); } - private void ToggleSwitchEnablePalmEraser_Toggled(object sender, RoutedEventArgs e) { + private void ToggleSwitchEnablePalmEraser_Toggled(object sender, RoutedEventArgs e) + { if (!isLoaded) return; Settings.Canvas.EnablePalmEraser = ToggleSwitchEnablePalmEraser.IsOn; SaveSettingsToFile(); diff --git a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs index 03e8dcd7..faea06b2 100644 --- a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs +++ b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs @@ -1,4 +1,8 @@ -using System; +using Hardcodet.Wpf.TaskbarNotification; +using Ink_Canvas.Helpers; +using Newtonsoft.Json; +using OSVersionExtension; +using System; using System.Reflection; using System.Windows; using System.Windows.Controls; @@ -6,64 +10,80 @@ using System.Windows.Ink; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; -using Hardcodet.Wpf.TaskbarNotification; -using Ink_Canvas.Helpers; -using Newtonsoft.Json; -using OSVersionExtension; using File = System.IO.File; using OperatingSystem = OSVersionExtension.OperatingSystem; -namespace Ink_Canvas { - public partial class MainWindow : Window { - private void LoadSettings(bool isStartup = false) { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { + private void LoadSettings(bool isStartup = false) + { AppVersionTextBlock.Text = Assembly.GetExecutingAssembly().GetName().Version.ToString(); - try { - if (File.Exists(App.RootPath + settingsFileName)) { - try { + try + { + if (File.Exists(App.RootPath + settingsFileName)) + { + try + { string text = File.ReadAllText(App.RootPath + settingsFileName); Settings = JsonConvert.DeserializeObject(text); } catch { } - } else { + } + else + { BtnResetToSuggestion_Click(null, null); } } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error); } // Startup - if (isStartup) { + if (isStartup) + { CursorIcon_Click(null, null); } - try { + try + { if (File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + - "\\Ink Canvas Annotation.lnk")) { + "\\Ink Canvas Annotation.lnk")) + { ToggleSwitchRunAtStartup.IsOn = true; } } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error); } - if (Settings.Startup != null) { - if (isStartup) { - if (Settings.Automation.AutoDelSavedFiles) { + if (Settings.Startup != null) + { + if (isStartup) + { + if (Settings.Automation.AutoDelSavedFiles) + { DelAutoSavedFiles.DeleteFilesOlder(Settings.Automation.AutoSavedStrokesLocation, Settings.Automation.AutoDelSavedFilesDaysThreshold); } - if (Settings.Startup.IsFoldAtStartup) { + if (Settings.Startup.IsFoldAtStartup) + { FoldFloatingBar_MouseUp(Fold_Icon, null); } } - if (Settings.Startup.IsEnableNibMode) { + if (Settings.Startup.IsEnableNibMode) + { ToggleSwitchEnableNibMode.IsOn = true; BoardToggleSwitchEnableNibMode.IsOn = true; BoundsWidth = Settings.Advanced.NibModeBoundsWidth; - } else { + } + else + { ToggleSwitchEnableNibMode.IsOn = false; BoardToggleSwitchEnableNibMode.IsOn = false; BoundsWidth = Settings.Advanced.FingerModeBoundsWidth; @@ -71,29 +91,36 @@ namespace Ink_Canvas { // 设置自动更新相关选项 ToggleSwitchIsAutoUpdate.IsOn = Settings.Startup.IsAutoUpdate; - + // 只有在启用了自动更新功能时才检查更新 - if (Settings.Startup.IsAutoUpdate) { - if (isStartup) { - LogHelper.WriteLogToFile("AutoUpdate | Running auto-update check at startup"); - AutoUpdate(); - } + if (Settings.Startup.IsAutoUpdate) + { + if (isStartup) + { + LogHelper.WriteLogToFile("AutoUpdate | Running auto-update check at startup"); + AutoUpdate(); + } // 当设置被修改时也检查更新(非启动时) - else { - LogHelper.WriteLogToFile("AutoUpdate | Running auto-update check after settings change"); - AutoUpdate(); + else + { + LogHelper.WriteLogToFile("AutoUpdate | Running auto-update check after settings change"); + AutoUpdate(); } } // ToggleSwitchIsAutoUpdateWithSilence.Visibility = Settings.Startup.IsAutoUpdate ? Visibility.Visible : Visibility.Collapsed; - if (Settings.Startup.IsAutoUpdateWithSilence) { + if (Settings.Startup.IsAutoUpdateWithSilence) + { ToggleSwitchIsAutoUpdateWithSilence.IsOn = true; } // 初始化更新通道选择 - foreach (var radioButton in UpdateChannelSelector.Items) { - if (radioButton is RadioButton rb) { - if (rb.Tag.ToString() == Settings.Startup.UpdateChannel.ToString()) { + foreach (var radioButton in UpdateChannelSelector.Items) + { + if (radioButton is RadioButton rb) + { + if (rb.Tag.ToString() == Settings.Startup.UpdateChannel.ToString()) + { rb.IsChecked = true; break; } @@ -110,7 +137,9 @@ namespace Ink_Canvas { AutoUpdateWithSilenceEndTimeComboBox.SelectedItem = Settings.Startup.AutoUpdateWithSilenceEndTime; ToggleSwitchFoldAtStartup.IsOn = Settings.Startup.IsFoldAtStartup; - } else { + } + else + { Settings.Startup = new Startup(); } @@ -131,11 +160,15 @@ namespace Ink_Canvas { } // Appearance - if (Settings.Appearance != null) { - if (!Settings.Appearance.IsEnableDisPlayNibModeToggler) { + if (Settings.Appearance != null) + { + if (!Settings.Appearance.IsEnableDisPlayNibModeToggler) + { NibModeSimpleStackPanel.Visibility = Visibility.Collapsed; BoardNibModeSimpleStackPanel.Visibility = Visibility.Collapsed; - } else { + } + else + { NibModeSimpleStackPanel.Visibility = Visibility.Visible; BoardNibModeSimpleStackPanel.Visibility = Visibility.Visible; } @@ -175,7 +208,8 @@ namespace Ink_Canvas { } ComboBoxUnFoldBtnImg.SelectedIndex = Settings.Appearance.UnFoldButtonImageType; - switch (Settings.Appearance.UnFoldButtonImageType) { + switch (Settings.Appearance.UnFoldButtonImageType) + { case 0: RightUnFoldBtnImgChevron.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/new-icons/unfold-chevron.png")); @@ -224,7 +258,9 @@ namespace Ink_Canvas { //ViewboxBlackboardRightSideScaleTransform.ScaleY = 0.8; ToggleSwitchEnableViewboxBlackBoardScaleTransform.IsOn = true; - } else { + } + else + { //ViewboxBlackboardLeftSideScaleTransform.ScaleX = 1; //ViewboxBlackboardLeftSideScaleTransform.ScaleY = 1; ViewboxBlackboardCenterSideScaleTransform.ScaleX = 1; @@ -235,9 +271,12 @@ namespace Ink_Canvas { ToggleSwitchEnableViewboxBlackBoardScaleTransform.IsOn = false; } - if (Settings.Appearance.IsTransparentButtonBackground) { + if (Settings.Appearance.IsTransparentButtonBackground) + { BtnExit.Background = new SolidColorBrush(StringToColor("#7F909090")); - } else { + } + else + { //Light BtnExit.Background = BtnSwitchTheme.Content.ToString() == "深色" ? new SolidColorBrush(StringToColor("#FFCCCCCC")) @@ -248,16 +287,16 @@ namespace Ink_Canvas { // 更新自定义图标下拉列表 UpdateCustomIconsInComboBox(); - + // 设置选中的图标索引 // 如果索引超出范围(自定义图标可能已删除),使用默认图标 if (Settings.Appearance.FloatingBarImg >= ComboBoxFloatingBarImg.Items.Count) { Settings.Appearance.FloatingBarImg = 0; } - + ComboBoxFloatingBarImg.SelectedIndex = Settings.Appearance.FloatingBarImg; - + // 更新浮动栏图标 UpdateFloatingBarIcon(); @@ -268,18 +307,24 @@ namespace Ink_Canvas { Settings.Appearance.EnableChickenSoupInWhiteboardMode; SystemEvents_UserPreferenceChanged(null, null); - } else { + } + else + { Settings.Appearance = new Appearance(); } // PowerPointSettings - if (Settings.PowerPointSettings != null) { - - - if (Settings.PowerPointSettings.PowerPointSupport) { + if (Settings.PowerPointSettings != null) + { + + + if (Settings.PowerPointSettings.PowerPointSupport) + { ToggleSwitchSupportPowerPoint.IsOn = true; // PPT监控将在Window_Loaded中启动 - } else { + } + else + { ToggleSwitchSupportPowerPoint.IsOn = false; // PPT监控将保持停止状态 } @@ -306,12 +351,15 @@ namespace Ink_Canvas { var dops = Settings.PowerPointSettings.PPTButtonsDisplayOption.ToString(); var dopsc = dops.ToCharArray(); if ((dopsc[0] == '1' || dopsc[0] == '2') && (dopsc[1] == '1' || dopsc[1] == '2') && - (dopsc[2] == '1' || dopsc[2] == '2') && (dopsc[3] == '1' || dopsc[3] == '2')) { + (dopsc[2] == '1' || dopsc[2] == '2') && (dopsc[3] == '1' || dopsc[3] == '2')) + { CheckboxEnableLBPPTButton.IsChecked = dopsc[0] == '2'; CheckboxEnableRBPPTButton.IsChecked = dopsc[1] == '2'; CheckboxEnableLSPPTButton.IsChecked = dopsc[2] == '2'; CheckboxEnableRSPPTButton.IsChecked = dopsc[3] == '2'; - } else { + } + else + { Settings.PowerPointSettings.PPTButtonsDisplayOption = 2222; CheckboxEnableLBPPTButton.IsChecked = true; CheckboxEnableRBPPTButton.IsChecked = true; @@ -376,12 +424,15 @@ namespace Ink_Canvas { Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint; ToggleSwitchEnableWppProcessKill.IsOn = Settings.PowerPointSettings.EnableWppProcessKill; ToggleSwitchAlwaysGoToFirstPageOnReenter.IsOn = Settings.PowerPointSettings.IsAlwaysGoToFirstPageOnReenter; - } else { + } + else + { Settings.PowerPointSettings = new PowerPointSettings(); } // Gesture - if (Settings.Gesture != null) { + if (Settings.Gesture != null) + { ToggleSwitchEnableMultiTouchMode.IsOn = Settings.Gesture.IsEnableMultiTouchMode; ToggleSwitchEnableTwoFingerZoom.IsOn = Settings.Gesture.IsEnableTwoFingerZoom; @@ -400,13 +451,17 @@ namespace Ink_Canvas { ToggleSwitchEnableTwoFingerRotationOnSelection.IsOn = Settings.Gesture.IsEnableTwoFingerRotationOnSelection; - if (Settings.Gesture.AutoSwitchTwoFingerGesture) { - if (Topmost) { + if (Settings.Gesture.AutoSwitchTwoFingerGesture) + { + if (Topmost) + { ToggleSwitchEnableTwoFingerTranslate.IsOn = false; BoardToggleSwitchEnableTwoFingerTranslate.IsOn = false; Settings.Gesture.IsEnableTwoFingerTranslate = false; if (!isInMultiTouchMode) ToggleSwitchEnableMultiTouchMode.IsOn = true; - } else { + } + else + { ToggleSwitchEnableTwoFingerTranslate.IsOn = true; BoardToggleSwitchEnableTwoFingerTranslate.IsOn = true; Settings.Gesture.IsEnableTwoFingerTranslate = true; @@ -415,12 +470,15 @@ namespace Ink_Canvas { } CheckEnableTwoFingerGestureBtnColorPrompt(); - } else { + } + else + { Settings.Gesture = new Gesture(); } // Canvas - if (Settings.Canvas != null) { + if (Settings.Canvas != null) + { drawingAttributes.Height = Settings.Canvas.InkWidth; drawingAttributes.Width = Settings.Canvas.InkWidth; @@ -429,13 +487,16 @@ namespace Ink_Canvas { ComboBoxHyperbolaAsymptoteOption.SelectedIndex = (int)Settings.Canvas.HyperbolaAsymptoteOption; - if (Settings.Canvas.UsingWhiteboard) { + if (Settings.Canvas.UsingWhiteboard) + { GridBackgroundCover.Background = new SolidColorBrush(Color.FromRgb(234, 235, 237)); WaterMarkTime.Foreground = new SolidColorBrush(Color.FromRgb(22, 41, 36)); WaterMarkDate.Foreground = new SolidColorBrush(Color.FromRgb(22, 41, 36)); BlackBoardWaterMark.Foreground = new SolidColorBrush(Color.FromRgb(22, 41, 36)); isUselightThemeColor = false; - } else { + } + else + { GridBackgroundCover.Background = new SolidColorBrush(Color.FromRgb(22, 41, 36)); WaterMarkTime.Foreground = new SolidColorBrush(Color.FromRgb(234, 235, 237)); WaterMarkDate.Foreground = new SolidColorBrush(Color.FromRgb(234, 235, 237)); @@ -443,17 +504,20 @@ namespace Ink_Canvas { isUselightThemeColor = true; } - if (Settings.Canvas.IsShowCursor) { + if (Settings.Canvas.IsShowCursor) + { ToggleSwitchShowCursor.IsOn = true; inkCanvas.ForceCursor = true; - } else { + } + else + { ToggleSwitchShowCursor.IsOn = false; inkCanvas.ForceCursor = false; } // 初始化压感触屏模式开关状态 ToggleSwitchEnablePressureTouchMode.IsOn = Settings.Canvas.EnablePressureTouchMode; - + // 初始化屏蔽压感开关状态 ToggleSwitchDisablePressure.IsOn = Settings.Canvas.DisablePressure; @@ -468,49 +532,54 @@ namespace Ink_Canvas { Settings.Canvas.ClearCanvasAndClearTimeMachine; ToggleSwitchClearCanvasAlsoClearImages.IsOn = Settings.Canvas.ClearCanvasAlsoClearImages; - switch (Settings.Canvas.EraserShapeType) { - case 0: { - double k = 1; - switch (Settings.Canvas.EraserSize) { - case 0: - k = 0.5; - break; - case 1: - k = 0.8; - break; - case 3: - k = 1.25; - break; - case 4: - k = 1.5; - break; - } + switch (Settings.Canvas.EraserShapeType) + { + case 0: + { + double k = 1; + switch (Settings.Canvas.EraserSize) + { + case 0: + k = 0.5; + break; + case 1: + k = 0.8; + break; + case 3: + k = 1.25; + break; + case 4: + k = 1.5; + break; + } - inkCanvas.EraserShape = new EllipseStylusShape(k * 90, k * 90); - inkCanvas.EditingMode = InkCanvasEditingMode.None; - break; - } - case 1: { - double k = 1; - switch (Settings.Canvas.EraserSize) { - case 0: - k = 0.7; - break; - case 1: - k = 0.9; - break; - case 3: - k = 1.2; - break; - case 4: - k = 1.5; - break; + inkCanvas.EraserShape = new EllipseStylusShape(k * 90, k * 90); + inkCanvas.EditingMode = InkCanvasEditingMode.None; + break; } + case 1: + { + double k = 1; + switch (Settings.Canvas.EraserSize) + { + case 0: + k = 0.7; + break; + case 1: + k = 0.9; + break; + case 3: + k = 1.2; + break; + case 4: + k = 1.5; + break; + } - inkCanvas.EraserShape = new RectangleStylusShape(k * 90 * 0.6, k * 90); - inkCanvas.EditingMode = InkCanvasEditingMode.None; - break; - } + inkCanvas.EraserShape = new RectangleStylusShape(k * 90 * 0.6, k * 90); + inkCanvas.EditingMode = InkCanvasEditingMode.None; + break; + } } CheckEraserTypeTab(); @@ -556,7 +625,7 @@ namespace Ink_Canvas { // 可以添加提示文本说明硬件加速不可用 } */ - + // 初始化直线自动拉直相关设置 ToggleSwitchAutoStraightenLine.IsOn = Settings.Canvas.AutoStraightenLine; AutoStraightenLineThresholdSlider.Value = Settings.Canvas.AutoStraightenLineThreshold; @@ -564,21 +633,25 @@ namespace Ink_Canvas { LineStraightenSensitivitySlider.Value = Settings.InkToShape.LineStraightenSensitivity; // 初始化高精度直线拉直设置 ToggleSwitchHighPrecisionLineStraighten.IsOn = Settings.Canvas.HighPrecisionLineStraighten; - + // 初始化直线端点吸附相关设置 ToggleSwitchLineEndpointSnapping.IsOn = Settings.Canvas.LineEndpointSnapping; ToggleSwitchCompressPicturesUploaded.IsOn = Settings.Canvas.IsCompressPicturesUploaded; - } else { + } + else + { Settings.Canvas = new Canvas(); } // Palm Eraser - if (Settings.Canvas != null) { + if (Settings.Canvas != null) + { ToggleSwitchEnablePalmEraser.IsOn = Settings.Canvas.EnablePalmEraser; } // Advanced - if (Settings.Advanced != null) { + if (Settings.Advanced != null) + { TouchMultiplierSlider.Value = Settings.Advanced.TouchMultiplier; FingerModeBoundsWidthSlider.Value = Settings.Advanced.FingerModeBoundsWidth; NibModeBoundsWidthSlider.Value = Settings.Advanced.NibModeBoundsWidth; @@ -595,25 +668,30 @@ namespace Ink_Canvas { ToggleSwitchIsEnableDPIChangeDetection.IsOn = Settings.Advanced.IsEnableDPIChangeDetection; ToggleSwitchIsEnableAvoidFullScreenHelper.IsOn = Settings.Advanced.IsEnableAvoidFullScreenHelper; ToggleSwitchIsAutoBackupBeforeUpdate.IsOn = Settings.Advanced.IsAutoBackupBeforeUpdate; - if (Settings.Advanced.IsEnableFullScreenHelper) { + if (Settings.Advanced.IsEnableFullScreenHelper) + { FullScreenHelper.MarkFullscreenWindowTaskbarList(new WindowInteropHelper(this).Handle, true); } if (Settings.Advanced.IsEnableAvoidFullScreenHelper) { AvoidFullScreenHelper.StartAvoidFullScreen(this); } - if (Settings.Advanced.IsEnableEdgeGestureUtil) { + if (Settings.Advanced.IsEnableEdgeGestureUtil) + { if (OSVersion.GetOperatingSystem() >= OperatingSystem.Windows10) EdgeGestureUtil.DisableEdgeGestures(new WindowInteropHelper(this).Handle, true); } TouchMultiplierSlider.Visibility = ToggleSwitchIsSpecialScreen.IsOn ? Visibility.Visible : Visibility.Collapsed; - } else { + } + else + { Settings.Advanced = new Advanced(); } // InkToShape - if (Settings.InkToShape != null) { + if (Settings.InkToShape != null) + { ToggleSwitchEnableInkToShape.IsOn = Settings.InkToShape.IsInkToShapeEnabled; ToggleSwitchEnableInkToShapeNoFakePressureRectangle.IsOn = @@ -627,14 +705,17 @@ namespace Ink_Canvas { ToggleCheckboxEnableInkToShapeRectangle.IsChecked = Settings.InkToShape.IsInkToShapeRectangle; ToggleCheckboxEnableInkToShapeRounded.IsChecked = Settings.InkToShape.IsInkToShapeRounded; - + // 直线拉直灵敏度在Canvas部分已经初始化,这里不再重复 - } else { + } + else + { Settings.InkToShape = new InkToShape(); } // RandSettings - if (Settings.RandSettings != null) { + if (Settings.RandSettings != null) + { ToggleSwitchDisplayRandWindowNamesInputBtn.IsOn = Settings.RandSettings.DisplayRandWindowNamesInputBtn; RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency; RandWindowOnceMaxStudentsSlider.Value = Settings.RandSettings.RandWindowOnceMaxStudents; @@ -642,17 +723,19 @@ namespace Ink_Canvas { ToggleSwitchDirectCallCiRand.IsOn = Settings.RandSettings.DirectCallCiRand; RandomDrawPanel.Visibility = Settings.RandSettings.ShowRandomAndSingleDraw ? Visibility.Visible : Visibility.Collapsed; SingleDrawPanel.Visibility = Settings.RandSettings.ShowRandomAndSingleDraw ? Visibility.Visible : Visibility.Collapsed; - + // 加载自定义点名背景 UpdatePickNameBackgroundsInComboBox(); - + // 设置选择的背景索引 if (Settings.RandSettings.SelectedBackgroundIndex >= ComboBoxPickNameBackground.Items.Count) { Settings.RandSettings.SelectedBackgroundIndex = 0; } ComboBoxPickNameBackground.SelectedIndex = Settings.RandSettings.SelectedBackgroundIndex; - } else { + } + else + { Settings.RandSettings = new RandSettings(); ToggleSwitchDisplayRandWindowNamesInputBtn.IsOn = Settings.RandSettings.DisplayRandWindowNamesInputBtn; RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency; @@ -661,7 +744,8 @@ namespace Ink_Canvas { } // Automation - if (Settings.Automation != null) { + if (Settings.Automation != null) + { StartOrStoptimerCheckAutoFold(); ToggleSwitchAutoFoldInEasiNote.IsOn = Settings.Automation.IsAutoFoldInEasiNote; @@ -698,12 +782,13 @@ namespace Ink_Canvas { ToggleSwitchAutoFoldInMaxHubWhiteboard.IsOn = Settings.Automation.IsAutoFoldInMaxHubWhiteboard; SettingsPPTInkingAndAutoFoldExplictBorder.Visibility = Visibility.Collapsed; - if (Settings.Automation.IsAutoFoldInPPTSlideShow) { + if (Settings.Automation.IsAutoFoldInPPTSlideShow) + { SettingsPPTInkingAndAutoFoldExplictBorder.Visibility = Visibility.Visible; SettingsShowCanvasAtNewSlideShowStackPanel.Opacity = 0.5; SettingsShowCanvasAtNewSlideShowStackPanel.IsHitTestVisible = false; } - + ToggleSwitchAutoFoldInPPTSlideShow.IsOn = Settings.Automation.IsAutoFoldInPPTSlideShow; @@ -713,9 +798,12 @@ namespace Ink_Canvas { Settings.Automation.IsAutoKillHiteAnnotation || Settings.Automation.IsAutoKillInkCanvas || Settings.Automation.IsAutoKillICA || Settings.Automation.IsAutoKillIDT || Settings.Automation.IsAutoKillVComYouJiao - || Settings.Automation.IsAutoKillSeewoLauncher2DesktopAnnotation) { + || Settings.Automation.IsAutoKillSeewoLauncher2DesktopAnnotation) + { timerKillProcess.Start(); - } else { + } + else + { timerKillProcess.Stop(); } @@ -741,7 +829,7 @@ namespace Ink_Canvas { ToggleSwitchSaveScreenshotsInDateFolders.IsOn = Settings.Automation.IsSaveScreenshotsInDateFolders; ToggleSwitchAutoSaveStrokesAtScreenshot.IsOn = Settings.Automation.IsAutoSaveStrokesAtScreenshot; - + ToggleSwitchSaveFullPageStrokes.IsOn = Settings.Automation.IsSaveFullPageStrokes; SideControlMinimumAutomationSlider.Value = Settings.Automation.MinimumAutomationStrokeNumber; @@ -750,17 +838,22 @@ namespace Ink_Canvas { ToggleSwitchAutoDelSavedFiles.IsOn = Settings.Automation.AutoDelSavedFiles; ComboBoxAutoDelSavedFilesDaysThreshold.Text = Settings.Automation.AutoDelSavedFilesDaysThreshold.ToString(); - + // 加载退出收纳模式自动切换至批注模式设置 ToggleSwitchAutoEnterAnnotationModeWhenExitFoldMode.IsOn = Settings.Automation.IsAutoEnterAnnotationModeWhenExitFoldMode; - } else { + } + else + { Settings.Automation = new Automation(); } // auto align - if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) { + if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) + { ViewboxFloatingBarMarginAnimation(60); - } else { + } + else + { ViewboxFloatingBarMarginAnimation(100, true); } } diff --git a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs index 72a38995..fd2dbfb2 100644 --- a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs +++ b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs @@ -1,4 +1,6 @@ -using System; +using Ink_Canvas.Helpers; +using iNKORE.UI.WPF.Modern.Controls; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; @@ -8,23 +10,25 @@ using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; -using Ink_Canvas.Helpers; -using iNKORE.UI.WPF.Modern.Controls; using MessageBox = System.Windows.MessageBox; using Point = System.Windows.Point; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { #region Floating Bar Control - private void ImageDrawShape_MouseUp(object sender, MouseButtonEventArgs e) { + private void ImageDrawShape_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel) ((Panel)lastBorderMouseDownObject).Background = new SolidColorBrush(Colors.Transparent); if (sender == ShapeDrawFloatingBarBtn && lastBorderMouseDownObject != ShapeDrawFloatingBarBtn) return; // FloatingBarIcons_MouseUp_New(sender); - if (BorderDrawShape.Visibility == Visibility.Visible) { + if (BorderDrawShape.Visibility == Visibility.Visible) + { AnimationsHelper.HideWithSlideAndFade(EraserSizePanel); AnimationsHelper.HideWithSlideAndFade(BorderTools); AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); @@ -38,7 +42,8 @@ namespace Ink_Canvas { AnimationsHelper.HideWithSlideAndFade(TwoFingerGestureBorder); AnimationsHelper.HideWithSlideAndFade(BoardTwoFingerGestureBorder); } - else { + else + { AnimationsHelper.HideWithSlideAndFade(EraserSizePanel); AnimationsHelper.HideWithSlideAndFade(BorderTools); AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); @@ -61,7 +66,8 @@ namespace Ink_Canvas { #region Buttons - private void SymbolIconPinBorderDrawShape_MouseUp(object sender, MouseButtonEventArgs e) { + private void SymbolIconPinBorderDrawShape_MouseUp(object sender, MouseButtonEventArgs e) + { if (lastBorderMouseDownObject != sender) return; ToggleSwitchDrawShapeBorderAutoHide.IsOn = !ToggleSwitchDrawShapeBorderAutoHide.IsOn; @@ -75,13 +81,15 @@ namespace Ink_Canvas { private object lastMouseDownSender; private DateTime lastMouseDownTime = DateTime.MinValue; - private async void Image_MouseDown(object sender, MouseButtonEventArgs e) { + private async void Image_MouseDown(object sender, MouseButtonEventArgs e) + { lastMouseDownSender = sender; lastMouseDownTime = DateTime.Now; await Task.Delay(500); - if (lastMouseDownSender == sender) { + if (lastMouseDownSender == sender) + { lastMouseDownSender = null; var dA = new DoubleAnimation(1, 0.3, new Duration(TimeSpan.FromMilliseconds(100))); ((UIElement)sender).BeginAnimation(OpacityProperty, dA); @@ -103,7 +111,8 @@ namespace Ink_Canvas { } } - private void BtnPen_Click(object sender, RoutedEventArgs e) { + private void BtnPen_Click(object sender, RoutedEventArgs e) + { // 禁用高级橡皮擦系统 DisableAdvancedEraserSystem(); @@ -112,7 +121,8 @@ namespace Ink_Canvas { ExitMultiTouchModeIfNeeded(); // 如果当前已是批注模式,再次点击弹出批注子面板 - if (penType == 0 && inkCanvas.EditingMode == InkCanvasEditingMode.Ink && !drawingAttributes.IsHighlighter) { + if (penType == 0 && inkCanvas.EditingMode == InkCanvasEditingMode.Ink && !drawingAttributes.IsHighlighter) + { return; } // 否则只切换到批注模式,不弹出子面板 @@ -131,17 +141,19 @@ namespace Ink_Canvas { SetCursorBasedOnEditingMode(inkCanvas); } - private Task CheckIsDrawingShapesInMultiTouchMode() { - if (isInMultiTouchMode) { + private Task CheckIsDrawingShapesInMultiTouchMode() + { + if (isInMultiTouchMode) + { // 不关闭多指书写模式,而是保存状态,暂时禁用多指书写相关的事件处理 // 不再调用 ToggleSwitchEnableMultiTouchMode.IsOn = false; - + // 暂时禁用多指书写事件处理,以避免冲突 inkCanvas.StylusDown -= MainWindow_StylusDown; inkCanvas.StylusMove -= MainWindow_StylusMove; inkCanvas.StylusUp -= MainWindow_StylusUp; inkCanvas.TouchDown -= MainWindow_TouchDown; - + // 记录已暂时禁用多指书写模式,但实际上多指书写开关仍然为打开状态 lastIsInMultiTouchMode = true; } @@ -149,12 +161,14 @@ namespace Ink_Canvas { return Task.FromResult(true); } - private async void BtnDrawLine_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawLine_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(1); CancelSingleFingerDragMode(); lastMouseDownSender = null; - if (isLongPressSelected) { + if (isLongPressSelected) + { if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape(); var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0))); ImageDrawLine.BeginAnimation(OpacityProperty, dA); @@ -162,12 +176,14 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawDashedLine_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawDashedLine_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(8); CancelSingleFingerDragMode(); lastMouseDownSender = null; - if (isLongPressSelected) { + if (isLongPressSelected) + { if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape(); var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0))); ImageDrawDashedLine.BeginAnimation(OpacityProperty, dA); @@ -175,12 +191,14 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawDotLine_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawDotLine_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(18); CancelSingleFingerDragMode(); lastMouseDownSender = null; - if (isLongPressSelected) { + if (isLongPressSelected) + { if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape(); var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0))); ImageDrawDotLine.BeginAnimation(OpacityProperty, dA); @@ -188,12 +206,14 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawArrow_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawArrow_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(2); CancelSingleFingerDragMode(); lastMouseDownSender = null; - if (isLongPressSelected) { + if (isLongPressSelected) + { if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape(); var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0))); ImageDrawArrow.BeginAnimation(OpacityProperty, dA); @@ -201,12 +221,14 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawParallelLine_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawParallelLine_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(15); CancelSingleFingerDragMode(); lastMouseDownSender = null; - if (isLongPressSelected) { + if (isLongPressSelected) + { if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape(); var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0))); ImageDrawParallelLine.BeginAnimation(OpacityProperty, dA); @@ -214,7 +236,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawCoordinate1_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawCoordinate1_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(11); CancelSingleFingerDragMode(); @@ -222,7 +245,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawCoordinate2_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawCoordinate2_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(12); CancelSingleFingerDragMode(); @@ -230,7 +254,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawCoordinate3_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawCoordinate3_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(13); CancelSingleFingerDragMode(); @@ -238,7 +263,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawCoordinate4_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawCoordinate4_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(14); CancelSingleFingerDragMode(); @@ -246,7 +272,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawCoordinate5_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawCoordinate5_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(17); CancelSingleFingerDragMode(); @@ -254,7 +281,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawRectangle_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawRectangle_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(3); CancelSingleFingerDragMode(); @@ -263,7 +291,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawRectangleCenter_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawRectangleCenter_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(19); CancelSingleFingerDragMode(); @@ -271,7 +300,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawEllipse_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawEllipse_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(4); CancelSingleFingerDragMode(); @@ -279,7 +309,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawCircle_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawCircle_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(5); CancelSingleFingerDragMode(); @@ -287,7 +318,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawCenterEllipse_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawCenterEllipse_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(16); CancelSingleFingerDragMode(); @@ -295,7 +327,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawCenterEllipseWithFocalPoint_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawCenterEllipseWithFocalPoint_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(23); CancelSingleFingerDragMode(); @@ -303,7 +336,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawDashedCircle_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawDashedCircle_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(10); CancelSingleFingerDragMode(); @@ -311,7 +345,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawHyperbola_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawHyperbola_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(24); drawMultiStepShapeCurrentStep = 0; @@ -320,7 +355,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawHyperbolaWithFocalPoint_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawHyperbolaWithFocalPoint_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(25); drawMultiStepShapeCurrentStep = 0; @@ -329,7 +365,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawParabola1_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawParabola1_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(20); CancelSingleFingerDragMode(); @@ -337,7 +374,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawParabolaWithFocalPoint_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawParabolaWithFocalPoint_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(22); CancelSingleFingerDragMode(); @@ -345,7 +383,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawParabola2_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawParabola2_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(21); CancelSingleFingerDragMode(); @@ -353,7 +392,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawCylinder_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawCylinder_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(6); CancelSingleFingerDragMode(); @@ -361,7 +401,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawCone_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawCone_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(7); CancelSingleFingerDragMode(); @@ -369,7 +410,8 @@ namespace Ink_Canvas { DrawShapePromptToPen(); } - private async void BtnDrawCuboid_Click(object sender, MouseButtonEventArgs e) { + private async void BtnDrawCuboid_Click(object sender, MouseButtonEventArgs e) + { await CheckIsDrawingShapesInMultiTouchMode(); EnterShapeDrawingMode(9); isFirstTouchCuboid = true; @@ -382,21 +424,27 @@ namespace Ink_Canvas { #endregion - private void inkCanvas_TouchMove(object sender, TouchEventArgs e) { + private void inkCanvas_TouchMove(object sender, TouchEventArgs e) + { // 确保套索选择模式下触摸移动时光标保持可见 - if (inkCanvas.EditingMode == InkCanvasEditingMode.Select) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.Select) + { SetCursorBasedOnEditingMode(inkCanvas); } // 处理几何绘制模式 - if (drawingShapeMode != 0) { + if (drawingShapeMode != 0) + { if (isWaitUntilNextTouchDown && dec.Count > 1) return; - if (dec.Count > 1) { - try { + if (dec.Count > 1) + { + try + { inkCanvas.Strokes.Remove(lastTempStroke); inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } return; @@ -410,7 +458,8 @@ namespace Ink_Canvas { // 其它模式下,允许橡皮、套索、批注等正常工作,不覆盖EditingMode if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint || inkCanvas.EditingMode == InkCanvasEditingMode.Select || - inkCanvas.EditingMode == InkCanvasEditingMode.Ink) { + inkCanvas.EditingMode == InkCanvasEditingMode.Ink) + { // 允许正常橡皮、套索、批注 } } @@ -425,7 +474,8 @@ namespace Ink_Canvas { #region 形状绘制主函数 - private void MouseTouchMove(Point endP) { + private void MouseTouchMove(Point endP) + { // 禁用原有的FitToCurve,使用新的高级贝塞尔曲线平滑 if (Settings.Canvas.FitToCurve) drawingAttributes.FitToCurve = false; ViewboxFloatingBar.IsHitTestVisible = false; @@ -435,7 +485,8 @@ namespace Ink_Canvas { Stroke stroke; var strokes = new StrokeCollection(); var newIniP = iniP; - switch (drawingShapeMode) { + switch (drawingShapeMode) + { case 1: _currentCommitType = CommitReason.ShapeDrawing; pointList = new List { @@ -443,10 +494,12 @@ namespace Ink_Canvas { new Point(endP.X, endP.Y) }; point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; - try { + try + { inkCanvas.Strokes.Remove(lastTempStroke); } catch { } @@ -457,10 +510,12 @@ namespace Ink_Canvas { case 8: _currentCommitType = CommitReason.ShapeDrawing; strokes.Add(GenerateDashedLineStrokeCollection(iniP, endP)); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -470,10 +525,12 @@ namespace Ink_Canvas { case 18: _currentCommitType = CommitReason.ShapeDrawing; strokes.Add(GenerateDotLineStrokeCollection(iniP, endP)); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -495,10 +552,12 @@ namespace Ink_Canvas { new Point(endP.X + (w * cost + h * sint), endP.Y - (h * cost - w * sint)) }; point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; - try { + try + { inkCanvas.Strokes.Remove(lastTempStroke); } catch { } @@ -514,7 +573,8 @@ namespace Ink_Canvas { var cosTheta = (endP.X - iniP.X) / d; var tanTheta = Math.Abs(sinTheta / cosTheta); double x = 25; - if (Math.Abs(tanTheta) < 1.0 / 12) { + if (Math.Abs(tanTheta) < 1.0 / 12) + { sinTheta = 0; cosTheta = 1; endP.Y = iniP.Y; @@ -544,7 +604,8 @@ namespace Ink_Canvas { endP.X = iniP.X + d * cosTheta; } - if (Math.Abs(cosTheta / sinTheta) < 1.0 / 12) { + if (Math.Abs(cosTheta / sinTheta) < 1.0 / 12) + { endP.X = iniP.X; sinTheta = 1; cosTheta = 0; @@ -558,10 +619,12 @@ namespace Ink_Canvas { new Point(endP.X + x * sinTheta, endP.Y + x * cosTheta))); strokes.Add(GenerateLineStroke(new Point(iniP.X + 3 * x * sinTheta, iniP.Y + 3 * x * cosTheta), new Point(endP.X + 3 * x * sinTheta, endP.Y + 3 * x * cosTheta))); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -574,10 +637,12 @@ namespace Ink_Canvas { new Point(endP.X, iniP.Y))); strokes.Add(GenerateArrowLineStroke(new Point(iniP.X, 2 * iniP.Y - (endP.Y + 20)), new Point(iniP.X, endP.Y))); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -592,10 +657,12 @@ namespace Ink_Canvas { new Point(endP.X, iniP.Y))); strokes.Add(GenerateArrowLineStroke(new Point(iniP.X, 2 * iniP.Y - (endP.Y + 20)), new Point(iniP.X, endP.Y))); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -610,10 +677,12 @@ namespace Ink_Canvas { strokes.Add(GenerateArrowLineStroke( new Point(iniP.X, iniP.Y + (iniP.Y - endP.Y) / Math.Abs(iniP.Y - endP.Y) * 25), new Point(iniP.X, endP.Y))); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -629,10 +698,12 @@ namespace Ink_Canvas { strokes.Add(GenerateArrowLineStroke( new Point(iniP.X, iniP.Y + (iniP.Y - endP.Y) / Math.Abs(iniP.Y - endP.Y) * 25), new Point(iniP.X, endP.Y))); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -648,10 +719,12 @@ namespace Ink_Canvas { d = (Math.Abs(iniP.X - endP.X) + Math.Abs(iniP.Y - endP.Y)) / 2; strokes.Add(GenerateArrowLineStroke(new Point(iniP.X, iniP.Y), new Point(iniP.X - d / 1.76, iniP.Y + d / 1.76))); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -668,10 +741,12 @@ namespace Ink_Canvas { new Point(iniP.X, iniP.Y) }; point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; - try { + try + { inkCanvas.Strokes.Remove(lastTempStroke); } catch { } @@ -691,10 +766,12 @@ namespace Ink_Canvas { new Point(iniP.X - a, iniP.Y - b) }; point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; - try { + try + { inkCanvas.Strokes.Remove(lastTempStroke); } catch { } @@ -706,10 +783,12 @@ namespace Ink_Canvas { _currentCommitType = CommitReason.ShapeDrawing; pointList = GenerateEllipseGeometry(iniP, endP); point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; - try { + try + { inkCanvas.Strokes.Remove(lastTempStroke); } catch { } @@ -723,10 +802,12 @@ namespace Ink_Canvas { pointList = GenerateEllipseGeometry(new Point(iniP.X - R, iniP.Y - R), new Point(iniP.X + R, iniP.Y + R)); point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; - try { + try + { inkCanvas.Strokes.Remove(lastTempStroke); } catch { } @@ -741,10 +822,12 @@ namespace Ink_Canvas { pointList = GenerateEllipseGeometry(new Point(iniP.X - halfA, iniP.Y - halfB), new Point(iniP.X + halfA, iniP.Y + halfB)); point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; - try { + try + { inkCanvas.Strokes.Remove(lastTempStroke); } catch { } @@ -759,46 +842,54 @@ namespace Ink_Canvas { pointList = GenerateEllipseGeometry(new Point(iniP.X - a, iniP.Y - b), new Point(iniP.X + a, iniP.Y + b)); point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke); var c = Math.Sqrt(Math.Abs(a * a - b * b)); StylusPoint stylusPoint; - if (a > b) { + if (a > b) + { stylusPoint = new StylusPoint(iniP.X + c, iniP.Y, (float)1.0); point = new StylusPointCollection(); point.Add(stylusPoint); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); stylusPoint = new StylusPoint(iniP.X - c, iniP.Y, (float)1.0); point = new StylusPointCollection(); point.Add(stylusPoint); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); } - else if (a < b) { + else if (a < b) + { stylusPoint = new StylusPoint(iniP.X, iniP.Y - c, (float)1.0); point = new StylusPointCollection(); point.Add(stylusPoint); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); stylusPoint = new StylusPoint(iniP.X, iniP.Y + c, (float)1.0); point = new StylusPointCollection(); point.Add(stylusPoint); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); } - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } catch { } @@ -811,10 +902,12 @@ namespace Ink_Canvas { R = GetDistance(iniP, endP); strokes = GenerateDashedLineEllipseStrokeCollection(new Point(iniP.X - R, iniP.Y - R), new Point(iniP.X + R, iniP.Y + R)); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -829,7 +922,8 @@ namespace Ink_Canvas { var pointList2 = new List(); var pointList3 = new List(); var pointList4 = new List(); - if (drawMultiStepShapeCurrentStep == 0) { + if (drawMultiStepShapeCurrentStep == 0) + { //第一笔:画渐近线 var k = Math.Abs((endP.Y - iniP.Y) / (endP.X - iniP.X)); strokes.Add( @@ -840,17 +934,20 @@ namespace Ink_Canvas { drawMultiStepShapeSpecialParameter3 = k; drawMultiStepShapeSpecialStrokeCollection = strokes; } - else { + else + { //第二笔:画双曲线 var k = drawMultiStepShapeSpecialParameter3; var isHyperbolaFocalPointOnXAxis = Math.Abs((endP.Y - iniP.Y) / (endP.X - iniP.X)) < k; - if (isHyperbolaFocalPointOnXAxis) { + if (isHyperbolaFocalPointOnXAxis) + { // 焦点在 x 轴上 a = Math.Sqrt(Math.Abs((endP.X - iniP.X) * (endP.X - iniP.X) - (endP.Y - iniP.Y) * (endP.Y - iniP.Y) / (k * k))); b = a * k; pointList = new List(); - for (var i = a; i <= Math.Abs(endP.X - iniP.X); i += 0.5) { + for (var i = a; i <= Math.Abs(endP.X - iniP.X); i += 0.5) + { var rY = Math.Sqrt(Math.Abs(k * k * i * i - b * b)); pointList.Add(new Point(iniP.X + i, iniP.Y - rY)); pointList2.Add(new Point(iniP.X + i, iniP.Y + rY)); @@ -858,13 +955,15 @@ namespace Ink_Canvas { pointList4.Add(new Point(iniP.X - i, iniP.Y + rY)); } } - else { + else + { // 焦点在 y 轴上 a = Math.Sqrt(Math.Abs((endP.Y - iniP.Y) * (endP.Y - iniP.Y) - (endP.X - iniP.X) * (endP.X - iniP.X) * (k * k))); b = a / k; pointList = new List(); - for (var i = a; i <= Math.Abs(endP.Y - iniP.Y); i += 0.5) { + for (var i = a; i <= Math.Abs(endP.Y - iniP.Y); i += 0.5) + { var rX = Math.Sqrt(Math.Abs(i * i / k / k - b * b)); pointList.Add(new Point(iniP.X - rX, iniP.Y + i)); pointList2.Add(new Point(iniP.X + rX, iniP.Y + i)); @@ -873,24 +972,26 @@ namespace Ink_Canvas { } } - try { + try + { point = new StylusPointCollection(pointList); stroke = new Stroke(point) - { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); point = new StylusPointCollection(pointList2); stroke = new Stroke(point) - { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); point = new StylusPointCollection(pointList3); stroke = new Stroke(point) - { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); point = new StylusPointCollection(pointList4); stroke = new Stroke(point) - { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); - if (drawingShapeMode == 25) { + if (drawingShapeMode == 25) + { //画焦点 c = Math.Sqrt(a * a + b * b); stylusPoint = isHyperbolaFocalPointOnXAxis @@ -899,7 +1000,7 @@ namespace Ink_Canvas { point = new StylusPointCollection(); point.Add(stylusPoint); stroke = new Stroke(point) - { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); stylusPoint = isHyperbolaFocalPointOnXAxis ? new StylusPoint(iniP.X - c, iniP.Y, (float)1.0) @@ -907,19 +1008,22 @@ namespace Ink_Canvas { point = new StylusPointCollection(); point.Add(stylusPoint); stroke = new Stroke(point) - { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); } } - catch { + catch + { return; } } - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -933,25 +1037,30 @@ namespace Ink_Canvas { a = (iniP.Y - endP.Y) / ((iniP.X - endP.X) * (iniP.X - endP.X)); pointList = new List(); pointList2 = new List(); - for (var i = 0.0; i <= Math.Abs(endP.X - iniP.X); i += 0.5) { + for (var i = 0.0; i <= Math.Abs(endP.X - iniP.X); i += 0.5) + { pointList.Add(new Point(iniP.X + i, iniP.Y - a * i * i)); pointList2.Add(new Point(iniP.X - i, iniP.Y - a * i * i)); } point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); point = new StylusPointCollection(pointList2); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -965,25 +1074,30 @@ namespace Ink_Canvas { a = (iniP.X - endP.X) / ((iniP.Y - endP.Y) * (iniP.Y - endP.Y)); pointList = new List(); pointList2 = new List(); - for (var i = 0.0; i <= Math.Abs(endP.Y - iniP.Y); i += 0.5) { + for (var i = 0.0; i <= Math.Abs(endP.Y - iniP.Y); i += 0.5) + { pointList.Add(new Point(iniP.X - a * i * i, iniP.Y + i)); pointList2.Add(new Point(iniP.X - a * i * i, iniP.Y - i)); } point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); point = new StylusPointCollection(pointList2); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -998,32 +1112,38 @@ namespace Ink_Canvas { a = 0.5 / p; pointList = new List(); pointList2 = new List(); - for (var i = 0.0; i <= Math.Abs(endP.Y - iniP.Y); i += 0.5) { + for (var i = 0.0; i <= Math.Abs(endP.Y - iniP.Y); i += 0.5) + { pointList.Add(new Point(iniP.X - a * i * i, iniP.Y + i)); pointList2.Add(new Point(iniP.X - a * i * i, iniP.Y - i)); } point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); point = new StylusPointCollection(pointList2); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); stylusPoint = new StylusPoint(iniP.X - p / 2, iniP.Y, (float)1.0); point = new StylusPointCollection(); point.Add(stylusPoint); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -1033,7 +1153,8 @@ namespace Ink_Canvas { case 6: _currentCommitType = CommitReason.ShapeDrawing; newIniP = iniP; - if (iniP.Y > endP.Y) { + if (iniP.Y > endP.Y) + { newIniP = new Point(iniP.X, endP.Y); endP = new Point(endP.X, iniP.Y); } @@ -1044,7 +1165,8 @@ namespace Ink_Canvas { pointList = GenerateEllipseGeometry(new Point(newIniP.X, newIniP.Y - topB / 2), new Point(endP.X, newIniP.Y + topB / 2)); point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); @@ -1052,7 +1174,8 @@ namespace Ink_Canvas { pointList = GenerateEllipseGeometry(new Point(newIniP.X, endP.Y - topB / 2), new Point(endP.X, endP.Y + topB / 2), false); point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); @@ -1064,7 +1187,8 @@ namespace Ink_Canvas { new Point(newIniP.X, endP.Y) }; point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); @@ -1074,14 +1198,17 @@ namespace Ink_Canvas { new Point(endP.X, endP.Y) }; point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -1090,7 +1217,8 @@ namespace Ink_Canvas { break; case 7: _currentCommitType = CommitReason.ShapeDrawing; - if (iniP.Y > endP.Y) { + if (iniP.Y > endP.Y) + { newIniP = new Point(iniP.X, endP.Y); endP = new Point(endP.X, iniP.Y); } @@ -1101,7 +1229,8 @@ namespace Ink_Canvas { pointList = GenerateEllipseGeometry(new Point(newIniP.X, endP.Y - bottomB / 2), new Point(endP.X, endP.Y + bottomB / 2), false); point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); @@ -1113,7 +1242,8 @@ namespace Ink_Canvas { new Point(newIniP.X, endP.Y) }; point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); @@ -1123,14 +1253,17 @@ namespace Ink_Canvas { new Point(endP.X, endP.Y) }; point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -1140,16 +1273,19 @@ namespace Ink_Canvas { case 9: // 画长方体 _currentCommitType = CommitReason.ShapeDrawing; - if (isFirstTouchCuboid) { + if (isFirstTouchCuboid) + { //分开画线条方便后期单独擦除某一条棱 strokes.Add(GenerateLineStroke(new Point(iniP.X, iniP.Y), new Point(iniP.X, endP.Y))); strokes.Add(GenerateLineStroke(new Point(iniP.X, endP.Y), new Point(endP.X, endP.Y))); strokes.Add(GenerateLineStroke(new Point(endP.X, endP.Y), new Point(endP.X, iniP.Y))); strokes.Add(GenerateLineStroke(new Point(iniP.X, iniP.Y), new Point(endP.X, iniP.Y))); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -1158,7 +1294,8 @@ namespace Ink_Canvas { CuboidFrontRectIniP = iniP; CuboidFrontRectEndP = endP; } - else { + else + { d = CuboidFrontRectIniP.Y - endP.Y; if (d < 0) d = -d; //就是懒不想做反向的,不要让我去做,想做自己做好之后 Pull Request a = CuboidFrontRectEndP.X - CuboidFrontRectIniP.X; //正面矩形长 @@ -1212,10 +1349,12 @@ namespace Ink_Canvas { stroke = new Stroke(point) { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); - try { + try + { inkCanvas.Strokes.Remove(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -1239,16 +1378,19 @@ namespace Ink_Canvas { private bool isWaitUntilNextTouchDown; private List GenerateEllipseGeometry(Point st, Point ed, bool isDrawTop = true, - bool isDrawBottom = true) { + bool isDrawBottom = true) + { var a = 0.5 * (ed.X - st.X); var b = 0.5 * (ed.Y - st.Y); var pointList = new List(); - if (isDrawTop && isDrawBottom) { + if (isDrawTop && isDrawBottom) + { for (double r = 0; r <= 2 * Math.PI; r = r + 0.01) pointList.Add(new Point(0.5 * (st.X + ed.X) + a * Math.Cos(r), 0.5 * (st.Y + ed.Y) + b * Math.Sin(r))); } - else { + else + { if (isDrawBottom) for (double r = 0; r <= Math.PI; r = r + 0.01) pointList.Add(new Point(0.5 * (st.X + ed.X) + a * Math.Cos(r), @@ -1263,7 +1405,8 @@ namespace Ink_Canvas { } private StrokeCollection GenerateDashedLineEllipseStrokeCollection(Point st, Point ed, bool isDrawTop = true, - bool isDrawBottom = true) { + bool isDrawBottom = true) + { var a = 0.5 * (ed.X - st.X); var b = 0.5 * (ed.Y - st.Y); var step = 0.05; @@ -1272,26 +1415,30 @@ namespace Ink_Canvas { Stroke stroke; var strokes = new StrokeCollection(); if (isDrawBottom) - for (var i = 0.0; i < 1.0; i += step * 1.66) { + for (var i = 0.0; i < 1.0; i += step * 1.66) + { pointList = new List(); for (var r = Math.PI * i; r <= Math.PI * (i + step); r = r + 0.01) pointList.Add(new Point(0.5 * (st.X + ed.X) + a * Math.Cos(r), 0.5 * (st.Y + ed.Y) + b * Math.Sin(r))); point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); } if (isDrawTop) - for (var i = 1.0; i < 2.0; i += step * 1.66) { + for (var i = 1.0; i < 2.0; i += step * 1.66) + { pointList = new List(); for (var r = Math.PI * i; r <= Math.PI * (i + step); r = r + 0.01) pointList.Add(new Point(0.5 * (st.X + ed.X) + a * Math.Cos(r), 0.5 * (st.Y + ed.Y) + b * Math.Sin(r))); point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); @@ -1300,7 +1447,8 @@ namespace Ink_Canvas { return strokes; } - private Stroke GenerateLineStroke(Point st, Point ed) { + private Stroke GenerateLineStroke(Point st, Point ed) + { var pointList = new List(); StylusPointCollection point; Stroke stroke; @@ -1309,13 +1457,15 @@ namespace Ink_Canvas { new Point(ed.X, ed.Y) }; point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; return stroke; } - private Stroke GenerateArrowLineStroke(Point st, Point ed) { + private Stroke GenerateArrowLineStroke(Point st, Point ed) + { var pointList = new List(); StylusPointCollection point; Stroke stroke; @@ -1333,14 +1483,16 @@ namespace Ink_Canvas { new Point(ed.X + (w * cost + h * sint), ed.Y - (h * cost - w * sint)) }; point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; return stroke; } - private StrokeCollection GenerateDashedLineStrokeCollection(Point st, Point ed) { + private StrokeCollection GenerateDashedLineStrokeCollection(Point st, Point ed) + { double step = 5; var pointList = new List(); StylusPointCollection point; @@ -1349,13 +1501,15 @@ namespace Ink_Canvas { var d = GetDistance(st, ed); var sinTheta = (ed.Y - st.Y) / d; var cosTheta = (ed.X - st.X) / d; - for (var i = 0.0; i < d; i += step * 2.76) { + for (var i = 0.0; i < d; i += step * 2.76) + { pointList = new List { new Point(st.X + i * cosTheta, st.Y + i * sinTheta), new Point(st.X + Math.Min(i + step, d) * cosTheta, st.Y + Math.Min(i + step, d) * sinTheta) }; point = new StylusPointCollection(pointList); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); @@ -1364,7 +1518,8 @@ namespace Ink_Canvas { return strokes; } - private StrokeCollection GenerateDotLineStrokeCollection(Point st, Point ed) { + private StrokeCollection GenerateDotLineStrokeCollection(Point st, Point ed) + { double step = 3; var pointList = new List(); StylusPointCollection point; @@ -1373,11 +1528,13 @@ namespace Ink_Canvas { var d = GetDistance(st, ed); var sinTheta = (ed.Y - st.Y) / d; var cosTheta = (ed.X - st.X) / d; - for (var i = 0.0; i < d; i += step * 2.76) { + for (var i = 0.0; i < d; i += step * 2.76) + { var stylusPoint = new StylusPoint(st.X + i * cosTheta, st.Y + i * sinTheta, (float)0.8); point = new StylusPointCollection(); point.Add(stylusPoint); - stroke = new Stroke(point) { + stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; strokes.Add(stroke.Clone()); @@ -1388,7 +1545,8 @@ namespace Ink_Canvas { private bool isMouseDown; - private void inkCanvas_MouseDown(object sender, MouseButtonEventArgs e) { + private void inkCanvas_MouseDown(object sender, MouseButtonEventArgs e) + { inkCanvas.CaptureMouse(); ViewboxFloatingBar.IsHitTestVisible = false; BlackboardUIGridForInkReplay.IsHitTestVisible = false; @@ -1397,17 +1555,21 @@ namespace Ink_Canvas { if (NeedUpdateIniP()) iniP = e.GetPosition(inkCanvas); } - private void inkCanvas_MouseMove(object sender, MouseEventArgs e) { + private void inkCanvas_MouseMove(object sender, MouseEventArgs e) + { if (isMouseDown) MouseTouchMove(e.GetPosition(inkCanvas)); } - private void inkCanvas_MouseUp(object sender, MouseButtonEventArgs e) { + private void inkCanvas_MouseUp(object sender, MouseButtonEventArgs e) + { inkCanvas.ReleaseMouseCapture(); ViewboxFloatingBar.IsHitTestVisible = true; BlackboardUIGridForInkReplay.IsHitTestVisible = true; - if (drawingShapeMode == 5) { - if (lastTempStroke != null) { + if (drawingShapeMode == 5) + { + if (lastTempStroke != null) + { var circle = new Circle(new Point(), 0, lastTempStroke); circle.R = GetDistance(circle.Stroke.StylusPoints[0].ToPoint(), circle.Stroke.StylusPoints[circle.Stroke.StylusPoints.Count / 2].ToPoint()) / 2; @@ -1419,45 +1581,52 @@ namespace Ink_Canvas { circles.Add(circle); } - if (lastIsInMultiTouchMode) { + if (lastIsInMultiTouchMode) + { // 不再重新启用开关,而是恢复多指书写相关的事件处理 // ToggleSwitchEnableMultiTouchMode.IsOn = true; - + // 恢复多指书写事件处理 inkCanvas.StylusDown += MainWindow_StylusDown; inkCanvas.StylusMove += MainWindow_StylusMove; inkCanvas.StylusUp += MainWindow_StylusUp; inkCanvas.TouchDown += MainWindow_TouchDown; - + lastIsInMultiTouchMode = false; } } // 修改此处逻辑,确保在正确的情况下才切换回笔模式 - if (drawingShapeMode != 9 && drawingShapeMode != 0 && drawingShapeMode != 24 && drawingShapeMode != 25) { - if (isLongPressSelected) { + if (drawingShapeMode != 9 && drawingShapeMode != 0 && drawingShapeMode != 24 && drawingShapeMode != 25) + { + if (isLongPressSelected) + { // 如果是长按选中的情况,保持图形模式,不做任何切换 isWaitUntilNextTouchDown = true; // 保持当前绘图模式直到下一次触摸 } - else { + else + { BtnPen_Click(null, null); //画完一次还原到笔模式 - if (lastIsInMultiTouchMode) { + if (lastIsInMultiTouchMode) + { // 不再重新启用开关,而是恢复多指书写相关的事件处理 // ToggleSwitchEnableMultiTouchMode.IsOn = true; - + // 恢复多指书写事件处理 inkCanvas.StylusDown += MainWindow_StylusDown; inkCanvas.StylusMove += MainWindow_StylusMove; inkCanvas.StylusUp += MainWindow_StylusUp; inkCanvas.TouchDown += MainWindow_TouchDown; - + lastIsInMultiTouchMode = false; } } } - if (drawingShapeMode == 9) { - if (isFirstTouchCuboid) { + if (drawingShapeMode == 9) + { + if (isFirstTouchCuboid) + { if (CuboidStrokeCollection == null) CuboidStrokeCollection = new StrokeCollection(); isFirstTouchCuboid = false; var newIniP = new Point(Math.Min(CuboidFrontRectIniP.X, CuboidFrontRectEndP.X), @@ -1466,33 +1635,40 @@ namespace Ink_Canvas { Math.Max(CuboidFrontRectIniP.Y, CuboidFrontRectEndP.Y)); CuboidFrontRectIniP = newIniP; CuboidFrontRectEndP = newEndP; - try { + try + { CuboidStrokeCollection.Add(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } } - else { + else + { BtnPen_Click(null, null); //画完还原到笔模式 - if (lastIsInMultiTouchMode) { + if (lastIsInMultiTouchMode) + { // 不再重新启用开关,而是恢复多指书写相关的事件处理 // ToggleSwitchEnableMultiTouchMode.IsOn = true; - + // 恢复多指书写事件处理 inkCanvas.StylusDown += MainWindow_StylusDown; inkCanvas.StylusMove += MainWindow_StylusMove; inkCanvas.StylusUp += MainWindow_StylusUp; inkCanvas.TouchDown += MainWindow_TouchDown; - + lastIsInMultiTouchMode = false; } - if (_currentCommitType == CommitReason.ShapeDrawing) { - try { + if (_currentCommitType == CommitReason.ShapeDrawing) + { + try + { CuboidStrokeCollection.Add(lastTempStrokeCollection); } - catch { + catch + { Trace.WriteLine("lastTempStrokeCollection failed."); } @@ -1503,15 +1679,20 @@ namespace Ink_Canvas { } } - if (drawingShapeMode == 24 || drawingShapeMode == 25) { - if (drawMultiStepShapeCurrentStep == 0) { + if (drawingShapeMode == 24 || drawingShapeMode == 25) + { + if (drawMultiStepShapeCurrentStep == 0) + { drawMultiStepShapeCurrentStep = 1; } - else { + else + { drawMultiStepShapeCurrentStep = 0; - if (drawMultiStepShapeSpecialStrokeCollection != null) { + if (drawMultiStepShapeSpecialStrokeCollection != null) + { var opFlag = false; - switch (Settings.Canvas.HyperbolaAsymptoteOption) { + switch (Settings.Canvas.HyperbolaAsymptoteOption) + { case OptionalOperation.Yes: opFlag = true; break; @@ -1529,29 +1710,32 @@ namespace Ink_Canvas { } BtnPen_Click(null, null); //画完还原到笔模式 - if (lastIsInMultiTouchMode) { + if (lastIsInMultiTouchMode) + { // 不再重新启用开关,而是恢复多指书写相关的事件处理 // ToggleSwitchEnableMultiTouchMode.IsOn = true; - + // 恢复多指书写事件处理 inkCanvas.StylusDown += MainWindow_StylusDown; inkCanvas.StylusMove += MainWindow_StylusMove; inkCanvas.StylusUp += MainWindow_StylusUp; inkCanvas.TouchDown += MainWindow_TouchDown; - + lastIsInMultiTouchMode = false; } } } isMouseDown = false; - if (ReplacedStroke != null || AddedStroke != null) { + if (ReplacedStroke != null || AddedStroke != null) + { timeMachine.CommitStrokeEraseHistory(ReplacedStroke, AddedStroke); AddedStroke = null; ReplacedStroke = null; } - if (_currentCommitType == CommitReason.ShapeDrawing && drawingShapeMode != 9) { + if (_currentCommitType == CommitReason.ShapeDrawing && drawingShapeMode != 9) + { _currentCommitType = CommitReason.UserInput; StrokeCollection collection = null; if (lastTempStrokeCollection != null && lastTempStrokeCollection.Count > 0) @@ -1605,34 +1789,43 @@ namespace Ink_Canvas { Debug.WriteLine($"形状绘制高级贝塞尔曲线平滑失败: {ex.Message}"); } } - else if (Settings.Canvas.FitToCurve) + else if (Settings.Canvas.FitToCurve) { drawingAttributes.FitToCurve = true; } } - private bool NeedUpdateIniP() { + private bool NeedUpdateIniP() + { if (drawingShapeMode == 24 || drawingShapeMode == 25) if (drawMultiStepShapeCurrentStep == 1) return false; return true; } - private void MainWindow_OnMouseMove(object sender, MouseEventArgs e) { - if (e.StylusDevice == null) { + private void MainWindow_OnMouseMove(object sender, MouseEventArgs e) + { + if (e.StylusDevice == null) + { // 鼠标移动时保持光标可见 System.Windows.Forms.Cursor.Show(); - + // 如果用户设置了显示光标,则确保光标显示正确 - if (Settings.Canvas.IsShowCursor && inkCanvas != null) { + if (Settings.Canvas.IsShowCursor && inkCanvas != null) + { inkCanvas.ForceCursor = true; inkCanvas.UseCustomCursor = true; } - } else { + } + else + { // 只有当用户未设置显示光标时才隐藏 - if (!Settings.Canvas.IsShowCursor) { + if (!Settings.Canvas.IsShowCursor) + { System.Windows.Forms.Cursor.Hide(); - } else if (inkCanvas != null) { + } + else if (inkCanvas != null) + { // 如果用户设置了显示光标,则确保光标显示正确 inkCanvas.ForceCursor = true; inkCanvas.UseCustomCursor = true; @@ -1642,7 +1835,8 @@ namespace Ink_Canvas { } // 在MainWindow类中添加: - private void EnterShapeDrawingMode(int mode) { + private void EnterShapeDrawingMode(int mode) + { forceEraser = true; forcePointEraser = false; drawingShapeMode = mode; diff --git a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs index 25e34f29..4dae95ad 100644 --- a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs +++ b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs @@ -1,4 +1,5 @@ -using System; +using Ink_Canvas.Helpers; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -8,11 +9,12 @@ using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; -using Ink_Canvas.Helpers; using Point = System.Windows.Point; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { private StrokeCollection newStrokes = new StrokeCollection(); private List circles = new List(); private const double LINE_STRAIGHTEN_THRESHOLD = 0.20; // 默认灵敏度阈值,与UI默认值对应 @@ -52,46 +54,57 @@ namespace Ink_Canvas { } } - private void inkCanvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e) { + private void inkCanvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e) + { // 标记是否进行了直线拉直 bool wasStraightened = false; - + // 禁用原有的FitToCurve,使用新的高级贝塞尔曲线平滑 if (Settings.Canvas.FitToCurve) drawingAttributes.FitToCurve = false; - try { + try + { inkCanvas.Opacity = 1; - + // 应用屏蔽压感功能 - 如果启用,所有笔画都使用统一粗细 - if (Settings.Canvas.DisablePressure) { + if (Settings.Canvas.DisablePressure) + { var uniformPoints = new StylusPointCollection(); - foreach (StylusPoint point in e.Stroke.StylusPoints) { + foreach (StylusPoint point in e.Stroke.StylusPoints) + { StylusPoint newPoint = new StylusPoint(point.X, point.Y, 0.5f); // 统一压感值为0.5 uniformPoints.Add(newPoint); } e.Stroke.StylusPoints = uniformPoints; } // 应用压感触屏模式 - 如果启用并且检测到触屏输入 - else if (Settings.Canvas.EnablePressureTouchMode) { + else if (Settings.Canvas.EnablePressureTouchMode) + { bool isTouchInput = true; - foreach (StylusPoint point in e.Stroke.StylusPoints) { + foreach (StylusPoint point in e.Stroke.StylusPoints) + { // 检测是否为压感笔输入(压感笔的PressureFactor不等于0.5或0) - if ((point.PressureFactor > 0.501 || point.PressureFactor < 0.5) && point.PressureFactor != 0) { + if ((point.PressureFactor > 0.501 || point.PressureFactor < 0.5) && point.PressureFactor != 0) + { isTouchInput = false; break; } } // 如果是触屏输入,则应用模拟压感 - if (isTouchInput) { - switch (Settings.Canvas.InkStyle) { + if (isTouchInput) + { + switch (Settings.Canvas.InkStyle) + { case 1: if (penType == 0) - try { + try + { var stylusPoints = new StylusPointCollection(); var n = e.Stroke.StylusPoints.Count - 1; - for (var i = 0; i <= n; i++) { + for (var i = 0; i <= n; i++) + { var speed = GetPointSpeed(e.Stroke.StylusPoints[Math.Max(i - 1, 0)].ToPoint(), e.Stroke.StylusPoints[i].ToPoint(), e.Stroke.StylusPoints[Math.Min(i + 1, n)].ToPoint()); @@ -114,14 +127,17 @@ namespace Ink_Canvas { break; case 0: if (penType == 0) - try { + try + { var stylusPoints = new StylusPointCollection(); var n = e.Stroke.StylusPoints.Count - 1; var pressure = 0.1; var x = 10; if (n == 1) return; - if (n >= x) { - for (var i = 0; i < n - x; i++) { + if (n >= x) + { + for (var i = 0; i < n - x; i++) + { var point = new StylusPoint(); point.PressureFactor = (float)0.5; @@ -130,7 +146,8 @@ namespace Ink_Canvas { stylusPoints.Add(point); } - for (var i = n - x; i <= n; i++) { + for (var i = n - x; i <= n; i++) + { var point = new StylusPoint(); point.PressureFactor = (float)((0.5 - pressure) * (n - i) / x + pressure); @@ -139,8 +156,10 @@ namespace Ink_Canvas { stylusPoints.Add(point); } } - else { - for (var i = 0; i <= n; i++) { + else + { + for (var i = 0; i <= n; i++) + { var point = new StylusPoint(); point.PressureFactor = (float)(0.4 * (n - i) / n + pressure); @@ -157,33 +176,38 @@ namespace Ink_Canvas { } } } - - // Apply line straightening and endpoint snapping if ink-to-shape is enabled - - if (Settings.InkToShape.IsInkToShapeEnabled) { + + // Apply line straightening and endpoint snapping if ink-to-shape is enabled + + if (Settings.InkToShape.IsInkToShapeEnabled) + { // 检查是否启用了直线自动拉直功能 - if (Settings.Canvas.AutoStraightenLine && IsPotentialStraightLine(e.Stroke)) { + if (Settings.Canvas.AutoStraightenLine && IsPotentialStraightLine(e.Stroke)) + { // Get start and end points of the stroke Point startPoint = e.Stroke.StylusPoints[0].ToPoint(); Point endPoint = e.Stroke.StylusPoints[e.Stroke.StylusPoints.Count - 1].ToPoint(); - + // 先完成所有直线判定,再考虑端点吸附 // 读取实际的灵敏度设置值 double sensitivity = Settings.InkToShape.LineStraightenSensitivity; Debug.WriteLine($"当前灵敏度值: {sensitivity}"); - + // 判断是否应该拉直线条 bool shouldStraighten = ShouldStraightenLine(e.Stroke); - + // 输出一些调试信息,帮助理解灵敏度设置的效果 Debug.WriteLine($"LineStraightenSensitivity: {Settings.InkToShape.LineStraightenSensitivity}, ShouldStraighten: {shouldStraighten}"); - + // 只有当确定要拉直线条时,才检查端点吸附 - if (shouldStraighten && Settings.Canvas.LineEndpointSnapping) { + if (shouldStraighten && Settings.Canvas.LineEndpointSnapping) + { // 只有在启用了形状识别(矩形或三角形)时才执行端点吸附 - if (Settings.InkToShape.IsInkToShapeRectangle || Settings.InkToShape.IsInkToShapeTriangle) { + if (Settings.InkToShape.IsInkToShapeRectangle || Settings.InkToShape.IsInkToShapeTriangle) + { Point[] snappedPoints = GetSnappedEndpoints(startPoint, endPoint); - if (snappedPoints != null) { + if (snappedPoints != null) + { startPoint = snappedPoints[0]; endPoint = snappedPoints[1]; } @@ -191,34 +215,40 @@ namespace Ink_Canvas { } // 如果确定要拉直,则创建直线 - if (shouldStraighten) { + if (shouldStraighten) + { StylusPointCollection straightLinePoints = CreateStraightLine(startPoint, endPoint); - Stroke straightStroke = new Stroke(straightLinePoints) { + Stroke straightStroke = new Stroke(straightLinePoints) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; - + // Replace the original stroke with the straightened one SetNewBackupOfStroke(); _currentCommitType = CommitReason.ShapeRecognition; inkCanvas.Strokes.Remove(e.Stroke); inkCanvas.Strokes.Add(straightStroke); _currentCommitType = CommitReason.UserInput; - + // We can't modify e.Stroke directly, but we need to update newStrokes // to ensure proper shape recognition for the straightened line - if (newStrokes.Contains(e.Stroke)) { + if (newStrokes.Contains(e.Stroke)) + { newStrokes.Remove(e.Stroke); newStrokes.Add(straightStroke); } - + wasStraightened = true; // 标记已进行直线拉直 } } } - if (Settings.InkToShape.IsInkToShapeEnabled && !Environment.Is64BitProcess) { - void InkToShapeProcess() { - try { + if (Settings.InkToShape.IsInkToShapeEnabled && !Environment.Is64BitProcess) + { + void InkToShapeProcess() + { + try + { newStrokes.Add(e.Stroke); if (newStrokes.Count > 4) newStrokes.RemoveAt(0); for (var i = 0; i < newStrokes.Count; i++) @@ -234,11 +264,13 @@ namespace Ink_Canvas { var strokeReco = new StrokeCollection(); var result = InkRecognizeHelper.RecognizeShape(newStrokes); - for (var i = newStrokes.Count - 1; i >= 0; i--) { + for (var i = newStrokes.Count - 1; i >= 0; i--) + { strokeReco.Add(newStrokes[i]); var newResult = InkRecognizeHelper.RecognizeShape(strokeReco); if (newResult.InkDrawingNode.GetShapeName() == "Circle" || - newResult.InkDrawingNode.GetShapeName() == "Ellipse") { + newResult.InkDrawingNode.GetShapeName() == "Ellipse") + { result = newResult; break; } @@ -247,17 +279,21 @@ namespace Ink_Canvas { } if (result.InkDrawingNode.GetShapeName() == "Circle" && - Settings.InkToShape.IsInkToShapeRounded) { + Settings.InkToShape.IsInkToShapeRounded) + { var shape = result.InkDrawingNode.GetShape(); - if (shape.Width > 75) { + if (shape.Width > 75) + { foreach (var circle in circles) //判断是否画同心圆 if (Math.Abs(result.Centroid.X - circle.Centroid.X) / shape.Width < 0.12 && - Math.Abs(result.Centroid.Y - circle.Centroid.Y) / shape.Width < 0.12) { + Math.Abs(result.Centroid.Y - circle.Centroid.Y) / shape.Width < 0.12) + { result.Centroid = circle.Centroid; break; } - else { + else + { var d = (result.Centroid.X - circle.Centroid.X) * (result.Centroid.X - circle.Centroid.X) + (result.Centroid.Y - circle.Centroid.Y) * @@ -265,7 +301,8 @@ namespace Ink_Canvas { d = Math.Sqrt(d); //判断是否画外切圆 var x = shape.Width / 2.0 + circle.R - d; - if (Math.Abs(x) / shape.Width < 0.1) { + if (Math.Abs(x) / shape.Width < 0.1) + { var sinTheta = (result.Centroid.Y - circle.Centroid.Y) / d; var cosTheta = (result.Centroid.X - circle.Centroid.X) / d; var newX = result.Centroid.X + x * cosTheta; @@ -275,7 +312,8 @@ namespace Ink_Canvas { //判断是否画外切圆 x = Math.Abs(circle.R - shape.Width / 2.0) - d; - if (Math.Abs(x) / shape.Width < 0.1) { + if (Math.Abs(x) / shape.Width < 0.1) + { var sinTheta = (result.Centroid.Y - circle.Centroid.Y) / d; var cosTheta = (result.Centroid.X - circle.Centroid.X) / d; var newX = result.Centroid.X + x * cosTheta; @@ -290,7 +328,8 @@ namespace Ink_Canvas { result.Centroid.Y + shape.Height / 2); var pointList = GenerateEllipseGeometry(iniP, endP); var point = new StylusPointCollection(pointList); - var stroke = new Stroke(point) { + var stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; circles.Add(new Circle(result.Centroid, shape.Width / 2.0, stroke)); @@ -303,7 +342,8 @@ namespace Ink_Canvas { } } else if (result.InkDrawingNode.GetShapeName().Contains("Ellipse") && - Settings.InkToShape.IsInkToShapeRounded) { + Settings.InkToShape.IsInkToShapeRounded) + { var shape = result.InkDrawingNode.GetShape(); //var shape1 = result.InkDrawingNode.GetShape(); //shape1.Fill = Brushes.Gray; @@ -311,7 +351,8 @@ namespace Ink_Canvas { var p = result.InkDrawingNode.HotPoints; var a = GetDistance(p[0], p[2]) / 2; //长半轴 var b = GetDistance(p[1], p[3]) / 2; //短半轴 - if (a < b) { + if (a < b) + { var t = a; a = b; b = t; @@ -320,7 +361,8 @@ namespace Ink_Canvas { result.Centroid = new Point((p[0].X + p[2].X) / 2, (p[0].Y + p[2].Y) / 2); var needRotation = true; - if (shape.Width > 75 || (shape.Height > 75 && p.Count == 4)) { + if (shape.Width > 75 || (shape.Height > 75 && p.Count == 4)) + { var iniP = new Point(result.Centroid.X - shape.Width / 2, result.Centroid.Y - shape.Height / 2); var endP = new Point(result.Centroid.X + shape.Width / 2, @@ -329,7 +371,8 @@ namespace Ink_Canvas { foreach (var circle in circles) //判断是否画同心椭圆 if (Math.Abs(result.Centroid.X - circle.Centroid.X) / a < 0.2 && - Math.Abs(result.Centroid.Y - circle.Centroid.Y) / a < 0.2) { + Math.Abs(result.Centroid.Y - circle.Centroid.Y) / a < 0.2) + { result.Centroid = circle.Centroid; iniP = new Point(result.Centroid.X - shape.Width / 2, result.Centroid.Y - shape.Height / 2); @@ -337,14 +380,17 @@ namespace Ink_Canvas { result.Centroid.Y + shape.Height / 2); //再判断是否与圆相切 - if (Math.Abs(a - circle.R) / a < 0.2) { - if (shape.Width >= shape.Height) { + if (Math.Abs(a - circle.R) / a < 0.2) + { + if (shape.Width >= shape.Height) + { iniP.X = result.Centroid.X - circle.R; endP.X = result.Centroid.X + circle.R; iniP.Y = result.Centroid.Y - b; endP.Y = result.Centroid.Y + b; } - else { + else + { iniP.Y = result.Centroid.Y - circle.R; endP.Y = result.Centroid.Y + circle.R; iniP.X = result.Centroid.X - a; @@ -354,13 +400,15 @@ namespace Ink_Canvas { break; } - else if (Math.Abs(result.Centroid.X - circle.Centroid.X) / a < 0.2) { + else if (Math.Abs(result.Centroid.X - circle.Centroid.X) / a < 0.2) + { var sinTheta = Math.Abs(circle.Centroid.Y - result.Centroid.Y) / circle.R; var cosTheta = Math.Sqrt(1 - sinTheta * sinTheta); var newA = circle.R * cosTheta; if (circle.R * sinTheta / circle.R < 0.9 && a / b > 2 && - Math.Abs(newA - a) / newA < 0.3) { + Math.Abs(newA - a) / newA < 0.3) + { iniP.X = circle.Centroid.X - newA; endP.X = circle.Centroid.X + newA; iniP.Y = result.Centroid.Y - newA / 5; @@ -375,7 +423,8 @@ namespace Ink_Canvas { var _pointList = GenerateEllipseGeometry(iniP, endP, false); var _point = new StylusPointCollection(_pointList); - var _stroke = new Stroke(_point) { + var _stroke = new Stroke(_point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; var _dashedLineStroke = @@ -389,13 +438,15 @@ namespace Ink_Canvas { return; } } - else if (Math.Abs(result.Centroid.Y - circle.Centroid.Y) / a < 0.2) { + else if (Math.Abs(result.Centroid.Y - circle.Centroid.Y) / a < 0.2) + { var cosTheta = Math.Abs(circle.Centroid.X - result.Centroid.X) / circle.R; var sinTheta = Math.Sqrt(1 - cosTheta * cosTheta); var newA = circle.R * sinTheta; if (circle.R * sinTheta / circle.R < 0.9 && a / b > 2 && - Math.Abs(newA - a) / newA < 0.3) { + Math.Abs(newA - a) / newA < 0.3) + { iniP.X = result.Centroid.X - newA / 5; endP.X = result.Centroid.X + newA / 5; iniP.Y = circle.Centroid.Y - newA; @@ -414,11 +465,13 @@ namespace Ink_Canvas { var pointList = GenerateEllipseGeometry(iniP, endP); var point = new StylusPointCollection(pointList); - var stroke = new Stroke(point) { + var stroke = new Stroke(point) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; - if (needRotation) { + if (needRotation) + { var m = new Matrix(); var fe = e.Source as FrameworkElement; var tanTheta = (p[2].Y - p[0].Y) / (p[2].X - p[0].X); @@ -437,14 +490,16 @@ namespace Ink_Canvas { } } else if (result.InkDrawingNode.GetShapeName().Contains("Triangle") && - Settings.InkToShape.IsInkToShapeTriangle) { + Settings.InkToShape.IsInkToShapeTriangle) + { var shape = result.InkDrawingNode.GetShape(); var p = result.InkDrawingNode.HotPoints; if ((Math.Max(Math.Max(p[0].X, p[1].X), p[2].X) - Math.Min(Math.Min(p[0].X, p[1].X), p[2].X) >= 100 || Math.Max(Math.Max(p[0].Y, p[1].Y), p[2].Y) - Math.Min(Math.Min(p[0].Y, p[1].Y), p[2].Y) >= 100) && - result.InkDrawingNode.HotPoints.Count == 3) { + result.InkDrawingNode.HotPoints.Count == 3) + { //纠正垂直与水平关系 var newPoints = FixPointsDirection(p[0], p[1]); p[0] = newPoints[0]; @@ -459,7 +514,8 @@ namespace Ink_Canvas { var pointList = p.ToList(); //pointList.Add(p[0]); var point = new StylusPointCollection(pointList); - var stroke = new Stroke(GenerateFakePressureTriangle(point)) { + var stroke = new Stroke(GenerateFakePressureTriangle(point)) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; SetNewBackupOfStroke(); @@ -476,14 +532,16 @@ namespace Ink_Canvas { result.InkDrawingNode.GetShapeName().Contains("Parallelogram") || result.InkDrawingNode.GetShapeName().Contains("Square") || result.InkDrawingNode.GetShapeName().Contains("Trapezoid")) && - Settings.InkToShape.IsInkToShapeRectangle) { + Settings.InkToShape.IsInkToShapeRectangle) + { var shape = result.InkDrawingNode.GetShape(); var p = result.InkDrawingNode.HotPoints; if ((Math.Max(Math.Max(Math.Max(p[0].X, p[1].X), p[2].X), p[3].X) - Math.Min(Math.Min(Math.Min(p[0].X, p[1].X), p[2].X), p[3].X) >= 100 || Math.Max(Math.Max(Math.Max(p[0].Y, p[1].Y), p[2].Y), p[3].Y) - Math.Min(Math.Min(Math.Min(p[0].Y, p[1].Y), p[2].Y), p[3].Y) >= 100) && - result.InkDrawingNode.HotPoints.Count == 4) { + result.InkDrawingNode.HotPoints.Count == 4) + { //纠正垂直与水平关系 var newPoints = FixPointsDirection(p[0], p[1]); p[0] = newPoints[0]; @@ -501,7 +559,8 @@ namespace Ink_Canvas { var pointList = p.ToList(); pointList.Add(p[0]); var point = new StylusPointCollection(pointList); - var stroke = new Stroke(GenerateFakePressureRectangle(point)) { + var stroke = new Stroke(GenerateFakePressureRectangle(point)) + { DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; SetNewBackupOfStroke(); @@ -528,8 +587,10 @@ namespace Ink_Canvas { stylusPoint.PressureFactor != 0) return; - try { - if (e.Stroke.StylusPoints.Count > 3) { + try + { + if (e.Stroke.StylusPoints.Count > 3) + { var random = new Random(); var _speed = GetPointSpeed( e.Stroke.StylusPoints[random.Next(0, e.Stroke.StylusPoints.Count - 1)].ToPoint(), @@ -541,15 +602,18 @@ namespace Ink_Canvas { } catch { } - switch (Settings.Canvas.InkStyle) { + switch (Settings.Canvas.InkStyle) + { case 1: if (penType == 0) - try { + try + { var stylusPoints = new StylusPointCollection(); var n = e.Stroke.StylusPoints.Count - 1; var s = ""; - for (var i = 0; i <= n; i++) { + for (var i = 0; i <= n; i++) + { var speed = GetPointSpeed(e.Stroke.StylusPoints[Math.Max(i - 1, 0)].ToPoint(), e.Stroke.StylusPoints[i].ToPoint(), e.Stroke.StylusPoints[Math.Min(i + 1, n)].ToPoint()); @@ -574,14 +638,17 @@ namespace Ink_Canvas { break; case 0: if (penType == 0) - try { + try + { var stylusPoints = new StylusPointCollection(); var n = e.Stroke.StylusPoints.Count - 1; var pressure = 0.1; var x = 10; if (n == 1) return; - if (n >= x) { - for (var i = 0; i < n - x; i++) { + if (n >= x) + { + for (var i = 0; i < n - x; i++) + { var point = new StylusPoint(); point.PressureFactor = (float)0.5; @@ -590,7 +657,8 @@ namespace Ink_Canvas { stylusPoints.Add(point); } - for (var i = n - x; i <= n; i++) { + for (var i = n - x; i <= n; i++) + { var point = new StylusPoint(); point.PressureFactor = (float)((0.5 - pressure) * (n - i) / x + pressure); @@ -599,8 +667,10 @@ namespace Ink_Canvas { stylusPoints.Add(point); } } - else { - for (var i = 0; i <= n; i++) { + else + { + for (var i = 0; i <= n; i++) + { var point = new StylusPoint(); point.PressureFactor = (float)(0.4 * (n - i) / n + pressure); @@ -656,7 +726,7 @@ namespace Ink_Canvas { Debug.WriteLine($"高级贝塞尔曲线平滑失败: {ex.Message}"); } } - else if (Settings.Canvas.FitToCurve && !wasStraightened) + else if (Settings.Canvas.FitToCurve && !wasStraightened) { drawingAttributes.FitToCurve = true; } @@ -689,7 +759,8 @@ namespace Ink_Canvas { } // New method: Checks if a stroke is potentially a straight line - private bool IsPotentialStraightLine(Stroke stroke) { + private bool IsPotentialStraightLine(Stroke stroke) + { // 确保有足够的点来进行线条分析 if (stroke.StylusPoints.Count < 5) return false; @@ -710,66 +781,75 @@ namespace Ink_Canvas { // 新增:检查是否为明显的曲线 if (IsObviousCurve(stroke)) return false; - + // 获取用户设置的灵敏度值,确保使用正确的设置 double sensitivity = Settings.InkToShape.LineStraightenSensitivity; - + // 输出当前灵敏度值(调试用) Debug.WriteLine($"IsPotentialStraightLine - sensitivity: {sensitivity}, length: {lineLength}"); - + // 根据灵敏度调整快速检查阈值 double quickThreshold; - + // 如果灵敏度超过1.0,使用更宽松的快速检查标准 - if (sensitivity > 1.0) { + if (sensitivity > 1.0) + { // 高灵敏度模式 - 使用更宽松的阈值 quickThreshold = Math.Min(0.2 + (sensitivity - 1.0) * 0.3, 0.5); // 映射到0.2-0.5范围 - } else { + } + else + { // 常规灵敏度模式 quickThreshold = Math.Min(sensitivity * 1.5, 0.20); } - + Debug.WriteLine($"使用快速检查阈值: {quickThreshold}"); - + // 快速检查:计算几个关键点与直线的距离 - if (stroke.StylusPoints.Count >= 10) { + if (stroke.StylusPoints.Count >= 10) + { // 取中点和1/4、3/4位置的点,快速检查偏差 int quarterIdx = stroke.StylusPoints.Count / 4; int midIdx = stroke.StylusPoints.Count / 2; int threeQuarterIdx = quarterIdx * 3; - + Point quarterPoint = stroke.StylusPoints[quarterIdx].ToPoint(); Point midPoint = stroke.StylusPoints[midIdx].ToPoint(); Point threeQuarterPoint = stroke.StylusPoints[threeQuarterIdx].ToPoint(); - + double quarterDeviation = DistanceFromLineToPoint(start, end, quarterPoint); double midDeviation = DistanceFromLineToPoint(start, end, midPoint); double threeQuarterDeviation = DistanceFromLineToPoint(start, end, threeQuarterPoint); - + // 使用相对偏差:偏差与线长的比例,并使用灵敏度进行调整 double quickRelativeThreshold = lineLength * quickThreshold; - + // 记录检测到的偏差(调试用) Debug.WriteLine($"Deviations: q={quarterDeviation}, m={midDeviation}, tq={threeQuarterDeviation}, threshold={quickRelativeThreshold}"); - + // 如果灵敏度超过1.5,则即使有一个点满足条件也认为可能是直线 - if (sensitivity > 1.5) { + if (sensitivity > 1.5) + { // 超高灵敏度模式:只要有一个关键点偏差小,就认为可能是直线 - if (quarterDeviation <= quickRelativeThreshold || - midDeviation <= quickRelativeThreshold || - threeQuarterDeviation <= quickRelativeThreshold) { + if (quarterDeviation <= quickRelativeThreshold || + midDeviation <= quickRelativeThreshold || + threeQuarterDeviation <= quickRelativeThreshold) + { return true; } - } else { + } + else + { // 常规判断:如果任一点偏离太大,直接排除 - if (quarterDeviation > quickRelativeThreshold || - midDeviation > quickRelativeThreshold || - threeQuarterDeviation > quickRelativeThreshold) { + if (quarterDeviation > quickRelativeThreshold || + midDeviation > quickRelativeThreshold || + threeQuarterDeviation > quickRelativeThreshold) + { return false; } } } - + return true; } @@ -1051,7 +1131,8 @@ namespace Ink_Canvas { } // New method: Determines if a stroke should be straightened into a line - private bool ShouldStraightenLine(Stroke stroke) { + private bool ShouldStraightenLine(Stroke stroke) + { Point start = stroke.StylusPoints.First().ToPoint(); Point end = stroke.StylusPoints.Last().ToPoint(); double maxDeviation = 0; @@ -1059,7 +1140,8 @@ namespace Ink_Canvas { // 分辨率自适应阈值 double adaptiveThreshold = Settings.Canvas.AutoStraightenLineThreshold * GetResolutionScale(); // 如果线条太短,不进行拉直处理,使用自适应阈值 - if (lineLength < adaptiveThreshold) { + if (lineLength < adaptiveThreshold) + { Debug.WriteLine($"线条太短: {lineLength} < {adaptiveThreshold}"); return false; } @@ -1080,98 +1162,109 @@ namespace Ink_Canvas { Debug.WriteLine($"拒绝拉直:直线度评分过低 {straightnessScore:F3} < {minStraightnessThreshold}"); return false; } - + // 获取用户设置的灵敏度值,确保使用正确的值进行后续判断 double sensitivity = Settings.InkToShape.LineStraightenSensitivity; - + // 输出详细的调试信息 Debug.WriteLine($"ShouldStraightenLine - sensitivity: {sensitivity}, length: {lineLength}"); - + // 临时:显示调试消息框 // MessageBox.Show($"灵敏度值: {sensitivity}", "调试信息"); - + // 计算点与直线的偏差 double totalDeviation = 0; int pointCount = 0; - + // 检查是否启用了高精度直线拉直 bool useHighPrecision = Settings.Canvas.HighPrecisionLineStraighten; - - if (useHighPrecision) { + + if (useHighPrecision) + { Debug.WriteLine("使用高精度直线拉直模式"); - + // 高精度模式:每隔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(); + 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) { + 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 { + } + 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++) { + for (int i = 1; i < stroke.StylusPoints.Count; i++) + { Point currentPoint = stroke.StylusPoints[i].ToPoint(); double segmentLength = GetDistance(lastPoint, currentPoint); - + // 如果这段线段跨越了下一个采样点 - while (currentLength + segmentLength >= nextSampleAt) { + 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 { + } + else + { // 原始模式:使用所有点 - foreach (StylusPoint sp in stroke.StylusPoints) { + foreach (StylusPoint sp in stroke.StylusPoints) + { Point p = sp.ToPoint(); double deviation = DistanceFromLineToPoint(start, end, p); maxDeviation = Math.Max(maxDeviation, deviation); @@ -1179,26 +1272,28 @@ namespace Ink_Canvas { pointCount++; } } - + // 计算平均偏差 double avgDeviation = totalDeviation / pointCount; - + // 更详细的调试信息 Debug.WriteLine($"Max deviation: {maxDeviation}, Avg: {avgDeviation}, Threshold: {sensitivity * lineLength}, Points: {pointCount}"); - + // 支持更广泛的灵敏度范围 (0.05-2.0) - + // 如果灵敏度高于1.0,使用更宽松的判断标准 - if (sensitivity > 1.0) { + if (sensitivity > 1.0) + { // 高灵敏度模式 - 允许更大的偏差 double adjustedSensitivity = 0.5 + (sensitivity - 1.0) * 1.5; // 映射到0.5-2.0范围 - + // 只判断平均偏差和相对偏差 - if (maxDeviation / lineLength < adjustedSensitivity && avgDeviation < lineLength * 0.1 * adjustedSensitivity) { + if (maxDeviation / lineLength < adjustedSensitivity && avgDeviation < lineLength * 0.1 * adjustedSensitivity) + { Debug.WriteLine("接受拉直 (高灵敏度模式)"); return true; } - + Debug.WriteLine("拒绝拉直 (高灵敏度模式)"); return false; } @@ -1206,115 +1301,130 @@ namespace Ink_Canvas { // 检查点分布的一致性 - 如果有些点偏离很大而其他点很接近直线,表明线条有明显弯曲 double deviationVariance = 0; - + // 使用相同的高精度/原始模式来计算方差 - if (useHighPrecision) { + if (useHighPrecision) + { // 高精度模式:重新采样计算方差 double strokeLength = 0; double sampleInterval = 10.0; // 10像素间隔 - + // 计算笔画的总长度,用于后续采样 - for (int i = 1; i < stroke.StylusPoints.Count; i++) { - Point p1 = stroke.StylusPoints[i-1].ToPoint(); + 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) { + 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 { + } + 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++) { + for (int i = 1; i < stroke.StylusPoints.Count; i++) + { Point currentPoint = stroke.StylusPoints[i].ToPoint(); double segmentLength = GetDistance(lastPoint, currentPoint); - + // 如果这段线段跨越了下一个采样点 - while (currentLength + segmentLength >= nextSampleAt) { + 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 { + } + else + { // 原始模式:使用所有点计算方差 - foreach (StylusPoint sp in stroke.StylusPoints) { + foreach (StylusPoint sp in stroke.StylusPoints) + { Point p = sp.ToPoint(); double deviation = DistanceFromLineToPoint(start, end, p); deviationVariance += Math.Pow(deviation - avgDeviation, 2); } } - + deviationVariance /= pointCount; - + // 输出更多调试信息 Debug.WriteLine($"Deviation variance: {deviationVariance}, Threshold: {sensitivity * lineLength * 0.05}"); - + // 如果最大偏差超过线长的阈值比例,或者偏差方差较大(表示不均匀弯曲),则不拉直 // 灵敏度越大,容许的偏差越大,更容易将线条识别为直线 - if ((maxDeviation / lineLength) > sensitivity) { + if ((maxDeviation / lineLength) > sensitivity) + { Debug.WriteLine("拒绝拉直:最大偏差过大"); return false; } - + // 如果偏差方差大,说明线条弯曲不均匀 // 灵敏度越大,容许的偏差方差越大 - if (deviationVariance > (sensitivity * lineLength * 0.05)) { + if (deviationVariance > (sensitivity * lineLength * 0.05)) + { Debug.WriteLine("拒绝拉直:偏差方差过大"); return false; } - + // 检查中点偏离情况 - 针对弧形线条特别有效 - if (stroke.StylusPoints.Count > 10) { + if (stroke.StylusPoints.Count > 10) + { int midIndex = stroke.StylusPoints.Count / 2; Point midPoint = stroke.StylusPoints[midIndex].ToPoint(); double midDeviation = DistanceFromLineToPoint(start, end, midPoint); - + // 输出中点偏差信息 Debug.WriteLine($"Mid deviation: {midDeviation}, Threshold: {lineLength * sensitivity * 0.8}"); - + // 如果中点偏离过大,不拉直 // 使用灵敏度作为判断基准,灵敏度越大,容许的中点偏离越大 - if (midDeviation > (lineLength * sensitivity * 0.8)) { + if (midDeviation > (lineLength * sensitivity * 0.8)) + { Debug.WriteLine("拒绝拉直:中点偏差过大"); return false; } } - + Debug.WriteLine($"接受拉直:直线度评分 = {straightnessScore:F3}"); return true; } @@ -1420,23 +1530,27 @@ namespace Ink_Canvas { return directionScore; } - + // New method: Creates a straight line stroke between two points - private StylusPointCollection CreateStraightLine(Point start, Point end) { + private StylusPointCollection CreateStraightLine(Point start, Point end) + { StylusPointCollection points = new StylusPointCollection(); - + // 根据是否启用压感触屏模式决定如何设置压感 // 如果未启用压感触屏模式,则使用均匀粗细 - if (!Settings.Canvas.EnablePressureTouchMode || Settings.Canvas.DisablePressure || - Settings.InkToShape.IsInkToShapeNoFakePressureRectangle || penType == 1) { + if (!Settings.Canvas.EnablePressureTouchMode || Settings.Canvas.DisablePressure || + Settings.InkToShape.IsInkToShapeNoFakePressureRectangle || penType == 1) + { // 使用均匀粗细(所有点压感值都是0.5f) points.Add(new StylusPoint(start.X, start.Y, 0.5f)); - + // 可以添加一些额外的中间点使线条更平滑(均匀粗细) double distance = GetDistance(start, end); - if (distance > 100) { + if (distance > 100) + { // 对于较长的线条,添加几个中间点 - for (int i = 1; i < 3; i++) { + for (int i = 1; i < 3; i++) + { double ratio = i / 3.0; Point midPoint = new Point( start.X + (end.X - start.X) * ratio, @@ -1444,93 +1558,108 @@ namespace Ink_Canvas { points.Add(new StylusPoint(midPoint.X, midPoint.Y, 0.5f)); } } - + points.Add(new StylusPoint(end.X, end.Y, 0.5f)); - } else { + } + else + { // 启用了压感触屏模式,使用变化的粗细(原有行为) points.Add(new StylusPoint(start.X, start.Y, 0.4f)); - + // 添加中点,压感值较高,使线条中间较粗 Point midPoint = new Point((start.X + end.X) / 2, (start.Y + end.Y) / 2); points.Add(new StylusPoint(midPoint.X, midPoint.Y, 0.8f)); - + points.Add(new StylusPoint(end.X, end.Y, 0.4f)); } - + return points; } - + // New method: Gets distance from point to a line defined by two points - private double DistanceFromLineToPoint(Point lineStart, Point lineEnd, Point point) { + private double DistanceFromLineToPoint(Point lineStart, Point lineEnd, Point point) + { // Calculate distance from point to line defined by lineStart and lineEnd double lineLength = GetDistance(lineStart, lineEnd); if (lineLength == 0) return GetDistance(point, lineStart); - + // Calculate the cross product to get the perpendicular distance - double distance = Math.Abs((lineEnd.Y - lineStart.Y) * point.X - - (lineEnd.X - lineStart.X) * point.Y + + double distance = Math.Abs((lineEnd.Y - lineStart.Y) * point.X - + (lineEnd.X - lineStart.X) * point.Y + lineEnd.X * lineStart.Y - lineEnd.Y * lineStart.X) / lineLength; return distance; } - + // New method: Attempts to snap endpoints to existing stroke endpoints - private Point[] GetSnappedEndpoints(Point start, Point end) { + private Point[] GetSnappedEndpoints(Point start, Point end) + { // 如果端点吸附功能关闭,直接返回null // 这里不再返回原始点,因为调用此方法的地方会判断返回值是否为null if (!Settings.Canvas.LineEndpointSnapping) return null; - + bool startSnapped = false; bool endSnapped = false; Point snappedStart = start; Point snappedEnd = end; - + // 使用设置中的吸附距离阈值 double snapThreshold = Settings.Canvas.LineEndpointSnappingThreshold; - + // Check all strokes in canvas for potential snap points - foreach (Stroke stroke in inkCanvas.Strokes) { + foreach (Stroke stroke in inkCanvas.Strokes) + { if (stroke.StylusPoints.Count == 0) continue; - + // Get stroke endpoints Point strokeStart = stroke.StylusPoints.First().ToPoint(); Point strokeEnd = stroke.StylusPoints.Last().ToPoint(); - + // Check if start point should snap to an endpoint - if (!startSnapped) { - if (GetDistance(start, strokeStart) < snapThreshold) { + if (!startSnapped) + { + if (GetDistance(start, strokeStart) < snapThreshold) + { snappedStart = strokeStart; startSnapped = true; - } else if (GetDistance(start, strokeEnd) < snapThreshold) { + } + else if (GetDistance(start, strokeEnd) < snapThreshold) + { snappedStart = strokeEnd; startSnapped = true; } } - + // Check if end point should snap to an endpoint - if (!endSnapped) { - if (GetDistance(end, strokeStart) < snapThreshold) { + if (!endSnapped) + { + if (GetDistance(end, strokeStart) < snapThreshold) + { snappedEnd = strokeStart; endSnapped = true; - } else if (GetDistance(end, strokeEnd) < snapThreshold) { + } + else if (GetDistance(end, strokeEnd) < snapThreshold) + { snappedEnd = strokeEnd; endSnapped = true; } } - + // If both endpoints are snapped, we're done if (startSnapped && endSnapped) break; } - + // Return snapped points if any snapping occurred - if (startSnapped || endSnapped) { + if (startSnapped || endSnapped) + { return new[] { snappedStart, snappedEnd }; } - + return null; } - private void SetNewBackupOfStroke() { + private void SetNewBackupOfStroke() + { lastTouchDownStrokeCollection = inkCanvas.Strokes.Clone(); var whiteboardIndex = CurrentWhiteboardIndex; if (currentMode == 0) whiteboardIndex = 0; @@ -1538,12 +1667,14 @@ namespace Ink_Canvas { strokeCollections[whiteboardIndex] = lastTouchDownStrokeCollection; } - public double GetDistance(Point point1, Point point2) { + public double GetDistance(Point point1, Point point2) + { return Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) + (point1.Y - point2.Y) * (point1.Y - point2.Y)); } - public double GetPointSpeed(Point point1, Point point2, Point point3) { + public double GetPointSpeed(Point point1, Point point2, Point point3) + { return (Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) + (point1.Y - point2.Y) * (point1.Y - point2.Y)) + Math.Sqrt((point3.X - point2.X) * (point3.X - point2.X) + @@ -1551,27 +1682,34 @@ namespace Ink_Canvas { / 20; } - public Point[] FixPointsDirection(Point p1, Point p2) { - if (Math.Abs(p1.X - p2.X) / Math.Abs(p1.Y - p2.Y) > 8) { + public Point[] FixPointsDirection(Point p1, Point p2) + { + if (Math.Abs(p1.X - p2.X) / Math.Abs(p1.Y - p2.Y) > 8) + { //水平 var x = Math.Abs(p1.Y - p2.Y) / 2; - if (p1.Y > p2.Y) { + if (p1.Y > p2.Y) + { p1.Y -= x; p2.Y += x; } - else { + else + { p1.Y += x; p2.Y -= x; } } - else if (Math.Abs(p1.Y - p2.Y) / Math.Abs(p1.X - p2.X) > 8) { + else if (Math.Abs(p1.Y - p2.Y) / Math.Abs(p1.X - p2.X) > 8) + { //垂直 var x = Math.Abs(p1.X - p2.X) / 2; - if (p1.X > p2.X) { + if (p1.X > p2.X) + { p1.X -= x; p2.X += x; } - else { + else + { p1.X += x; p2.X -= x; } @@ -1580,8 +1718,10 @@ namespace Ink_Canvas { return new Point[2] { p1, p2 }; } - public StylusPointCollection GenerateFakePressureTriangle(StylusPointCollection points) { - if (Settings.InkToShape.IsInkToShapeNoFakePressureTriangle || penType == 1) { + public StylusPointCollection GenerateFakePressureTriangle(StylusPointCollection points) + { + if (Settings.InkToShape.IsInkToShapeNoFakePressureTriangle || penType == 1) + { var newPoint = new StylusPointCollection(); newPoint.Add(new StylusPoint(points[0].X, points[0].Y)); var cPoint = GetCenterPoint(points[0], points[1]); @@ -1597,7 +1737,8 @@ namespace Ink_Canvas { newPoint.Add(new StylusPoint(points[0].X, points[0].Y)); return newPoint; } - else { + else + { var newPoint = new StylusPointCollection(); newPoint.Add(new StylusPoint(points[0].X, points[0].Y, (float)0.4)); var cPoint = GetCenterPoint(points[0], points[1]); @@ -1617,7 +1758,8 @@ namespace Ink_Canvas { public StylusPointCollection GenerateFakePressureRectangle(StylusPointCollection points) { - if (Settings.InkToShape.IsInkToShapeNoFakePressureRectangle || penType == 1) { + if (Settings.InkToShape.IsInkToShapeNoFakePressureRectangle || penType == 1) + { return points; } @@ -1641,11 +1783,13 @@ namespace Ink_Canvas { return newPoint; } - public Point GetCenterPoint(Point point1, Point point2) { + public Point GetCenterPoint(Point point1, Point point2) + { return new Point((point1.X + point2.X) / 2, (point1.Y + point2.Y) / 2); } - public StylusPoint GetCenterPoint(StylusPoint point1, StylusPoint point2) { + public StylusPoint GetCenterPoint(StylusPoint point1, StylusPoint point2) + { return new StylusPoint((point1.X + point2.X) / 2, (point1.Y + point2.Y) / 2); } diff --git a/Ink Canvas/MainWindow_cs/MW_TimeMachine.cs b/Ink Canvas/MainWindow_cs/MW_TimeMachine.cs index 6642350e..cc44b98b 100644 --- a/Ink Canvas/MainWindow_cs/MW_TimeMachine.cs +++ b/Ink Canvas/MainWindow_cs/MW_TimeMachine.cs @@ -1,4 +1,5 @@ -using System; +using Ink_Canvas.Helpers; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Windows; @@ -6,11 +7,13 @@ using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; -using Ink_Canvas.Helpers; -namespace Ink_Canvas { - public partial class MainWindow : Window { - private enum CommitReason { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { + private enum CommitReason + { UserInput, CodeInput, ShapeDrawing, @@ -44,25 +47,34 @@ namespace Ink_Canvas { private TimeMachine timeMachine = new TimeMachine(); - private void ApplyHistoryToCanvas(TimeMachineHistory item, InkCanvas applyCanvas = null) { + private void ApplyHistoryToCanvas(TimeMachineHistory item, InkCanvas applyCanvas = null) + { _currentCommitType = CommitReason.CodeInput; var canvas = inkCanvas; - if (applyCanvas != null && applyCanvas is InkCanvas) { + if (applyCanvas != null && applyCanvas is InkCanvas) + { canvas = applyCanvas; } - if (item.CommitType == TimeMachineHistoryType.UserInput) { - if (!item.StrokeHasBeenCleared) { + if (item.CommitType == TimeMachineHistoryType.UserInput) + { + if (!item.StrokeHasBeenCleared) + { foreach (var strokes in item.CurrentStroke) if (!canvas.Strokes.Contains(strokes)) canvas.Strokes.Add(strokes); - } else { + } + else + { foreach (var strokes in item.CurrentStroke) if (canvas.Strokes.Contains(strokes)) canvas.Strokes.Remove(strokes); } - } else if (item.CommitType == TimeMachineHistoryType.ShapeRecognition) { - if (item.StrokeHasBeenCleared) { + } + else if (item.CommitType == TimeMachineHistoryType.ShapeRecognition) + { + if (item.StrokeHasBeenCleared) + { foreach (var strokes in item.CurrentStroke) if (canvas.Strokes.Contains(strokes)) canvas.Strokes.Remove(strokes); @@ -70,7 +82,9 @@ namespace Ink_Canvas { foreach (var strokes in item.ReplacedStroke) if (!canvas.Strokes.Contains(strokes)) canvas.Strokes.Add(strokes); - } else { + } + else + { foreach (var strokes in item.CurrentStroke) if (!canvas.Strokes.Contains(strokes)) canvas.Strokes.Add(strokes); @@ -79,36 +93,57 @@ namespace Ink_Canvas { if (canvas.Strokes.Contains(strokes)) canvas.Strokes.Remove(strokes); } - } else if (item.CommitType == TimeMachineHistoryType.Manipulation) { - if (!item.StrokeHasBeenCleared) { - foreach (var currentStroke in item.StylusPointDictionary) { - if (canvas.Strokes.Contains(currentStroke.Key)) { + } + else if (item.CommitType == TimeMachineHistoryType.Manipulation) + { + if (!item.StrokeHasBeenCleared) + { + foreach (var currentStroke in item.StylusPointDictionary) + { + if (canvas.Strokes.Contains(currentStroke.Key)) + { currentStroke.Key.StylusPoints = currentStroke.Value.Item2; } } - } else { - foreach (var currentStroke in item.StylusPointDictionary) { - if (canvas.Strokes.Contains(currentStroke.Key)) { + } + else + { + foreach (var currentStroke in item.StylusPointDictionary) + { + if (canvas.Strokes.Contains(currentStroke.Key)) + { currentStroke.Key.StylusPoints = currentStroke.Value.Item1; } } } - } else if (item.CommitType == TimeMachineHistoryType.DrawingAttributes) { - if (!item.StrokeHasBeenCleared) { - foreach (var currentStroke in item.DrawingAttributes) { - if (canvas.Strokes.Contains(currentStroke.Key)) { + } + else if (item.CommitType == TimeMachineHistoryType.DrawingAttributes) + { + if (!item.StrokeHasBeenCleared) + { + foreach (var currentStroke in item.DrawingAttributes) + { + if (canvas.Strokes.Contains(currentStroke.Key)) + { currentStroke.Key.DrawingAttributes = currentStroke.Value.Item2; } } - } else { - foreach (var currentStroke in item.DrawingAttributes) { - if (canvas.Strokes.Contains(currentStroke.Key)) { + } + else + { + foreach (var currentStroke in item.DrawingAttributes) + { + if (canvas.Strokes.Contains(currentStroke.Key)) + { currentStroke.Key.DrawingAttributes = currentStroke.Value.Item1; } } } - } else if (item.CommitType == TimeMachineHistoryType.Clear) { - if (!item.StrokeHasBeenCleared) { + } + else if (item.CommitType == TimeMachineHistoryType.Clear) + { + if (!item.StrokeHasBeenCleared) + { if (item.CurrentStroke != null) foreach (var currentStroke in item.CurrentStroke) if (!canvas.Strokes.Contains(currentStroke)) @@ -118,7 +153,9 @@ namespace Ink_Canvas { foreach (var replacedStroke in item.ReplacedStroke) if (canvas.Strokes.Contains(replacedStroke)) canvas.Strokes.Remove(replacedStroke); - } else { + } + else + { if (item.ReplacedStroke != null) foreach (var replacedStroke in item.ReplacedStroke) if (!canvas.Strokes.Contains(replacedStroke)) @@ -129,29 +166,39 @@ namespace Ink_Canvas { if (canvas.Strokes.Contains(currentStroke)) canvas.Strokes.Remove(currentStroke); } - } else if (item.CommitType == TimeMachineHistoryType.ElementInsert) { + } + else if (item.CommitType == TimeMachineHistoryType.ElementInsert) + { // 使用传入的canvas参数,而不是总是使用inkCanvas var targetCanvas = canvas ?? inkCanvas; - if (item.StrokeHasBeenCleared) { + if (item.StrokeHasBeenCleared) + { // Undo: 移除元素 if (item.InsertedElement != null && targetCanvas.Children.Contains(item.InsertedElement)) targetCanvas.Children.Remove(item.InsertedElement); - } else { + } + else + { // Redo: 添加元素 - if (item.InsertedElement != null && !targetCanvas.Children.Contains(item.InsertedElement)) { + if (item.InsertedElement != null && !targetCanvas.Children.Contains(item.InsertedElement)) + { targetCanvas.Children.Add(item.InsertedElement); // 重新绑定事件处理器(仅对主画布) - if (targetCanvas == inkCanvas) { - if (item.InsertedElement is Image img) { + if (targetCanvas == inkCanvas) + { + if (item.InsertedElement is Image img) + { img.MouseDown -= UIElement_MouseDown; img.MouseDown += UIElement_MouseDown; img.IsManipulationEnabled = true; // 重新应用CenterAndScaleElement变换 CenterAndScaleElement(img); - } else if (item.InsertedElement is MediaElement media) { + } + else if (item.InsertedElement is MediaElement media) + { media.MouseDown -= UIElement_MouseDown; media.MouseDown += UIElement_MouseDown; media.IsManipulationEnabled = true; @@ -167,18 +214,23 @@ namespace Ink_Canvas { _currentCommitType = CommitReason.UserInput; } - private StrokeCollection ApplyHistoriesToNewStrokeCollection(TimeMachineHistory[] items) { - InkCanvas fakeInkCanv = new InkCanvas { + private StrokeCollection ApplyHistoriesToNewStrokeCollection(TimeMachineHistory[] items) + { + InkCanvas fakeInkCanv = new InkCanvas + { Width = inkCanvas.ActualWidth, Height = inkCanvas.ActualHeight, EditingMode = InkCanvasEditingMode.None, }; - if (items != null && items.Length > 0) { - foreach (var timeMachineHistory in items) { + if (items != null && items.Length > 0) + { + foreach (var timeMachineHistory in items) + { // 只处理笔画历史,不处理图片元素历史 // 因为页面预览只需要显示笔画,图片元素会影响主画布 - if (timeMachineHistory.CommitType != TimeMachineHistoryType.ElementInsert) { + if (timeMachineHistory.CommitType != TimeMachineHistoryType.ElementInsert) + { ApplyHistoryToCanvas(timeMachineHistory, fakeInkCanv); } } @@ -188,14 +240,18 @@ namespace Ink_Canvas { } // 新增:获取页面的所有图片元素 - private List GetPageImageElements(TimeMachineHistory[] items) { + private List GetPageImageElements(TimeMachineHistory[] items) + { var imageElements = new List(); - if (items != null && items.Length > 0) { - foreach (var timeMachineHistory in items) { + if (items != null && items.Length > 0) + { + foreach (var timeMachineHistory in items) + { if (timeMachineHistory.CommitType == TimeMachineHistoryType.ElementInsert && timeMachineHistory.InsertedElement != null && - !timeMachineHistory.StrokeHasBeenCleared) { + !timeMachineHistory.StrokeHasBeenCleared) + { imageElements.Add(timeMachineHistory.InsertedElement); } } @@ -204,32 +260,38 @@ namespace Ink_Canvas { return imageElements; } - private void TimeMachine_OnUndoStateChanged(bool status) { + private void TimeMachine_OnUndoStateChanged(bool status) + { var result = status ? Visibility.Visible : Visibility.Collapsed; BtnUndo.Visibility = result; BtnUndo.IsEnabled = status; } - private void TimeMachine_OnRedoStateChanged(bool status) { + private void TimeMachine_OnRedoStateChanged(bool status) + { var result = status ? Visibility.Visible : Visibility.Collapsed; BtnRedo.Visibility = result; BtnRedo.IsEnabled = status; } - private void StrokesOnStrokesChanged(object sender, StrokeCollectionChangedEventArgs e) { - if (!isHidingSubPanelsWhenInking) { + private void StrokesOnStrokesChanged(object sender, StrokeCollectionChangedEventArgs e) + { + if (!isHidingSubPanelsWhenInking) + { isHidingSubPanelsWhenInking = true; HideSubPanels(); // 书写时自动隐藏二级菜单 } - foreach (var stroke in e?.Removed) { + foreach (var stroke in e?.Removed) + { stroke.StylusPointsChanged -= Stroke_StylusPointsChanged; stroke.StylusPointsReplaced -= Stroke_StylusPointsReplaced; stroke.DrawingAttributesChanged -= Stroke_DrawingAttributesChanged; StrokeInitialHistory.Remove(stroke); } - foreach (var stroke in e?.Added) { + foreach (var stroke in e?.Added) + { stroke.StylusPointsChanged += Stroke_StylusPointsChanged; stroke.StylusPointsReplaced += Stroke_StylusPointsReplaced; stroke.DrawingAttributesChanged += Stroke_DrawingAttributesChanged; @@ -238,7 +300,8 @@ namespace Ink_Canvas { if (_currentCommitType == CommitReason.CodeInput || _currentCommitType == CommitReason.ShapeDrawing) return; - if ((e.Added.Count != 0 || e.Removed.Count != 0) && IsEraseByPoint) { + if ((e.Added.Count != 0 || e.Removed.Count != 0) && IsEraseByPoint) + { if (AddedStroke == null) AddedStroke = new StrokeCollection(); if (ReplacedStroke == null) ReplacedStroke = new StrokeCollection(); AddedStroke.Add(e.Added); @@ -248,7 +311,8 @@ namespace Ink_Canvas { if (e.Added.Count != 0) { - if (_currentCommitType == CommitReason.ShapeRecognition) { + if (_currentCommitType == CommitReason.ShapeRecognition) + { timeMachine.CommitStrokeShapeHistory(ReplacedStroke, e.Added); ReplacedStroke = null; return; @@ -258,51 +322,64 @@ namespace Ink_Canvas { return; } - if (e.Removed.Count != 0) { - if (_currentCommitType == CommitReason.ShapeRecognition) { + if (e.Removed.Count != 0) + { + if (_currentCommitType == CommitReason.ShapeRecognition) + { ReplacedStroke = e.Removed; - } else if (!IsEraseByPoint || _currentCommitType == CommitReason.ClearingCanvas) { + } + else if (!IsEraseByPoint || _currentCommitType == CommitReason.ClearingCanvas) + { timeMachine.CommitStrokeEraseHistory(e.Removed); } } } - private void Stroke_DrawingAttributesChanged(object sender, PropertyDataChangedEventArgs e) { + private void Stroke_DrawingAttributesChanged(object sender, PropertyDataChangedEventArgs e) + { var key = sender as Stroke; var currentValue = key.DrawingAttributes.Clone(); DrawingAttributesHistory.TryGetValue(key, out var previousTuple); var previousValue = previousTuple?.Item1 ?? currentValue.Clone(); var needUpdateValue = !DrawingAttributesHistoryFlag[e.PropertyGuid].Contains(key); - if (needUpdateValue) { + if (needUpdateValue) + { DrawingAttributesHistoryFlag[e.PropertyGuid].Add(key); Debug.Write(e.PreviousValue.ToString()); } - if (e.PropertyGuid == DrawingAttributeIds.Color && needUpdateValue) { + if (e.PropertyGuid == DrawingAttributeIds.Color && needUpdateValue) + { previousValue.Color = (Color)e.PreviousValue; } - if (e.PropertyGuid == DrawingAttributeIds.IsHighlighter && needUpdateValue) { + if (e.PropertyGuid == DrawingAttributeIds.IsHighlighter && needUpdateValue) + { previousValue.IsHighlighter = (bool)e.PreviousValue; } - if (e.PropertyGuid == DrawingAttributeIds.StylusHeight && needUpdateValue) { + if (e.PropertyGuid == DrawingAttributeIds.StylusHeight && needUpdateValue) + { previousValue.Height = (double)e.PreviousValue; } - if (e.PropertyGuid == DrawingAttributeIds.StylusWidth && needUpdateValue) { + if (e.PropertyGuid == DrawingAttributeIds.StylusWidth && needUpdateValue) + { previousValue.Width = (double)e.PreviousValue; } - if (e.PropertyGuid == DrawingAttributeIds.StylusTip && needUpdateValue) { + if (e.PropertyGuid == DrawingAttributeIds.StylusTip && needUpdateValue) + { previousValue.StylusTip = (StylusTip)e.PreviousValue; } - if (e.PropertyGuid == DrawingAttributeIds.StylusTipTransform && needUpdateValue) { + if (e.PropertyGuid == DrawingAttributeIds.StylusTipTransform && needUpdateValue) + { previousValue.StylusTipTransform = (Matrix)e.PreviousValue; } - if (e.PropertyGuid == DrawingAttributeIds.DrawingFlags && needUpdateValue) { + if (e.PropertyGuid == DrawingAttributeIds.DrawingFlags && needUpdateValue) + { previousValue.IgnorePressure = (bool)e.PreviousValue; } @@ -310,15 +387,18 @@ namespace Ink_Canvas { new Tuple(previousValue, currentValue); } - private void Stroke_StylusPointsReplaced(object sender, StylusPointsReplacedEventArgs e) { + private void Stroke_StylusPointsReplaced(object sender, StylusPointsReplacedEventArgs e) + { StrokeInitialHistory[sender as Stroke] = e.NewStylusPoints.Clone(); } - private void Stroke_StylusPointsChanged(object sender, EventArgs e) { + private void Stroke_StylusPointsChanged(object sender, EventArgs e) + { var selectedStrokes = inkCanvas.GetSelectedStrokes(); var count = selectedStrokes.Count; if (count == 0) count = inkCanvas.Strokes.Count; - if (StrokeManipulationHistory == null) { + if (StrokeManipulationHistory == null) + { StrokeManipulationHistory = new Dictionary>(); } @@ -326,9 +406,11 @@ namespace Ink_Canvas { StrokeManipulationHistory[sender as Stroke] = new Tuple(StrokeInitialHistory[sender as Stroke], (sender as Stroke).StylusPoints.Clone()); - if ((StrokeManipulationHistory.Count == count || sender == null) && dec.Count == 0) { + if ((StrokeManipulationHistory.Count == count || sender == null) && dec.Count == 0) + { timeMachine.CommitStrokeManipulationHistory(StrokeManipulationHistory); - foreach (var item in StrokeManipulationHistory) { + foreach (var item in StrokeManipulationHistory) + { StrokeInitialHistory[item.Key] = item.Value.Item2; } diff --git a/Ink Canvas/MainWindow_cs/MW_Timer.cs b/Ink Canvas/MainWindow_cs/MW_Timer.cs index c620b848..3c9e0e4b 100644 --- a/Ink Canvas/MainWindow_cs/MW_Timer.cs +++ b/Ink Canvas/MainWindow_cs/MW_Timer.cs @@ -1,4 +1,5 @@ -using System; +using Ink_Canvas.Helpers; +using System; using System.ComponentModel; using System.Diagnostics; using System.IO; @@ -11,27 +12,34 @@ using System.Threading.Tasks; using System.Timers; using System.Windows; using System.Windows.Controls; -using Ink_Canvas.Helpers; -namespace Ink_Canvas { - public class TimeViewModel : INotifyPropertyChanged { +namespace Ink_Canvas +{ + public class TimeViewModel : INotifyPropertyChanged + { private string _nowTime; private string _nowDate; - public string nowTime { + public string nowTime + { get => _nowTime; - set { - if (_nowTime != value) { + set + { + if (_nowTime != value) + { _nowTime = value; OnPropertyChanged(); } } } - public string nowDate { + public string nowDate + { get => _nowDate; - set { - if (_nowDate != value) { + set + { + if (_nowDate != value) + { _nowDate = value; OnPropertyChanged(); } @@ -40,12 +48,14 @@ namespace Ink_Canvas { public event PropertyChangedEventHandler PropertyChanged; - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } - public partial class MainWindow : Window { + public partial class MainWindow : Window + { private Timer timerCheckPPT = new Timer(); private Timer timerKillProcess = new Timer(); private Timer timerCheckAutoFold = new Timer(); @@ -88,7 +98,8 @@ namespace Ink_Canvas { } // 修改InitTimers方法中的初始时间和日期格式 - private void InitTimers() { + private void InitTimers() + { // PPT检查现在由PPTManager处理,不再需要定时器 // timerCheckPPT.Elapsed += TimerCheckPPT_Elapsed; // timerCheckPPT.Interval = 500; @@ -123,27 +134,33 @@ namespace Ink_Canvas { } // 修改TimerDisplayDate_Elapsed方法中的日期格式 - private void TimerDisplayDate_Elapsed(object sender, ElapsedEventArgs e) { + private void TimerDisplayDate_Elapsed(object sender, ElapsedEventArgs e) + { nowTimeVM.nowDate = DateTime.Now.ToString("yyyy'年'MM'月'dd'日' dddd"); } - private void TimerKillProcess_Elapsed(object sender, ElapsedEventArgs e) { - try { + private void TimerKillProcess_Elapsed(object sender, ElapsedEventArgs e) + { + try + { // 希沃相关: easinote swenserver RemoteProcess EasiNote.MediaHttpService smartnote.cloud EasiUpdate smartnote EasiUpdate3 EasiUpdate3Protect SeewoP2P CefSharp.BrowserSubprocess SeewoUploadService var arg = "/F"; - if (Settings.Automation.IsAutoKillPptService) { + if (Settings.Automation.IsAutoKillPptService) + { var processes = Process.GetProcessesByName("PPTService"); if (processes.Length > 0) arg += " /IM PPTService.exe"; processes = Process.GetProcessesByName("SeewoIwbAssistant"); if (processes.Length > 0) arg += " /IM SeewoIwbAssistant.exe" + " /IM Sia.Guard.exe"; } - if (Settings.Automation.IsAutoKillEasiNote) { + if (Settings.Automation.IsAutoKillEasiNote) + { var processes = Process.GetProcessesByName("EasiNote"); if (processes.Length > 0) arg += " /IM EasiNote.exe"; } - if (Settings.Automation.IsAutoKillHiteAnnotation) { + if (Settings.Automation.IsAutoKillHiteAnnotation) + { var processes = Process.GetProcessesByName("HiteAnnotation"); if (processes.Length > 0) arg += " /IM HiteAnnotation.exe"; } @@ -154,101 +171,123 @@ namespace Ink_Canvas { if (processes.Length > 0) arg += " /IM VcomTeach.exe" + " /IM VcomDaemon.exe" + " /IM VcomRender.exe"; } - if (Settings.Automation.IsAutoKillICA) { + if (Settings.Automation.IsAutoKillICA) + { var processesAnnotation = Process.GetProcessesByName("Ink Canvas Annotation"); var processesArtistry = Process.GetProcessesByName("Ink Canvas Artistry"); if (processesAnnotation.Length > 0) arg += " /IM \"Ink Canvas Annotation.exe\""; if (processesArtistry.Length > 0) arg += " /IM \"Ink Canvas Artistry.exe\""; } - if (Settings.Automation.IsAutoKillInkCanvas) { + if (Settings.Automation.IsAutoKillInkCanvas) + { var processes = Process.GetProcessesByName("Ink Canvas"); if (processes.Length > 0) arg += " /IM \"Ink Canvas.exe\""; } - if (Settings.Automation.IsAutoKillIDT) { + if (Settings.Automation.IsAutoKillIDT) + { var processes = Process.GetProcessesByName("Inkeys"); if (processes.Length > 0) arg += " /IM \"Inkeys.exe\""; } - if (Settings.Automation.IsAutoKillSeewoLauncher2DesktopAnnotation) { + if (Settings.Automation.IsAutoKillSeewoLauncher2DesktopAnnotation) + { //由于希沃桌面2.0提供的桌面批注是64位应用程序,32位程序无法访问,目前暂不做精准匹配,只匹配进程名称,后面会考虑封装一套基于P/Invoke和WMI的综合进程识别方案。 var processes = Process.GetProcessesByName("DesktopAnnotation"); if (processes.Length > 0) arg += " /IM DesktopAnnotation.exe"; } - if (arg != "/F") { + if (arg != "/F") + { var p = new Process(); p.StartInfo = new ProcessStartInfo("taskkill", arg); p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; p.Start(); - if (arg.Contains("EasiNote")) { - Dispatcher.Invoke(() => { + if (arg.Contains("EasiNote")) + { + Dispatcher.Invoke(() => + { ShowNotification("“希沃白板 5”已自动关闭"); }); } - if (arg.Contains("HiteAnnotation")) { - Dispatcher.Invoke(() => { + if (arg.Contains("HiteAnnotation")) + { + Dispatcher.Invoke(() => + { ShowNotification("“鸿合屏幕书写”已自动关闭"); - if (Settings.Automation.IsAutoKillHiteAnnotation && Settings.Automation.IsAutoEnterAnnotationAfterKillHite) { + if (Settings.Automation.IsAutoKillHiteAnnotation && Settings.Automation.IsAutoEnterAnnotationAfterKillHite) + { // 自动进入批注状态 PenIcon_Click(null, null); } }); } - if (arg.Contains("Ink Canvas Annotation") || arg.Contains("Ink Canvas Artistry")) { - Dispatcher.Invoke(() => { + if (arg.Contains("Ink Canvas Annotation") || arg.Contains("Ink Canvas Artistry")) + { + Dispatcher.Invoke(() => + { ShowNewMessage("“ICA”已自动关闭"); }); } - if (arg.Contains("\"Ink Canvas.exe\"")) { - Dispatcher.Invoke(() => { + if (arg.Contains("\"Ink Canvas.exe\"")) + { + Dispatcher.Invoke(() => + { ShowNotification("“Ink Canvas”已自动关闭"); }); } - if (arg.Contains("Inkeys")) { - Dispatcher.Invoke(() => { + if (arg.Contains("Inkeys")) + { + Dispatcher.Invoke(() => + { ShowNotification("“智绘教Inkeys”已自动关闭"); }); } if (arg.Contains("VcomTeach")) { - Dispatcher.Invoke(() => { + Dispatcher.Invoke(() => + { ShowNotification("“优教授课端”已自动关闭"); }); } if (arg.Contains("DesktopAnnotation")) { - Dispatcher.Invoke(() => { + Dispatcher.Invoke(() => + { ShowNotification("“希沃桌面2.0 桌面批注”已自动关闭"); }); } } } - catch {} + catch { } } private bool foldFloatingBarByUser, // 保持收纳操作不受自动收纳的控制 unfoldFloatingBarByUser; // 允许用户在希沃软件内进行展开操作 - private void timerCheckAutoFold_Elapsed(object sender, ElapsedEventArgs e) { + private void timerCheckAutoFold_Elapsed(object sender, ElapsedEventArgs e) + { if (isFloatingBarChangingHideMode) return; - try { + try + { var windowProcessName = ForegroundWindowInfo.ProcessName(); var windowTitle = ForegroundWindowInfo.WindowTitle(); //LogHelper.WriteLogToFile("windowTitle | " + windowTitle + " | windowProcessName | " + windowProcessName); - if (windowProcessName == "EasiNote") { + if (windowProcessName == "EasiNote") + { // 检测到有可能是EasiNote5或者EasiNote3/3C - if (ForegroundWindowInfo.ProcessPath() != "Unknown") { + if (ForegroundWindowInfo.ProcessPath() != "Unknown") + { var versionInfo = FileVersionInfo.GetVersionInfo(ForegroundWindowInfo.ProcessPath()); string version = versionInfo.FileVersion; string prodName = versionInfo.ProductName; @@ -256,93 +295,131 @@ namespace Ink_Canvas { Trace.WriteLine(version); Trace.WriteLine(prodName); if (version.StartsWith("5.") && Settings.Automation.IsAutoFoldInEasiNote && (!(windowTitle.Length == 0 && ForegroundWindowInfo.WindowRect().Height < 500) || - !Settings.Automation.IsAutoFoldInEasiNoteIgnoreDesktopAnno)) { // EasiNote5 + !Settings.Automation.IsAutoFoldInEasiNoteIgnoreDesktopAnno)) + { // EasiNote5 if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); - } else if (version.StartsWith("3.") && Settings.Automation.IsAutoFoldInEasiNote3) { // EasiNote3 + } + else if (version.StartsWith("3.") && Settings.Automation.IsAutoFoldInEasiNote3) + { // EasiNote3 if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); - } else if (prodName.Contains("3C") && Settings.Automation.IsAutoFoldInEasiNote3C && + } + else if (prodName.Contains("3C") && Settings.Automation.IsAutoFoldInEasiNote3C && ForegroundWindowInfo.WindowRect().Height >= SystemParameters.WorkArea.Height - 16 && - ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) { // EasiNote3C + ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) + { // EasiNote3C if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); } } // EasiCamera - } else if (Settings.Automation.IsAutoFoldInEasiCamera && windowProcessName == "EasiCamera" && + } + else if (Settings.Automation.IsAutoFoldInEasiCamera && windowProcessName == "EasiCamera" && ForegroundWindowInfo.WindowRect().Height >= SystemParameters.WorkArea.Height - 16 && - ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) { + ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) + { if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); // EasiNote5C - } else if (Settings.Automation.IsAutoFoldInEasiNote5C && windowProcessName == "EasiNote5C" && + } + else if (Settings.Automation.IsAutoFoldInEasiNote5C && windowProcessName == "EasiNote5C" && ForegroundWindowInfo.WindowRect().Height >= SystemParameters.WorkArea.Height - 16 && - ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) { + ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) + { if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); // SeewoPinco - } else if (Settings.Automation.IsAutoFoldInSeewoPincoTeacher && (windowProcessName == "BoardService" || windowProcessName == "seewoPincoTeacher")) { + } + else if (Settings.Automation.IsAutoFoldInSeewoPincoTeacher && (windowProcessName == "BoardService" || windowProcessName == "seewoPincoTeacher")) + { if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); // HiteCamera - } else if (Settings.Automation.IsAutoFoldInHiteCamera && windowProcessName == "HiteCamera" && + } + else if (Settings.Automation.IsAutoFoldInHiteCamera && windowProcessName == "HiteCamera" && ForegroundWindowInfo.WindowRect().Height >= SystemParameters.WorkArea.Height - 16 && - ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) { + ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) + { if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); // HiteTouchPro - } else if (Settings.Automation.IsAutoFoldInHiteTouchPro && windowProcessName == "HiteTouchPro" && + } + else if (Settings.Automation.IsAutoFoldInHiteTouchPro && windowProcessName == "HiteTouchPro" && ForegroundWindowInfo.WindowRect().Height >= SystemParameters.WorkArea.Height - 16 && - ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) { + ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) + { if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); // WxBoardMain - } else if (Settings.Automation.IsAutoFoldInWxBoardMain && windowProcessName == "WxBoardMain" && + } + else if (Settings.Automation.IsAutoFoldInWxBoardMain && windowProcessName == "WxBoardMain" && ForegroundWindowInfo.WindowRect().Height >= SystemParameters.WorkArea.Height - 16 && - ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) { + ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) + { if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); // MSWhiteboard - } else if (Settings.Automation.IsAutoFoldInMSWhiteboard && (windowProcessName == "MicrosoftWhiteboard" || - windowProcessName == "msedgewebview2")) { + } + else if (Settings.Automation.IsAutoFoldInMSWhiteboard && (windowProcessName == "MicrosoftWhiteboard" || + windowProcessName == "msedgewebview2")) + { if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); // OldZyBoard - } else if (Settings.Automation.IsAutoFoldInOldZyBoard && // 中原旧白板 + } + else if (Settings.Automation.IsAutoFoldInOldZyBoard && // 中原旧白板 (WinTabWindowsChecker.IsWindowExisted("WhiteBoard - DrawingWindow") - || WinTabWindowsChecker.IsWindowExisted("InstantAnnotationWindow"))) { + || WinTabWindowsChecker.IsWindowExisted("InstantAnnotationWindow"))) + { if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); // HiteLightBoard - } else if (Settings.Automation.IsAutoFoldInHiteLightBoard && windowProcessName == "HiteLightBoard" && + } + else if (Settings.Automation.IsAutoFoldInHiteLightBoard && windowProcessName == "HiteLightBoard" && ForegroundWindowInfo.WindowRect().Height >= SystemParameters.WorkArea.Height - 16 && - ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) { + ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) + { if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); // AdmoxWhiteboard - } else if (Settings.Automation.IsAutoFoldInAdmoxWhiteboard && windowProcessName == "Amdox.WhiteBoard" && + } + else if (Settings.Automation.IsAutoFoldInAdmoxWhiteboard && windowProcessName == "Amdox.WhiteBoard" && ForegroundWindowInfo.WindowRect().Height >= SystemParameters.WorkArea.Height - 16 && - ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) { + ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) + { if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); // AdmoxBooth - } else if (Settings.Automation.IsAutoFoldInAdmoxBooth && windowProcessName == "Amdox.Booth" && + } + else if (Settings.Automation.IsAutoFoldInAdmoxBooth && windowProcessName == "Amdox.Booth" && ForegroundWindowInfo.WindowRect().Height >= SystemParameters.WorkArea.Height - 16 && - ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) { + ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) + { if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); // QPoint - } else if (Settings.Automation.IsAutoFoldInQPoint && windowProcessName == "QPoint" && + } + else if (Settings.Automation.IsAutoFoldInQPoint && windowProcessName == "QPoint" && ForegroundWindowInfo.WindowRect().Height >= SystemParameters.WorkArea.Height - 16 && - ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) { + ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) + { if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); // YiYunVisualPresenter - } else if (Settings.Automation.IsAutoFoldInYiYunVisualPresenter && windowProcessName == "YiYunVisualPresenter" && + } + else if (Settings.Automation.IsAutoFoldInYiYunVisualPresenter && windowProcessName == "YiYunVisualPresenter" && ForegroundWindowInfo.WindowRect().Height >= SystemParameters.WorkArea.Height - 16 && - ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) { + ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) + { if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); // MaxHubWhiteboard - } else if (Settings.Automation.IsAutoFoldInMaxHubWhiteboard && windowProcessName == "WhiteBoard" && + } + else if (Settings.Automation.IsAutoFoldInMaxHubWhiteboard && windowProcessName == "WhiteBoard" && WinTabWindowsChecker.IsWindowExisted("白板书写") && ForegroundWindowInfo.WindowRect().Height >= SystemParameters.WorkArea.Height - 16 && - ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) { - if (ForegroundWindowInfo.ProcessPath() != "Unknown") { + ForegroundWindowInfo.WindowRect().Width >= SystemParameters.WorkArea.Width - 16) + { + if (ForegroundWindowInfo.ProcessPath() != "Unknown") + { var versionInfo = FileVersionInfo.GetVersionInfo(ForegroundWindowInfo.ProcessPath()); var version = versionInfo.FileVersion; var prodName = versionInfo.ProductName; - if (version.StartsWith("6.") && prodName=="WhiteBoard") if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); + if (version.StartsWith("6.") && prodName == "WhiteBoard") if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); } - } else if (WinTabWindowsChecker.IsWindowExisted("幻灯片放映", false)) { + } + else if (WinTabWindowsChecker.IsWindowExisted("幻灯片放映", false)) + { // 处于幻灯片放映状态 if (!Settings.Automation.IsAutoFoldInPPTSlideShow && isFloatingBarFolded && !foldFloatingBarByUser) UnFoldFloatingBar_MouseUp(new object(), null); - } else { + } + else + { if (isFloatingBarFolded && !foldFloatingBarByUser) UnFoldFloatingBar_MouseUp(new object(), null); unfoldFloatingBarByUser = false; } @@ -350,34 +427,40 @@ namespace Ink_Canvas { catch { } } - private void timerCheckAutoUpdateWithSilence_Elapsed(object sender, ElapsedEventArgs e) { + private void timerCheckAutoUpdateWithSilence_Elapsed(object sender, ElapsedEventArgs e) + { // 停止计时器,避免重复触发 timerCheckAutoUpdateWithSilence.Stop(); - - try { + + try + { // 检查是否有可用的更新 - if (string.IsNullOrEmpty(AvailableLatestVersion)) { + if (string.IsNullOrEmpty(AvailableLatestVersion)) + { LogHelper.WriteLogToFile("AutoUpdate | No available update version found"); return; } - + // 检查是否启用了静默更新 - if (!Settings.Startup.IsAutoUpdateWithSilence) { + if (!Settings.Startup.IsAutoUpdateWithSilence) + { LogHelper.WriteLogToFile("AutoUpdate | Silent update is disabled"); return; } - + // 检查更新文件是否已下载 string updatesFolderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "AutoUpdate"); string statusFilePath = Path.Combine(updatesFolderPath, $"DownloadV{AvailableLatestVersion}Status.txt"); - - if (!File.Exists(statusFilePath) || File.ReadAllText(statusFilePath).Trim().ToLower() != "true") { + + if (!File.Exists(statusFilePath) || File.ReadAllText(statusFilePath).Trim().ToLower() != "true") + { LogHelper.WriteLogToFile("AutoUpdate | Update file not downloaded yet"); - + // 尝试下载更新文件,使用多线路组下载功能 - Task.Run(async () => { + Task.Run(async () => + { bool isDownloadSuccessful = false; - + try { // 如果主要线路组可用,直接使用 @@ -386,7 +469,7 @@ namespace Ink_Canvas { LogHelper.WriteLogToFile($"AutoUpdate | 使用主要线路组下载: {AvailableLatestLineGroup.GroupName}"); isDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFile(AvailableLatestVersion, AvailableLatestLineGroup); } - + // 如果主要线路组不可用或下载失败,获取所有可用线路组 if (!isDownloadSuccessful) { @@ -403,76 +486,94 @@ namespace Ink_Canvas { { LogHelper.WriteLogToFile($"AutoUpdate | 下载更新时出错: {ex.Message}", LogHelper.LogType.Error); } - - if (isDownloadSuccessful) { + + if (isDownloadSuccessful) + { LogHelper.WriteLogToFile("AutoUpdate | Update downloaded successfully, will check again for installation"); // 重新启动计时器,下次检查时安装 timerCheckAutoUpdateWithSilence.Start(); - } else { + } + else + { LogHelper.WriteLogToFile("AutoUpdate | Failed to download update", LogHelper.LogType.Error); } }); - + return; } - + // 检查是否在静默更新时间段内 bool isInSilencePeriod = AutoUpdateWithSilenceTimeComboBox.CheckIsInSilencePeriod( Settings.Startup.AutoUpdateWithSilenceStartTime, Settings.Startup.AutoUpdateWithSilenceEndTime); - - if (!isInSilencePeriod) { + + if (!isInSilencePeriod) + { LogHelper.WriteLogToFile("AutoUpdate | Not in silence update time period"); // 重新启动计时器,稍后再检查 timerCheckAutoUpdateWithSilence.Start(); return; } - + // 检查应用程序状态,确保可以安全更新 // 空闲状态的判定为不处于批注模式和画板模式 bool canSafelyUpdate = false; - - Dispatcher.Invoke(() => { - try { + + Dispatcher.Invoke(() => + { + try + { // 判断是否处于批注模式(inkCanvas.EditingMode == InkCanvasEditingMode.Ink) // 判断是否处于画板模式(!Topmost) - if (inkCanvas.EditingMode != InkCanvasEditingMode.Ink && Topmost) { + if (inkCanvas.EditingMode != InkCanvasEditingMode.Ink && Topmost) + { // 检查是否有未保存的内容或正在进行的操作 - if (!isHidingSubPanelsWhenInking) { + if (!isHidingSubPanelsWhenInking) + { canSafelyUpdate = true; LogHelper.WriteLogToFile("AutoUpdate | Application is in a safe state for update - not in ink or board mode"); - } else { + } + else + { LogHelper.WriteLogToFile("AutoUpdate | Application is currently performing operations"); } - } else { + } + else + { LogHelper.WriteLogToFile("AutoUpdate | Application is in ink or board mode, cannot update now"); } } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"AutoUpdate | Error checking application state: {ex.Message}", LogHelper.LogType.Error); } }); - - if (canSafelyUpdate) { + + if (canSafelyUpdate) + { LogHelper.WriteLogToFile("AutoUpdate | Installing update now"); - + // 设置为用户主动退出,避免被看门狗判定为崩溃 App.IsAppExitByUser = true; - + // 执行更新安装 AutoUpdateHelper.InstallNewVersionApp(AvailableLatestVersion, true); - + // 关闭应用程序 - Dispatcher.Invoke(() => { + Dispatcher.Invoke(() => + { Application.Current.Shutdown(); }); - } else { + } + else + { LogHelper.WriteLogToFile("AutoUpdate | Cannot safely update now, will try again later"); // 重新启动计时器,稍后再检查 timerCheckAutoUpdateWithSilence.Start(); } } - catch (Exception ex) { + catch (Exception ex) + { LogHelper.WriteLogToFile($"AutoUpdate | Error in silent update check: {ex.Message}", LogHelper.LogType.Error); // 出错时重新启动计时器,稍后再检查 timerCheckAutoUpdateWithSilence.Start(); diff --git a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs index aa2b5074..960c1cce 100644 --- a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs +++ b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs @@ -1,3 +1,4 @@ +using Ink_Canvas.Helpers; using System; using System.Collections.Generic; using System.Linq; @@ -7,11 +8,12 @@ using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; -using Ink_Canvas.Helpers; using Point = System.Windows.Point; -namespace Ink_Canvas { - public partial class MainWindow : Window { +namespace Ink_Canvas +{ + public partial class MainWindow : Window + { #region Multi-Touch private bool isInMultiTouchMode; @@ -60,14 +62,17 @@ namespace Ink_Canvas { } } - private void BorderMultiTouchMode_MouseUp(object sender, MouseButtonEventArgs e) { - if (isInMultiTouchMode) { + private void BorderMultiTouchMode_MouseUp(object sender, MouseButtonEventArgs e) + { + if (isInMultiTouchMode) + { inkCanvas.StylusDown -= MainWindow_StylusDown; inkCanvas.StylusMove -= MainWindow_StylusMove; inkCanvas.StylusUp -= MainWindow_StylusUp; inkCanvas.TouchDown -= MainWindow_TouchDown; inkCanvas.TouchDown += Main_Grid_TouchDown; - if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint) { + if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint) + { inkCanvas.EditingMode = InkCanvasEditingMode.Ink; } // 保存非笔画元素(如图片) @@ -78,14 +83,16 @@ namespace Ink_Canvas { isInMultiTouchMode = false; } - else { + else + { inkCanvas.StylusDown += MainWindow_StylusDown; inkCanvas.StylusMove += MainWindow_StylusMove; inkCanvas.StylusUp += MainWindow_StylusUp; inkCanvas.TouchDown += MainWindow_TouchDown; inkCanvas.TouchDown -= Main_Grid_TouchDown; - if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint) { + if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint) + { inkCanvas.EditingMode = InkCanvasEditingMode.None; } // 保存非笔画元素(如图片) @@ -97,12 +104,14 @@ namespace Ink_Canvas { } } - private void MainWindow_TouchDown(object sender, TouchEventArgs e) { + private void MainWindow_TouchDown(object sender, TouchEventArgs e) + { if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint || inkCanvas.EditingMode == InkCanvasEditingMode.EraseByStroke || inkCanvas.EditingMode == InkCanvasEditingMode.Select) return; - if (!isHidingSubPanelsWhenInking) { + if (!isHidingSubPanelsWhenInking) + { isHidingSubPanelsWhenInking = true; HideSubPanels(); // 书写时自动隐藏二级菜单 } @@ -110,12 +119,14 @@ namespace Ink_Canvas { // 只保留普通橡皮逻辑 TouchDownPointsList[e.TouchDevice.Id] = InkCanvasEditingMode.None; inkCanvas.EraserShape = new EllipseStylusShape(50, 50); - if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint) { + if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint) + { inkCanvas.EditingMode = InkCanvasEditingMode.None; } } - private void MainWindow_StylusDown(object sender, StylusDownEventArgs e) { + private void MainWindow_StylusDown(object sender, StylusDownEventArgs e) + { SetCursorBasedOnEditingMode(inkCanvas); inkCanvas.CaptureStylus(); @@ -123,19 +134,23 @@ namespace Ink_Canvas { BlackboardUIGridForInkReplay.IsHitTestVisible = false; // 确保手写笔模式下显示光标 - if (Settings.Canvas.IsShowCursor) { + if (Settings.Canvas.IsShowCursor) + { inkCanvas.ForceCursor = true; inkCanvas.UseCustomCursor = true; - + // 根据当前编辑模式设置不同的光标 - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { inkCanvas.Cursor = Cursors.Cross; - } else if (inkCanvas.EditingMode == InkCanvasEditingMode.Ink) { + } + else if (inkCanvas.EditingMode == InkCanvasEditingMode.Ink) + { var sri = Application.GetResourceStream(new Uri("Resources/Cursors/Pen.cur", UriKind.Relative)); if (sri != null) inkCanvas.Cursor = new Cursor(sri.Stream); } - + // 强制显示光标 System.Windows.Forms.Cursor.Show(); } @@ -147,8 +162,10 @@ namespace Ink_Canvas { TouchDownPointsList[e.StylusDevice.Id] = InkCanvasEditingMode.None; } - private async void MainWindow_StylusUp(object sender, StylusEventArgs e) { - try { + private async void MainWindow_StylusUp(object sender, StylusEventArgs e) + { + try + { inkCanvas.Strokes.Add(GetStrokeVisual(e.StylusDevice.Id).Stroke); await Task.Delay(5); // 避免渲染墨迹完成前预览墨迹被删除导致墨迹闪烁 inkCanvas.Children.Remove(GetVisualCanvas(e.StylusDevice.Id)); @@ -156,18 +173,23 @@ namespace Ink_Canvas { inkCanvas_StrokeCollected(inkCanvas, new InkCanvasStrokeCollectedEventArgs(GetStrokeVisual(e.StylusDevice.Id).Stroke)); } - catch (Exception ex) { + catch (Exception ex) + { Label.Content = ex.ToString(); } - try { + try + { StrokeVisualList.Remove(e.StylusDevice.Id); VisualCanvasList.Remove(e.StylusDevice.Id); TouchDownPointsList.Remove(e.StylusDevice.Id); - if (StrokeVisualList.Count == 0 || VisualCanvasList.Count == 0 || TouchDownPointsList.Count == 0) { + if (StrokeVisualList.Count == 0 || VisualCanvasList.Count == 0 || TouchDownPointsList.Count == 0) + { // 只清除手写笔预览相关的Canvas,不清除所有子元素 - foreach (var canvas in VisualCanvasList.Values.ToList()) { - if (inkCanvas.Children.Contains(canvas)) { + foreach (var canvas in VisualCanvasList.Values.ToList()) + { + if (inkCanvas.Children.Contains(canvas)) + { inkCanvas.Children.Remove(canvas); } } @@ -183,16 +205,20 @@ namespace Ink_Canvas { BlackboardUIGridForInkReplay.IsHitTestVisible = true; } - private void MainWindow_StylusMove(object sender, StylusEventArgs e) { - try { + private void MainWindow_StylusMove(object sender, StylusEventArgs e) + { + try + { if (GetTouchDownPointsList(e.StylusDevice.Id) != InkCanvasEditingMode.None) return; - try { + try + { if (e.StylusDevice.StylusButtons[1].StylusButtonState == StylusButtonState.Down) return; } catch { } // 确保手写笔移动时光标保持可见 - if (Settings.Canvas.IsShowCursor) { + if (Settings.Canvas.IsShowCursor) + { inkCanvas.ForceCursor = true; inkCanvas.UseCustomCursor = true; System.Windows.Forms.Cursor.Show(); @@ -207,7 +233,8 @@ namespace Ink_Canvas { catch { } } - private StrokeVisual GetStrokeVisual(int id) { + private StrokeVisual GetStrokeVisual(int id) + { if (StrokeVisualList.TryGetValue(id, out var visual)) return visual; var strokeVisual = new StrokeVisual(inkCanvas.DefaultDrawingAttributes.Clone()); @@ -220,11 +247,13 @@ namespace Ink_Canvas { return strokeVisual; } - private VisualCanvas GetVisualCanvas(int id) { + private VisualCanvas GetVisualCanvas(int id) + { return VisualCanvasList.TryGetValue(id, out var visualCanvas) ? visualCanvas : null; } - private InkCanvasEditingMode GetTouchDownPointsList(int id) { + private InkCanvasEditingMode GetTouchDownPointsList(int id) + { return TouchDownPointsList.TryGetValue(id, out var inkCanvasEditingMode) ? inkCanvasEditingMode : inkCanvas.EditingMode; } @@ -241,32 +270,40 @@ namespace Ink_Canvas { private Point iniP = new Point(0, 0); - private void Main_Grid_TouchDown(object sender, TouchEventArgs e) { + private void Main_Grid_TouchDown(object sender, TouchEventArgs e) + { SetCursorBasedOnEditingMode(inkCanvas); inkCanvas.CaptureTouch(e.TouchDevice); - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { // 橡皮状态下只return,保证橡皮状态可保持 return; } - if (inkCanvas.EditingMode == InkCanvasEditingMode.Select) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.Select) + { // 套索选状态下只return,保证套索选可用 return; } - if (drawingShapeMode == 9) { - if (isFirstTouchCuboid) { + if (drawingShapeMode == 9) + { + if (isFirstTouchCuboid) + { CuboidFrontRectIniP = e.GetTouchPoint(inkCanvas).Position; } // 允许MouseTouchMove在TouchMove时处理 return; } - if (drawingShapeMode != 0) { + if (drawingShapeMode != 0) + { return; } - if (inkCanvas.EditingMode == InkCanvasEditingMode.Ink) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.Ink) + { return; } - if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint) { + if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint) + { inkCanvas.EditingMode = InkCanvasEditingMode.Ink; } } @@ -277,9 +314,11 @@ namespace Ink_Canvas { private bool palmEraserLastIsHighlighter; private bool palmEraserWasEnabledBeforeMultiTouch; - private void inkCanvas_PreviewTouchDown(object sender, TouchEventArgs e) { + private void inkCanvas_PreviewTouchDown(object sender, TouchEventArgs e) + { // 橡皮状态下不做任何切换,直接return,保证橡皮可持续 - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { return; } SetCursorBasedOnEditingMode(inkCanvas); @@ -290,10 +329,12 @@ namespace Ink_Canvas { dec.Add(e.TouchDevice.Id); // Palm Eraser 逻辑 - if (Settings.Canvas.EnablePalmEraser && dec.Count >= 2 && !isPalmEraserActive) { + if (Settings.Canvas.EnablePalmEraser && dec.Count >= 2 && !isPalmEraserActive) + { var bounds = e.GetTouchPoint(inkCanvas).Bounds; double palmThreshold = 40; // 触摸面积阈值,可根据实际调整 - if (bounds.Width >= palmThreshold || bounds.Height >= palmThreshold) { + if (bounds.Width >= palmThreshold || bounds.Height >= palmThreshold) + { // 记录当前编辑模式和高光状态 palmEraserLastEditingMode = inkCanvas.EditingMode; palmEraserLastIsHighlighter = drawingAttributes.IsHighlighter; @@ -303,12 +344,14 @@ namespace Ink_Canvas { } } //设备1个的时候,记录中心点 - if (dec.Count == 1) { + if (dec.Count == 1) + { var touchPoint = e.GetTouchPoint(inkCanvas); centerPoint = touchPoint.Position; // 新增:几何绘制模式下,记录初始点 - if (drawingShapeMode != 0) { + if (drawingShapeMode != 0) + { iniP = touchPoint.Position; } @@ -316,20 +359,24 @@ namespace Ink_Canvas { lastTouchDownStrokeCollection = inkCanvas.Strokes.Clone(); } //设备两个及两个以上,将画笔功能关闭 - if (dec.Count > 1 || isSingleFingerDragMode || !Settings.Gesture.IsEnableTwoFingerGesture) { + if (dec.Count > 1 || isSingleFingerDragMode || !Settings.Gesture.IsEnableTwoFingerGesture) + { if (isInMultiTouchMode || !Settings.Gesture.IsEnableTwoFingerGesture) return; if (inkCanvas.EditingMode == InkCanvasEditingMode.None || inkCanvas.EditingMode == InkCanvasEditingMode.Select) return; lastInkCanvasEditingMode = inkCanvas.EditingMode; - if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint) { + if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint) + { inkCanvas.EditingMode = InkCanvasEditingMode.None; } } } - private void inkCanvas_PreviewTouchUp(object sender, TouchEventArgs e) { + private void inkCanvas_PreviewTouchUp(object sender, TouchEventArgs e) + { // 橡皮状态下不做任何切换,直接return,保证橡皮可持续 - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint && !isPalmEraserActive) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint && !isPalmEraserActive) + { return; } inkCanvas.ReleaseAllTouchCaptures(); @@ -338,23 +385,31 @@ namespace Ink_Canvas { // Palm Eraser 逻辑:所有点抬起后恢复原编辑模式 dec.Remove(e.TouchDevice.Id); - if (isPalmEraserActive && dec.Count == 0) { + if (isPalmEraserActive && dec.Count == 0) + { // 恢复高光状态 drawingAttributes.IsHighlighter = palmEraserLastIsHighlighter; // 恢复编辑模式 - if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) { - if (palmEraserLastEditingMode == InkCanvasEditingMode.Ink) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + { + if (palmEraserLastEditingMode == InkCanvasEditingMode.Ink) + { PenIcon_Click(null, null); - } else if (palmEraserLastEditingMode == InkCanvasEditingMode.Select) { + } + else if (palmEraserLastEditingMode == InkCanvasEditingMode.Select) + { SymbolIconSelect_MouseUp(null, null); - } else { + } + else + { inkCanvas.EditingMode = palmEraserLastEditingMode; } } isPalmEraserActive = false; } // 新增:几何绘制模式下,触摸抬手时自动落笔 - if (drawingShapeMode != 0) { + if (drawingShapeMode != 0) + { var mouseArgs = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left) { RoutedEvent = MouseLeftButtonUpEvent, @@ -365,18 +420,24 @@ namespace Ink_Canvas { //手势完成后切回之前的状态 // 修复:改进多指手势恢复逻辑,确保从橡皮擦切换到笔时多指手势能正确恢复 - if (dec.Count > 1) { - if (inkCanvas.EditingMode == InkCanvasEditingMode.None) { - if (lastInkCanvasEditingMode != InkCanvasEditingMode.EraseByPoint) { + if (dec.Count > 1) + { + if (inkCanvas.EditingMode == InkCanvasEditingMode.None) + { + if (lastInkCanvasEditingMode != InkCanvasEditingMode.EraseByPoint) + { inkCanvas.EditingMode = lastInkCanvasEditingMode; } } - } else if (dec.Count == 0) { + } + else if (dec.Count == 0) + { // 当所有触摸点都抬起时,确保正确恢复编辑模式 // 这对于从橡皮擦切换到笔后恢复多指手势功能很重要 if (inkCanvas.EditingMode == InkCanvasEditingMode.None && lastInkCanvasEditingMode != InkCanvasEditingMode.None && - lastInkCanvasEditingMode != InkCanvasEditingMode.EraseByPoint) { + lastInkCanvasEditingMode != InkCanvasEditingMode.EraseByPoint) + { inkCanvas.EditingMode = lastInkCanvasEditingMode; } } @@ -384,29 +445,34 @@ namespace Ink_Canvas { if (dec.Count == 0) if (lastTouchDownStrokeCollection.Count() != inkCanvas.Strokes.Count() && - !(drawingShapeMode == 9 && !isFirstTouchCuboid)) { + !(drawingShapeMode == 9 && !isFirstTouchCuboid)) + { var whiteboardIndex = CurrentWhiteboardIndex; if (currentMode == 0) whiteboardIndex = 0; strokeCollections[whiteboardIndex] = lastTouchDownStrokeCollection; } } - private void inkCanvas_ManipulationStarting(object sender, ManipulationStartingEventArgs e) { + private void inkCanvas_ManipulationStarting(object sender, ManipulationStartingEventArgs e) + { e.Mode = ManipulationModes.All; } private void inkCanvas_ManipulationInertiaStarting(object sender, ManipulationInertiaStartingEventArgs e) { } - private void Main_Grid_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) { + private void Main_Grid_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) + { if (e.Manipulators.Count() != 0) return; - if (drawingShapeMode == 0 && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint) { + if (drawingShapeMode == 0 && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint) + { inkCanvas.EditingMode = InkCanvasEditingMode.Ink; // 修复:确保多指手势完成后正确更新lastInkCanvasEditingMode lastInkCanvasEditingMode = InkCanvasEditingMode.Ink; } } - private void Main_Grid_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) { + private void Main_Grid_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) + { // 手掌擦时禁止移动/缩放 if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) return; @@ -416,7 +482,8 @@ namespace Ink_Canvas { if ((dec.Count >= 2 && (Settings.PowerPointSettings.IsEnableTwoFingerGestureInPresentationMode || StackPanelPPTControls.Visibility != Visibility.Visible || StackPanelPPTButtons.Visibility == Visibility.Collapsed)) || - isSingleFingerDragMode) { + isSingleFingerDragMode) + { var md = e.DeltaManipulation; var trans = md.Translation; // 获得位移矢量 @@ -425,7 +492,8 @@ namespace Ink_Canvas { if (Settings.Gesture.IsEnableTwoFingerTranslate) m.Translate(trans.X, trans.Y); // 移动 - if (Settings.Gesture.IsEnableTwoFingerGestureTranslateOrRotation) { + if (Settings.Gesture.IsEnableTwoFingerGestureTranslateOrRotation) + { var rotate = md.Rotation; // 获得旋转角度 var scale = md.Scale; // 获得缩放倍数 @@ -441,12 +509,15 @@ namespace Ink_Canvas { } var strokes = inkCanvas.GetSelectedStrokes(); - if (strokes.Count != 0) { - foreach (var stroke in strokes) { + if (strokes.Count != 0) + { + foreach (var stroke in strokes) + { stroke.Transform(m, false); foreach (var circle in circles) - if (stroke == circle.Stroke) { + if (stroke == circle.Stroke) + { circle.R = GetDistance(circle.Stroke.StylusPoints[0].ToPoint(), circle.Stroke.StylusPoints[circle.Stroke.StylusPoints.Count / 2].ToPoint()) / 2; circle.Centroid = new Point( @@ -458,18 +529,23 @@ namespace Ink_Canvas { } if (!Settings.Gesture.IsEnableTwoFingerZoom) continue; - try { + try + { stroke.DrawingAttributes.Width *= md.Scale.X; stroke.DrawingAttributes.Height *= md.Scale.Y; } catch { } } } - else { - if (Settings.Gesture.IsEnableTwoFingerZoom) { - foreach (var stroke in inkCanvas.Strokes) { + else + { + if (Settings.Gesture.IsEnableTwoFingerZoom) + { + foreach (var stroke in inkCanvas.Strokes) + { stroke.Transform(m, false); - try { + try + { stroke.DrawingAttributes.Width *= md.Scale.X; stroke.DrawingAttributes.Height *= md.Scale.Y; } @@ -478,12 +554,14 @@ namespace Ink_Canvas { ; } - else { + else + { foreach (var stroke in inkCanvas.Strokes) stroke.Transform(m, false); ; } - foreach (var circle in circles) { + foreach (var circle in circles) + { circle.R = GetDistance(circle.Stroke.StylusPoints[0].ToPoint(), circle.Stroke.StylusPoints[circle.Stroke.StylusPoints.Count / 2].ToPoint()) / 2; circle.Centroid = new Point( @@ -518,7 +596,8 @@ namespace Ink_Canvas { RestoreNonStrokeElements(preservedElements); isInMultiTouchMode = false; // 关闭多指书写时,恢复手掌擦开关 - if (palmEraserWasEnabledBeforeMultiTouch) { + if (palmEraserWasEnabledBeforeMultiTouch) + { Settings.Canvas.EnablePalmEraser = true; if (ToggleSwitchEnablePalmEraser != null) ToggleSwitchEnablePalmEraser.IsOn = true; diff --git a/Ink Canvas/MainWindow_cs/MW_TrayIcon.cs b/Ink Canvas/MainWindow_cs/MW_TrayIcon.cs index d3c22217..ec79414c 100644 --- a/Ink Canvas/MainWindow_cs/MW_TrayIcon.cs +++ b/Ink Canvas/MainWindow_cs/MW_TrayIcon.cs @@ -1,24 +1,26 @@ -using System; +using Hardcodet.Wpf.TaskbarNotification; +using Ink_Canvas.Helpers; +using iNKORE.UI.WPF.Modern.Controls; +using System; using System.Diagnostics; using System.Windows; using System.Windows.Controls; using System.Windows.Forms; using System.Windows.Interop; -using Hardcodet.Wpf.TaskbarNotification; -using Ink_Canvas.Helpers; -using iNKORE.UI.WPF.Modern.Controls; using Application = System.Windows.Application; using ContextMenu = System.Windows.Controls.ContextMenu; using MenuItem = System.Windows.Controls.MenuItem; namespace Ink_Canvas { - public partial class App : Application { + public partial class App : Application + { - private void SysTrayMenu_Opened(object sender, RoutedEventArgs e) { + private void SysTrayMenu_Opened(object sender, RoutedEventArgs e) + { var s = (ContextMenu)sender; var FoldFloatingBarTrayIconMenuItemIconEyeOff = - (Image)((Grid)((MenuItem)s.Items[s.Items.Count-5]).Icon).Children[0]; + (Image)((Grid)((MenuItem)s.Items[s.Items.Count - 5]).Icon).Children[0]; var FoldFloatingBarTrayIconMenuItemIconEyeOn = (Image)((Grid)((MenuItem)s.Items[s.Items.Count - 5]).Icon).Children[1]; var FoldFloatingBarTrayIconMenuItemHeaderText = @@ -26,64 +28,79 @@ namespace Ink_Canvas var ResetFloatingBarPositionTrayIconMenuItem = (MenuItem)s.Items[s.Items.Count - 4]; var HideICCMainWindowTrayIconMenuItem = (MenuItem)s.Items[s.Items.Count - 9]; var mainWin = (MainWindow)Current.MainWindow; - if (mainWin.IsLoaded) { + if (mainWin.IsLoaded) + { // 判斷是否在收納模式中 - if (mainWin.isFloatingBarFolded) { + if (mainWin.isFloatingBarFolded) + { FoldFloatingBarTrayIconMenuItemIconEyeOff.Visibility = Visibility.Hidden; FoldFloatingBarTrayIconMenuItemIconEyeOn.Visibility = Visibility.Visible; FoldFloatingBarTrayIconMenuItemHeaderText.Text = "退出收纳模式"; - if (!HideICCMainWindowTrayIconMenuItem.IsChecked) { + if (!HideICCMainWindowTrayIconMenuItem.IsChecked) + { ResetFloatingBarPositionTrayIconMenuItem.IsEnabled = false; ResetFloatingBarPositionTrayIconMenuItem.Opacity = 0.5; } - } else { + } + else + { FoldFloatingBarTrayIconMenuItemIconEyeOff.Visibility = Visibility.Visible; FoldFloatingBarTrayIconMenuItemIconEyeOn.Visibility = Visibility.Hidden; FoldFloatingBarTrayIconMenuItemHeaderText.Text = "切换为收纳模式"; - if (!HideICCMainWindowTrayIconMenuItem.IsChecked) { + if (!HideICCMainWindowTrayIconMenuItem.IsChecked) + { ResetFloatingBarPositionTrayIconMenuItem.IsEnabled = true; ResetFloatingBarPositionTrayIconMenuItem.Opacity = 1; } - + } } } - private void CloseAppTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e) { + private void CloseAppTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e) + { var mainWin = (MainWindow)Current.MainWindow; - if (mainWin.IsLoaded) { + if (mainWin.IsLoaded) + { IsAppExitByUser = true; Current.Shutdown(); // mainWin.BtnExit_Click(null,null); } } - private void RestartAppTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e) { + private void RestartAppTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e) + { var mainWin = (MainWindow)Current.MainWindow; - if (mainWin.IsLoaded) { + if (mainWin.IsLoaded) + { IsAppExitByUser = true; - - try { + + try + { // 启动新实例 string exePath = Process.GetCurrentProcess().MainModule.FileName; ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = exePath; startInfo.UseShellExecute = true; - + // 启动进程但不等待 Process.Start(startInfo); - } catch (Exception ex) { + } + catch (Exception ex) + { LogHelper.NewLog($"重启程序时出错: {ex.Message}"); } - + // 退出当前实例 Current.Shutdown(); } } - private void ForceFullScreenTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e) { + private void ForceFullScreenTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e) + { var mainWin = (MainWindow)Current.MainWindow; - if (mainWin.IsLoaded) { + if (mainWin.IsLoaded) + { Ink_Canvas.MainWindow.MoveWindow(new WindowInteropHelper(mainWin).Handle, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, true); Ink_Canvas.MainWindow.ShowNewMessage($"已强制全屏化:{Screen.PrimaryScreen.Bounds.Width}x{Screen.PrimaryScreen.Bounds.Height}(缩放比例为{Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth}x{Screen.PrimaryScreen.Bounds.Height / SystemParameters.PrimaryScreenHeight})"); @@ -94,29 +111,34 @@ namespace Ink_Canvas { var mainWin = (MainWindow)Current.MainWindow; if (mainWin.IsLoaded) - if (mainWin.isFloatingBarFolded) mainWin.UnFoldFloatingBar_MouseUp(new object(),null); - else mainWin.FoldFloatingBar_MouseUp(new object(),null); + if (mainWin.isFloatingBarFolded) mainWin.UnFoldFloatingBar_MouseUp(new object(), null); + else mainWin.FoldFloatingBar_MouseUp(new object(), null); } private void ResetFloatingBarPositionTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e) { var mainWin = (MainWindow)Current.MainWindow; - if (mainWin.IsLoaded) { + if (mainWin.IsLoaded) + { var isInPPTPresentationMode = false; - Dispatcher.Invoke(() => { + Dispatcher.Invoke(() => + { isInPPTPresentationMode = mainWin.BtnPPTSlideShowEnd.Visibility == Visibility.Visible; }); - if (!mainWin.isFloatingBarFolded) { + if (!mainWin.isFloatingBarFolded) + { if (!isInPPTPresentationMode) mainWin.PureViewboxFloatingBarMarginAnimationInDesktopMode(); else mainWin.PureViewboxFloatingBarMarginAnimationInPPTMode(); } } } - private void HideICCMainWindowTrayIconMenuItem_Checked(object sender, RoutedEventArgs e) { + private void HideICCMainWindowTrayIconMenuItem_Checked(object sender, RoutedEventArgs e) + { var mi = (MenuItem)sender; var mainWin = (MainWindow)Current.MainWindow; - if (mainWin.IsLoaded) { + if (mainWin.IsLoaded) + { mainWin.Hide(); var s = ((TaskbarIcon)Current.Resources["TaskbarTrayIcon"]).ContextMenu; var ResetFloatingBarPositionTrayIconMenuItem = (MenuItem)s.Items[s.Items.Count - 4]; @@ -128,16 +150,20 @@ namespace Ink_Canvas ResetFloatingBarPositionTrayIconMenuItem.Opacity = 0.5; FoldFloatingBarTrayIconMenuItem.Opacity = 0.5; ForceFullScreenTrayIconMenuItem.Opacity = 0.5; - } else { + } + else + { mi.IsChecked = false; } - + } - private void HideICCMainWindowTrayIconMenuItem_UnChecked(object sender, RoutedEventArgs e) { + private void HideICCMainWindowTrayIconMenuItem_UnChecked(object sender, RoutedEventArgs e) + { var mi = (MenuItem)sender; var mainWin = (MainWindow)Current.MainWindow; - if (mainWin.IsLoaded) { + if (mainWin.IsLoaded) + { mainWin.Show(); var s = ((TaskbarIcon)Current.Resources["TaskbarTrayIcon"]).ContextMenu; var ResetFloatingBarPositionTrayIconMenuItem = (MenuItem)s.Items[s.Items.Count - 4]; @@ -149,7 +175,9 @@ namespace Ink_Canvas ResetFloatingBarPositionTrayIconMenuItem.Opacity = 1; FoldFloatingBarTrayIconMenuItem.Opacity = 1; ForceFullScreenTrayIconMenuItem.Opacity = 1; - } else { + } + else + { mi.IsChecked = false; } } diff --git a/Ink Canvas/Resources/ChickenSoup.cs b/Ink Canvas/Resources/ChickenSoup.cs index f18f3e73..1d9ff510 100644 --- a/Ink Canvas/Resources/ChickenSoup.cs +++ b/Ink Canvas/Resources/ChickenSoup.cs @@ -1,6 +1,7 @@ namespace Ink_Canvas { - public static class ChickenSoup { + public static class ChickenSoup + { public static string[] OSUPlayerYuLu = { "澳洲原神,启动!", "一眼丁真,鉴定为玩osu!玩的", diff --git a/Ink Canvas/Resources/Settings.cs b/Ink Canvas/Resources/Settings.cs index 8d9291f2..e17be230 100644 --- a/Ink Canvas/Resources/Settings.cs +++ b/Ink Canvas/Resources/Settings.cs @@ -1,7 +1,7 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.IO; -using Newtonsoft.Json; namespace Ink_Canvas { @@ -41,7 +41,7 @@ namespace Ink_Canvas public int InkStyle { get; set; } [JsonProperty("eraserSize")] public int EraserSize { get; set; } = 2; - [JsonProperty("eraserType")] + [JsonProperty("eraserType")] public int EraserType { get; set; } // 0 - 图标切换模式 1 - 面积擦 2 - 线条擦 [JsonProperty("eraserShapeType")] public int EraserShapeType { get; set; } // 0 - 圆形擦 1 - 黑板擦 @@ -158,7 +158,7 @@ namespace Ink_Canvas // public bool EnableViewboxFloatingBarScaleTransform { get; set; } = false; [JsonProperty("viewboxFloatingBarScaleTransformValue")] public double ViewboxFloatingBarScaleTransformValue { get; set; } = 1.0; - [JsonProperty("floatingBarImg")] + [JsonProperty("floatingBarImg")] public int FloatingBarImg { get; set; } [JsonProperty("customFloatingBarImgs")] public List CustomFloatingBarImgs { get; set; } = new List(); @@ -193,7 +193,7 @@ namespace Ink_Canvas [JsonProperty("isShowModeFingerToggleSwitch")] public bool IsShowModeFingerToggleSwitch { get; set; } = true; [JsonProperty("theme")] - public int Theme { get; set; } + public int Theme { get; set; } } public class PowerPointSettings @@ -259,7 +259,7 @@ namespace Ink_Canvas public class Automation { [JsonIgnore] - public bool IsEnableAutoFold => + public bool IsEnableAutoFold => IsAutoFoldInEasiNote || IsAutoFoldInEasiCamera || IsAutoFoldInEasiNote3C @@ -388,7 +388,7 @@ namespace Ink_Canvas [JsonProperty("autoDelSavedFilesDaysThreshold")] public int AutoDelSavedFilesDaysThreshold = 15; - + [JsonProperty("isSaveFullPageStrokes")] public bool IsSaveFullPageStrokes; @@ -418,7 +418,7 @@ namespace Ink_Canvas [JsonProperty("isLogEnabled")] public bool IsLogEnabled { get; set; } = true; - + [JsonProperty("isSaveLogByDate")] public bool IsSaveLogByDate { get; set; } = true; @@ -445,7 +445,7 @@ namespace Ink_Canvas [JsonProperty("isEnableAvoidFullScreenHelper")] public bool IsEnableAvoidFullScreenHelper { get; set; } - + [JsonProperty("isAutoBackupBeforeUpdate")] public bool IsAutoBackupBeforeUpdate { get; set; } = true; @@ -471,7 +471,8 @@ namespace Ink_Canvas public double LineStraightenSensitivity { get; set; } = 0.20; // 直线检测灵敏度,值越小越严格(0.05-2.0) } - public class RandSettings { + public class RandSettings + { [JsonProperty("displayRandWindowNamesInputBtn")] public bool DisplayRandWindowNamesInputBtn { get; set; } [JsonProperty("randWindowOnceCloseLatency")] @@ -487,39 +488,39 @@ namespace Ink_Canvas [JsonProperty("customPickNameBackgrounds")] public List CustomPickNameBackgrounds { get; set; } = new List(); } - + public class CustomPickNameBackground { [JsonProperty("name")] public string Name { get; set; } - + [JsonProperty("filePath")] public string FilePath { get; set; } - + public CustomPickNameBackground(string name, string filePath) { Name = name; FilePath = filePath; } - + // 用于JSON序列化 public CustomPickNameBackground() { } } - + public class CustomFloatingBarIcon { [JsonProperty("name")] public string Name { get; set; } - + [JsonProperty("filePath")] public string FilePath { get; set; } - + public CustomFloatingBarIcon(string name, string filePath) { Name = name; FilePath = filePath; } - + // 用于JSON序列化 public CustomFloatingBarIcon() { } } diff --git a/Ink Canvas/Windows/AddCustomIconWindow.xaml.cs b/Ink Canvas/Windows/AddCustomIconWindow.xaml.cs index 22515ccd..a214c9f2 100644 --- a/Ink Canvas/Windows/AddCustomIconWindow.xaml.cs +++ b/Ink Canvas/Windows/AddCustomIconWindow.xaml.cs @@ -1,8 +1,8 @@ +using Microsoft.Win32; using System; using System.IO; using System.Windows; using System.Windows.Media.Imaging; -using Microsoft.Win32; namespace Ink_Canvas { @@ -20,7 +20,7 @@ namespace Ink_Canvas InitializeComponent(); mainWindow = owner; IsSuccess = false; - + // 添加TextBox内容变化事件以检查是否可以保存 IconNameTextBox.TextChanged += (s, e) => ValidateSaveButton(); } @@ -37,7 +37,7 @@ namespace Ink_Canvas { selectedFilePath = openFileDialog.FileName; IconPathTextBox.Text = selectedFilePath; - + // 显示预览 try { @@ -51,15 +51,15 @@ namespace Ink_Canvas { MessageBox.Show($"无法加载图像: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } - + // 自动填充名称建议(文件名,不包括扩展名) string suggestedName = Path.GetFileNameWithoutExtension(selectedFilePath); IconNameTextBox.Text = suggestedName; - + ValidateSaveButton(); } } - + private void ValidateSaveButton() { SaveButton.IsEnabled = !string.IsNullOrWhiteSpace(IconNameTextBox.Text) && !string.IsNullOrEmpty(selectedFilePath); @@ -77,37 +77,37 @@ namespace Ink_Canvas // 创建pictures/icons文件夹结构(如果不存在) string picturesFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "pictures"); string iconsFolder = Path.Combine(picturesFolder, "icons"); - + if (!Directory.Exists(picturesFolder)) { Directory.CreateDirectory(picturesFolder); } - + if (!Directory.Exists(iconsFolder)) { Directory.CreateDirectory(iconsFolder); } - + // 生成一个唯一的文件名(使用GUID) string extension = Path.GetExtension(selectedFilePath); string newFileName = $"{Guid.NewGuid()}{extension}"; string destPath = Path.Combine(iconsFolder, newFileName); - + // 复制文件到pictures/icons文件夹 File.Copy(selectedFilePath, destPath); - + // 创建新的自定义图标对象 var customIcon = new CustomFloatingBarIcon(IconNameTextBox.Text, destPath); - + // 添加到主窗口的设置中 MainWindow.Settings.Appearance.CustomFloatingBarImgs.Add(customIcon); - + // 更新ComboBox mainWindow.UpdateCustomIconsInComboBox(); - + // 保存设置 MainWindow.SaveSettingsToFile(); - + IsSuccess = true; Close(); } @@ -117,4 +117,4 @@ namespace Ink_Canvas } } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Windows/AddPickNameBackgroundWindow.xaml.cs b/Ink Canvas/Windows/AddPickNameBackgroundWindow.xaml.cs index 9840f70a..bc602748 100644 --- a/Ink Canvas/Windows/AddPickNameBackgroundWindow.xaml.cs +++ b/Ink Canvas/Windows/AddPickNameBackgroundWindow.xaml.cs @@ -1,8 +1,8 @@ +using Microsoft.Win32; using System; using System.IO; using System.Windows; using System.Windows.Media.Imaging; -using Microsoft.Win32; namespace Ink_Canvas { @@ -20,7 +20,7 @@ namespace Ink_Canvas InitializeComponent(); mainWindow = owner; IsSuccess = false; - + // 添加TextBox内容变化事件以检查是否可以保存 BackgroundNameTextBox.TextChanged += (s, e) => ValidateSaveButton(); } @@ -37,7 +37,7 @@ namespace Ink_Canvas { selectedFilePath = openFileDialog.FileName; BackgroundPathTextBox.Text = selectedFilePath; - + // 显示预览 try { @@ -52,15 +52,15 @@ namespace Ink_Canvas { MessageBox.Show($"无法加载图像: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } - + // 自动填充名称建议(文件名,不包括扩展名) string suggestedName = Path.GetFileNameWithoutExtension(selectedFilePath); BackgroundNameTextBox.Text = suggestedName; - + ValidateSaveButton(); } } - + private void ValidateSaveButton() { SaveButton.IsEnabled = !string.IsNullOrWhiteSpace(BackgroundNameTextBox.Text) && !string.IsNullOrEmpty(selectedFilePath); @@ -78,37 +78,37 @@ namespace Ink_Canvas // 创建pictures/picknamebackgrounds文件夹结构(如果不存在) string picturesFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "pictures"); string backgroundsFolder = Path.Combine(picturesFolder, "picknamebackgrounds"); - + if (!Directory.Exists(picturesFolder)) { Directory.CreateDirectory(picturesFolder); } - + if (!Directory.Exists(backgroundsFolder)) { Directory.CreateDirectory(backgroundsFolder); } - + // 生成一个唯一的文件名(使用GUID) string extension = Path.GetExtension(selectedFilePath); string newFileName = $"{Guid.NewGuid()}{extension}"; string destPath = Path.Combine(backgroundsFolder, newFileName); - + // 复制文件到pictures/picknamebackgrounds文件夹 File.Copy(selectedFilePath, destPath); - + // 创建新的自定义背景对象 var customBackground = new CustomPickNameBackground(BackgroundNameTextBox.Text, destPath); - + // 添加到主窗口的设置中 MainWindow.Settings.RandSettings.CustomPickNameBackgrounds.Add(customBackground); - + // 更新ComboBox mainWindow.UpdatePickNameBackgroundsInComboBox(); - + // 保存设置 MainWindow.SaveSettingsToFile(); - + IsSuccess = true; Close(); } @@ -118,4 +118,4 @@ namespace Ink_Canvas } } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Windows/CountdownTimerWindow.xaml.cs b/Ink Canvas/Windows/CountdownTimerWindow.xaml.cs index c6528338..5b1ce454 100644 --- a/Ink Canvas/Windows/CountdownTimerWindow.xaml.cs +++ b/Ink Canvas/Windows/CountdownTimerWindow.xaml.cs @@ -1,4 +1,6 @@ -using System; +using Ink_Canvas.Helpers; +using iNKORE.UI.WPF.Modern.Controls; +using System; using System.ComponentModel; using System.Media; using System.Timers; @@ -7,8 +9,6 @@ using System.Windows.Forms; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; -using Ink_Canvas.Helpers; -using iNKORE.UI.WPF.Modern.Controls; using Application = System.Windows.Application; using MouseEventArgs = System.Windows.Input.MouseEventArgs; using Timer = System.Timers.Timer; @@ -364,7 +364,8 @@ namespace Ink_Canvas // Set to center double dpiScaleX = 1, dpiScaleY = 1; PresentationSource source = PresentationSource.FromVisual(this); - if (source != null) { + if (source != null) + { dpiScaleX = source.CompositionTarget.TransformToDevice.M11; dpiScaleY = source.CompositionTarget.TransformToDevice.M22; } diff --git a/Ink Canvas/Windows/CustomIconWindow.xaml.cs b/Ink Canvas/Windows/CustomIconWindow.xaml.cs index 2fd8bc61..fb89d189 100644 --- a/Ink Canvas/Windows/CustomIconWindow.xaml.cs +++ b/Ink Canvas/Windows/CustomIconWindow.xaml.cs @@ -16,7 +16,7 @@ namespace Ink_Canvas { InitializeComponent(); mainWindow = owner; - + // 从主窗口的设置获取自定义图标列表 CustomIcons = new ObservableCollection(MainWindow.Settings.Appearance.CustomFloatingBarImgs); CustomIconsListView.ItemsSource = CustomIcons; @@ -28,26 +28,26 @@ namespace Ink_Canvas { // 从列表中移除图标 CustomIcons.Remove(icon); - + // 更新主窗口的设置 MainWindow.Settings.Appearance.CustomFloatingBarImgs.Clear(); foreach (var customIcon in CustomIcons) { MainWindow.Settings.Appearance.CustomFloatingBarImgs.Add(customIcon); } - + // 如果当前选中的是被删除的图标,重置为默认图标 - if (MainWindow.Settings.Appearance.FloatingBarImg >= 8 && + if (MainWindow.Settings.Appearance.FloatingBarImg >= 8 && MainWindow.Settings.Appearance.FloatingBarImg - 8 >= MainWindow.Settings.Appearance.CustomFloatingBarImgs.Count) { MainWindow.Settings.Appearance.FloatingBarImg = 0; mainWindow.ComboBoxFloatingBarImg.SelectedIndex = 0; mainWindow.UpdateFloatingBarIcon(); } - + // 更新ComboBox mainWindow.UpdateCustomIconsInComboBox(); - + // 保存设置 MainWindow.SaveSettingsToFile(); } @@ -58,4 +58,4 @@ namespace Ink_Canvas Close(); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Windows/HasNewUpdateWindow.xaml.cs b/Ink Canvas/Windows/HasNewUpdateWindow.xaml.cs index b5561fec..94e169cf 100644 --- a/Ink Canvas/Windows/HasNewUpdateWindow.xaml.cs +++ b/Ink Canvas/Windows/HasNewUpdateWindow.xaml.cs @@ -1,4 +1,7 @@ -using System; +using Ink_Canvas.Helpers; +using iNKORE.UI.WPF.Modern.Controls; +using MdXaml; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -10,9 +13,6 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Interop; using System.Windows.Media; -using Ink_Canvas.Helpers; -using iNKORE.UI.WPF.Modern.Controls; -using MdXaml; namespace Ink_Canvas { @@ -72,34 +72,34 @@ namespace Ink_Canvas public HasNewUpdateWindow(string currentVersion, string newVersion, string releaseDate, string releaseNotes = null) { InitializeComponent(); - + // 设置版本信息 CurrentVersion = currentVersion; NewVersion = newVersion; ReleaseDate = releaseDate; ReleaseNotes = releaseNotes; - + // 更新UI updateVersionInfo.Text = $"本次更新: {CurrentVersion} -> {NewVersion}"; updateDateInfo.Text = $"{ReleaseDate}发布更新"; - + // 如果有发布说明,设置到Markdown内容中 if (!string.IsNullOrEmpty(ReleaseNotes)) { markdownContent.Markdown = ReleaseNotes; } - + // 自动更新和静默更新设置已移至设置界面,此处不再需要 - + // 确保按钮可见且可用 EnsureButtonsVisibility(); - + // 显示窗口动画 AnimationsHelper.ShowWithFadeIn(this, 0.25); - + // 设置深色模式 UseImmersiveDarkMode(new WindowInteropHelper(this).Handle, true); - + // 窗口加载完成后再次确保按钮可见 Loaded += HasNewUpdateWindow_Loaded; } @@ -108,7 +108,7 @@ namespace Ink_Canvas { // 窗口加载完成后再次确保按钮可见 EnsureButtonsVisibility(); - + // 调整窗口大小以适应屏幕分辨率 AdjustWindowSizeForScreenResolution(); } @@ -119,18 +119,18 @@ namespace Ink_Canvas // 确保立即更新按钮可见 UpdateNowButton.Visibility = Visibility.Visible; UpdateNowButton.IsEnabled = true; - + // 确保稍后更新按钮可见 UpdateLaterButton.Visibility = Visibility.Visible; UpdateLaterButton.IsEnabled = true; - + // 确保跳过版本按钮可见 SkipVersionButton.Visibility = Visibility.Visible; SkipVersionButton.IsEnabled = true; - + // 强制刷新UI UpdateLayout(); - + // 记录日志 LogHelper.WriteLogToFile("AutoUpdate | Update dialog buttons visibility ensured"); } @@ -154,7 +154,8 @@ namespace Ink_Canvas var groups = AutoUpdateHelper.ChannelLineGroups[MainWindow.Settings.Startup.UpdateChannel]; downloadSuccess = await AutoUpdateHelper.DownloadSetupFileWithFallback(NewVersion, groups, (percent, text) => { - Dispatcher.Invoke(() => { + Dispatcher.Invoke(() => + { DownloadProgressBar.Value = percent; DownloadProgressText.Text = text; }); @@ -176,10 +177,10 @@ namespace Ink_Canvas DownloadProgressBar.Value = 100; DownloadProgressText.Text = "下载完成,准备安装..."; await Task.Delay(800); - // 设置结果为立即更新 - Result = UpdateResult.UpdateNow; - DialogResult = true; - Close(); + // 设置结果为立即更新 + Result = UpdateResult.UpdateNow; + DialogResult = true; + Close(); } else { @@ -193,10 +194,10 @@ namespace Ink_Canvas private void UpdateLaterButton_Click(object sender, RoutedEventArgs e) { LogHelper.WriteLogToFile("AutoUpdate | Update Later button clicked"); - + // 设置结果为稍后更新 Result = UpdateResult.UpdateLater; - + // 关闭窗口 DialogResult = true; Close(); @@ -205,16 +206,16 @@ namespace Ink_Canvas private void SkipVersionButton_Click(object sender, RoutedEventArgs e) { LogHelper.WriteLogToFile("AutoUpdate | Skip Version button clicked"); - + // 设置结果为跳过该版本 Result = UpdateResult.SkipVersion; - + // 关闭窗口 DialogResult = true; Close(); } - - + + // 根据屏幕分辨率调整窗口大小 private void AdjustWindowSizeForScreenResolution() @@ -224,15 +225,15 @@ namespace Ink_Canvas // 获取主屏幕分辨率 double screenWidth = SystemParameters.PrimaryScreenWidth; double screenHeight = SystemParameters.PrimaryScreenHeight; - + LogHelper.WriteLogToFile($"AutoUpdate | Screen resolution: {screenWidth}x{screenHeight}"); - + // 始终确保窗口不超过屏幕大小的85% double maxHeight = screenHeight * 0.85; double maxWidth = screenWidth * 0.85; - + bool needsAdjustment = false; - + // 如果窗口高度超过最大允许高度,调整窗口高度 if (Height > maxHeight) { @@ -240,7 +241,7 @@ namespace Ink_Canvas needsAdjustment = true; LogHelper.WriteLogToFile($"AutoUpdate | Adjusted window height to: {Height}"); } - + // 如果窗口宽度超过最大允许宽度,调整窗口宽度 if (Width > maxWidth) { @@ -248,7 +249,7 @@ namespace Ink_Canvas needsAdjustment = true; LogHelper.WriteLogToFile($"AutoUpdate | Adjusted window width to: {Width}"); } - + // 如果屏幕分辨率较低,调整更多UI元素 if (screenHeight < 768 || screenWidth < 1024 || needsAdjustment) { @@ -257,7 +258,7 @@ namespace Ink_Canvas var updateNowButton = FindName("UpdateNowButton") as Button; var updateLaterButton = FindName("UpdateLaterButton") as Button; var skipVersionButton = FindName("SkipVersionButton") as Button; - + // 查找包含ScrollViewer的边框控件,减小其高度 var contentBorders = FindVisualChildren().ToList(); foreach (var border in contentBorders) @@ -277,7 +278,7 @@ namespace Ink_Canvas } } } - + // 调整按钮大小 if (updateNowButton != null && updateLaterButton != null && skipVersionButton != null) { @@ -290,13 +291,13 @@ namespace Ink_Canvas LogHelper.WriteLogToFile("AutoUpdate | Reduced button sizes for small screen"); } } - + // 确保窗口在屏幕范围内 if (Left < 0) Left = 0; if (Top < 0) Top = 0; if (Left + Width > screenWidth) Left = screenWidth - Width; if (Top + Height > screenHeight) Top = screenHeight - Height; - + LogHelper.WriteLogToFile($"AutoUpdate | Final window size: {Width}x{Height}"); } catch (Exception ex) @@ -304,13 +305,13 @@ namespace Ink_Canvas LogHelper.WriteLogToFile($"AutoUpdate | Error adjusting window size: {ex.Message}", LogHelper.LogType.Error); } } - + // 递归查找指定类型的所有子控件 private IEnumerable FindVisualChildren(DependencyObject depObj = null) where T : DependencyObject { if (depObj == null) depObj = this; - + if (depObj != null) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) @@ -341,7 +342,8 @@ namespace Ink_Canvas LogHelper.WriteLogToFile($"AutoUpdate | 开始安装版本: {version}"); AutoUpdateHelper.InstallNewVersionApp(version, false); App.IsAppExitByUser = true; - Application.Current.Dispatcher.Invoke(() => { + Application.Current.Dispatcher.Invoke(() => + { Application.Current.Shutdown(); }); return true; diff --git a/Ink Canvas/Windows/HistoryRollbackWindow.xaml.cs b/Ink Canvas/Windows/HistoryRollbackWindow.xaml.cs index b45a0c34..15e96c61 100644 --- a/Ink Canvas/Windows/HistoryRollbackWindow.xaml.cs +++ b/Ink Canvas/Windows/HistoryRollbackWindow.xaml.cs @@ -1,3 +1,4 @@ +using Ink_Canvas.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; @@ -7,7 +8,6 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; -using Ink_Canvas.Helpers; // Added for OrderByDescending namespace Ink_Canvas @@ -104,7 +104,8 @@ namespace Ink_Canvas channel, (percent, text) => { - Dispatcher.Invoke(() => { + Dispatcher.Invoke(() => + { DownloadProgressBar.Value = percent; DownloadProgressText.Text = text; }); @@ -139,4 +140,4 @@ namespace Ink_Canvas base.OnClosing(e); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Windows/ManagePickNameBackgroundsWindow.xaml.cs b/Ink Canvas/Windows/ManagePickNameBackgroundsWindow.xaml.cs index 6d4c1d90..a19b9f20 100644 --- a/Ink Canvas/Windows/ManagePickNameBackgroundsWindow.xaml.cs +++ b/Ink Canvas/Windows/ManagePickNameBackgroundsWindow.xaml.cs @@ -18,7 +18,7 @@ namespace Ink_Canvas { InitializeComponent(); mainWindow = owner; - + // 从主窗口的设置获取自定义背景列表 Backgrounds = new ObservableCollection(MainWindow.Settings.RandSettings.CustomPickNameBackgrounds); BackgroundsListView.ItemsSource = Backgrounds; @@ -30,16 +30,16 @@ namespace Ink_Canvas { // 找到背景在列表中的索引(加8,因为前8个是默认值) int index = Backgrounds.IndexOf(background) + 1; // 增加1因为索引0将是"默认" - + // 更新设置 MainWindow.Settings.RandSettings.SelectedBackgroundIndex = index; - + // 更新UI mainWindow.UpdatePickNameBackgroundDisplay(); - + // 保存设置 MainWindow.SaveSettingsToFile(); - + MessageBox.Show($"已将\"{background.Name}\"设置为当前点名背景", "设置成功", MessageBoxButton.OK, MessageBoxImage.Information); } } @@ -57,17 +57,17 @@ namespace Ink_Canvas { File.Delete(background.FilePath); } - + // 从列表中移除背景 Backgrounds.Remove(background); - + // 更新主窗口的设置 MainWindow.Settings.RandSettings.CustomPickNameBackgrounds.Clear(); foreach (var bg in Backgrounds) { MainWindow.Settings.RandSettings.CustomPickNameBackgrounds.Add(bg); } - + // 如果当前选中的是被删除的背景,重置为默认背景 int selectedIndex = MainWindow.Settings.RandSettings.SelectedBackgroundIndex; if (selectedIndex > 0 && selectedIndex - 1 >= MainWindow.Settings.RandSettings.CustomPickNameBackgrounds.Count) @@ -75,10 +75,10 @@ namespace Ink_Canvas MainWindow.Settings.RandSettings.SelectedBackgroundIndex = 0; mainWindow.UpdatePickNameBackgroundDisplay(); } - + // 更新ComboBox mainWindow.UpdatePickNameBackgroundsInComboBox(); - + // 保存设置 MainWindow.SaveSettingsToFile(); } @@ -95,4 +95,4 @@ namespace Ink_Canvas Close(); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Windows/NamesInputWindow.xaml.cs b/Ink Canvas/Windows/NamesInputWindow.xaml.cs index 9e9a637a..ab020adc 100644 --- a/Ink Canvas/Windows/NamesInputWindow.xaml.cs +++ b/Ink Canvas/Windows/NamesInputWindow.xaml.cs @@ -1,7 +1,7 @@ -using System.ComponentModel; +using Ink_Canvas.Helpers; +using System.ComponentModel; using System.IO; using System.Windows; -using Ink_Canvas.Helpers; namespace Ink_Canvas { diff --git a/Ink Canvas/Windows/OperatingGuideWindow.xaml.cs b/Ink Canvas/Windows/OperatingGuideWindow.xaml.cs index 3c429a4f..3357980f 100644 --- a/Ink Canvas/Windows/OperatingGuideWindow.xaml.cs +++ b/Ink Canvas/Windows/OperatingGuideWindow.xaml.cs @@ -1,7 +1,7 @@ -using System.Windows; -using System.Windows.Input; -using Ink_Canvas.Helpers; +using Ink_Canvas.Helpers; using iNKORE.UI.WPF.Modern.Controls; +using System.Windows; +using System.Windows.Input; namespace Ink_Canvas { @@ -26,17 +26,22 @@ namespace Ink_Canvas if (e.LeftButton == MouseButtonState.Pressed) DragMove(); } - private void BtnFullscreen_MouseUp(object sender, MouseButtonEventArgs e) { - if (WindowState == WindowState.Normal) { + private void BtnFullscreen_MouseUp(object sender, MouseButtonEventArgs e) + { + if (WindowState == WindowState.Normal) + { WindowState = WindowState.Maximized; SymbolIconFullscreen.Symbol = Symbol.BackToWindow; - } else { + } + else + { WindowState = WindowState.Normal; SymbolIconFullscreen.Symbol = Symbol.FullScreen; } } - private void SCManipulationBoundaryFeedback(object sender, ManipulationBoundaryFeedbackEventArgs e) { + private void SCManipulationBoundaryFeedback(object sender, ManipulationBoundaryFeedbackEventArgs e) + { e.Handled = true; } } diff --git a/Ink Canvas/Windows/PluginSettingsWindow.xaml.cs b/Ink Canvas/Windows/PluginSettingsWindow.xaml.cs index 678d52c4..3fa180fa 100644 --- a/Ink Canvas/Windows/PluginSettingsWindow.xaml.cs +++ b/Ink Canvas/Windows/PluginSettingsWindow.xaml.cs @@ -1,3 +1,9 @@ +using Ink_Canvas.Helpers; +using Ink_Canvas.Helpers.Plugins; +using Ink_Canvas.Helpers.Plugins.BuiltIn; +using Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher; +using iNKORE.UI.WPF.Modern.Controls; +using Microsoft.Win32; using System; using System.Collections.ObjectModel; using System.ComponentModel; @@ -6,12 +12,6 @@ using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Threading; -using Ink_Canvas.Helpers; -using Ink_Canvas.Helpers.Plugins; -using Ink_Canvas.Helpers.Plugins.BuiltIn; -using Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher; -using iNKORE.UI.WPF.Modern.Controls; -using Microsoft.Win32; using MessageBox = System.Windows.MessageBox; namespace Ink_Canvas.Windows @@ -22,14 +22,14 @@ namespace Ink_Canvas.Windows public partial class PluginSettingsWindow : Window, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; - + /// /// 刷新插件列表 /// public void RefreshPluginList() { LoadPlugins(); - + // 如果当前选中的插件仍然存在,保持其选中状态 if (SelectedPlugin != null) { @@ -39,13 +39,13 @@ namespace Ink_Canvas.Windows PluginListView.SelectedItem = matchingPlugin; } } - + OnPropertyChanged(nameof(SelectedPlugin)); LogHelper.WriteLogToFile("插件列表已刷新"); } private IPlugin _selectedPlugin; - + /// /// 当前选中的插件 /// @@ -83,21 +83,21 @@ namespace Ink_Canvas.Windows public PluginSettingsWindow() { InitializeComponent(); - + // 设置数据上下文 PluginDetailGrid.DataContext = this; - + // 设置导出按钮初始状态 BtnExportPlugin.IsEnabled = false; BtnExportPlugin.ToolTip = "请先选择要导出的插件"; - + // 加载插件列表 LoadPlugins(); - + // 注册窗口关闭事件 Closing += PluginSettingsWindow_Closing; } - + /// /// 窗口关闭事件处理 /// @@ -115,44 +115,44 @@ namespace Ink_Canvas.Windows LogHelper.WriteLogToFile($"关闭窗口时保存插件配置出错: {ex.Message}", LogHelper.LogType.Error); } } - + /// /// 加载插件列表 /// private void LoadPlugins() { Plugins.Clear(); - + LogHelper.WriteLogToFile($"开始加载插件列表到UI,插件总数: {PluginManager.Instance.Plugins.Count}"); - + // 添加所有已加载的插件 foreach (var plugin in PluginManager.Instance.Plugins) { bool isEnabled = false; - + // 从插件实例获取启用状态 if (plugin is PluginBase pluginBase) { isEnabled = pluginBase.IsEnabled; } - + // 记录插件详细信息 LogHelper.WriteLogToFile($"正在加载插件到UI: 类型={plugin.GetType().FullName}, 名称={plugin.Name ?? "未命名"}, 状态={isEnabled}"); - + // 创建视图模型并添加到集合 var viewModel = new PluginViewModel(plugin) { IsEnabled = isEnabled }; Plugins.Add(viewModel); - + LogHelper.WriteLogToFile($"已加载插件到UI列表: {plugin.Name},状态: {(isEnabled ? "启用" : "禁用")}"); } - + // 绑定到ListView LogHelper.WriteLogToFile($"绑定 {Plugins.Count} 个插件到ListView"); PluginListView.ItemsSource = Plugins; - + // 如果有插件,选择第一个 if (Plugins.Count > 0) { @@ -164,7 +164,7 @@ namespace Ink_Canvas.Windows LogHelper.WriteLogToFile("没有找到任何插件", LogHelper.LogType.Warning); } } - + /// /// 更新属性变更通知 /// @@ -173,7 +173,7 @@ namespace Ink_Canvas.Windows { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } - + /// /// 插件列表选择变更事件 /// @@ -183,13 +183,13 @@ namespace Ink_Canvas.Windows { // 设置当前选中的插件 SelectedPlugin = viewModel.Plugin; - + // 加载插件设置界面 PluginSettingsContainer.Content = SelectedPlugin.GetSettingsView(); - + // 设置删除按钮的可见性 BtnDeletePlugin.Visibility = !SelectedPlugin.IsBuiltIn ? Visibility.Visible : Visibility.Collapsed; - + // 设置导出按钮的可用状态 BtnExportPlugin.IsEnabled = !SelectedPlugin.IsBuiltIn; if (SelectedPlugin.IsBuiltIn) @@ -210,7 +210,7 @@ namespace Ink_Canvas.Windows BtnExportPlugin.ToolTip = "请先选择要导出的插件"; } } - + /// /// 加载本地插件按钮点击事件 /// @@ -224,38 +224,38 @@ namespace Ink_Canvas.Windows Filter = "ICC插件文件(*.iccpp)|*.iccpp", Title = "选择要加载的插件文件" }; - + // 显示对话框 if (dialog.ShowDialog() == true) { // 获取插件文件路径 string pluginPath = dialog.FileName; - + // 检查是否在Plugins目录下 string pluginsDirectory = Path.Combine(App.RootPath, "Plugins"); string targetPath = Path.Combine(pluginsDirectory, Path.GetFileName(pluginPath)); - + // 确保Plugins目录存在 if (!Directory.Exists(pluginsDirectory)) { Directory.CreateDirectory(pluginsDirectory); } - + // 如果插件不在Plugins目录下,复制过去 if (!string.Equals(pluginPath, targetPath, StringComparison.OrdinalIgnoreCase)) { File.Copy(pluginPath, targetPath, true); pluginPath = targetPath; } - + // 加载插件 IPlugin plugin = PluginManager.Instance.LoadExternalPlugin(pluginPath); - + if (plugin != null) { // 刷新插件列表 LoadPlugins(); - + // 选择新加载的插件 foreach (var item in Plugins) { @@ -265,7 +265,7 @@ namespace Ink_Canvas.Windows break; } } - + MessageBox.Show($"插件 {plugin.Name} v{plugin.Version} 已成功加载!", "成功", MessageBoxButton.OK, MessageBoxImage.Information); } else @@ -279,47 +279,47 @@ namespace Ink_Canvas.Windows MessageBox.Show($"加载插件时发生错误:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } - + /// /// 删除插件按钮点击事件 /// private void BtnDeletePlugin_Click(object sender, RoutedEventArgs e) { if (SelectedPlugin == null) return; - + // 不能删除内置插件 if (SelectedPlugin.IsBuiltIn) { MessageBox.Show("内置插件无法删除。", "提示", MessageBoxButton.OK, MessageBoxImage.Information); return; } - + // 保存插件名称,以便在删除后使用 string pluginName = SelectedPlugin.Name; - + // 确认删除 MessageBoxResult result = MessageBox.Show( - $"确定要删除插件 {pluginName} 吗?\n此操作将永久删除插件文件,无法恢复。", - "删除确认", - MessageBoxButton.YesNo, + $"确定要删除插件 {pluginName} 吗?\n此操作将永久删除插件文件,无法恢复。", + "删除确认", + MessageBoxButton.YesNo, MessageBoxImage.Warning); - + if (result == MessageBoxResult.Yes) { // 删除插件 bool success = PluginManager.Instance.DeletePlugin(SelectedPlugin); - + if (success) { // 刷新插件列表 LoadPlugins(); - + // 如果还有插件,选择第一个 if (Plugins.Count > 0) { PluginListView.SelectedIndex = 0; } - + MessageBox.Show($"插件 {pluginName} 已成功删除。", "成功", MessageBoxButton.OK, MessageBoxImage.Information); } else @@ -328,7 +328,7 @@ namespace Ink_Canvas.Windows } } } - + /// /// 导出插件按钮点击事件 /// @@ -403,7 +403,7 @@ namespace Ink_Canvas.Windows MessageBox.Show($"导出插件时发生错误: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } - + /// /// 插件开关切换事件 /// @@ -411,26 +411,26 @@ namespace Ink_Canvas.Windows { try { - if (sender is ToggleSwitch toggleSwitch && + if (sender is ToggleSwitch toggleSwitch && toggleSwitch.Tag is IPlugin plugin) { // 记录当前开关状态 bool targetState = toggleSwitch.IsOn; - + // 记录插件类型名称和名称,用于稍后查找重载后的插件 string pluginTypeName = plugin.GetType().FullName; string pluginName = plugin.Name; bool wasBuiltIn = plugin.IsBuiltIn; - + LogHelper.WriteLogToFile($"UI开关切换: {pluginName}, 目标状态: {(targetState ? "启用" : "禁用")}"); - + // 切换插件状态 PluginManager.Instance.TogglePlugin(plugin, targetState); - + // 立即同步保存配置到文件(确保状态被立即持久化) PluginManager.Instance.SaveConfig(); LogHelper.WriteLogToFile("插件状态已立即保存到配置文件"); - + // 延迟一下再检查状态,确保变更已应用 Dispatcher.BeginInvoke(new Action(() => { @@ -446,17 +446,17 @@ namespace Ink_Canvas.Windows break; } } - + if (currentPlugin == null) { LogHelper.WriteLogToFile($"无法找到插件: {pluginName},UI状态可能不准确", LogHelper.LogType.Warning); return; } - + // 检查实际状态 bool actualState = currentPlugin is PluginBase pb && pb.IsEnabled; LogHelper.WriteLogToFile($"插件 {pluginName} 实际状态: {(actualState ? "启用" : "禁用")}"); - + // 更新视图模型 PluginViewModel viewModel = null; if (toggleSwitch.DataContext is PluginViewModel vm) @@ -467,7 +467,7 @@ namespace Ink_Canvas.Windows { viewModel = Plugins.FirstOrDefault(p => p.Plugin == currentPlugin); } - + if (viewModel != null) { // 确保视图模型状态与实际状态一致 @@ -476,7 +476,7 @@ namespace Ink_Canvas.Windows LogHelper.WriteLogToFile($"同步视图模型状态: {(actualState ? "启用" : "禁用")}"); viewModel.IsEnabled = actualState; } - + // 确保UI开关状态与实际状态一致 if (toggleSwitch.IsOn != actualState) { @@ -484,25 +484,25 @@ namespace Ink_Canvas.Windows toggleSwitch.IsOn = actualState; } } - + // 如果是当前选中的插件,更新属性 if (currentPlugin == SelectedPlugin) { OnPropertyChanged(nameof(IsEnabled)); } - + // 对于内置插件,特别处理 if (wasBuiltIn) { // 特殊插件刷新逻辑,如果是超级启动台插件,立即刷新UI - if (currentPlugin is SuperLauncherPlugin && + if (currentPlugin is SuperLauncherPlugin && PluginSettingsContainer.Content is LauncherSettingsControl) { // 重新获取设置界面 PluginSettingsContainer.Content = currentPlugin.GetSettingsView(); } } - + LogHelper.WriteLogToFile($"插件 {pluginName} UI状态同步完成"); } catch (Exception ex) @@ -518,7 +518,7 @@ namespace Ink_Canvas.Windows MessageBox.Show($"切换插件状态时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } - + /// /// 保存插件状态按钮点击事件 /// @@ -527,7 +527,7 @@ namespace Ink_Canvas.Windows try { int syncCount = 0; - + // 遍历界面上所有插件视图模型,获取开关状态 foreach (var viewModel in Plugins) { @@ -537,10 +537,10 @@ namespace Ink_Canvas.Windows { // 获取UI中开关的当前状态(从界面控件读取) bool uiState = viewModel.IsEnabled; - + // 获取插件类型名,用于查找配置 string pluginTypeName = viewModel.Plugin.GetType().FullName; - + // 查找实际的插件实例(可能与viewModel.Plugin不同,因为可能已经重新加载) IPlugin actualPlugin = null; foreach (var p in PluginManager.Instance.Plugins) @@ -551,21 +551,21 @@ namespace Ink_Canvas.Windows break; } } - + // 如果找不到对应的实际插件实例,跳过 if (actualPlugin == null) { LogHelper.WriteLogToFile($"手动保存:无法找到与UI对应的插件实例:{viewModel.Name}", LogHelper.LogType.Warning); continue; } - + // 获取插件实际状态 bool pluginState = false; if (actualPlugin is PluginBase pluginBase) { pluginState = pluginBase.IsEnabled; } - + // 如果界面状态与插件实际状态不一致,应用界面状态 if (uiState != pluginState) { @@ -574,7 +574,7 @@ namespace Ink_Canvas.Windows LogHelper.WriteLogToFile($"手动保存:同步插件 {actualPlugin.Name} 状态 {pluginState} -> {uiState}"); syncCount++; } - + // 确保配置中的状态也与界面一致 if (PluginManager.Instance.PluginStates.TryGetValue(pluginTypeName, out bool configState) && configState != uiState) { @@ -590,19 +590,19 @@ namespace Ink_Canvas.Windows LogHelper.WriteLogToFile($"手动保存:处理插件 {viewModel.Name} 时出错: {pluginEx.Message}", LogHelper.LogType.Error); } } - + // 保存插件状态配置 PluginManager.Instance.SaveConfig(); - + // 记录日志 LogHelper.WriteLogToFile($"用户手动保存插件状态配置,同步了 {syncCount} 个状态变更"); - + // 刷新插件列表,确保UI与最新状态同步 RefreshPluginList(); - + // 显示保存成功提示 - string message = syncCount > 0 - ? $"插件状态已成功保存,同步了 {syncCount} 个状态变更" + string message = syncCount > 0 + ? $"插件状态已成功保存,同步了 {syncCount} 个状态变更" : "插件状态已成功保存,所有插件状态已是最新"; MessageBox.Show(message, "保存成功", MessageBoxButton.OK, MessageBoxImage.Information); } @@ -610,12 +610,12 @@ namespace Ink_Canvas.Windows { // 记录错误日志 LogHelper.WriteLogToFile($"手动保存插件状态时出错: {ex.Message}", LogHelper.LogType.Error); - + // 显示错误信息 MessageBox.Show($"保存插件状态时发生错误: {ex.Message}", "保存失败", MessageBoxButton.OK, MessageBoxImage.Error); } } - + /// /// 关闭按钮点击事件 /// @@ -625,32 +625,32 @@ namespace Ink_Canvas.Windows Close(); } } - + /// /// 插件视图模型 /// public class PluginViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; - + /// /// 插件实例 /// public IPlugin Plugin { get; } - + /// /// 插件名称 /// - public string Name - { - get + public string Name + { + get { string name = Plugin?.Name ?? "未命名插件"; LogHelper.WriteLogToFile($"获取插件名称: {name},类型: {Plugin?.GetType().FullName ?? "未知"}"); return name; } } - + /// /// 插件是否启用 /// @@ -667,24 +667,24 @@ namespace Ink_Canvas.Windows } } } - + public PluginViewModel(IPlugin plugin) { Plugin = plugin; - + // 获取实际状态 _isEnabled = plugin is PluginBase pluginBase && pluginBase.IsEnabled; - + // 记录日志 LogHelper.WriteLogToFile($"创建插件视图模型: {plugin?.GetType().FullName ?? "未知"}, 名称: {plugin?.Name ?? "未命名"}"); - + // 注册插件状态变更事件 if (plugin is PluginBase pb) { pb.EnabledStateChanged += Plugin_EnabledStateChanged; } } - + /// /// 处理插件状态变更事件 /// @@ -694,7 +694,7 @@ namespace Ink_Canvas.Windows Application.Current.Dispatcher.BeginInvoke(new Action(() => { IsEnabled = isEnabled; - + // 确保配置立即保存 if (sender is IPlugin plugin) { @@ -704,7 +704,7 @@ namespace Ink_Canvas.Windows } })); } - + /// /// 属性变更通知 /// @@ -713,4 +713,4 @@ namespace Ink_Canvas.Windows PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Windows/RandWindow.xaml.cs b/Ink Canvas/Windows/RandWindow.xaml.cs index 35617167..13cfd923 100644 --- a/Ink Canvas/Windows/RandWindow.xaml.cs +++ b/Ink Canvas/Windows/RandWindow.xaml.cs @@ -1,4 +1,7 @@ -using System; +using Ink_Canvas.Helpers; +using iNKORE.UI.WPF.Modern.Controls; +using Microsoft.VisualBasic; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -8,27 +11,27 @@ using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; -using Ink_Canvas.Helpers; -using iNKORE.UI.WPF.Modern.Controls; -using Microsoft.VisualBasic; using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox; -namespace Ink_Canvas { +namespace Ink_Canvas +{ /// /// Interaction logic for RandWindow.xaml /// - public partial class RandWindow : Window { - public RandWindow(Settings settings) { + public partial class RandWindow : Window + { + public RandWindow(Settings settings) + { InitializeComponent(); AnimationsHelper.ShowWithSlideFromBottomAndFade(this, 0.25); BorderBtnHelp.Visibility = settings.RandSettings.DisplayRandWindowNamesInputBtn == false ? Visibility.Collapsed : Visibility.Visible; RandMaxPeopleOneTime = settings.RandSettings.RandWindowOnceMaxStudents; - RandDoneAutoCloseWaitTime = (int)settings.RandSettings.RandWindowOnceCloseLatency*1000; - + RandDoneAutoCloseWaitTime = (int)settings.RandSettings.RandWindowOnceCloseLatency * 1000; + // 加载背景 LoadBackground(settings); } - + private void LoadBackground(Settings settings) { try @@ -60,7 +63,8 @@ namespace Ink_Canvas { } } - public RandWindow(Settings settings, bool IsAutoClose) { + public RandWindow(Settings settings, bool IsAutoClose) + { InitializeComponent(); isAutoClose = IsAutoClose; PeopleControlPane.Opacity = 0.4; @@ -68,13 +72,15 @@ namespace Ink_Canvas { BorderBtnHelp.Visibility = settings.RandSettings.DisplayRandWindowNamesInputBtn == false ? Visibility.Collapsed : Visibility.Visible; RandMaxPeopleOneTime = settings.RandSettings.RandWindowOnceMaxStudents; RandDoneAutoCloseWaitTime = (int)settings.RandSettings.RandWindowOnceCloseLatency * 1000; - + // 加载背景 LoadBackground(settings); - new Thread(() => { + new Thread(() => + { Thread.Sleep(100); - Application.Current.Dispatcher.Invoke(() => { + Application.Current.Dispatcher.Invoke(() => + { BorderBtnRand_MouseUp(BorderBtnRand, null); }); }).Start(); @@ -88,7 +94,8 @@ namespace Ink_Canvas { public int PeopleCount = 60; public List Names = new List(); - private void BorderBtnAdd_MouseUp(object sender, MouseButtonEventArgs e) { + private void BorderBtnAdd_MouseUp(object sender, MouseButtonEventArgs e) + { if (RandMaxPeopleOneTime == -1 && TotalCount >= PeopleCount) return; if (RandMaxPeopleOneTime != -1 && TotalCount >= RandMaxPeopleOneTime) return; TotalCount++; @@ -98,11 +105,13 @@ namespace Ink_Canvas { BorderBtnMinus.Opacity = 1; } - private void BorderBtnMinus_MouseUp(object sender, MouseButtonEventArgs e) { + private void BorderBtnMinus_MouseUp(object sender, MouseButtonEventArgs e) + { if (TotalCount < 2) return; TotalCount--; LabelNumberCount.Text = TotalCount.ToString(); - if (TotalCount == 1) { + if (TotalCount == 1) + { SymbolIconStart.Symbol = Symbol.Contact; } } @@ -112,7 +121,8 @@ namespace Ink_Canvas { public int RandMaxPeopleOneTime = 10; public int RandDoneAutoCloseWaitTime = 2500; - private void BorderBtnRand_MouseUp(object sender, MouseButtonEventArgs e) { + private void BorderBtnRand_MouseUp(object sender, MouseButtonEventArgs e) + { Random random = new Random();// randSeed + DateTime.Now.Millisecond / 10 % 10); string outputString = ""; List outputs = new List(); @@ -121,18 +131,25 @@ namespace Ink_Canvas { LabelOutput2.Visibility = Visibility.Collapsed; LabelOutput3.Visibility = Visibility.Collapsed; - new Thread(() => { - for (int i = 0; i < RandWaitingTimes; i++) { + new Thread(() => + { + for (int i = 0; i < RandWaitingTimes; i++) + { int rand = random.Next(1, PeopleCount + 1); - while (rands.Contains(rand)) { + while (rands.Contains(rand)) + { rand = random.Next(1, PeopleCount + 1); } rands.Add(rand); if (rands.Count >= PeopleCount) rands = new List(); - Application.Current.Dispatcher.Invoke(() => { - if (Names.Count != 0) { + Application.Current.Dispatcher.Invoke(() => + { + if (Names.Count != 0) + { LabelOutput.Content = Names[rand - 1]; - } else { + } + else + { LabelOutput.Content = rand.ToString(); } }); @@ -141,61 +158,80 @@ namespace Ink_Canvas { } rands = new List(); - Application.Current.Dispatcher.Invoke(() => { - for (int i = 0; i < TotalCount; i++) { + Application.Current.Dispatcher.Invoke(() => + { + for (int i = 0; i < TotalCount; i++) + { int rand = random.Next(1, PeopleCount + 1); - while (rands.Contains(rand)) { + while (rands.Contains(rand)) + { rand = random.Next(1, PeopleCount + 1); } rands.Add(rand); if (rands.Count >= PeopleCount) rands = new List(); - if (Names.Count != 0) { + if (Names.Count != 0) + { outputs.Add(Names[rand - 1]); outputString += Names[rand - 1] + Environment.NewLine; - } else { + } + else + { outputs.Add(rand.ToString()); outputString += rand + Environment.NewLine; } } - if (TotalCount <= 5) { + if (TotalCount <= 5) + { LabelOutput.Content = outputString.Trim(); - } else if (TotalCount <= 10) { + } + else if (TotalCount <= 10) + { LabelOutput2.Visibility = Visibility.Visible; outputString = ""; - for (int i = 0; i < (outputs.Count + 1) / 2; i++) { + for (int i = 0; i < (outputs.Count + 1) / 2; i++) + { outputString += outputs[i] + Environment.NewLine; } LabelOutput.Content = outputString.Trim(); outputString = ""; - for (int i = (outputs.Count + 1) / 2; i < outputs.Count; i++) { + for (int i = (outputs.Count + 1) / 2; i < outputs.Count; i++) + { outputString += outputs[i] + Environment.NewLine; } LabelOutput2.Content = outputString.Trim(); - } else { + } + else + { LabelOutput2.Visibility = Visibility.Visible; LabelOutput3.Visibility = Visibility.Visible; outputString = ""; - for (int i = 0; i < (outputs.Count + 1) / 3; i++) { + for (int i = 0; i < (outputs.Count + 1) / 3; i++) + { outputString += outputs[i] + Environment.NewLine; } LabelOutput.Content = outputString.Trim(); outputString = ""; - for (int i = (outputs.Count + 1) / 3; i < (outputs.Count + 1) * 2 / 3; i++) { + for (int i = (outputs.Count + 1) / 3; i < (outputs.Count + 1) * 2 / 3; i++) + { outputString += outputs[i] + Environment.NewLine; } LabelOutput2.Content = outputString.Trim(); outputString = ""; - for (int i = (outputs.Count + 1) * 2 / 3; i < outputs.Count; i++) { + for (int i = (outputs.Count + 1) * 2 / 3; i < outputs.Count; i++) + { outputString += outputs[i] + Environment.NewLine; } LabelOutput3.Content = outputString.Trim(); } - if (isAutoClose) { - new Thread(() => { + if (isAutoClose) + { + new Thread(() => + { Thread.Sleep(RandDoneAutoCloseWaitTime); - Application.Current.Dispatcher.Invoke(() => { + Application.Current.Dispatcher.Invoke(() => + { PeopleControlPane.Opacity = 1; PeopleControlPane.IsHitTestVisible = true; Close(); @@ -206,22 +242,28 @@ namespace Ink_Canvas { }).Start(); } - private void Window_Loaded(object sender, RoutedEventArgs e) { + private void Window_Loaded(object sender, RoutedEventArgs e) + { Names = new List(); - if (File.Exists(App.RootPath + "Names.txt")) { + if (File.Exists(App.RootPath + "Names.txt")) + { string[] fileNames = File.ReadAllLines(App.RootPath + "Names.txt"); string[] replaces = new string[0]; - if (File.Exists(App.RootPath + "Replace.txt")) { + if (File.Exists(App.RootPath + "Replace.txt")) + { replaces = File.ReadAllLines(App.RootPath + "Replace.txt"); } //Fix emtpy lines - foreach (string str in fileNames) { + foreach (string str in fileNames) + { string s = str; //Make replacement - foreach (string replace in replaces) { - if (s == Strings.Left(replace, replace.IndexOf("-->"))) { + foreach (string replace in replaces) + { + if (s == Strings.Left(replace, replace.IndexOf("-->"))) + { s = Strings.Mid(replace, replace.IndexOf("-->") + 4); } } @@ -231,19 +273,22 @@ namespace Ink_Canvas { PeopleCount = Names.Count(); TextBlockPeopleCount.Text = PeopleCount.ToString(); - if (PeopleCount == 0) { + if (PeopleCount == 0) + { PeopleCount = 60; TextBlockPeopleCount.Text = "点击此处以导入名单"; } } } - private void BorderBtnHelp_MouseUp(object sender, MouseButtonEventArgs e) { + private void BorderBtnHelp_MouseUp(object sender, MouseButtonEventArgs e) + { new NamesInputWindow().ShowDialog(); Window_Loaded(this, null); } - private void BtnClose_MouseUp(object sender, MouseButtonEventArgs e) { + private void BtnClose_MouseUp(object sender, MouseButtonEventArgs e) + { Close(); } diff --git a/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml.cs b/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml.cs index 7e85a9dd..f8ed207f 100644 --- a/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml.cs +++ b/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml.cs @@ -1,19 +1,14 @@ using System; using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Drawing2D; using System.Windows; -using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Shapes; using Brushes = System.Windows.Media.Brushes; using Color = System.Windows.Media.Color; - +using DrawingRectangle = System.Drawing.Rectangle; // 为了避免命名冲突,使用别名 using WpfCanvas = System.Windows.Controls.Canvas; -using DrawingRectangle = System.Drawing.Rectangle; -using WpfRectangle = System.Windows.Shapes.Rectangle; namespace Ink_Canvas { @@ -25,20 +20,20 @@ namespace Ink_Canvas private System.Windows.Point _currentPoint; private List _freehandPoints; private Polyline _freehandPolyline; - + public DrawingRectangle? SelectedArea { get; private set; } public List SelectedPath { get; private set; } public ScreenshotSelectorWindow() { InitializeComponent(); - + // 设置窗口覆盖所有屏幕 SetupFullScreenOverlay(); - + // 初始化自由绘制模式 InitializeFreehandMode(); - + // 隐藏提示文字的定时器 var timer = new System.Windows.Threading.DispatcherTimer(); timer.Interval = TimeSpan.FromSeconds(5); @@ -49,7 +44,7 @@ namespace Ink_Canvas }; timer.Start(); } - + private void InitializeFreehandMode() { _freehandPoints = new List(); @@ -97,28 +92,28 @@ namespace Ink_Canvas Close(); } } - + private void RectangleModeButton_Click(object sender, RoutedEventArgs e) { _isFreehandMode = false; RectangleModeButton.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); // 蓝色 FreehandModeButton.Background = new SolidColorBrush(Color.FromRgb(107, 114, 128)); // 灰色 HintText.Text = "拖拽鼠标选择矩形区域"; - + // 清除自由绘制的内容 _freehandPoints.Clear(); _freehandPolyline.Points.Clear(); SelectionPath.Visibility = Visibility.Collapsed; SelectionRectangle.Visibility = Visibility.Collapsed; } - + private void FreehandModeButton_Click(object sender, RoutedEventArgs e) { _isFreehandMode = true; FreehandModeButton.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); // 蓝色 RectangleModeButton.Background = new SolidColorBrush(Color.FromRgb(107, 114, 128)); // 灰色 HintText.Text = "按住鼠标左键绘制任意形状,松开完成"; - + // 清除矩形选择的内容 SelectionRectangle.Visibility = Visibility.Collapsed; _freehandPoints.Clear(); @@ -130,10 +125,10 @@ namespace Ink_Canvas _isSelecting = true; _startPoint = e.GetPosition(this); _currentPoint = _startPoint; - + // 隐藏提示文字 HintText.Visibility = Visibility.Collapsed; - + if (_isFreehandMode) { // 自由绘制模式 @@ -148,10 +143,10 @@ namespace Ink_Canvas SelectionRectangle.Visibility = Visibility.Visible; SizeInfoBorder.Visibility = Visibility.Visible; } - + // 捕获鼠标 CaptureMouse(); - + if (!_isFreehandMode) { UpdateSelection(); @@ -163,7 +158,7 @@ namespace Ink_Canvas if (_isSelecting) { _currentPoint = e.GetPosition(this); - + if (_isFreehandMode) { // 自由绘制模式:添加点到路径 @@ -193,20 +188,20 @@ namespace Ink_Canvas // 闭合路径 _freehandPoints.Add(_startPoint); _freehandPolyline.Points.Add(_startPoint); - + // 保存选择的路径 SelectedPath = new List(_freehandPoints); - + // 计算边界矩形用于截图 var bounds = CalculatePathBounds(_freehandPoints); var dpiScale = GetDpiScale(); var virtualScreen = System.Windows.Forms.SystemInformation.VirtualScreen; - + int screenX = (int)((bounds.X * dpiScale) + virtualScreen.Left); int screenY = (int)((bounds.Y * dpiScale) + virtualScreen.Top); int screenWidth = (int)(bounds.Width * dpiScale); int screenHeight = (int)(bounds.Height * dpiScale); - + SelectedArea = new DrawingRectangle(screenX, screenY, screenWidth, screenHeight); DialogResult = true; } @@ -275,20 +270,20 @@ namespace Ink_Canvas double y = Math.Min(_startPoint.Y, _currentPoint.Y); double width = Math.Abs(_currentPoint.X - _startPoint.X); double height = Math.Abs(_currentPoint.Y - _startPoint.Y); - + return new Rect(x, y, width, height); } - + private Rect CalculatePathBounds(List points) { if (points == null || points.Count == 0) return new Rect(); - + double minX = points[0].X; double minY = points[0].Y; double maxX = points[0].X; double maxY = points[0].Y; - + foreach (var point in points) { minX = Math.Min(minX, point.X); @@ -296,7 +291,7 @@ namespace Ink_Canvas maxX = Math.Max(maxX, point.X); maxY = Math.Max(maxY, point.Y); } - + return new Rect(minX, minY, maxX - minX, maxY - minY); } } diff --git a/Ink Canvas/Windows/YesOrNoNotificationWindow.xaml.cs b/Ink Canvas/Windows/YesOrNoNotificationWindow.xaml.cs index 6033ec13..241884b9 100644 --- a/Ink Canvas/Windows/YesOrNoNotificationWindow.xaml.cs +++ b/Ink Canvas/Windows/YesOrNoNotificationWindow.xaml.cs @@ -46,7 +46,8 @@ namespace Ink_Canvas Close(); } - private void Window_Closed(object sender, EventArgs e) { + private void Window_Closed(object sender, EventArgs e) + { _windowClose?.Invoke(); } } diff --git a/Ink Canvas/obj/Debug/net472/InkCanvasForClass.csproj.AssemblyReference.cache b/Ink Canvas/obj/Debug/net472/InkCanvasForClass.csproj.AssemblyReference.cache index 4af914e22079d93b58f0e03491291464a0dba41e..c6ec84df6166e1991a81c2fb04df5aad35b82eb5 100644 GIT binary patch delta 1266 zcmZ2Ch3VTArU~cN-JGprLW@(2iemzbQqvNXQ&XJti_&9U@{>z*Q}arSW85=KJW7)$ zK2c@cb8jDS`T5EGjK=zYX_+~xR{Hw-&Q|(h-TKJ7_2IhpA-XpwFeWppdk|;U z?19c=@mTGfeA8>j4~IVsb*9=;Zeiyp#1KLgdN_8Rs@RFOGfl`v@ggu~d9UrpV4mV_$DW(dQ4X9Knv1Ssh%uip4e^I$|{lz#B1~B-C5UJ z#3He4Uzy(}mxy0`P(duSco!pf{l|+h$WLO#Yrv!msm&Kls+q(>u^W+GUN_md4b{t= zD&8=PMPXOZT-7t#xBylC=54iJTo?(>CvC&vX_~aJGsGElw>ej&V%M z&CJUzE-6YZ$uF90=RHF{1E$~EN*}C7A4SdPFW$kd;<-2shz(pWUrN9LrJ$3{;>kD+ zU<{ikpN-#uNs$(t--a17is$1r!(#G=RKCe;BKRkFMnuY&<2P?pWIn5S8UeFT$A!t~ z;WuYer0?dQ_-m}<@p#P&n|#e%h!-VHCq=q#&Prou5%V8Dv{-HhVFI1H$4Y>V!Z