fix:issue #133
This commit is contained in:
@@ -841,7 +841,20 @@
|
||||
IsOn="False" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||
Toggled="ToggleSwitchEnablePalmEraser_Toggled" />
|
||||
</ui:SimpleStackPanel>
|
||||
<TextBlock Text="# 开启后,两个及以上触点且触摸面积较大时自动切换为橡皮擦,抬手后恢复原编辑模式。" TextWrapping="Wrap" Foreground="#a1a1aa" />
|
||||
<TextBlock Text="# 开启后,两个及以上触点且触摸面积较大时自动切换为橡皮擦,抬手后恢复原编辑模式。" TextWrapping="Wrap" Foreground="#a1a1aa" />
|
||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left"
|
||||
Visibility="{Binding ElementName=ToggleSwitchEnablePalmEraser, Path=IsOn, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<TextBlock Foreground="#fafafa" Text="手掌擦敏感度" VerticalAlignment="Center"
|
||||
FontSize="14" Margin="0,0,16,0" />
|
||||
<ComboBox Name="ComboBoxPalmEraserSensitivity" Width="120" SelectionChanged="ComboBoxPalmEraserSensitivity_SelectionChanged">
|
||||
<ComboBoxItem Content="低敏感度" />
|
||||
<ComboBoxItem Content="中敏感度" />
|
||||
<ComboBoxItem Content="高敏感度" />
|
||||
</ComboBox>
|
||||
</ui:SimpleStackPanel>
|
||||
<TextBlock Text="# 低敏感度:需要更大的触摸面积和更多触摸点,减少误判;高敏感度:更容易触发手掌擦,但可能误判手指。"
|
||||
TextWrapping="Wrap" Foreground="#a1a1aa"
|
||||
Visibility="{Binding ElementName=ToggleSwitchEnablePalmEraser, Path=IsOn, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||
</ui:SimpleStackPanel>
|
||||
</GroupBox>
|
||||
<GroupBox Name="GroupBoxInkRecognition">
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,6 +683,7 @@ namespace Ink_Canvas
|
||||
if (Settings.Canvas != null)
|
||||
{
|
||||
ToggleSwitchEnablePalmEraser.IsOn = Settings.Canvas.EnablePalmEraser;
|
||||
ComboBoxPalmEraserSensitivity.SelectedIndex = Settings.Canvas.PalmEraserSensitivity;
|
||||
}
|
||||
|
||||
// Advanced
|
||||
|
||||
@@ -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<int> palmEraserTouchIds = new HashSet<int>(); // 新增:记录参与手掌擦的触摸点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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")]
|
||||
|
||||
Reference in New Issue
Block a user