From fea6576dfbc5585296ff004d6913030c34c95d1d Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 5 Apr 2026 20:37:48 +0800 Subject: [PATCH 1/7] =?UTF-8?q?improve:pdf=E6=8F=92=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow_cs/MW_BoardControls.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Ink Canvas/MainWindow_cs/MW_BoardControls.cs b/Ink Canvas/MainWindow_cs/MW_BoardControls.cs index 447cb267..e5f6f717 100644 --- a/Ink Canvas/MainWindow_cs/MW_BoardControls.cs +++ b/Ink Canvas/MainWindow_cs/MW_BoardControls.cs @@ -226,6 +226,7 @@ namespace Ink_Canvas if (TimeMachineHistories[targetIndex] == null) { timeMachine.ClearStrokeHistory(); + SyncPdfPageSidebarWithCanvas(); return; } @@ -282,7 +283,11 @@ namespace Ink_Canvas /// private void ProcessElementsAfterRestore(List elements) { - if (elements == null || elements.Count == 0) return; + if (elements == null || elements.Count == 0) + { + SyncPdfPageSidebarWithCanvas(); + return; + } // 使用低优先级异步处理,让 UI 先响应,图片位置和事件绑定稍后完成 Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() => @@ -322,6 +327,8 @@ namespace Ink_Canvas BindElementEvents(pdf); } } + + SyncPdfPageSidebarWithCanvas(); })); } From 0c078ef86330e5ea173f79b7b59b7d4ac9450d55 Mon Sep 17 00:00:00 2001 From: CJK_mkp <113243675+CJKmkp@users.noreply.github.com> Date: Sun, 5 Apr 2026 20:43:40 +0800 Subject: [PATCH 2/7] =?UTF-8?q?fix:=E6=89=8B=E6=8E=8C=E6=93=A6=20(#419)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MainWindow_cs/MW_FloatingBarIcons.cs | 3 + Ink Canvas/MainWindow_cs/MW_Settings.cs | 12 + Ink Canvas/MainWindow_cs/MW_TouchEvents.cs | 224 +++++++++++++++--- 3 files changed, 200 insertions(+), 39 deletions(-) diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index 9baa7736..2788a77f 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -3298,6 +3298,9 @@ namespace Ink_Canvas // 清空触摸点计数器 dec.Clear(); + if (isPalmEraserActive) + isPalmEraserActive = false; + // 确保触摸事件能正常响应 inkCanvas.IsHitTestVisible = true; inkCanvas.IsManipulationEnabled = true; diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs index 7fe730bf..acacfedc 100644 --- a/Ink Canvas/MainWindow_cs/MW_Settings.cs +++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs @@ -3597,6 +3597,11 @@ namespace Ink_Canvas RestoreNonStrokeElements(preservedElements); isInMultiTouchMode = true; + palmEraserWasEnabledBeforeMultiTouch = Settings.Canvas.EnablePalmEraser; + Settings.Canvas.EnablePalmEraser = false; + if (ToggleSwitchEnablePalmEraser != null) + ToggleSwitchEnablePalmEraser.IsOn = false; + // 恢复到之前的编辑状态 inkCanvas.EditingMode = currentEditingMode; drawingShapeMode = currentDrawingShapeMode; @@ -3627,6 +3632,13 @@ namespace Ink_Canvas RestoreNonStrokeElements(preservedElements); isInMultiTouchMode = false; + if (palmEraserWasEnabledBeforeMultiTouch) + { + Settings.Canvas.EnablePalmEraser = true; + if (ToggleSwitchEnablePalmEraser != null) + ToggleSwitchEnablePalmEraser.IsOn = true; + } + // 恢复到之前的编辑状态 inkCanvas.EditingMode = currentEditingMode; drawingShapeMode = currentDrawingShapeMode; diff --git a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs index 1b399479..dc70ea42 100644 --- a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs +++ b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs @@ -44,6 +44,9 @@ namespace Ink_Canvas /// 多点触控延迟时间(毫秒) /// private const double MULTI_TOUCH_DELAY_MS = 100; + private bool isMultiTouchTimerActive; + private bool isPalmEraserActive; + private bool palmEraserWasEnabledBeforeMultiTouch; /// /// 保存画布上的非笔画元素(如图片、媒体元素等) @@ -227,6 +230,12 @@ namespace Ink_Canvas RestoreNonStrokeElements(preservedElements); isInMultiTouchMode = false; + if (palmEraserWasEnabledBeforeMultiTouch) + { + Settings.Canvas.EnablePalmEraser = true; + if (ToggleSwitchEnablePalmEraser != null) + ToggleSwitchEnablePalmEraser.IsOn = true; + } } else { @@ -247,6 +256,11 @@ namespace Ink_Canvas // 恢复非笔画元素 RestoreNonStrokeElements(preservedElements); isInMultiTouchMode = true; + + palmEraserWasEnabledBeforeMultiTouch = Settings.Canvas.EnablePalmEraser; + Settings.Canvas.EnablePalmEraser = false; + if (ToggleSwitchEnablePalmEraser != null) + ToggleSwitchEnablePalmEraser.IsOn = false; } } @@ -721,21 +735,13 @@ namespace Ink_Canvas /// 触摸事件参数 /// 返回触摸边界宽度 /// - /// 根据触摸事件参数计算触摸边界宽度,包括以下逻辑: - /// 1. 获取触摸点的边界 - /// 2. 如果不是四边红外屏幕,使用边界宽度 - /// 3. 如果是四边红外屏幕,使用边界宽度和高度的平方根 - /// 4. 如果是特殊屏幕,乘以触摸倍数 - /// 5. 返回计算得到的触摸边界宽度 + /// 手掌擦阈值与特殊屏 TouchMultiplier 在激活逻辑中单独参与计算,此处仅返回几何接触尺寸。 /// public double GetTouchBoundWidth(TouchEventArgs e) { var args = e.GetTouchPoint(null).Bounds; - double value; - if (!Settings.Advanced.IsQuadIR) value = args.Width; - else value = Math.Sqrt(args.Width * args.Height); //四边红外 - if (Settings.Advanced.IsSpecialScreen) value *= Settings.Advanced.TouchMultiplier; - return value; + if (!Settings.Advanced.IsQuadIR) return args.Width; + return Math.Sqrt(args.Width * args.Height); } /// @@ -759,28 +765,146 @@ namespace Ink_Canvas /// private void InkCanvas_PreviewTouchDown(object sender, TouchEventArgs e) { + var touchPointForBar = e.GetTouchPoint(this); + var floatingBarBounds = ViewboxFloatingBar.TransformToAncestor(this).TransformBounds( + new Rect(0, 0, ViewboxFloatingBar.ActualWidth, ViewboxFloatingBar.ActualHeight)); + if (floatingBarBounds.Contains(touchPointForBar.Position)) + return; + + if ((inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint + || inkCanvas.EditingMode == InkCanvasEditingMode.EraseByStroke) + && !isPalmEraserActive) + { + return; + } + + if (drawingShapeMode != 0) + { + inkCanvas.EditingMode = InkCanvasEditingMode.None; + SetCursorBasedOnEditingMode(inkCanvas); + inkCanvas.CaptureTouch(e.TouchDevice); + ViewboxFloatingBar.IsHitTestVisible = false; + BlackboardUIGridForInkReplay.IsHitTestVisible = false; + + isTouchDown = true; + + if (dec.Count == 0) + { + var inkTouchPoint = e.GetTouchPoint(inkCanvas); + if (drawingShapeMode == 24 || drawingShapeMode == 25) + { + if (drawMultiStepShapeCurrentStep == 0) + iniP = inkTouchPoint.Position; + } + else + { + iniP = inkTouchPoint.Position; + } + lastTouchDownStrokeCollection = inkCanvas.Strokes.Clone(); + } + dec.Add(e.TouchDevice.Id); + return; + } + + SetCursorBasedOnEditingMode(inkCanvas); inkCanvas.CaptureTouch(e.TouchDevice); ViewboxFloatingBar.IsHitTestVisible = false; BlackboardUIGridForInkReplay.IsHitTestVisible = false; - + lastTouchDownTime = DateTime.Now; dec.Add(e.TouchDevice.Id); - //设备1个的时候,记录中心点 + + if (Settings.Canvas.EnablePalmEraser && !isPalmEraserActive && drawingShapeMode == 0) + { + var touchPoint = e.GetTouchPoint(inkCanvas); + double boundWidth = GetTouchBoundWidth(e); + + if ((Settings.Advanced.TouchMultiplier != 0 || !Settings.Advanced.IsSpecialScreen) + && (boundWidth > BoundsWidth)) + { + double thresholdMultiplier; + switch (Settings.Canvas.PalmEraserSensitivity) + { + case 0: + thresholdMultiplier = 3.0; + break; + case 1: + thresholdMultiplier = 2.5; + break; + case 2: + default: + thresholdMultiplier = 2.0; + break; + } + + double EraserThresholdValue = Settings.Startup.IsEnableNibMode + ? Settings.Advanced.NibModeBoundsWidthThresholdValue + : Settings.Advanced.FingerModeBoundsWidthThresholdValue; + + if (boundWidth > BoundsWidth * EraserThresholdValue * thresholdMultiplier) + { + boundWidth *= Settings.Startup.IsEnableNibMode + ? Settings.Advanced.NibModeBoundsWidthEraserSize + : Settings.Advanced.FingerModeBoundsWidthEraserSize; + + if (Settings.Advanced.IsSpecialScreen) + boundWidth *= Settings.Advanced.TouchMultiplier; + inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint; + isPalmEraserActive = true; + + EnableEraserOverlay(); + eraserWidth = boundWidth; + UpdateEraserStyle(); + touchPoint = e.GetTouchPoint(inkCanvas); + EraserOverlay_PointerDown(sender); + EraserOverlay_PointerMove(sender, touchPoint.Position); + if (Settings.Canvas.IsShowCursor) + { + inkCanvas.ForceCursor = false; + inkCanvas.UseCustomCursor = false; + } + } + } + } + if (dec.Count == 1) { var touchPoint = e.GetTouchPoint(inkCanvas); centerPoint = touchPoint.Position; - - //记录第一根手指点击时的 StrokeCollection lastTouchDownStrokeCollection = inkCanvas.Strokes.Clone(); } - //设备两个及两个以上,将画笔功能关闭 + if (dec.Count > 1 || isSingleFingerDragMode || !Settings.Gesture.IsEnableTwoFingerGesture) { if (isInMultiTouchMode || !Settings.Gesture.IsEnableTwoFingerGesture) return; if (inkCanvas.EditingMode == InkCanvasEditingMode.None || inkCanvas.EditingMode == InkCanvasEditingMode.Select) return; + var timeSinceLastTouch = (DateTime.Now - lastTouchDownTime).TotalMilliseconds; + if (timeSinceLastTouch < MULTI_TOUCH_DELAY_MS && inkCanvas.EditingMode == InkCanvasEditingMode.Ink) + { + if (!isMultiTouchTimerActive) + { + isMultiTouchTimerActive = true; + var remainingTime = MULTI_TOUCH_DELAY_MS - timeSinceLastTouch; + Task.Delay((int)remainingTime).ContinueWith(_ => + { + Dispatcher.Invoke(() => + { + if (dec.Count > 1 && inkCanvas.EditingMode == InkCanvasEditingMode.Ink) + inkCanvas.EditingMode = InkCanvasEditingMode.None; + isMultiTouchTimerActive = false; + }); + }); + } + return; + } + lastInkCanvasEditingMode = inkCanvas.EditingMode; - inkCanvas.EditingMode = InkCanvasEditingMode.None; + if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint + && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByStroke + && drawingShapeMode == 0) + { + inkCanvas.EditingMode = InkCanvasEditingMode.None; + } } } @@ -794,6 +918,11 @@ namespace Ink_Canvas /// private void InkCanvas_PreviewTouchMove(object sender, TouchEventArgs e) { + if (isPalmEraserActive) + { + var touchPoint = e.GetTouchPoint(inkCanvas); + EraserOverlay_PointerMove(sender, touchPoint.Position); + } } /// @@ -820,32 +949,18 @@ namespace Ink_Canvas /// private void InkCanvas_PreviewTouchUp(object sender, TouchEventArgs e) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint && !isPalmEraserActive) + { + return; + } inkCanvas.ReleaseAllTouchCaptures(); ViewboxFloatingBar.IsHitTestVisible = true; BlackboardUIGridForInkReplay.IsHitTestVisible = true; - //手势完成后切回之前的状态 - if (dec.Count > 1) - if (inkCanvas.EditingMode == InkCanvasEditingMode.None) - inkCanvas.EditingMode = lastInkCanvasEditingMode; dec.Remove(e.TouchDevice.Id); - if (dec.Count == 0) - { - isSingleFingerDragMode = false; - isWaitUntilNextTouchDown = false; - if (drawingShapeMode == 0 - && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint - && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByStroke - && inkCanvas.EditingMode != InkCanvasEditingMode.Select - && inkCanvas.EditingMode != InkCanvasEditingMode.None) - { - if (lastInkCanvasEditingMode != InkCanvasEditingMode.None) - { - inkCanvas.EditingMode = lastInkCanvasEditingMode; - } - } - } + if (dec.Count <= 1) + isMultiTouchTimerActive = false; if (drawingShapeMode != 0) { @@ -857,12 +972,10 @@ namespace Ink_Canvas { if (drawMultiStepShapeCurrentStep == 0) { - // 第一笔完成,进入第二笔 drawMultiStepShapeCurrentStep = 1; } else { - // 第二笔完成,完成绘制 var mouseArgs = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left) { RoutedEvent = MouseLeftButtonUpEvent, @@ -882,6 +995,36 @@ namespace Ink_Canvas } } + if (drawingShapeMode == 0) + { + if (dec.Count > 1) + { + if (inkCanvas.EditingMode == InkCanvasEditingMode.None) + { + if (lastInkCanvasEditingMode != InkCanvasEditingMode.EraseByPoint) + inkCanvas.EditingMode = lastInkCanvasEditingMode; + } + } + else if (dec.Count == 0) + { + isSingleFingerDragMode = false; + isWaitUntilNextTouchDown = false; + + if (inkCanvas.EditingMode == InkCanvasEditingMode.None && + lastInkCanvasEditingMode != InkCanvasEditingMode.None && + lastInkCanvasEditingMode != InkCanvasEditingMode.EraseByPoint) + { + inkCanvas.EditingMode = lastInkCanvasEditingMode; + } + + if (isPalmEraserActive) + { + isPalmEraserActive = false; + DisableEraserOverlay(); + } + } + } + inkCanvas.Opacity = 1; if (dec.Count == 0) @@ -979,6 +1122,9 @@ namespace Ink_Canvas /// private void Main_Grid_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) { + if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint) + return; + if (isInMultiTouchMode || !Settings.Gesture.IsEnableTwoFingerGesture) return; bool hasMultipleManipulators = e.Manipulators.Count() >= 2; From 6ca1c598d4b57bcfc85d282ef1cd232a27f5d3a5 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 5 Apr 2026 21:08:38 +0800 Subject: [PATCH 3/7] improve:UI --- Ink Canvas/Properties/Strings.en-US.resx | 2 +- Ink Canvas/Properties/Strings.resx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Ink Canvas/Properties/Strings.en-US.resx b/Ink Canvas/Properties/Strings.en-US.resx index 50a63586..36ee52db 100644 --- a/Ink Canvas/Properties/Strings.en-US.resx +++ b/Ink Canvas/Properties/Strings.en-US.resx @@ -1258,7 +1258,7 @@ Exit slide show - Show + Annotation bar Exit diff --git a/Ink Canvas/Properties/Strings.resx b/Ink Canvas/Properties/Strings.resx index 5a21029f..483d13e0 100644 --- a/Ink Canvas/Properties/Strings.resx +++ b/Ink Canvas/Properties/Strings.resx @@ -1301,7 +1301,7 @@ 退出放映 - 显示 + 批注栏 退出 From 8c090218d1aa1ebe534c3910795109f1941e2220 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 5 Apr 2026 21:19:19 +0800 Subject: [PATCH 4/7] =?UTF-8?q?improve:=E6=96=B0=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/Windows/SettingsViews2/SettingsWindow2.xaml.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Ink Canvas/Windows/SettingsViews2/SettingsWindow2.xaml.cs b/Ink Canvas/Windows/SettingsViews2/SettingsWindow2.xaml.cs index 273c3583..8bc43268 100644 --- a/Ink Canvas/Windows/SettingsViews2/SettingsWindow2.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews2/SettingsWindow2.xaml.cs @@ -200,13 +200,17 @@ namespace Ink_Canvas.Windows.SettingsViews2 { // 插件加载失败不影响主程序运行,仅输出调试日志 System.Diagnostics.Debug.WriteLine($"插件加载失败: {ex.Message}"); + _pluginPages = Array.Empty(); } + + if (_pluginPages == null) + _pluginPages = Array.Empty(); } private void InitializeNavigationMenu() { // 自动将插件页面添加到导航菜单 - foreach (var pluginPage in _pluginPages) + foreach (var pluginPage in _pluginPages ?? Enumerable.Empty()) { var navItem = new NavigationViewItem { From 243201502ba263beb10d066b8f6f3d4316a72f87 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 5 Apr 2026 21:32:01 +0800 Subject: [PATCH 5/7] add:issue #402 --- Ink Canvas/Helpers/GlobalHotkeyManager.cs | 12 ++++++++++++ Ink Canvas/MainWindow.xaml.cs | 16 ++++++++++++++++ Ink Canvas/Windows/HotkeySettingsWindow.xaml | 5 +++++ Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs | 8 ++++++++ 4 files changed, 41 insertions(+) diff --git a/Ink Canvas/Helpers/GlobalHotkeyManager.cs b/Ink Canvas/Helpers/GlobalHotkeyManager.cs index e9bfcd97..e0516650 100644 --- a/Ink Canvas/Helpers/GlobalHotkeyManager.cs +++ b/Ink Canvas/Helpers/GlobalHotkeyManager.cs @@ -285,6 +285,7 @@ namespace Ink_Canvas.Helpers // 功能快捷键 RegisterHotkey("DrawLine", Key.L, ModifierKeys.Alt, () => _mainWindow.BtnDrawLine_Click(null, null)); RegisterHotkey("Screenshot", Key.C, ModifierKeys.Alt, () => _mainWindow.SaveScreenShotToDesktop()); + RegisterHotkey("QuickDraw", Key.K, ModifierKeys.Alt, () => _mainWindow.OpenQuickDrawFromHotkey()); RegisterHotkey("Hide", Key.V, ModifierKeys.Alt, () => _mainWindow.SymbolIconEmoji_MouseUp(null, null)); // 退出快捷键 @@ -1033,6 +1034,7 @@ namespace Ink_Canvas.Helpers new HotkeyConfigItem { Name = "Pen5", Key = Key.D5, Modifiers = ModifierKeys.Alt }, new HotkeyConfigItem { Name = "DrawLine", Key = Key.L, Modifiers = ModifierKeys.Alt }, new HotkeyConfigItem { Name = "Screenshot", Key = Key.C, Modifiers = ModifierKeys.Alt }, + new HotkeyConfigItem { Name = "QuickDraw", Key = Key.K, Modifiers = ModifierKeys.Alt }, new HotkeyConfigItem { Name = "Hide", Key = Key.V, Modifiers = ModifierKeys.Alt }, new HotkeyConfigItem { Name = "Exit", Key = Key.Escape, Modifiers = ModifierKeys.None } }); @@ -1111,6 +1113,14 @@ namespace Ink_Canvas.Helpers } } + // 旧版 HotkeyConfig.json 无「快抽」项时补注册默认组合,避免升级后无快捷键 + if (successCount > 0 && !IsHotkeyRegistered("QuickDraw")) + { + var quickDrawAction = GetActionByName("QuickDraw"); + if (quickDrawAction != null && RegisterHotkey("QuickDraw", Key.K, ModifierKeys.Alt, quickDrawAction)) + successCount++; + } + if (successCount > 0) { _hotkeysShouldBeRegistered = true; @@ -1221,6 +1231,8 @@ namespace Ink_Canvas.Helpers return () => _mainWindow.BtnDrawLine_Click(null, null); case "Screenshot": return () => _mainWindow.SaveScreenShotToDesktop(); + case "QuickDraw": + return () => _mainWindow.OpenQuickDrawFromHotkey(); case "Hide": return () => _mainWindow.SymbolIconEmoji_MouseUp(null, null); case "Exit": diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs index da7c2853..4b5a2e7c 100644 --- a/Ink Canvas/MainWindow.xaml.cs +++ b/Ink Canvas/MainWindow.xaml.cs @@ -4711,6 +4711,22 @@ namespace Ink_Canvas } } + internal void OpenQuickDrawFromHotkey() + { + try + { + if (Settings?.RandSettings?.EnableQuickDraw != true) + return; + + var quickDrawWindow = new QuickDrawWindow(); + quickDrawWindow.ShowDialog(); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"打开快抽窗口失败: {ex.Message}", LogHelper.LogType.Error); + } + } + /// /// 显示快抽悬浮按钮 /// diff --git a/Ink Canvas/Windows/HotkeySettingsWindow.xaml b/Ink Canvas/Windows/HotkeySettingsWindow.xaml index 60928011..249de7b1 100644 --- a/Ink Canvas/Windows/HotkeySettingsWindow.xaml +++ b/Ink Canvas/Windows/HotkeySettingsWindow.xaml @@ -177,6 +177,11 @@ Description="保存屏幕截图到桌面" DefaultKey="C" DefaultModifiers="Alt"/> + _mainWindow.BtnDrawLine_Click(null, null); case "Screenshot": return () => _mainWindow.SaveScreenShotToDesktop(); + case "QuickDraw": + return () => _mainWindow.OpenQuickDrawFromHotkey(); case "Hide": return () => _mainWindow.SymbolIconEmoji_MouseUp(null, null); case "Exit": From f280358f56be9ca7060dcb1da4e0b555ef740e56 Mon Sep 17 00:00:00 2001 From: PrefacedCorg <1876568293@qq.com> Date: Sun, 5 Apr 2026 21:35:40 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E6=97=A7=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SettingsViews2/SettingsWindow2.xaml.cs | 76 +------------------ 1 file changed, 1 insertion(+), 75 deletions(-) diff --git a/Ink Canvas/Windows/SettingsViews2/SettingsWindow2.xaml.cs b/Ink Canvas/Windows/SettingsViews2/SettingsWindow2.xaml.cs index 8bc43268..703200cf 100644 --- a/Ink Canvas/Windows/SettingsViews2/SettingsWindow2.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews2/SettingsWindow2.xaml.cs @@ -6,32 +6,17 @@ using System.Windows; using System.Windows.Navigation; using System.Windows.Interop; using System.Windows.Input; -using System.ComponentModel.Composition; -using System.ComponentModel.Composition.Hosting; using System.Linq; using MessageBox = System.Windows.MessageBox; using Screen = System.Windows.Forms.Screen; namespace Ink_Canvas.Windows.SettingsViews2 { - // 插件设置页面契约接口,所有插件必须实现此接口即可自动接入 - public interface IPluginSettingsPage - { - string PageTag { get; } // 页面唯一标识,不可与内置页面重复 - string PageTitle { get; } // 导航菜单显示的标题 - string PageIconCode { get; } // Segoe MDL2 Assets 图标字符,例:"\xE713"(设置图标) - Type PageType { get; } // 插件设置页面的类型(继承自Page) - bool IsFooterItem { get; } // 是否放在导航底部菜单 - } - public partial class SettingsWindow2 : Window { private readonly Dictionary _pageTypes; private readonly Dictionary _pages = new Dictionary(); - [ImportMany(typeof(IPluginSettingsPage))] - private IEnumerable _pluginPages; // 自动导入所有插件页面 - // 保存窗口原始位置和大小 private double _originalLeft; private double _originalTop; @@ -63,11 +48,6 @@ namespace Ink_Canvas.Windows.SettingsViews2 { "Settings", typeof(SettingsPage) } }; - // 加载插件页面 - LoadPluginSettingsPages(); - // 初始化导航菜单(内置+插件) - InitializeNavigationMenu(); - // 默认选中首页 if (NavigationViewControl.MenuItems.Count > 0) { @@ -177,60 +157,6 @@ namespace Ink_Canvas.Windows.SettingsViews2 private static extern int ShowCursor(bool bShow); #endregion - #region 插件化动态设置页面核心逻辑 - private void LoadPluginSettingsPages() - { - try - { - // 扫描程序目录下Plugins文件夹中的插件dll - var pluginCatalog = new DirectoryCatalog("./Plugins", "*.dll"); - var container = new CompositionContainer(pluginCatalog); - container.ComposeParts(this); - - // 将插件页面注册到页面映射字典 - foreach (var pluginPage in _pluginPages) - { - if (!_pageTypes.ContainsKey(pluginPage.PageTag)) - { - _pageTypes.Add(pluginPage.PageTag, pluginPage.PageType); - } - } - } - catch (Exception ex) - { - // 插件加载失败不影响主程序运行,仅输出调试日志 - System.Diagnostics.Debug.WriteLine($"插件加载失败: {ex.Message}"); - _pluginPages = Array.Empty(); - } - - if (_pluginPages == null) - _pluginPages = Array.Empty(); - } - - private void InitializeNavigationMenu() - { - // 自动将插件页面添加到导航菜单 - foreach (var pluginPage in _pluginPages ?? Enumerable.Empty()) - { - var navItem = new NavigationViewItem - { - Tag = pluginPage.PageTag, - Content = pluginPage.PageTitle, - Icon = new FontIcon { Glyph = pluginPage.PageIconCode } - }; - - if (pluginPage.IsFooterItem) - { - NavigationViewControl.FooterMenuItems.Add(navItem); - } - else - { - NavigationViewControl.MenuItems.Add(navItem); - } - } - } - #endregion - #region 高DPI/多屏自适应窗口控制 /// @@ -505,7 +431,7 @@ namespace Ink_Canvas.Windows.SettingsViews2 sender.ItemsSource = suggestions; } - // 统一获取所有导航项(主菜单+子菜单+底部菜单+插件页面) + // 统一获取所有导航项(主菜单+子菜单+底部菜单) private List GetAllNavigationItems() { var items = new List(); From 74344c4782132c92b427450e7f8180605ef45136 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 5 Apr 2026 21:35:43 +0800 Subject: [PATCH 7/7] improve:issue #423 --- Ink Canvas/Windows/OperatingGuideWindow.xaml | 291 ++++++++++++------ .../Windows/OperatingGuideWindow.xaml.cs | 26 +- 2 files changed, 205 insertions(+), 112 deletions(-) diff --git a/Ink Canvas/Windows/OperatingGuideWindow.xaml b/Ink Canvas/Windows/OperatingGuideWindow.xaml index c911ada8..e2628752 100644 --- a/Ink Canvas/Windows/OperatingGuideWindow.xaml +++ b/Ink Canvas/Windows/OperatingGuideWindow.xaml @@ -3,99 +3,216 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:local="clr-namespace:Ink_Canvas" xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern" xmlns:ikw="http://schemas.inkore.net/lib/ui/wpf" - ui:ThemeManager.RequestedTheme="Light" Topmost="True" Background="Transparent" - mc:Ignorable="d" WindowStyle="None" AllowsTransparency="True" - WindowStartupLocation="CenterScreen" + mc:Ignorable="d" Title="Ink Canvas Annotation 使用指南" - Height="600" Width="500"> - - - - - - - - + Height="600" + Width="520" + MinHeight="400" + MinWidth="400" + WindowStartupLocation="CenterScreen" + Topmost="True" + ResizeMode="CanResize" + FontFamily="Microsoft YaHei UI" + ui:ThemeManager.IsThemeAware="True" + ui:TitleBar.ExtendViewIntoTitleBar="True" + ui:WindowHelper.SystemBackdropType="Mica" + ui:WindowHelper.UseModernWindowStyle="True" + ui:TitleBar.Height="48"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + diff --git a/Ink Canvas/Windows/OperatingGuideWindow.xaml.cs b/Ink Canvas/Windows/OperatingGuideWindow.xaml.cs index 823151bb..f65be003 100644 --- a/Ink Canvas/Windows/OperatingGuideWindow.xaml.cs +++ b/Ink Canvas/Windows/OperatingGuideWindow.xaml.cs @@ -1,6 +1,5 @@ using Ink_Canvas.Helpers; using iNKORE.UI.WPF.Modern; -using iNKORE.UI.WPF.Modern.Common.IconKeys; using System; using System.Windows; using System.Windows.Input; @@ -15,33 +14,10 @@ namespace Ink_Canvas public OperatingGuideWindow() { InitializeComponent(); + RefreshTheme(); AnimationsHelper.ShowWithSlideFromBottomAndFade(this, 0.25); } - private void BtnClose_MouseUp(object sender, MouseButtonEventArgs e) - { - Close(); - } - - private void WindowDragMove(object sender, MouseEventArgs e) - { - if (e.LeftButton == MouseButtonState.Pressed) DragMove(); - } - - private void BtnFullscreen_MouseUp(object sender, MouseButtonEventArgs e) - { - if (WindowState == WindowState.Normal) - { - WindowState = WindowState.Maximized; - FontIconFullscreen.Icon = SegoeFluentIcons.BackToWindow; - } - else - { - WindowState = WindowState.Normal; - FontIconFullscreen.Icon = SegoeFluentIcons.FullScreen; - } - } - private void SCManipulationBoundaryFeedback(object sender, ManipulationBoundaryFeedbackEventArgs e) { e.Handled = true;