From 649a939a576a4d90cc8add080c7bcc8df7ba816a Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Thu, 30 Apr 2026 17:51:43 +0800 Subject: [PATCH] =?UTF-8?q?improve:=E5=AE=9E=E6=97=B6=E7=AC=94=E9=94=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MainWindow_cs/MW_FloatingBarIcons.cs | 9 +- .../MW_SimulatePressure&InkToShape.cs | 79 ++++++++++------ Ink Canvas/MainWindow_cs/MW_TouchEvents.cs | 92 ++++++++++++++++--- 3 files changed, 135 insertions(+), 45 deletions(-) diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index fd295a62..c8fe6b0a 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -2244,9 +2244,14 @@ namespace Ink_Canvas SetFloatingBarHighlightPosition("pen"); - // 记录当前是否已经是批注模式且是否为高光显示模式 + bool isRealtimePenState = inkCanvas.EditingMode == InkCanvasEditingMode.None + && ShouldUseRealtimeVelocityBrushTip() + && string.Equals(GetCurrentSelectedMode(), "pen", StringComparison.OrdinalIgnoreCase); bool wasInInkMode = inkCanvas.EditingMode == InkCanvasEditingMode.Ink - || (Pen_Icon.Background != null && StackPanelCanvasControls.Visibility == Visibility.Visible); + || isRealtimePenState + || (Pen_Icon.Background != null + && StackPanelCanvasControls.Visibility == Visibility.Visible + && string.Equals(GetCurrentSelectedMode(), "pen", StringComparison.OrdinalIgnoreCase)); bool wasHighlighter = drawingAttributes.IsHighlighter; if (drawingShapeMode != 0 && !isLongPressSelected) diff --git a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs index 0b37b0bf..5b1ad744 100644 --- a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs +++ b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs @@ -571,11 +571,7 @@ namespace Ink_Canvas straightStroke.AddPropertyData(Helpers.ModernInkAnalyzer.ShapeStrokePropertyGuid, true); // Replace the original stroke with the straightened one - SetNewBackupOfStroke(); - _currentCommitType = CommitReason.ShapeRecognition; - inkCanvas.Strokes.Remove(e.Stroke); - inkCanvas.Strokes.Add(straightStroke); - _currentCommitType = CommitReason.UserInput; + ReplaceStrokesSafely(null, straightStroke, e.Stroke); straightStrokeForHandwritingKey = straightStroke; @@ -703,11 +699,7 @@ namespace Ink_Canvas }; stroke.AddPropertyData(Helpers.ModernInkAnalyzer.ShapeStrokePropertyGuid, true); circles.Add(new Circle(result.Centroid, result.ShapeWidth / 2.0, stroke)); - SetNewBackupOfStroke(); - _currentCommitType = CommitReason.ShapeRecognition; - inkCanvas.Strokes.Remove(result.StrokesToRemove); - inkCanvas.Strokes.Add(stroke); - _currentCommitType = CommitReason.UserInput; + ReplaceStrokesSafely(result.StrokesToRemove, stroke, e.Stroke); newStrokes = new StrokeCollection(); } } @@ -794,9 +786,6 @@ namespace Ink_Canvas var topB = endP.Y - iniP.Y; - SetNewBackupOfStroke(); - _currentCommitType = CommitReason.ShapeRecognition; - inkCanvas.Strokes.Remove(result.StrokesToRemove); newStrokes = new StrokeCollection(); var _pointList = GenerateEllipseGeometry(iniP, endP, false); @@ -812,8 +801,7 @@ namespace Ink_Canvas _stroke, _dashedLineStroke }; - inkCanvas.Strokes.Add(strokes); - _currentCommitType = CommitReason.UserInput; + ReplaceStrokesSafely(result.StrokesToRemove, strokes, e.Stroke); return; } } @@ -863,11 +851,7 @@ namespace Ink_Canvas stroke.Transform(m, false); } - SetNewBackupOfStroke(); - _currentCommitType = CommitReason.ShapeRecognition; - inkCanvas.Strokes.Remove(result.StrokesToRemove); - inkCanvas.Strokes.Add(stroke); - _currentCommitType = CommitReason.UserInput; + ReplaceStrokesSafely(result.StrokesToRemove, stroke, e.Stroke); GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; newStrokes = new StrokeCollection(); } @@ -901,11 +885,7 @@ namespace Ink_Canvas DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; stroke.AddPropertyData(Helpers.ModernInkAnalyzer.ShapeStrokePropertyGuid, true); - SetNewBackupOfStroke(); - _currentCommitType = CommitReason.ShapeRecognition; - inkCanvas.Strokes.Remove(result.StrokesToRemove); - inkCanvas.Strokes.Add(stroke); - _currentCommitType = CommitReason.UserInput; + ReplaceStrokesSafely(result.StrokesToRemove, stroke, e.Stroke); GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; newStrokes = new StrokeCollection(); } @@ -947,11 +927,7 @@ namespace Ink_Canvas DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() }; stroke.AddPropertyData(Helpers.ModernInkAnalyzer.ShapeStrokePropertyGuid, true); - SetNewBackupOfStroke(); - _currentCommitType = CommitReason.ShapeRecognition; - inkCanvas.Strokes.Remove(result.StrokesToRemove); - inkCanvas.Strokes.Add(stroke); - _currentCommitType = CommitReason.UserInput; + ReplaceStrokesSafely(result.StrokesToRemove, stroke, e.Stroke); GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; newStrokes = new StrokeCollection(); } @@ -2224,6 +2200,49 @@ namespace Ink_Canvas return true; } + private void ReplaceStrokesSafely(StrokeCollection strokesToRemove, Stroke replacementStroke, Stroke fallbackOriginalStroke = null) + { + if (replacementStroke == null) return; + try + { + SetNewBackupOfStroke(); + _currentCommitType = CommitReason.ShapeRecognition; + + if (strokesToRemove != null && strokesToRemove.Count > 0) + inkCanvas.Strokes.Remove(strokesToRemove); + if (fallbackOriginalStroke != null && inkCanvas.Strokes.Contains(fallbackOriginalStroke)) + inkCanvas.Strokes.Remove(fallbackOriginalStroke); + + if (!inkCanvas.Strokes.Contains(replacementStroke)) + inkCanvas.Strokes.Add(replacementStroke); + } + finally + { + _currentCommitType = CommitReason.UserInput; + } + } + + private void ReplaceStrokesSafely(StrokeCollection strokesToRemove, StrokeCollection replacementStrokes, Stroke fallbackOriginalStroke = null) + { + if (replacementStrokes == null || replacementStrokes.Count == 0) return; + try + { + SetNewBackupOfStroke(); + _currentCommitType = CommitReason.ShapeRecognition; + + if (strokesToRemove != null && strokesToRemove.Count > 0) + inkCanvas.Strokes.Remove(strokesToRemove); + if (fallbackOriginalStroke != null && inkCanvas.Strokes.Contains(fallbackOriginalStroke)) + inkCanvas.Strokes.Remove(fallbackOriginalStroke); + + inkCanvas.Strokes.Add(replacementStrokes); + } + finally + { + _currentCommitType = CommitReason.UserInput; + } + } + /// /// 将沿线速度映射为压感并与硬件压感混合,快写略细、慢写略粗;在落笔时(及手写笔移动时由调用方)统一施加。 /// 无压感设备上系统可能将 置为 true,此处强制关闭以便粗细随合成压感变化。 diff --git a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs index 5d98e354..ba37a2fb 100644 --- a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs +++ b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs @@ -52,6 +52,7 @@ namespace Ink_Canvas private readonly Guid RealtimeVelocityBrushTipAppliedGuid = new Guid("74E57D95-945F-4A8C-B52A-7D3EF2D4FD5B"); internal const int MouseRealtimeStrokeId = -100001; private readonly HashSet _activeRealtimeTouchStrokeIds = new HashSet(); + private readonly HashSet _activeTouchStrokeIds = new HashSet(); private sealed class OneEuroFilter { @@ -1202,6 +1203,28 @@ namespace Ink_Canvas return; } + if ((isInMultiTouchMode || Settings.Gesture.IsEnableMultiTouchMode) + && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint + && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByStroke + && inkCanvas.EditingMode != InkCanvasEditingMode.Select) + { + try + { + inkCanvas.EditingMode = InkCanvasEditingMode.None; + var touchId = e.TouchDevice.Id; + var p = e.GetTouchPoint(inkCanvas).Position; + _activeTouchStrokeIds.Add(touchId); + var sv = GetStrokeVisual(touchId); + sv.Add(new StylusPoint(p.X, p.Y, 0.5f)); + sv.Redraw(); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine(ex); + } + return; + } + if (Settings.Canvas.EnablePalmEraser && !isPalmEraserActive && drawingShapeMode == 0) { var touchPoint = e.GetTouchPoint(inkCanvas); @@ -1314,23 +1337,38 @@ namespace Ink_Canvas EraserOverlay_PointerMove(sender, touchPoint.Position); } - if (!ShouldUseRealtimeVelocityBrushTipForTouch()) - return; - var touchId = e.TouchDevice.Id; - if (!_activeRealtimeTouchStrokeIds.Contains(touchId)) + if (ShouldUseRealtimeVelocityBrushTipForTouch()) + { + if (!_activeRealtimeTouchStrokeIds.Contains(touchId)) + return; + try + { + var p = e.GetTouchPoint(inkCanvas).Position; + var sv = GetStrokeVisual(touchId); + if (TryAppendRealtimeVelocityBrushTipPoint(sv, touchId, p)) + sv.ForceRedraw(); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine(ex); + } return; - - try - { - var p = e.GetTouchPoint(inkCanvas).Position; - var sv = GetStrokeVisual(touchId); - if (TryAppendRealtimeVelocityBrushTipPoint(sv, touchId, p)) - sv.ForceRedraw(); } - catch (Exception ex) + + if (_activeTouchStrokeIds.Contains(touchId)) { - System.Diagnostics.Debug.WriteLine(ex); + try + { + var p = e.GetTouchPoint(inkCanvas).Position; + var sv = GetStrokeVisual(touchId); + sv.Add(new StylusPoint(p.X, p.Y, 0.5f)); + sv.Redraw(); + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine(ex); + } } } @@ -1389,6 +1427,34 @@ namespace Ink_Canvas _activeRealtimeTouchStrokeIds.Remove(touchId); } } + else if (_activeTouchStrokeIds.Contains(touchId)) + { + try + { + var sv = GetStrokeVisual(touchId); + sv?.Redraw(); + var stroke = sv?.Stroke; + if (stroke != null) + { + inkCanvas.Strokes.Add(stroke); + inkCanvas_StrokeCollected(inkCanvas, new InkCanvasStrokeCollectedEventArgs(stroke)); + } + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine(ex); + } + finally + { + if (VisualCanvasList.TryGetValue(touchId, out var visualCanvas) && inkCanvas.Children.Contains(visualCanvas)) + inkCanvas.Children.Remove(visualCanvas); + StrokeVisualList.Remove(touchId); + VisualCanvasList.Remove(touchId); + TouchDownPointsList.Remove(touchId); + CleanupRealtimeBrushTipState(touchId); + _activeTouchStrokeIds.Remove(touchId); + } + } if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint && !isPalmEraserActive) {