From 7095a5890c6ced6f5875997958f2d385689e0d50 Mon Sep 17 00:00:00 2001
From: CJKmkp <2564608840@qq.com>
Date: Sat, 30 Aug 2025 14:53:50 +0800
Subject: [PATCH] fix:issue #133
---
Ink Canvas/MainWindow.xaml | 15 +-
Ink Canvas/MainWindow_cs/MW_Settings.cs | 6 +
Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs | 1 +
Ink Canvas/MainWindow_cs/MW_TouchEvents.cs | 155 +++++++++++++-----
Ink Canvas/Resources/Settings.cs | 2 +
5 files changed, 135 insertions(+), 44 deletions(-)
diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml
index 4013c6ab..1a087381 100644
--- a/Ink Canvas/MainWindow.xaml
+++ b/Ink Canvas/MainWindow.xaml
@@ -841,7 +841,20 @@
IsOn="False" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
Toggled="ToggleSwitchEnablePalmEraser_Toggled" />
-
+
+
+
+
+
+
+
+
+
+
diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs
index 017cc6fd..9d7ca62a 100644
--- a/Ink Canvas/MainWindow_cs/MW_Settings.cs
+++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs
@@ -3034,6 +3034,12 @@ namespace Ink_Canvas
#endregion
+ private void ComboBoxPalmEraserSensitivity_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (!isLoaded) return;
+ Settings.Canvas.PalmEraserSensitivity = ComboBoxPalmEraserSensitivity.SelectedIndex;
+ SaveSettingsToFile();
+ }
}
}
diff --git a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
index 439fd7e5..a423b3c2 100644
--- a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
+++ b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
@@ -683,6 +683,7 @@ namespace Ink_Canvas
if (Settings.Canvas != null)
{
ToggleSwitchEnablePalmEraser.IsOn = Settings.Canvas.EnablePalmEraser;
+ ComboBoxPalmEraserSensitivity.SelectedIndex = Settings.Canvas.PalmEraserSensitivity;
}
// Advanced
diff --git a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs
index 92129d26..f3adbf3a 100644
--- a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs
+++ b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs
@@ -365,8 +365,9 @@ namespace Ink_Canvas
private bool palmEraserWasEnabledBeforeMultiTouch;
private bool palmEraserTouchDownHandled = false; // 新增:标记手掌擦触摸按下是否已处理
private DateTime palmEraserActivationTime; // 新增:记录手掌擦激活时间
- private const int PALM_ERASER_TIMEOUT_MS = 5000; // 新增:手掌擦超时时间(5秒)
+ private const int PALM_ERASER_TIMEOUT_MS = 3000; // 修改:减少手掌擦超时时间(3秒)
private System.Windows.Threading.DispatcherTimer palmEraserRecoveryTimer; // 新增:手掌擦恢复定时器
+ private HashSet palmEraserTouchIds = new HashSet(); // 新增:记录参与手掌擦的触摸点ID
private void inkCanvas_PreviewTouchDown(object sender, TouchEventArgs e)
{
@@ -419,16 +420,57 @@ namespace Ink_Canvas
BlackboardUIGridForInkReplay.IsHitTestVisible = false;
dec.Add(e.TouchDevice.Id);
- // Palm Eraser 逻辑 - 修复:只在触摸按下时处理一次,避免重复触发
+ // Palm Eraser 逻辑 - 优化:改进手掌判定条件,提高精度
if (Settings.Canvas.EnablePalmEraser && dec.Count >= 2 && !isPalmEraserActive && !palmEraserTouchDownHandled)
{
var bounds = e.GetTouchPoint(inkCanvas).Bounds;
- double palmThreshold = 40; // 触摸面积阈值,可根据实际调整
- if (bounds.Width >= palmThreshold || bounds.Height >= palmThreshold)
+
+ // 根据敏感度设置调整判定参数
+ double palmThreshold;
+ double aspectRatioThreshold;
+ int minTouchPoints;
+
+ switch (Settings.Canvas.PalmEraserSensitivity)
+ {
+ case 0: // 低敏感度 - 更严格的判定
+ palmThreshold = 80;
+ aspectRatioThreshold = 0.4;
+ minTouchPoints = 4;
+ break;
+ case 1: // 中敏感度 - 平衡的判定
+ palmThreshold = 60;
+ aspectRatioThreshold = 0.3;
+ minTouchPoints = 3;
+ break;
+ case 2: // 高敏感度 - 较宽松的判定
+ default:
+ palmThreshold = 50;
+ aspectRatioThreshold = 0.25;
+ minTouchPoints = 2;
+ break;
+ }
+
+ // 计算宽高比
+ double aspectRatio = Math.Min(bounds.Width, bounds.Height) / Math.Max(bounds.Width, bounds.Height);
+
+ // 更严格的手掌判定条件
+ bool isLargeTouch = bounds.Width >= palmThreshold && bounds.Height >= palmThreshold;
+ bool isPalmLikeShape = aspectRatio >= aspectRatioThreshold;
+ bool hasMultipleTouchPoints = dec.Count >= minTouchPoints;
+
+ if (isLargeTouch && isPalmLikeShape && hasMultipleTouchPoints)
{
// 记录当前编辑模式和高光状态
palmEraserLastEditingMode = inkCanvas.EditingMode;
palmEraserLastIsHighlighter = drawingAttributes.IsHighlighter;
+
+ // 记录参与手掌擦的触摸点ID
+ palmEraserTouchIds.Clear();
+ foreach (int touchId in dec)
+ {
+ palmEraserTouchIds.Add(touchId);
+ }
+
// 切换为橡皮擦
EraserIcon_Click(null, null);
isPalmEraserActive = true;
@@ -437,6 +479,9 @@ namespace Ink_Canvas
// 启动恢复定时器,防止卡死
StartPalmEraserRecoveryTimer();
+
+ // 记录日志
+ LogHelper.WriteLogToFile($"Palm eraser activated - Sensitivity: {Settings.Canvas.PalmEraserSensitivity}, Touch bounds: {bounds.Width}x{bounds.Height}, Aspect ratio: {aspectRatio:F2}, Touch points: {dec.Count}", LogHelper.LogType.Info);
}
}
@@ -497,41 +542,54 @@ namespace Ink_Canvas
ViewboxFloatingBar.IsHitTestVisible = true;
BlackboardUIGridForInkReplay.IsHitTestVisible = true;
- // Palm Eraser 逻辑:所有点抬起后恢复原编辑模式
+ // Palm Eraser 逻辑:优化状态恢复机制
dec.Remove(e.TouchDevice.Id);
- if (isPalmEraserActive && dec.Count == 0)
+
+ // 如果是手掌擦的触摸点,从记录中移除
+ if (palmEraserTouchIds.Contains(e.TouchDevice.Id))
+ {
+ palmEraserTouchIds.Remove(e.TouchDevice.Id);
+ }
+
+ // 当所有手掌擦触摸点都抬起时,恢复原编辑模式
+ if (isPalmEraserActive && palmEraserTouchIds.Count == 0)
{
// 恢复高光状态
drawingAttributes.IsHighlighter = palmEraserLastIsHighlighter;
- // 恢复编辑模式 - 修复:确保正确恢复状态
+
+ // 恢复编辑模式 - 优化:改进状态恢复逻辑
try
{
if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
{
- if (palmEraserLastEditingMode == InkCanvasEditingMode.Ink)
+ // 根据之前的状态恢复
+ switch (palmEraserLastEditingMode)
{
- PenIcon_Click(null, null);
- }
- else if (palmEraserLastEditingMode == InkCanvasEditingMode.Select)
- {
- SymbolIconSelect_MouseUp(null, null);
- }
- else
- {
- inkCanvas.EditingMode = palmEraserLastEditingMode;
+ case InkCanvasEditingMode.Ink:
+ PenIcon_Click(null, null);
+ break;
+ case InkCanvasEditingMode.Select:
+ SymbolIconSelect_MouseUp(null, null);
+ break;
+ default:
+ inkCanvas.EditingMode = palmEraserLastEditingMode;
+ break;
}
+
+ LogHelper.WriteLogToFile($"Palm eraser recovered to mode: {palmEraserLastEditingMode}", LogHelper.LogType.Info);
}
}
catch (Exception ex)
{
// 如果恢复失败,强制切换到批注模式
- Trace.WriteLine($"Palm eraser recovery failed: {ex.Message}, forcing to Ink mode");
+ LogHelper.WriteLogToFile($"Palm eraser recovery failed: {ex.Message}, forcing to Ink mode", LogHelper.LogType.Error);
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
}
// 重置手掌擦状态
isPalmEraserActive = false;
palmEraserTouchDownHandled = false;
+ palmEraserTouchIds.Clear();
// 停止恢复定时器
StopPalmEraserRecoveryTimer();
@@ -542,44 +600,47 @@ namespace Ink_Canvas
ViewboxFloatingBar.IsHitTestVisible = true;
BlackboardUIGridForInkReplay.IsHitTestVisible = true;
+
+ LogHelper.WriteLogToFile("Palm eraser state reset completed", LogHelper.LogType.Info);
}
// 新增:超时检测 - 如果手掌擦激活时间过长,强制重置状态
- if (isPalmEraserActive && dec.Count == 0)
+ if (isPalmEraserActive)
{
var timeSinceActivation = DateTime.Now - palmEraserActivationTime;
if (timeSinceActivation.TotalMilliseconds > PALM_ERASER_TIMEOUT_MS)
{
- Trace.WriteLine($"Palm eraser timeout detected ({timeSinceActivation.TotalMilliseconds}ms), forcing recovery");
+ LogHelper.WriteLogToFile($"Palm eraser timeout detected ({timeSinceActivation.TotalMilliseconds}ms), forcing recovery", LogHelper.LogType.Warning);
// 强制恢复状态
try
{
if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
{
- if (palmEraserLastEditingMode == InkCanvasEditingMode.Ink)
+ switch (palmEraserLastEditingMode)
{
- PenIcon_Click(null, null);
- }
- else if (palmEraserLastEditingMode == InkCanvasEditingMode.Select)
- {
- SymbolIconSelect_MouseUp(null, null);
- }
- else
- {
- inkCanvas.EditingMode = palmEraserLastEditingMode;
+ case InkCanvasEditingMode.Ink:
+ PenIcon_Click(null, null);
+ break;
+ case InkCanvasEditingMode.Select:
+ SymbolIconSelect_MouseUp(null, null);
+ break;
+ default:
+ inkCanvas.EditingMode = palmEraserLastEditingMode;
+ break;
}
}
}
catch (Exception ex)
{
- Trace.WriteLine($"Palm eraser timeout recovery failed: {ex.Message}, forcing to Ink mode");
+ LogHelper.WriteLogToFile($"Palm eraser timeout recovery failed: {ex.Message}, forcing to Ink mode", LogHelper.LogType.Error);
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
}
// 重置所有手掌擦状态
isPalmEraserActive = false;
palmEraserTouchDownHandled = false;
+ palmEraserTouchIds.Clear();
inkCanvas.IsHitTestVisible = true;
inkCanvas.IsManipulationEnabled = true;
@@ -588,6 +649,8 @@ namespace Ink_Canvas
// 停止恢复定时器
StopPalmEraserRecoveryTimer();
+
+ LogHelper.WriteLogToFile("Palm eraser timeout recovery completed", LogHelper.LogType.Info);
}
}
// 修复:几何绘制模式下,触摸抬手时应该正确处理,而不是简单模拟鼠标事件
@@ -656,6 +719,7 @@ namespace Ink_Canvas
// 如果手掌擦还在激活状态但触摸点已清空,强制重置状态
isPalmEraserActive = false;
palmEraserTouchDownHandled = false;
+ palmEraserTouchIds.Clear(); // 确保清空触摸点ID
inkCanvas.IsHitTestVisible = true;
inkCanvas.IsManipulationEnabled = true;
@@ -902,36 +966,39 @@ namespace Ink_Canvas
var timeSinceActivation = DateTime.Now - palmEraserActivationTime;
if (timeSinceActivation.TotalMilliseconds > PALM_ERASER_TIMEOUT_MS)
{
- Trace.WriteLine($"Palm eraser recovery timer triggered, forcing recovery after {timeSinceActivation.TotalMilliseconds}ms");
+ LogHelper.WriteLogToFile($"Palm eraser recovery timer triggered, forcing recovery after {timeSinceActivation.TotalMilliseconds}ms", LogHelper.LogType.Warning);
// 强制恢复状态
try
{
if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
{
- if (palmEraserLastEditingMode == InkCanvasEditingMode.Ink)
+ switch (palmEraserLastEditingMode)
{
- PenIcon_Click(null, null);
- }
- else if (palmEraserLastEditingMode == InkCanvasEditingMode.Select)
- {
- SymbolIconSelect_MouseUp(null, null);
- }
- else
- {
- inkCanvas.EditingMode = palmEraserLastEditingMode;
+ case InkCanvasEditingMode.Ink:
+ PenIcon_Click(null, null);
+ break;
+ case InkCanvasEditingMode.Select:
+ SymbolIconSelect_MouseUp(null, null);
+ break;
+ default:
+ inkCanvas.EditingMode = palmEraserLastEditingMode;
+ break;
}
+
+ LogHelper.WriteLogToFile($"Palm eraser timer recovery to mode: {palmEraserLastEditingMode}", LogHelper.LogType.Info);
}
}
catch (Exception ex)
{
- Trace.WriteLine($"Palm eraser recovery timer failed: {ex.Message}, forcing to Ink mode");
+ LogHelper.WriteLogToFile($"Palm eraser recovery timer failed: {ex.Message}, forcing to Ink mode", LogHelper.LogType.Error);
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
}
// 重置所有手掌擦状态
isPalmEraserActive = false;
palmEraserTouchDownHandled = false;
+ palmEraserTouchIds.Clear();
inkCanvas.IsHitTestVisible = true;
inkCanvas.IsManipulationEnabled = true;
@@ -940,6 +1007,8 @@ namespace Ink_Canvas
// 停止定时器
StopPalmEraserRecoveryTimer();
+
+ LogHelper.WriteLogToFile("Palm eraser timer recovery completed", LogHelper.LogType.Info);
}
}
}
diff --git a/Ink Canvas/Resources/Settings.cs b/Ink Canvas/Resources/Settings.cs
index 9b8ed589..fc4e687a 100644
--- a/Ink Canvas/Resources/Settings.cs
+++ b/Ink Canvas/Resources/Settings.cs
@@ -88,6 +88,8 @@ namespace Ink_Canvas
public bool IsCompressPicturesUploaded { get; set; }
[JsonProperty("enablePalmEraser")]
public bool EnablePalmEraser { get; set; } = true;
+ [JsonProperty("palmEraserSensitivity")]
+ public int PalmEraserSensitivity { get; set; } = 2; // 0-低敏感度, 1-中敏感度, 2-高敏感度
[JsonProperty("clearCanvasAlsoClearImages")]
public bool ClearCanvasAlsoClearImages { get; set; } = true;
[JsonProperty("showCircleCenter")]