diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml
index 226e5906..a0f875d4 100644
--- a/.github/workflows/prerelease.yml
+++ b/.github/workflows/prerelease.yml
@@ -12,6 +12,7 @@ on:
- patch
- minor
- major
+ - build
prerelease:
description: 'Create as pre-release'
required: true
@@ -51,7 +52,7 @@ jobs:
echo "Found latest tag: $latestTag"
} else {
# 如果没有tag,使用默认版本
- $version = "1.0.0"
+ $version = "1.0.0.0"
echo "No tags found, using default version"
}
echo "current_version=$version" >> $env:GITHUB_OUTPUT
@@ -63,16 +64,18 @@ jobs:
$currentVersion = "${{ steps.get_version.outputs.current_version }}"
$versionParts = $currentVersion.Split('.')
- # 确保版本号格式正确(至少3部分)
+ # 确保版本号格式正确(支持4部分)
if ($versionParts.Length -ge 3) {
$major = [int]$versionParts[0]
$minor = [int]$versionParts[1]
$patch = [int]$versionParts[2]
+ $build = [int]$versionParts[3]
} else {
# 如果版本号格式不正确,使用默认值
$major = 1
$minor = 0
$patch = 0
+ $build = 0
}
$versionType = "${{ github.event.inputs.version_type }}"
@@ -82,18 +85,24 @@ jobs:
$major++
$minor = 0
$patch = 0
+ $build = 0
}
"minor" {
$minor++
$patch = 0
+ $build = 0
}
"patch" {
$patch++
+ $build = 0
+ }
+ "build" {
+ $build++
}
}
- # 生成新版本号(保持3位格式,如1.7.13)
- $newVersion = "$major.$minor.$patch"
+ # 生成新版本号(4位格式,如1.7.18.0)
+ $newVersion = "$major.$minor.$patch.$build"
echo "new_version=$newVersion" >> $env:GITHUB_OUTPUT
echo "New version: $newVersion"
@@ -150,7 +159,7 @@ jobs:
# 生成changelog内容
$version = "${{ steps.calc_version.outputs.new_version }}"
- $changelog = "# ICC CE $version.0 更新日志`n`n## 修复 (Fixes)"
+ $changelog = "# ICC CE $version 更新日志`n`n## 修复 (Fixes)"
if ($fixes.Count -gt 0) {
foreach ($fix in $fixes) {
@@ -236,7 +245,7 @@ jobs:
- name: Create Release Archive
run: |
$version = "${{ steps.calc_version.outputs.new_version }}"
- $archiveName = "InkCanvasForClass.CE.$version.0.zip"
+ $archiveName = "InkCanvasForClass.CE.$version.zip"
# 创建发布目录
New-Item -ItemType Directory -Path "release" -Force
@@ -254,7 +263,7 @@ jobs:
with:
name: release-files-${{ steps.calc_version.outputs.new_version }}
path: |
- InkCanvasForClass.CE.${{ steps.calc_version.outputs.new_version }}.0.zip
+ InkCanvasForClass.CE.${{ steps.calc_version.outputs.new_version }}.zip
CHANGELOG_${{ steps.calc_version.outputs.new_version }}.md
- name: Prepare Release Info
@@ -265,14 +274,14 @@ jobs:
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
- tag_name: ${{ steps.calc_version.outputs.new_version }}.0
- name: ICC CE ${{ steps.calc_version.outputs.new_version }}.0
+ tag_name: ${{ steps.calc_version.outputs.new_version }}
+ name: ICC CE ${{ steps.calc_version.outputs.new_version }}
body: |
${{ steps.changelog.outputs.changelog }}
draft: false
prerelease: ${{ github.event.inputs.prerelease }}
files: |
- InkCanvasForClass.CE.${{ steps.calc_version.outputs.new_version }}.0.zip
+ InkCanvasForClass.CE.${{ steps.calc_version.outputs.new_version }}.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -285,7 +294,7 @@ jobs:
$changelogContent = Get-Content $changelogFile -Raw
# 生成预览内容
- $previewContent = "ICC CE $version.0 更新日志`n" + $changelogContent
+ $previewContent = "ICC CE $version 更新日志`n" + $changelogContent
echo "UpdateLog preview generated (not written to file):"
echo $previewContent
diff --git a/Ink Canvas/Helpers/PPTInkManager.cs b/Ink Canvas/Helpers/PPTInkManager.cs
index b450aae8..7f60ffce 100644
--- a/Ink Canvas/Helpers/PPTInkManager.cs
+++ b/Ink Canvas/Helpers/PPTInkManager.cs
@@ -273,7 +273,9 @@ namespace Ink_Canvas.Helpers
///
/// 保存所有墨迹到文件
///
- public void SaveAllStrokesToFile(Presentation presentation)
+ /// 演示文稿对象
+ /// 当前播放的页码,如果提供则使用此值保存位置,否则使用_lockedSlideIndex
+ public void SaveAllStrokesToFile(Presentation presentation, int currentSlideIndex = -1)
{
if (!IsAutoSaveEnabled || string.IsNullOrEmpty(AutoSaveLocation) || presentation == null) return;
@@ -290,7 +292,18 @@ namespace Ink_Canvas.Helpers
// 保存位置信息
try
{
- File.WriteAllText(Path.Combine(folderPath, "Position"), _lockedSlideIndex.ToString());
+ // 优先使用传入的当前页码,否则使用锁定的页码
+ int positionToSave = currentSlideIndex > 0 ? currentSlideIndex : _lockedSlideIndex;
+ // 如果都没有有效值,尝试使用最后切换的页码
+ if (positionToSave <= 0 && _lastSwitchSlideIndex > 0)
+ {
+ positionToSave = _lastSwitchSlideIndex;
+ }
+
+ if (positionToSave > 0)
+ {
+ File.WriteAllText(Path.Combine(folderPath, "Position"), positionToSave.ToString());
+ }
}
catch (Exception ex)
{
diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml
index 3a6ecac9..bec6434a 100644
--- a/Ink Canvas/MainWindow.xaml
+++ b/Ink Canvas/MainWindow.xaml
@@ -12,7 +12,6 @@
AllowsTransparency="True"
WindowStyle="None"
ResizeMode="NoResize"
- WindowState="Maximized"
Loaded="Window_Loaded"
Background="Transparent"
ShowInTaskbar="False"
@@ -605,6 +604,13 @@
IsOn="False" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
Toggled="ToggleSwitchNoFocusMode_Toggled" />
+
+
+
+
@@ -3214,14 +3220,14 @@
-
-
+
diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs
index 13e4676d..8863f794 100644
--- a/Ink Canvas/MainWindow.xaml.cs
+++ b/Ink Canvas/MainWindow.xaml.cs
@@ -514,6 +514,9 @@ namespace Ink_Canvas
// 加载自定义背景颜色
LoadCustomBackgroundColor();
+ // 设置窗口模式
+ SetWindowMode();
+
// 注册设置面板滚动事件
if (SettingsPanelScrollViewer != null)
{
@@ -769,6 +772,22 @@ namespace Ink_Canvas
}
}
+ private void SetWindowMode()
+ {
+ if (Settings.Advanced.WindowMode)
+ {
+ WindowState = WindowState.Normal;
+ Left = 0.0;
+ Top = 0.0;
+ Height = SystemParameters.PrimaryScreenHeight;
+ Width = SystemParameters.PrimaryScreenWidth;
+ }
+ else // 全屏
+ {
+ WindowState = WindowState.Maximized;
+ }
+ }
+
private void Window_Closing(object sender, CancelEventArgs e)
{
LogHelper.WriteLogToFile("Ink Canvas closing", LogHelper.LogType.Event);
@@ -3003,7 +3022,6 @@ namespace Ink_Canvas
else if (!isInSlideShow && IsVisible)
{
Hide();
- LogHelper.WriteLogToFile("PPT放映结束,隐藏主窗口(仅PPT模式)", LogHelper.LogType.Trace);
}
}
else
diff --git a/Ink Canvas/MainWindow_cs/MW_BoardControls.cs b/Ink Canvas/MainWindow_cs/MW_BoardControls.cs
index ab338002..681c0d79 100644
--- a/Ink Canvas/MainWindow_cs/MW_BoardControls.cs
+++ b/Ink Canvas/MainWindow_cs/MW_BoardControls.cs
@@ -206,9 +206,6 @@ namespace Ink_Canvas
// 检查是否保存了多指书写模式状态
if (savedMultiTouchModeStates[pageIndex])
{
- // 恢复多指书写模式
- EnterMultiTouchModeIfNeeded();
-
// 更新UI状态
if (ToggleSwitchEnableMultiTouchMode != null)
{
@@ -219,9 +216,6 @@ namespace Ink_Canvas
}
else
{
- // 确保多指书写模式关闭
- ExitMultiTouchModeIfNeeded();
-
// 更新UI状态
if (ToggleSwitchEnableMultiTouchMode != null)
{
diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs
index 1aec6e11..87fa368c 100644
--- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs
+++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs
@@ -73,80 +73,67 @@ namespace Ink_Canvas
///
/// 用於更新浮動工具欄的"手勢"按鈕和白板工具欄的"手勢"按鈕的樣式(開啟和關閉狀態)
///
- private void CheckEnableTwoFingerGestureBtnColorPrompt()
- {
- if (ToggleSwitchEnableMultiTouchMode.IsOn)
- {
- // 多指书写模式启用时,手势功能被禁用
+ private void CheckEnableTwoFingerGestureBtnColorPrompt() {
+ // 根据主题选择手势图标和颜色
+ bool isDarkTheme = Settings.Appearance.Theme == 1 ||
+ (Settings.Appearance.Theme == 2 && !IsSystemThemeLight());
+ bool isLightTheme = !isDarkTheme;
+ string gestureIconPath = isLightTheme ? "/Resources/new-icons/gesture.png" : "/Resources/new-icons/gesture_white.png";
+
+ // 根据主题设置白板模式下的颜色
+ Color boardBgColor, boardIconColor, boardTextColor, boardBorderColor;
+ if (isLightTheme) {
+ // 浅色主题
+ boardBgColor = Color.FromRgb(244, 244, 245);
+ boardIconColor = Color.FromRgb(24, 24, 27);
+ boardTextColor = Color.FromRgb(24, 24, 27);
+ boardBorderColor = Color.FromRgb(161, 161, 170);
+ } else {
+ // 深色主题
+ boardBgColor = Color.FromRgb(39, 39, 42);
+ boardIconColor = Color.FromRgb(244, 244, 245);
+ boardTextColor = Color.FromRgb(244, 244, 245);
+ boardBorderColor = Color.FromRgb(113, 113, 122);
+ }
+
+ if (ToggleSwitchEnableMultiTouchMode.IsOn) {
TwoFingerGestureSimpleStackPanel.Opacity = 0.5;
TwoFingerGestureSimpleStackPanel.IsHitTestVisible = false;
- EnableTwoFingerGestureBtn.Source = (BitmapImage)Application.Current.FindResource("GestureIcon");
-
- // 根据主题设置颜色
- if (Settings.Appearance.Theme == 1) // 深色主题
- {
- BoardGesture.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
- BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
- BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
- BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
- BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
- }
- else // 浅色主题或跟随系统
- {
- 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));
- BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
- BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
- }
+ EnableTwoFingerGestureBtn.Source =
+ new BitmapImage(new Uri(gestureIconPath, UriKind.Relative));
+
+ BoardGesture.Background = new SolidColorBrush(boardBgColor);
+ BoardGestureGeometry.Brush = new SolidColorBrush(boardIconColor);
+ BoardGestureGeometry2.Brush = new SolidColorBrush(boardIconColor);
+ BoardGestureLabel.Foreground = new SolidColorBrush(boardTextColor);
+ BoardGesture.BorderBrush = new SolidColorBrush(boardBorderColor);
BoardGestureGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.DisabledGestureIcon);
BoardGestureGeometry2.Geometry = Geometry.Parse("F0 M24,24z M0,0z");
-
- // 强制禁用所有双指手势功能
- ForceDisableTwoFingerGestures();
}
- else
- {
- // 多指书写模式禁用时,根据实际手势功能状态显示
+ else {
TwoFingerGestureSimpleStackPanel.Opacity = 1;
TwoFingerGestureSimpleStackPanel.IsHitTestVisible = true;
-
- // 检查是否有任何手势功能启用
- bool hasGestureEnabled = Settings.Gesture.IsEnableTwoFingerGesture;
-
- if (hasGestureEnabled)
- {
- EnableTwoFingerGestureBtn.Source = (BitmapImage)Application.Current.FindResource("GestureIconEnabled");
-
+ 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
- {
- EnableTwoFingerGestureBtn.Source = (BitmapImage)Application.Current.FindResource("GestureIcon");
-
- // 根据主题设置颜色
- if (Settings.Appearance.Theme == 1) // 深色主题
- {
- BoardGesture.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42));
- BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
- BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255));
- BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
- BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85));
- }
- else // 浅色主题或跟随系统
- {
- 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));
- BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
- BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
- }
+ else {
+ EnableTwoFingerGestureBtn.Source =
+ new BitmapImage(new Uri(gestureIconPath, UriKind.Relative));
+
+ BoardGesture.Background = new SolidColorBrush(boardBgColor);
+ BoardGestureGeometry.Brush = new SolidColorBrush(boardIconColor);
+ BoardGestureGeometry2.Brush = new SolidColorBrush(boardIconColor);
+ BoardGestureLabel.Foreground = new SolidColorBrush(boardTextColor);
+ BoardGesture.BorderBrush = new SolidColorBrush(boardBorderColor);
BoardGestureGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.DisabledGestureIcon);
BoardGestureGeometry2.Geometry = Geometry.Parse("F0 M24,24z M0,0z");
}
@@ -486,13 +473,23 @@ namespace Ink_Canvas
highlightColor = Color.FromRgb(30, 58, 138); // Keep current color for light theme
}
+ bool useLegacyUI = Settings.Appearance.UseLegacyFloatingBarUI;
+
switch (mode)
{
case "pen":
case "color":
{
- PenIconGeometry.Brush = new SolidColorBrush(highlightColor);
- PenIconGeometry.Geometry = Geometry.Parse(GetCorrectIcon("pen", true));
+ if (useLegacyUI)
+ {
+ PenIconGeometry.Brush = new SolidColorBrush(highlightColor);
+ PenIconGeometry.Geometry = Geometry.Parse(GetCorrectIcon("pen", false));
+ }
+ else
+ {
+ PenIconGeometry.Brush = new SolidColorBrush(highlightColor);
+ PenIconGeometry.Geometry = Geometry.Parse(GetCorrectIcon("pen", true));
+ }
BoardPen.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235));
BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235));
BoardPenGeometry.Brush = new SolidColorBrush(Colors.GhostWhite);
@@ -503,9 +500,18 @@ namespace Ink_Canvas
}
case "eraser":
{
- CircleEraserIconGeometry.Brush = new SolidColorBrush(highlightColor);
- CircleEraserIconGeometry.Geometry =
- Geometry.Parse(GetCorrectIcon("eraserCircle", true));
+ if (useLegacyUI)
+ {
+ CircleEraserIconGeometry.Brush = new SolidColorBrush(highlightColor);
+ CircleEraserIconGeometry.Geometry =
+ Geometry.Parse(GetCorrectIcon("eraserCircle", false));
+ }
+ else
+ {
+ CircleEraserIconGeometry.Brush = new SolidColorBrush(highlightColor);
+ CircleEraserIconGeometry.Geometry =
+ Geometry.Parse(GetCorrectIcon("eraserCircle", true));
+ }
BoardEraser.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235));
BoardEraser.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235));
BoardEraserGeometry.Brush = new SolidColorBrush(Colors.GhostWhite);
@@ -516,9 +522,18 @@ namespace Ink_Canvas
}
case "eraserByStrokes":
{
- StrokeEraserIconGeometry.Brush = new SolidColorBrush(highlightColor);
- StrokeEraserIconGeometry.Geometry =
- Geometry.Parse(GetCorrectIcon("eraserStroke", true));
+ if (useLegacyUI)
+ {
+ StrokeEraserIconGeometry.Brush = new SolidColorBrush(highlightColor);
+ StrokeEraserIconGeometry.Geometry =
+ Geometry.Parse(GetCorrectIcon("eraserStroke", false));
+ }
+ else
+ {
+ StrokeEraserIconGeometry.Brush = new SolidColorBrush(highlightColor);
+ StrokeEraserIconGeometry.Geometry =
+ Geometry.Parse(GetCorrectIcon("eraserStroke", true));
+ }
BoardEraser.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235));
BoardEraser.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235));
BoardEraserGeometry.Brush = new SolidColorBrush(Colors.GhostWhite);
@@ -529,9 +544,18 @@ namespace Ink_Canvas
}
case "select":
{
- LassoSelectIconGeometry.Brush = new SolidColorBrush(highlightColor);
- LassoSelectIconGeometry.Geometry =
- Geometry.Parse(GetCorrectIcon("lassoSelect", true));
+ if (useLegacyUI)
+ {
+ LassoSelectIconGeometry.Brush = new SolidColorBrush(highlightColor);
+ LassoSelectIconGeometry.Geometry =
+ Geometry.Parse(GetCorrectIcon("lassoSelect", false));
+ }
+ else
+ {
+ LassoSelectIconGeometry.Brush = new SolidColorBrush(highlightColor);
+ LassoSelectIconGeometry.Geometry =
+ Geometry.Parse(GetCorrectIcon("lassoSelect", true));
+ }
BoardSelect.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235));
BoardSelect.BorderBrush = new SolidColorBrush(Color.FromRgb(37, 99, 235));
BoardSelectGeometry.Brush = new SolidColorBrush(Colors.GhostWhite);
@@ -542,9 +566,18 @@ namespace Ink_Canvas
}
case "cursor":
{
- CursorIconGeometry.Brush = new SolidColorBrush(highlightColor);
- CursorIconGeometry.Geometry =
- Geometry.Parse(GetCorrectIcon("cursor", true));
+ if (useLegacyUI)
+ {
+ CursorIconGeometry.Brush = new SolidColorBrush(highlightColor);
+ CursorIconGeometry.Geometry =
+ Geometry.Parse(GetCorrectIcon("cursor", false));
+ }
+ else
+ {
+ CursorIconGeometry.Brush = new SolidColorBrush(highlightColor);
+ CursorIconGeometry.Geometry =
+ Geometry.Parse(GetCorrectIcon("cursor", true));
+ }
// 根据主题设置颜色
if (Settings.Appearance.Theme == 1) // 深色主题
{
@@ -1055,6 +1088,8 @@ namespace Ink_Canvas
{
if (TimerContainer != null && TimerControl != null)
{
+ // 每次打开计时器窗口时重置计时器
+ TimerControl.ResetTimerState();
TimerContainer.Visibility = Visibility.Visible;
if (MinimizedTimerContainer != null)
{
@@ -1823,7 +1858,7 @@ namespace Ink_Canvas
});
}
- public async void PureViewboxFloatingBarMarginAnimationInPPTMode()
+ public async void PureViewboxFloatingBarMarginAnimationInPPTMode(bool isRetry = false)
{
// 新增:在白板模式下不执行浮动栏动画
if (currentMode == 1)
@@ -1919,6 +1954,25 @@ namespace Ink_Canvas
{
ViewboxFloatingBar.Margin = new Thickness(pos.X, pos.Y, -2000, -200);
});
+
+ if (Settings.ModeSettings.IsPPTOnlyMode && !isRetry)
+ {
+ await Task.Delay(2000); // 等待动画完成后再检查
+
+ bool isFloatingBarVisible = false;
+ await Dispatcher.InvokeAsync(() =>
+ {
+ // 检查浮动栏是否真的显示了
+ isFloatingBarVisible = ViewboxFloatingBar.Visibility == Visibility.Visible &&
+ ViewboxFloatingBar.Margin.Left >= 0 &&
+ ViewboxFloatingBar.Margin.Top >= 0;
+ });
+
+ if (!isFloatingBarVisible)
+ {
+ PureViewboxFloatingBarMarginAnimationInPPTMode(true);
+ }
+ }
}
internal async void CursorIcon_Click(object sender, RoutedEventArgs e)
@@ -2062,7 +2116,6 @@ namespace Ink_Canvas
{
drawingShapeMode = 0;
isLongPressSelected = false;
- ResetAllShapeButtonsOpacity();
}
// 使用集中化的工具模式切换方法
@@ -2270,7 +2323,6 @@ namespace Ink_Canvas
internal void EraserIcon_Click(object sender, RoutedEventArgs e)
{
- EnterMultiTouchModeIfNeeded();
bool isAlreadyEraser = inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint;
forceEraser = false;
forcePointEraser = true;
@@ -2322,7 +2374,6 @@ namespace Ink_Canvas
private void BoardEraserIcon_Click(object sender, RoutedEventArgs e)
{
- EnterMultiTouchModeIfNeeded();
bool isAlreadyEraser = inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint;
forceEraser = false;
forcePointEraser = true;
@@ -2361,7 +2412,6 @@ namespace Ink_Canvas
private void EraserIconByStrokes_Click(object sender, RoutedEventArgs e)
{
- EnterMultiTouchModeIfNeeded();
if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel)
((Panel)lastBorderMouseDownObject).Background = new SolidColorBrush(Colors.Transparent);
@@ -2914,12 +2964,6 @@ namespace Ink_Canvas
// 清空触摸点计数器
dec.Clear();
- // 重置手掌擦状态
- if (isPalmEraserActive)
- {
- isPalmEraserActive = false;
- }
-
// 确保触摸事件能正常响应
inkCanvas.IsHitTestVisible = true;
inkCanvas.IsManipulationEnabled = true;
@@ -3017,10 +3061,26 @@ namespace Ink_Canvas
ClearStrokes(true);
RestoreStrokes(true);
- // 新增:在屏幕模式下恢复基础浮动栏的显示
+ // 退出白板模式时取消全屏
+ if (Settings.Advanced.IsEnableAvoidFullScreenHelper)
+ {
+ // 恢复为非画板模式,重新启用全屏限制
+ AvoidFullScreenHelper.SetBoardMode(false);
+
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ // 退出白板模式,恢复到工作区域大小
+ var workingArea = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea;
+ MainWindow.MoveWindow(new WindowInteropHelper(this).Handle,
+ workingArea.Left, workingArea.Top,
+ workingArea.Width, workingArea.Height, true);
+ }), DispatcherPriority.ApplicationIdle);
+ }
+
+ // 在屏幕模式下恢复基础浮动栏的显示
ViewboxFloatingBar.Visibility = Visibility.Visible;
- // 新增:退出白板时自动收纳功能 - 等待浮动栏完全展开后再收纳
+ // 退出白板时自动收纳功能 - 等待浮动栏完全展开后再收纳
if (Settings.Automation.IsAutoFoldWhenExitWhiteboard && !isFloatingBarFolded)
{
// 使用异步延迟,等待浮动栏展开动画完成后再收纳
@@ -3029,7 +3089,10 @@ namespace Ink_Canvas
await Task.Delay(700);
await Dispatcher.InvokeAsync(() =>
{
- FoldFloatingBar_MouseUp(new object(), null);
+ if (_pptManager?.IsInSlideShow != true)
+ {
+ FoldFloatingBar_MouseUp(new object(), null);
+ }
});
});
}
@@ -3070,6 +3133,19 @@ namespace Ink_Canvas
RestoreStrokes();
+ // 进入白板模式时全屏
+ if (Settings.Advanced.IsEnableAvoidFullScreenHelper)
+ {
+ // 设置为画板模式,允许全屏操作
+ AvoidFullScreenHelper.SetBoardMode(true);
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ MainWindow.MoveWindow(new WindowInteropHelper(this).Handle, 0, 0,
+ System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
+ System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, true);
+ }), DispatcherPriority.ApplicationIdle);
+ }
+
ViewboxFloatingBar.Visibility = Visibility.Collapsed;
BtnSwitch.Content = "屏幕";
diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs
index 2906d5b1..8fdc8413 100644
--- a/Ink Canvas/MainWindow_cs/MW_PPT.cs
+++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs
@@ -77,7 +77,6 @@ namespace Ink_Canvas
#endregion
#region PPT State Management
- private bool wasFloatingBarFoldedWhenEnterSlideShow;
private bool isEnteredSlideShowEndEvent;
private bool isPresentationHaveBlackSpace;
@@ -94,12 +93,16 @@ namespace Ink_Canvas
// 上次播放位置相关字段
private int _lastPlaybackPage = 0;
private bool _shouldNavigateToLastPage = false;
+
+ // 当前播放页码跟踪
+ private int _currentSlideShowPosition = 0;
// 页面切换防抖机制
private DateTime _lastSlideSwitchTime = DateTime.MinValue;
private int _pendingSlideIndex = -1;
private System.Timers.Timer _slideSwitchDebounceTimer;
- private const int SlideSwitchDebounceMs = 150; // 防抖延迟150毫秒
+ private const int SlideSwitchDebounceMs = 150;
+ private bool _isInkClearedByButton = false;
#endregion
#region PPT Managers
@@ -612,9 +615,6 @@ namespace Ink_Canvas
{
try
{
- // 始终记录进入放映时浮动栏收纳状态,用于退出时恢复
- wasFloatingBarFoldedWhenEnterSlideShow = isFloatingBarFolded;
-
if (Settings.Automation.IsAutoFoldInPPTSlideShow)
{
if (!isFloatingBarFolded)
@@ -641,12 +641,16 @@ namespace Ink_Canvas
activePresentation = wn.Presentation;
currentSlide = wn.View.CurrentShowPosition;
totalSlides = activePresentation.Slides.Count;
+ // 初始化当前播放页码跟踪
+ _currentSlideShowPosition = currentSlide;
}
else
{
activePresentation = _pptManager?.GetCurrentActivePresentation();
currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
totalSlides = _pptManager?.SlidesCount ?? 0;
+ // 初始化当前播放页码跟踪
+ _currentSlideShowPosition = currentSlide;
}
if (activePresentation != null)
@@ -765,19 +769,50 @@ namespace Ink_Canvas
if (!isFloatingBarFolded)
{
- new Thread(() =>
+ _ = Task.Run(async () =>
{
- Thread.Sleep(100);
- Application.Current.Dispatcher.Invoke(() =>
+ try
{
- ViewboxFloatingBarMarginAnimation(60);
- });
- }).Start();
+ await Task.Delay(100);
+
+ await Application.Current.Dispatcher.InvokeAsync(() =>
+ {
+ ViewboxFloatingBar.UpdateLayout();
+
+ // 如果浮动栏宽度仍未计算好,再等待一段时间
+ if (ViewboxFloatingBar.ActualWidth <= 0)
+ {
+ LogHelper.WriteLogToFile("浮动栏宽度未准备好,等待布局完成", LogHelper.LogType.Trace);
+ }
+ });
+
+ await Task.Delay(100);
+
+ await Application.Current.Dispatcher.InvokeAsync(() =>
+ {
+ PureViewboxFloatingBarMarginAnimationInPPTMode(false);
+ });
+ }
+ catch (Exception)
+ {
+
+ try
+ {
+ await Task.Delay(100);
+ await Application.Current.Dispatcher.InvokeAsync(() =>
+ {
+ ViewboxFloatingBarMarginAnimation(60);
+ });
+ }
+ catch (Exception)
+ {
+ }
+ }
+ });
}
}
- catch (Exception ex)
+ catch (Exception)
{
- LogHelper.WriteLogToFile($"处理幻灯片放映开始事件失败: {ex}", LogHelper.LogType.Error);
}
}
@@ -785,7 +820,7 @@ namespace Ink_Canvas
{
try
{
- Application.Current.Dispatcher.InvokeAsync(() =>
+ Application.Current.Dispatcher.Invoke(() =>
{
if (wn?.View == null || wn.Presentation == null)
{
@@ -796,8 +831,58 @@ namespace Ink_Canvas
var activePresentation = wn.Presentation;
var totalSlides = activePresentation.Slides.Count;
- // 使用防抖机制处理页面切换
- HandleSlideSwitchWithDebounce(currentSlide, totalSlides);
+ // 获取之前的页码(用于保存墨迹)
+ var previousSlide = _currentSlideShowPosition > 0 ? _currentSlideShowPosition :
+ (_pptManager?.GetCurrentSlideNumber() ?? 0);
+
+ if (_isInkClearedByButton)
+ {
+ _isInkClearedByButton = false;
+ }
+ else
+ {
+ StrokeCollection strokesToSave = null;
+ if (previousSlide > 0 && previousSlide != currentSlide && inkCanvas.Strokes.Count > 0)
+ {
+ strokesToSave = inkCanvas.Strokes.Clone();
+ }
+
+ // 清除墨迹
+ if (inkCanvas.Strokes.Count > 0)
+ {
+ ClearStrokes(true);
+ timeMachine.ClearStrokeHistory();
+ }
+
+ // 异步保存之前页面的墨迹
+ if (strokesToSave != null && previousSlide > 0 && previousSlide != currentSlide)
+ {
+ Task.Run(() =>
+ {
+ try
+ {
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ bool canWrite = _singlePPTInkManager?.CanWriteInk(previousSlide) == true;
+ if (canWrite)
+ {
+ _singlePPTInkManager?.SaveCurrentSlideStrokes(previousSlide, strokesToSave);
+ }
+ });
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"异步保存PPT页面墨迹失败: {ex}", LogHelper.LogType.Error);
+ }
+ });
+ }
+ }
+
+ // 更新当前播放页码
+ _currentSlideShowPosition = currentSlide;
+
+ LoadCurrentSlideInk(currentSlide, skipClear: true);
+ _pptUIManager?.UpdateCurrentSlideNumber(currentSlide, totalSlides);
});
}
@@ -811,39 +896,39 @@ namespace Ink_Canvas
{
try
{
- if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
+ // PPT退出时自动收纳浮动栏
+ if (!isFloatingBarFolded)
{
- if (wasFloatingBarFoldedWhenEnterSlideShow)
- {
- if (!isFloatingBarFolded) FoldFloatingBar_MouseUp(new object(), null);
- }
- else
- {
- if (isFloatingBarFolded) await UnFoldFloatingBar(new object());
- }
- }
- else
- {
- if (Settings.Automation.IsAutoFoldInPPTSlideShow)
- {
- if (isFloatingBarFolded)
- {
- await UnFoldFloatingBar(new object());
- }
- }
- else
- {
- if (isFloatingBarFolded)
- {
- await UnFoldFloatingBar(new object());
- }
- }
+ FoldFloatingBar_MouseUp(new object(), null);
}
if (isEnteredSlideShowEndEvent) return;
isEnteredSlideShowEndEvent = true;
- _singlePPTInkManager?.SaveAllStrokesToFile(pres);
+ // 获取当前播放页码,优先使用跟踪的页码,否则尝试从PPT管理器获取
+ int currentPage = _currentSlideShowPosition;
+ if (currentPage <= 0)
+ {
+ try
+ {
+ currentPage = _pptManager?.GetCurrentSlideNumber() ?? 0;
+ }
+ catch
+ {
+ // 如果无法获取,尝试从演示文稿的SlideShowWindow获取
+ try
+ {
+ if (pres.SlideShowWindow != null && pres.SlideShowWindow.View != null)
+ {
+ currentPage = pres.SlideShowWindow.View.CurrentShowPosition;
+ }
+ }
+ catch { }
+ }
+ }
+
+ // 保存墨迹和位置信息
+ _singlePPTInkManager?.SaveAllStrokesToFile(pres, currentPage);
await Application.Current.Dispatcher.InvokeAsync(() =>
{
@@ -917,7 +1002,7 @@ namespace Ink_Canvas
await Application.Current.Dispatcher.InvokeAsync(() =>
{
PureViewboxFloatingBarMarginAnimationInDesktopMode();
- ViewboxFloatingBarMarginAnimation(100, true);
+ ViewboxFloatingBarMarginAnimation(-60);
});
}
catch (Exception ex)
@@ -1098,13 +1183,16 @@ namespace Ink_Canvas
}
}
- private void LoadCurrentSlideInk(int slideIndex)
+ private void LoadCurrentSlideInk(int slideIndex, bool skipClear = false)
{
try
{
- ClearStrokes(true);
- timeMachine.ClearStrokeHistory();
-
+ // 如果未跳过清除,则清除当前墨迹
+ if (!skipClear)
+ {
+ ClearStrokes(true);
+ timeMachine.ClearStrokeHistory();
+ }
StrokeCollection strokes = _singlePPTInkManager?.LoadSlideStrokes(slideIndex);
if (strokes != null && strokes.Count > 0)
@@ -1140,9 +1228,6 @@ namespace Ink_Canvas
{
try
{
- // 重置进入PPT时的浮动栏收纳状态记录
- wasFloatingBarFoldedWhenEnterSlideShow = false;
-
// 重置PPT放映结束事件标志
isEnteredSlideShowEndEvent = false;
@@ -1152,6 +1237,9 @@ namespace Ink_Canvas
// 重置上次播放位置相关字段
_lastPlaybackPage = 0;
_shouldNavigateToLastPage = false;
+
+ // 重置当前播放页码跟踪
+ _currentSlideShowPosition = 0;
// 重置页面切换防抖机制
_lastSlideSwitchTime = DateTime.MinValue;
@@ -1170,51 +1258,14 @@ namespace Ink_Canvas
///
private void HandleSlideSwitchWithDebounce(int currentSlide, int totalSlides)
{
- try
- {
- var now = DateTime.Now;
-
- // 如果距离上次切换时间太短,使用防抖机制
- if (now - _lastSlideSwitchTime < TimeSpan.FromMilliseconds(SlideSwitchDebounceMs))
- {
- _pendingSlideIndex = currentSlide;
-
- // 停止之前的定时器
- _slideSwitchDebounceTimer?.Stop();
-
- // 创建新的定时器
- _slideSwitchDebounceTimer = new System.Timers.Timer(SlideSwitchDebounceMs);
- _slideSwitchDebounceTimer.Elapsed += (sender, e) =>
- {
- Application.Current.Dispatcher.Invoke(() =>
- {
- if (_pendingSlideIndex > 0)
- {
- SwitchSlideInk(_pendingSlideIndex);
- _pptUIManager?.UpdateCurrentSlideNumber(_pendingSlideIndex, totalSlides);
- _pendingSlideIndex = -1;
- }
- });
- _slideSwitchDebounceTimer?.Stop();
- };
- _slideSwitchDebounceTimer.Start();
- }
- else
- {
- // 直接处理页面切换
- SwitchSlideInk(currentSlide);
- _pptUIManager?.UpdateCurrentSlideNumber(currentSlide, totalSlides);
- }
-
- _lastSlideSwitchTime = now;
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"处理页面切换防抖失败: {ex}", LogHelper.LogType.Error);
- }
}
- private void SwitchSlideInk(int newSlideIndex)
+ ///
+ /// 切换页面墨迹
+ ///
+ /// 新页面索引
+ /// 是否跳过清除操作(如果已在翻页时立即清除,则设为true)
+ private void SwitchSlideInk(int newSlideIndex, bool skipClear = false)
{
try
{
@@ -1235,18 +1286,23 @@ namespace Ink_Canvas
}
// 如果有当前墨迹且不是第一次切换,先保存到当前页面
- if (inkCanvas.Strokes.Count > 0 && currentSlideIndex > 0 && currentSlideIndex != newSlideIndex)
+ if (currentSlideIndex > 0 && currentSlideIndex != newSlideIndex)
{
bool canWrite = _singlePPTInkManager?.CanWriteInk(currentSlideIndex) == true;
-
- if (canWrite)
+
+ if (canWrite && inkCanvas.Strokes.Count > 0)
{
_singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlideIndex, inkCanvas.Strokes);
}
}
- ClearStrokes(true);
- timeMachine.ClearStrokeHistory();
+ if (!skipClear)
+ {
+ ClearStrokes(true);
+ timeMachine.ClearStrokeHistory();
+ }
+
+ // 加载新页面的墨迹
StrokeCollection newStrokes = _singlePPTInkManager?.SwitchToSlide(newSlideIndex, null);
if (newStrokes != null && newStrokes.Count > 0)
@@ -1383,25 +1439,72 @@ namespace Ink_Canvas
{
try
{
- // 保存当前页墨迹
- var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
- if (currentSlide > 0)
+ var previousSlideBeforeNavigate = _pptManager?.GetCurrentSlideNumber() ?? 0;
+
+ StrokeCollection strokesToSave = null;
+ if (previousSlideBeforeNavigate > 0 && inkCanvas.Strokes.Count > 0)
{
- _singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
+ strokesToSave = inkCanvas.Strokes.Clone();
}
- // 保存截图(如果启用)
- if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
- Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
- {
- var presentationName = _pptManager?.GetPresentationName() ?? "";
- SaveScreenShot(true, $"{presentationName}/{currentSlide}");
- }
-
- // 执行翻页
if (_pptManager?.TryNavigatePrevious() == true)
{
- // 翻页成功,等待事件处理墨迹切换
+ var currentSlideAfterNavigate = _pptManager?.GetCurrentSlideNumber() ?? 0;
+
+ if (previousSlideBeforeNavigate == currentSlideAfterNavigate && previousSlideBeforeNavigate > 0)
+ {
+ Thread.Sleep(50);
+ currentSlideAfterNavigate = _pptManager?.GetCurrentSlideNumber() ?? 0;
+ }
+
+ if (previousSlideBeforeNavigate != currentSlideAfterNavigate && previousSlideBeforeNavigate > 0)
+ {
+ if (inkCanvas.Strokes.Count > 0)
+ {
+ ClearStrokes(true);
+ timeMachine.ClearStrokeHistory();
+ _isInkClearedByButton = true;
+ }
+
+ if (strokesToSave != null && previousSlideBeforeNavigate > 0)
+ {
+ Task.Run(() =>
+ {
+ try
+ {
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ _singlePPTInkManager?.SaveCurrentSlideStrokes(previousSlideBeforeNavigate, strokesToSave);
+ });
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"异步保存PPT上一页墨迹失败: {ex}", LogHelper.LogType.Error);
+ }
+ });
+
+ // 异步保存截图(如果启用)
+ if (strokesToSave.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
+ Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
+ {
+ Task.Run(() =>
+ {
+ try
+ {
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ var presentationName = _pptManager?.GetPresentationName() ?? "";
+ SaveScreenShot(true, $"{presentationName}/{previousSlideBeforeNavigate}");
+ });
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"异步保存PPT上一页截图失败: {ex}", LogHelper.LogType.Error);
+ }
+ });
+ }
+ }
+ }
}
else
{
@@ -1423,25 +1526,72 @@ namespace Ink_Canvas
{
try
{
- // 保存当前页墨迹
- var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
- if (currentSlide > 0)
+ var previousSlideBeforeNavigate = _pptManager?.GetCurrentSlideNumber() ?? 0;
+
+ StrokeCollection strokesToSave = null;
+ if (previousSlideBeforeNavigate > 0 && inkCanvas.Strokes.Count > 0)
{
- _singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
+ strokesToSave = inkCanvas.Strokes.Clone();
}
- // 保存截图(如果启用)
- if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
- Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
- {
- var presentationName = _pptManager?.GetPresentationName() ?? "";
- SaveScreenShot(true, $"{presentationName}/{currentSlide}");
- }
-
- // 执行翻页
if (_pptManager?.TryNavigateNext() == true)
{
- // 翻页成功,等待事件处理墨迹切换
+ var currentSlideAfterNavigate = _pptManager?.GetCurrentSlideNumber() ?? 0;
+
+ if (previousSlideBeforeNavigate == currentSlideAfterNavigate && previousSlideBeforeNavigate > 0)
+ {
+ Thread.Sleep(50);
+ currentSlideAfterNavigate = _pptManager?.GetCurrentSlideNumber() ?? 0;
+ }
+
+ if (previousSlideBeforeNavigate != currentSlideAfterNavigate && previousSlideBeforeNavigate > 0)
+ {
+ if (inkCanvas.Strokes.Count > 0)
+ {
+ ClearStrokes(true);
+ timeMachine.ClearStrokeHistory();
+ _isInkClearedByButton = true;
+ }
+
+ if (strokesToSave != null && previousSlideBeforeNavigate > 0)
+ {
+ Task.Run(() =>
+ {
+ try
+ {
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ _singlePPTInkManager?.SaveCurrentSlideStrokes(previousSlideBeforeNavigate, strokesToSave);
+ });
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"异步保存PPT下一页墨迹失败: {ex}", LogHelper.LogType.Error);
+ }
+ });
+
+ // 异步保存截图(如果启用)
+ if (strokesToSave.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
+ Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
+ {
+ Task.Run(() =>
+ {
+ try
+ {
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ var presentationName = _pptManager?.GetPresentationName() ?? "";
+ SaveScreenShot(true, $"{presentationName}/{previousSlideBeforeNavigate}");
+ });
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"异步保存PPT下一页截图失败: {ex}", LogHelper.LogType.Error);
+ }
+ });
+ }
+ }
+ }
}
else
{
@@ -1609,7 +1759,7 @@ namespace Ink_Canvas
LogHelper.WriteLogToFile("手动更新放映结束UI状态", LogHelper.LogType.Trace);
});
- // 手动处理收纳状态恢复,因为OnPPTSlideShowEnd事件可能未触发
+ // 手动处理自动收纳,因为OnPPTSlideShowEnd事件可能未触发
await HandleManualSlideShowEnd();
}
@@ -1617,28 +1767,8 @@ namespace Ink_Canvas
SetCurrentToolMode(InkCanvasEditingMode.None);
await Task.Delay(150);
- if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
- {
- if (wasFloatingBarFoldedWhenEnterSlideShow)
- {
- ViewboxFloatingBarMarginAnimation(-60);
- }
- else
- {
- ViewboxFloatingBarMarginAnimation(100, true);
- }
- }
- else
- {
- if (isFloatingBarFolded)
- {
- ViewboxFloatingBarMarginAnimation(-60);
- }
- else
- {
- ViewboxFloatingBarMarginAnimation(100, true);
- }
- }
+ // PPT退出时自动收纳,使用收纳状态的边距动画
+ ViewboxFloatingBarMarginAnimation(-60);
}
catch (Exception ex)
{
@@ -1651,76 +1781,31 @@ namespace Ink_Canvas
_pptUIManager?.UpdateSidebarExitButtons(false);
});
- // 异常情况下也手动处理收纳状态恢复
+ // 异常情况下也手动处理自动收纳
await HandleManualSlideShowEnd();
- // 异常情况下也要根据设置决定浮动栏边距
+ // 异常情况下也要自动收纳,使用收纳状态的边距动画
await Task.Delay(150);
- if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
- {
- if (wasFloatingBarFoldedWhenEnterSlideShow)
- {
- ViewboxFloatingBarMarginAnimation(-60);
- }
- else
- {
- ViewboxFloatingBarMarginAnimation(100, true);
- }
- }
- else
- {
- if (isFloatingBarFolded)
- {
- ViewboxFloatingBarMarginAnimation(-60);
- }
- else
- {
- ViewboxFloatingBarMarginAnimation(100, true);
- }
- }
+ ViewboxFloatingBarMarginAnimation(-60);
}
}
///
- /// 手动处理PPT放映结束时的收纳状态恢复
+ /// 手动处理PPT放映结束时的自动收纳
///
private async Task HandleManualSlideShowEnd()
{
try
{
- if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
+ // PPT退出时自动收纳浮动栏
+ if (!isFloatingBarFolded)
{
- if (wasFloatingBarFoldedWhenEnterSlideShow)
- {
- if (!isFloatingBarFolded) FoldFloatingBar_MouseUp(new object(), null);
- }
- else
- {
- if (isFloatingBarFolded) await UnFoldFloatingBar(new object());
- }
- }
- else
- {
- if (Settings.Automation.IsAutoFoldInPPTSlideShow)
- {
- if (isFloatingBarFolded)
- {
- await UnFoldFloatingBar(new object());
- }
- }
- else
- {
- // 如果两个功能都关闭,确保浮动栏展开
- if (isFloatingBarFolded)
- {
- await UnFoldFloatingBar(new object());
- }
- }
+ FoldFloatingBar_MouseUp(new object(), null);
}
}
catch (Exception ex)
{
- LogHelper.WriteLogToFile($"手动处理PPT放映结束收纳状态恢复失败: {ex}", LogHelper.LogType.Error);
+ LogHelper.WriteLogToFile($"手动处理PPT放映结束自动收纳失败: {ex}", LogHelper.LogType.Error);
}
}
diff --git a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs
index 892527ad..df0121e2 100644
--- a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs
+++ b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs
@@ -354,7 +354,6 @@ namespace Ink_Canvas
private void BtnSelect_Click(object sender, RoutedEventArgs e)
{
- ExitMultiTouchModeIfNeeded();
forceEraser = true;
drawingShapeMode = 0;
inkCanvas.IsManipulationEnabled = false;
@@ -709,7 +708,6 @@ namespace Ink_Canvas
private void LassoSelect_Click(object sender, RoutedEventArgs e)
{
- ExitMultiTouchModeIfNeeded();
forceEraser = false;
forcePointEraser = false;
drawingShapeMode = 0;
@@ -720,7 +718,6 @@ namespace Ink_Canvas
private void BtnLassoSelect_Click(object sender, RoutedEventArgs e)
{
- ExitMultiTouchModeIfNeeded();
forceEraser = false;
forcePointEraser = false;
drawingShapeMode = 0;
diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs
index 0c29fcfe..033d48f3 100644
--- a/Ink Canvas/MainWindow_cs/MW_Settings.cs
+++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs
@@ -2532,6 +2532,14 @@ namespace Ink_Canvas
SaveSettingsToFile();
}
+ private void ToggleSwitchWindowMode_Toggled(object sender, RoutedEventArgs e)
+ {
+ if (!isLoaded) return;
+ Settings.Advanced.WindowMode = ToggleSwitchWindowMode.IsOn;
+ SaveSettingsToFile();
+ SetWindowMode();
+ }
+
private void ToggleSwitchIsAutoBackupBeforeUpdate_Toggled(object sender, RoutedEventArgs e)
{
if (!isLoaded) return;
diff --git a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
index bde4b36b..76c46951 100644
--- a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
+++ b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs
@@ -795,6 +795,7 @@ namespace Ink_Canvas
ToggleSwitchIsLogEnabled.IsOn = Settings.Advanced.IsLogEnabled;
ToggleSwitchIsSaveLogByDate.IsOn = Settings.Advanced.IsSaveLogByDate;
ToggleSwitchIsSecondConfimeWhenShutdownApp.IsOn = Settings.Advanced.IsSecondConfirmWhenShutdownApp;
+ ToggleSwitchWindowMode.IsOn = Settings.Advanced.WindowMode;
ToggleSwitchIsSpecialScreen.IsOn = Settings.Advanced.IsSpecialScreen;
ToggleSwitchIsQuadIR.IsOn = Settings.Advanced.IsQuadIR;
ToggleSwitchEraserBindTouchMultiplier.IsOn = Settings.Advanced.EraserBindTouchMultiplier;
diff --git a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs
index 17d1511a..f8869cf3 100644
--- a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs
+++ b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs
@@ -117,436 +117,355 @@ namespace Ink_Canvas
}
}
- private void BtnPen_Click(object sender, RoutedEventArgs e)
- {
- // 如果当前有选中的图片元素,先取消选中
- if (currentSelectedElement != null)
- {
- UnselectElement(currentSelectedElement);
- currentSelectedElement = null;
- }
-
- // 禁用高级橡皮擦系统
- DisableEraserOverlay();
- ExitMultiTouchModeIfNeeded();
-
- // 如果当前已是批注模式,再次点击弹出批注子面板
- if (penType == 0 && inkCanvas.EditingMode == InkCanvasEditingMode.Ink && !drawingAttributes.IsHighlighter)
- {
- return;
- }
- // 否则只切换到批注模式,不弹出子面板
+ private void BtnPen_Click(object sender, RoutedEventArgs e) {
forceEraser = false;
- forcePointEraser = false;
drawingShapeMode = 0;
- penType = 0;
- drawingAttributes.IsHighlighter = false;
- drawingAttributes.StylusTip = StylusTip.Ellipse;
- // 禁止几何绘制模式下切换到Ink
- if (drawingShapeMode != 0)
- {
- return;
- }
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
-
-
- // 更新lastInkCanvasEditingMode以确保多指手势逻辑正确
- lastInkCanvasEditingMode = InkCanvasEditingMode.Ink;
-
- ResetAllShapeButtonsOpacity();
-
- SetCursorBasedOnEditingMode(inkCanvas);
+ inkCanvas.IsManipulationEnabled = true;
+ CancelSingleFingerDragMode();
+ isLongPressSelected = false;
}
- private Task CheckIsDrawingShapesInMultiTouchMode()
- {
- if (isInMultiTouchMode)
- {
- // 不关闭多指书写模式,而是保存状态,暂时禁用多指书写相关的事件处理
- // 不再调用 ToggleSwitchEnableMultiTouchMode.IsOn = false;
-
- // 暂时禁用多指书写事件处理,以避免冲突
- inkCanvas.StylusDown -= MainWindow_StylusDown;
- inkCanvas.StylusMove -= MainWindow_StylusMove;
- inkCanvas.StylusUp -= MainWindow_StylusUp;
- inkCanvas.TouchDown -= MainWindow_TouchDown;
-
- // 记录已暂时禁用多指书写模式,但实际上多指书写开关仍然为打开状态
+ private Task CheckIsDrawingShapesInMultiTouchMode() {
+ if (isInMultiTouchMode) {
+ ToggleSwitchEnableMultiTouchMode.IsOn = false;
lastIsInMultiTouchMode = true;
}
- if (drawingShapeMode != 0)
- {
- inkCanvas.EditingMode = InkCanvasEditingMode.None;
- }
-
return Task.FromResult(true);
}
- internal async void BtnDrawLine_Click(object sender, MouseButtonEventArgs e)
- {
+ public async void BtnDrawLine_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(1);
- lastMouseDownSender = null;
-
- // 先保存长按状态,避免被CancelSingleFingerDragMode重置
- bool wasLongPressed = isLongPressSelected;
-
+ if (lastMouseDownSender == sender) {
+ forceEraser = true;
+ drawingShapeMode = 1;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
+ }
- if (wasLongPressed)
- {
+ lastMouseDownSender = null;
+ if (isLongPressSelected) {
if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape();
var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0)));
ImageDrawLine.BeginAnimation(OpacityProperty, dA);
- // 恢复长按状态,保持工具选中
- isLongPressSelected = true;
}
+
DrawShapePromptToPen();
}
- private async void BtnDrawDashedLine_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawDashedLine_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(8);
- lastMouseDownSender = null;
-
- // 先保存长按状态,避免被CancelSingleFingerDragMode重置
- bool wasLongPressed = isLongPressSelected;
-
+ if (lastMouseDownSender == sender) {
+ forceEraser = true;
+ drawingShapeMode = 8;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
+ }
- if (wasLongPressed)
- {
+ lastMouseDownSender = null;
+ if (isLongPressSelected) {
if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape();
var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0)));
ImageDrawDashedLine.BeginAnimation(OpacityProperty, dA);
- // 恢复长按状态,保持工具选中
- isLongPressSelected = true;
}
+
DrawShapePromptToPen();
}
- private async void BtnDrawDotLine_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawDotLine_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(18);
- lastMouseDownSender = null;
-
- // 先保存长按状态,避免被CancelSingleFingerDragMode重置
- bool wasLongPressed = isLongPressSelected;
-
+ if (lastMouseDownSender == sender) {
+ forceEraser = true;
+ drawingShapeMode = 18;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
+ }
- if (wasLongPressed)
- {
+ lastMouseDownSender = null;
+ if (isLongPressSelected) {
if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape();
var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0)));
ImageDrawDotLine.BeginAnimation(OpacityProperty, dA);
- // 恢复长按状态,保持工具选中
- isLongPressSelected = true;
}
+
DrawShapePromptToPen();
}
- private async void BtnDrawArrow_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawArrow_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(2);
- lastMouseDownSender = null;
-
- // 先保存长按状态,避免被CancelSingleFingerDragMode重置
- bool wasLongPressed = isLongPressSelected;
-
+ if (lastMouseDownSender == sender) {
+ forceEraser = true;
+ drawingShapeMode = 2;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
+ }
- if (wasLongPressed)
- {
+ lastMouseDownSender = null;
+ if (isLongPressSelected) {
if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape();
var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0)));
ImageDrawArrow.BeginAnimation(OpacityProperty, dA);
- // 恢复长按状态,保持工具选中
- isLongPressSelected = true;
}
+
DrawShapePromptToPen();
}
- private async void BtnDrawParallelLine_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawParallelLine_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(15);
- lastMouseDownSender = null;
-
- // 先保存长按状态,避免被CancelSingleFingerDragMode重置
- bool wasLongPressed = isLongPressSelected;
-
+ if (lastMouseDownSender == sender) {
+ forceEraser = true;
+ drawingShapeMode = 15;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
+ }
- if (wasLongPressed)
- {
+ lastMouseDownSender = null;
+ if (isLongPressSelected) {
if (ToggleSwitchDrawShapeBorderAutoHide.IsOn) CollapseBorderDrawShape();
var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0)));
ImageDrawParallelLine.BeginAnimation(OpacityProperty, dA);
- // 恢复长按状态,保持工具选中
- isLongPressSelected = true;
}
+
DrawShapePromptToPen();
}
- private async void BtnDrawCoordinate1_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawCoordinate1_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(11);
+ forceEraser = true;
+ drawingShapeMode = 11;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawCoordinate2_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawCoordinate2_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(12);
+ forceEraser = true;
+ drawingShapeMode = 12;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawCoordinate3_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawCoordinate3_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(13);
+ forceEraser = true;
+ drawingShapeMode = 13;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawCoordinate4_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawCoordinate4_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(14);
+ forceEraser = true;
+ drawingShapeMode = 14;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawCoordinate5_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawCoordinate5_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(17);
+ forceEraser = true;
+ drawingShapeMode = 17;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawRectangle_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawRectangle_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(3);
+ forceEraser = true;
+ drawingShapeMode = 3;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- isLongPressSelected = false;
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawRectangleCenter_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawRectangleCenter_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(19);
+ forceEraser = true;
+ drawingShapeMode = 19;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawEllipse_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawEllipse_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(4);
+ forceEraser = true;
+ drawingShapeMode = 4;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawCircle_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawCircle_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(5);
+ forceEraser = true;
+ drawingShapeMode = 5;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawCenterEllipse_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawCenterEllipse_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(16);
+ forceEraser = true;
+ drawingShapeMode = 16;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawCenterEllipseWithFocalPoint_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawCenterEllipseWithFocalPoint_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(23);
+ forceEraser = true;
+ drawingShapeMode = 23;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawDashedCircle_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawDashedCircle_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(10);
+ forceEraser = true;
+ drawingShapeMode = 10;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawHyperbola_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawHyperbola_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(24);
+ forceEraser = true;
+ drawingShapeMode = 24;
drawMultiStepShapeCurrentStep = 0;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawHyperbolaWithFocalPoint_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawHyperbolaWithFocalPoint_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(25);
+ forceEraser = true;
+ drawingShapeMode = 25;
drawMultiStepShapeCurrentStep = 0;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawParabola1_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawParabola1_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(20);
+ forceEraser = true;
+ drawingShapeMode = 20;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawParabolaWithFocalPoint_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawParabolaWithFocalPoint_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(22);
+ forceEraser = true;
+ drawingShapeMode = 22;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawParabola2_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawParabola2_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(21);
+ forceEraser = true;
+ drawingShapeMode = 21;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawCylinder_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawCylinder_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(6);
+ forceEraser = true;
+ drawingShapeMode = 6;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawCone_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawCone_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(7);
+ forceEraser = true;
+ drawingShapeMode = 7;
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
- private async void BtnDrawCuboid_Click(object sender, MouseButtonEventArgs e)
- {
+ private async void BtnDrawCuboid_Click(object sender, MouseButtonEventArgs e) {
await CheckIsDrawingShapesInMultiTouchMode();
- EnterShapeDrawingMode(9);
+ forceEraser = true;
+ drawingShapeMode = 9;
isFirstTouchCuboid = true;
CuboidFrontRectIniP = new Point();
CuboidFrontRectEndP = new Point();
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
+ inkCanvas.IsManipulationEnabled = true;
CancelSingleFingerDragMode();
- lastMouseDownSender = null;
DrawShapePromptToPen();
}
#endregion
- private void inkCanvas_TouchMove(object sender, TouchEventArgs e)
- {
- // 确保套索选择模式下触摸移动时光标保持可见
- if (inkCanvas.EditingMode == InkCanvasEditingMode.Select)
- {
- SetCursorBasedOnEditingMode(inkCanvas);
- }
-
- if (drawingShapeMode != 0)
- {
- inkCanvas.EditingMode = InkCanvasEditingMode.None;
-
- if (!isTouchDown) return;
-
- if (isWaitUntilNextTouchDown && dec.Count > 1) return;
-
- // 对于多笔图形绘制,允许第二笔绘制,即使dec.Count > 1
- if (dec.Count > 1 && !((drawingShapeMode == 24 || drawingShapeMode == 25) && drawMultiStepShapeCurrentStep == 1))
- {
- // 其他情况正常删除临时笔画
- try
- {
+ private void inkCanvas_TouchMove(object sender, TouchEventArgs e) {
+ if (isSingleFingerDragMode) return;
+ if (drawingShapeMode != 0) {
+ //EraserContainer.Background = null;
+ //ImageEraser.Visibility = Visibility.Visible;
+ if (isWaitUntilNextTouchDown) return;
+ if (dec.Count > 1) {
+ isWaitUntilNextTouchDown = true;
+ try {
inkCanvas.Strokes.Remove(lastTempStroke);
inkCanvas.Strokes.Remove(lastTempStrokeCollection);
}
- catch
- {
+ catch {
Trace.WriteLine("lastTempStrokeCollection failed.");
}
+
return;
}
- // 第二笔绘制双曲线时,只删除第二笔的临时笔画,保留第一笔的辅助线
- if ((drawingShapeMode == 24 || drawingShapeMode == 25) && drawMultiStepShapeCurrentStep == 1)
- {
- try
- {
- inkCanvas.Strokes.Remove(lastTempStroke);
- }
- catch { }
- // 不直接返回,继续执行绘制逻辑
- }
-
- Point touchPoint = e.GetTouchPoint(inkCanvas).Position;
- if ((drawingShapeMode == 24 || drawingShapeMode == 25) && drawMultiStepShapeCurrentStep == 1)
- {
- // 第二笔绘制双曲线时,使用触摸位置作为终点,但保持第一笔的起点
- // 这里不需要特殊处理,因为MouseTouchMove函数内部已经正确处理了双曲线的绘制逻辑
- MouseTouchMove(touchPoint);
- }
- else
- {
- // 其他情况正常处理
- MouseTouchMove(touchPoint);
- }
-
- return; // 处理完几何绘制后直接返回,不执行后面的代码
+ if (inkCanvas.EditingMode != InkCanvasEditingMode.None)
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
}
- // 其它模式下,允许橡皮、套索、批注等正常工作,不覆盖EditingMode
- if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint ||
- inkCanvas.EditingMode == InkCanvasEditingMode.Select ||
- inkCanvas.EditingMode == InkCanvasEditingMode.Ink)
- {
- // 允许正常橡皮、套索、批注
- }
+ MouseTouchMove(e.GetTouchPoint(inkCanvas).Position);
}
private int drawMultiStepShapeCurrentStep; //多笔完成的图形 当前所处在的笔画
@@ -559,8 +478,7 @@ namespace Ink_Canvas
#region 形状绘制主函数
- private void MouseTouchMove(Point endP)
- {
+ private void MouseTouchMove(Point endP) {
// 禁用原有的FitToCurve,使用新的高级贝塞尔曲线平滑
if (Settings.Canvas.FitToCurve) drawingAttributes.FitToCurve = false;
// 在绘制过程中禁用浮动栏交互,避免干扰绘制
@@ -580,24 +498,42 @@ 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 {
+ inkCanvas.Strokes.Remove(lastTempStroke);
+ }
+ catch { }
- UpdateTempStrokeSafely(stroke);
+ lastTempStroke = stroke;
+ inkCanvas.Strokes.Add(stroke);
break;
case 8:
_currentCommitType = CommitReason.ShapeDrawing;
strokes.Add(GenerateDashedLineStrokeCollection(iniP, endP));
+ try {
+ inkCanvas.Strokes.Remove(lastTempStrokeCollection);
+ }
+ catch {
+ Trace.WriteLine("lastTempStrokeCollection failed.");
+ }
- UpdateTempStrokeCollectionSafely(strokes);
+ lastTempStrokeCollection = strokes;
+ inkCanvas.Strokes.Add(strokes);
break;
case 18:
_currentCommitType = CommitReason.ShapeDrawing;
strokes.Add(GenerateDotLineStrokeCollection(iniP, endP));
+ try {
+ inkCanvas.Strokes.Remove(lastTempStrokeCollection);
+ }
+ catch {
+ Trace.WriteLine("lastTempStrokeCollection failed.");
+ }
- UpdateTempStrokeCollectionSafely(strokes);
+ lastTempStrokeCollection = strokes;
+ inkCanvas.Strokes.Add(strokes);
break;
case 2:
_currentCommitType = CommitReason.ShapeDrawing;
@@ -614,13 +550,16 @@ 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 {
+ inkCanvas.Strokes.Remove(lastTempStroke);
+ }
+ catch { }
- // 优化:使用更安全的临时笔画更新方式,减少闪烁
- UpdateTempStrokeSafely(stroke);
+ lastTempStroke = stroke;
+ inkCanvas.Strokes.Add(stroke);
break;
case 15:
_currentCommitType = CommitReason.ShapeDrawing;
@@ -676,12 +615,10 @@ 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.");
}
@@ -694,12 +631,10 @@ 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.");
}
@@ -714,12 +649,10 @@ 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.");
}
@@ -734,12 +667,10 @@ 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.");
}
@@ -755,12 +686,10 @@ 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.");
}
@@ -776,12 +705,10 @@ 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.");
}
@@ -798,12 +725,10 @@ 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 { }
@@ -823,12 +748,10 @@ 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 { }
@@ -840,12 +763,10 @@ 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 { }
@@ -859,12 +780,10 @@ 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 { }
@@ -873,8 +792,7 @@ namespace Ink_Canvas
inkCanvas.Strokes.Add(stroke);
// 如果启用了圆心标记功能,则绘制圆心
- if (Settings.Canvas.ShowCircleCenter)
- {
+ if (Settings.Canvas.ShowCircleCenter) {
DrawCircleCenter(iniP);
}
break;
@@ -885,12 +803,10 @@ 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 { }
@@ -905,54 +821,46 @@ 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 { }
@@ -965,23 +873,15 @@ 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.");
}
lastTempStrokeCollection = strokes;
inkCanvas.Strokes.Add(strokes);
-
- // 如果启用了圆心标记功能,则绘制圆心
- if (Settings.Canvas.ShowCircleCenter)
- {
- DrawCircleCenter(iniP);
- }
break;
case 24:
case 25:
@@ -991,8 +891,7 @@ 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(
@@ -1002,29 +901,25 @@ namespace Ink_Canvas
new Point(endP.X, 2 * iniP.Y - endP.Y)));
drawMultiStepShapeSpecialParameter3 = k;
drawMultiStepShapeSpecialStrokeCollection = strokes;
-
- try
- {
- inkCanvas.Strokes.Remove(lastTempStrokeCollection);
- }
- catch { }
- lastTempStrokeCollection = strokes;
- inkCanvas.Strokes.Add(strokes);
}
- else
- {
+ else {
//第二笔:画双曲线
+ // 先将第一笔的渐近线添加到strokes中
+ if (drawMultiStepShapeSpecialStrokeCollection != null && drawMultiStepShapeSpecialStrokeCollection.Count > 0) {
+ foreach (var asymptoteStroke in drawMultiStepShapeSpecialStrokeCollection) {
+ strokes.Add(asymptoteStroke.Clone());
+ }
+ }
+
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));
@@ -1032,15 +927,13 @@ 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));
@@ -1049,8 +942,7 @@ namespace Ink_Canvas
}
}
- try
- {
+ try {
point = new StylusPointCollection(pointList);
stroke = new Stroke(point)
{ DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() };
@@ -1067,8 +959,7 @@ namespace Ink_Canvas
stroke = new Stroke(point)
{ DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone() };
strokes.Add(stroke.Clone());
- if (drawingShapeMode == 25)
- {
+ if (drawingShapeMode == 25) {
//画焦点
c = Math.Sqrt(a * a + b * b);
stylusPoint = isHyperbolaFocalPointOnXAxis
@@ -1077,7 +968,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)
@@ -1085,49 +976,24 @@ 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);
-
- // 创建包含辅助线和双曲线的完整笔画集合
- var completeStrokes = new StrokeCollection();
-
- // 添加第一笔的辅助线
- if (drawMultiStepShapeSpecialStrokeCollection != null && drawMultiStepShapeSpecialStrokeCollection.Count > 0)
- {
- foreach (var stroke1 in drawMultiStepShapeSpecialStrokeCollection)
- {
- completeStrokes.Add(stroke1.Clone());
- }
- }
-
- // 添加第二笔的双曲线
- foreach (var stroke1 in strokes)
- {
- completeStrokes.Add(stroke1.Clone());
- }
-
- lastTempStrokeCollection = completeStrokes;
- inkCanvas.Strokes.Add(completeStrokes);
}
- catch (Exception ex)
- {
- Trace.WriteLine($"双曲线绘制完成处理失败: {ex.Message}");
- // 如果合并失败,至少添加双曲线部分
+ catch {
+ Trace.WriteLine("lastTempStrokeCollection failed.");
+ }
+
lastTempStrokeCollection = strokes;
inkCanvas.Strokes.Add(strokes);
- }
break;
case 20:
_currentCommitType = CommitReason.ShapeDrawing;
@@ -1791,10 +1657,8 @@ namespace Ink_Canvas
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;
@@ -1806,52 +1670,25 @@ namespace Ink_Canvas
circles.Add(circle);
}
- if (lastIsInMultiTouchMode)
- {
- // 不再重新启用开关,而是恢复多指书写相关的事件处理
- // ToggleSwitchEnableMultiTouchMode.IsOn = true;
-
- // 恢复多指书写事件处理
- inkCanvas.StylusDown += MainWindow_StylusDown;
- inkCanvas.StylusMove += MainWindow_StylusMove;
- inkCanvas.StylusUp += MainWindow_StylusUp;
- inkCanvas.TouchDown += MainWindow_TouchDown;
-
+ if (lastIsInMultiTouchMode) {
+ ToggleSwitchEnableMultiTouchMode.IsOn = true;
lastIsInMultiTouchMode = false;
}
}
- // 修改此处逻辑,确保在正确的情况下才切换回笔模式
- if (drawingShapeMode != 9 && drawingShapeMode != 0 && drawingShapeMode != 24 && drawingShapeMode != 25)
- {
- if (isLongPressSelected)
- {
- // 如果是长按选中的情况,保持图形模式,不做任何切换
- isWaitUntilNextTouchDown = true; // 保持当前绘图模式直到下一次触摸
- }
- else
- {
+ if (drawingShapeMode != 9 && drawingShapeMode != 0 && drawingShapeMode != 24 && drawingShapeMode != 25) {
+ if (isLongPressSelected) { }
+ else {
BtnPen_Click(null, null); //画完一次还原到笔模式
- if (lastIsInMultiTouchMode)
- {
- // 不再重新启用开关,而是恢复多指书写相关的事件处理
- // ToggleSwitchEnableMultiTouchMode.IsOn = true;
-
- // 恢复多指书写事件处理
- inkCanvas.StylusDown += MainWindow_StylusDown;
- inkCanvas.StylusMove += MainWindow_StylusMove;
- inkCanvas.StylusUp += MainWindow_StylusUp;
- inkCanvas.TouchDown += MainWindow_TouchDown;
-
+ if (lastIsInMultiTouchMode) {
+ ToggleSwitchEnableMultiTouchMode.IsOn = true;
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),
@@ -1860,40 +1697,25 @@ 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)
- {
- // 不再重新启用开关,而是恢复多指书写相关的事件处理
- // ToggleSwitchEnableMultiTouchMode.IsOn = true;
-
- // 恢复多指书写事件处理
- inkCanvas.StylusDown += MainWindow_StylusDown;
- inkCanvas.StylusMove += MainWindow_StylusMove;
- inkCanvas.StylusUp += MainWindow_StylusUp;
- inkCanvas.TouchDown += MainWindow_TouchDown;
-
+ if (lastIsInMultiTouchMode) {
+ ToggleSwitchEnableMultiTouchMode.IsOn = true;
lastIsInMultiTouchMode = false;
}
- if (_currentCommitType == CommitReason.ShapeDrawing)
- {
- try
- {
+ if (_currentCommitType == CommitReason.ShapeDrawing) {
+ try {
CuboidStrokeCollection.Add(lastTempStrokeCollection);
}
- catch
- {
+ catch {
Trace.WriteLine("lastTempStrokeCollection failed.");
}
@@ -1904,20 +1726,15 @@ 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;
@@ -1935,17 +1752,8 @@ namespace Ink_Canvas
}
BtnPen_Click(null, null); //画完还原到笔模式
- if (lastIsInMultiTouchMode)
- {
- // 不再重新启用开关,而是恢复多指书写相关的事件处理
- // ToggleSwitchEnableMultiTouchMode.IsOn = true;
-
- // 恢复多指书写事件处理
- inkCanvas.StylusDown += MainWindow_StylusDown;
- inkCanvas.StylusMove += MainWindow_StylusMove;
- inkCanvas.StylusUp += MainWindow_StylusUp;
- inkCanvas.TouchDown += MainWindow_TouchDown;
-
+ if (lastIsInMultiTouchMode) {
+ ToggleSwitchEnableMultiTouchMode.IsOn = true;
lastIsInMultiTouchMode = false;
}
}
@@ -1992,32 +1800,7 @@ namespace Ink_Canvas
}
}
- // 应用高级贝塞尔曲线平滑
- if (Settings.Canvas.UseAdvancedBezierSmoothing)
- {
- try
- {
- // 对临时笔画应用平滑
- if (lastTempStroke != null && _inkSmoothingManager != null)
- {
- var smoothedStroke = _inkSmoothingManager.SmoothStroke(lastTempStroke);
- if (smoothedStroke != lastTempStroke)
- {
- inkCanvas.Strokes.Remove(lastTempStroke);
- lastTempStroke = smoothedStroke;
- inkCanvas.Strokes.Add(smoothedStroke);
- }
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine($"形状绘制高级贝塞尔曲线平滑失败: {ex.Message}");
- }
- }
- else if (Settings.Canvas.FitToCurve)
- {
- drawingAttributes.FitToCurve = true;
- }
+ if (Settings.Canvas.FitToCurve == true) drawingAttributes.FitToCurve = true;
}
private bool NeedUpdateIniP()
@@ -2029,79 +1812,6 @@ namespace Ink_Canvas
}
return true;
}
-
- private void MainWindow_OnMouseMove(object sender, MouseEventArgs e)
- {
- if (e.StylusDevice == null)
- {
- // 鼠标移动时保持光标可见
- System.Windows.Forms.Cursor.Show();
-
- // 如果用户设置了显示光标,则确保光标显示正确
- if (Settings.Canvas.IsShowCursor && inkCanvas != null)
- {
- inkCanvas.ForceCursor = true;
- inkCanvas.UseCustomCursor = true;
- }
- }
- else
- {
- // 只有当用户未设置显示光标时才隐藏
- if (!Settings.Canvas.IsShowCursor)
- {
- System.Windows.Forms.Cursor.Hide();
- }
- else if (inkCanvas != null)
- {
- // 如果用户设置了显示光标,则确保光标显示正确
- inkCanvas.ForceCursor = true;
- inkCanvas.UseCustomCursor = true;
- System.Windows.Forms.Cursor.Show();
- }
- }
- }
-
- private void EnterShapeDrawingMode(int mode)
- {
- forceEraser = true;
- forcePointEraser = false;
- drawingShapeMode = mode;
- inkCanvas.EditingMode = InkCanvasEditingMode.None;
- SetCursorBasedOnEditingMode(inkCanvas);
- ResetAllShapeButtonsOpacity();
- }
-
- ///
- /// 重置所有几何绘制按钮的透明度状态
- ///
- private void ResetAllShapeButtonsOpacity()
- {
- try
- {
- // 重置所有几何绘制按钮的透明度为1(完全不透明)
- var buttons = new UIElement[] {
- ImageDrawLine, BoardImageDrawLine,
- ImageDrawDashedLine, BoardImageDrawDashedLine,
- ImageDrawDotLine, BoardImageDrawDotLine,
- ImageDrawArrow, BoardImageDrawArrow,
- ImageDrawParallelLine, BoardImageDrawParallelLine,
- };
-
- foreach (var button in buttons)
- {
- if (button != null)
- {
- var dA = new DoubleAnimation(1, 1, new Duration(TimeSpan.FromMilliseconds(0)));
- button.BeginAnimation(OpacityProperty, dA);
- }
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"重置几何绘制按钮透明度失败: {ex.Message}", LogHelper.LogType.Error);
- }
- }
-
///
/// 绘制圆心标记
///
@@ -2142,5 +1852,12 @@ namespace Ink_Canvas
Debug.WriteLine($"绘制圆心标记失败: {ex.Message}");
}
}
+ private void MainWindow_OnMouseMove(object sender, MouseEventArgs e) {
+ if (e.StylusDevice == null) {
+ System.Windows.Forms.Cursor.Show();
+ } else {
+ System.Windows.Forms.Cursor.Hide();
+ }
+ }
}
}
diff --git a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs
index e56b1ac3..d6542764 100644
--- a/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs
+++ b/Ink Canvas/MainWindow_cs/MW_SimulatePressure&InkToShape.cs
@@ -18,21 +18,19 @@ namespace Ink_Canvas
{
private StrokeCollection newStrokes = new StrokeCollection();
private List circles = new List();
- private const double LINE_STRAIGHTEN_THRESHOLD = 0.20; // 默认灵敏度阈值,与UI默认值对应
+ private const double LINE_STRAIGHTEN_THRESHOLD = 0.20;
- // 矩形参考线系统
private List rectangleGuideLines = new List();
- private const double RECTANGLE_ENDPOINT_THRESHOLD = 30.0; // 端点相交判断阈值
- private const double RECTANGLE_ANGLE_THRESHOLD = 15.0; // 角度判断阈值(度)
+ private const double RECTANGLE_ENDPOINT_THRESHOLD = 30.0;
+ private const double RECTANGLE_ANGLE_THRESHOLD = 15.0;
- // 矩形参考线数据结构
private class RectangleGuideLine
{
public Stroke OriginalStroke { get; set; }
public Point StartPoint { get; set; }
public Point EndPoint { get; set; }
public DateTime CreatedTime { get; set; }
- public double Angle { get; set; } // 直线角度(弧度)
+ public double Angle { get; set; }
public bool IsHorizontal { get; set; }
public bool IsVertical { get; set; }
@@ -64,7 +62,6 @@ namespace Ink_Canvas
var startPoint = e.Stroke.StylusPoints.Count > 0 ? e.Stroke.StylusPoints[0].ToPoint() : new Point();
var endPoint = e.Stroke.StylusPoints.Count > 0 ? e.Stroke.StylusPoints[e.Stroke.StylusPoints.Count - 1].ToPoint() : new Point();
- // 确保InkCanvas保持Ink编辑模式,防止自动切换到鼠标模式
if (inkCanvas.EditingMode != InkCanvasEditingMode.Ink)
{
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
@@ -80,19 +77,15 @@ namespace Ink_Canvas
LogHelper.WriteLogToFile("StrokeCollected: 墨迹渐隐管理器为空,无法添加墨迹", LogHelper.LogType.Error);
}
- // 延迟移除墨迹,避免立即移除导致模式切换
- // 使用Dispatcher.BeginInvoke确保在UI线程上异步执行
Dispatcher.BeginInvoke(new Action(() =>
{
try
{
- // 再次确保InkCanvas保持Ink编辑模式
if (inkCanvas.EditingMode != InkCanvasEditingMode.Ink)
{
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
}
- // 从InkCanvas中移除墨迹,因为我们要用渐隐管理器来管理它
if (inkCanvas.Strokes.Contains(e.Stroke))
{
inkCanvas.Strokes.Remove(e.Stroke);
@@ -104,21 +97,18 @@ namespace Ink_Canvas
}
}), DispatcherPriority.Background);
- // 墨迹渐隐模式下不参与墨迹纠正和其他处理,直接返回
return;
}
// 标记是否进行了直线拉直
bool wasStraightened = false;
- // 禁用原有的FitToCurve,使用新的高级贝塞尔曲线平滑
if (Settings.Canvas.FitToCurve) drawingAttributes.FitToCurve = false;
try
{
inkCanvas.Opacity = 1;
- // 应用屏蔽压感功能 - 如果启用,所有笔画都使用统一粗细
if (Settings.Canvas.DisablePressure)
{
var uniformPoints = new StylusPointCollection();
@@ -129,13 +119,11 @@ namespace Ink_Canvas
}
e.Stroke.StylusPoints = uniformPoints;
}
- // 应用压感触屏模式 - 如果启用并且检测到触屏输入
else if (Settings.Canvas.EnablePressureTouchMode)
{
bool isTouchInput = true;
foreach (StylusPoint point in e.Stroke.StylusPoints)
{
- // 检测是否为压感笔输入(压感笔的PressureFactor不等于0.5或0)
if ((point.PressureFactor > 0.501 || point.PressureFactor < 0.5) && point.PressureFactor != 0)
{
isTouchInput = false;
@@ -143,7 +131,6 @@ namespace Ink_Canvas
}
}
- // 如果是触屏输入,则应用模拟压感
if (isTouchInput)
{
switch (Settings.Canvas.InkStyle)
@@ -859,30 +846,61 @@ namespace Ink_Canvas
// 快速检查:计算几个关键点与直线的距离
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}");
-
- if (quarterDeviation > quickRelativeThreshold ||
- midDeviation > quickRelativeThreshold ||
- threeQuarterDeviation > quickRelativeThreshold)
+ List checkPoints;
+
+ // 使用采样点进行更准确的判断
+ if (Settings.Canvas.HighPrecisionLineStraighten)
{
- return false;
+ var allPoints = stroke.StylusPoints.Select(p => p.ToPoint()).ToList();
+ checkPoints = SamplePointsByDistance(allPoints, 10.0);
+ Debug.WriteLine($"高精度模式快速检查:原始点数={allPoints.Count}, 采样点数={checkPoints.Count}");
+ }
+ else
+ {
+ // 取中点和1/4、3/4位置的点
+ int quarterIdx = stroke.StylusPoints.Count / 4;
+ int midIdx = stroke.StylusPoints.Count / 2;
+ int threeQuarterIdx = quarterIdx * 3;
+
+ checkPoints = new List
+ {
+ stroke.StylusPoints[quarterIdx].ToPoint(),
+ stroke.StylusPoints[midIdx].ToPoint(),
+ stroke.StylusPoints[threeQuarterIdx].ToPoint()
+ };
+ }
+
+ // 计算所有检查点与直线的平均偏差
+ double totalDeviation = 0;
+ double maxDeviation = 0;
+ int validPointCount = 0;
+
+ foreach (Point checkPoint in checkPoints)
+ {
+ double deviation = DistanceFromLineToPoint(start, end, checkPoint);
+ totalDeviation += deviation;
+ maxDeviation = Math.Max(maxDeviation, deviation);
+ validPointCount++;
+ }
+
+ if (validPointCount > 0)
+ {
+ double avgDeviation = totalDeviation / validPointCount;
+ // 使用相对偏差:偏差与线长的比例,并使用灵敏度进行调整
+ double quickRelativeThreshold = lineLength * quickThreshold;
+
+ // 使用平均偏差和最大偏差的综合判断
+ double deviationThreshold = Settings.Canvas.HighPrecisionLineStraighten
+ ? Math.Max(avgDeviation, maxDeviation * 0.7) // 高精度模式更严格
+ : maxDeviation;
+
+ // 记录检测到的偏差
+ Debug.WriteLine($"Deviations: avg={avgDeviation:F2}, max={maxDeviation:F2}, threshold={quickRelativeThreshold:F2}, highPrecision={Settings.Canvas.HighPrecisionLineStraighten}");
+
+ if (deviationThreshold > quickRelativeThreshold)
+ {
+ return false;
+ }
}
}
@@ -1177,14 +1195,29 @@ namespace Ink_Canvas
return false;
}
+ List workingPoints = points;
+ if (Settings.Canvas.HighPrecisionLineStraighten)
+ {
+ workingPoints = SamplePointsByDistance(points, 10.0);
+ Debug.WriteLine($"高精度模式:原始点数={points.Count}, 采样后点数={workingPoints.Count}");
+ }
+
// 使用总最小二乘法(TLS/PCA)进行直线拟合
- int n = points.Count - 8;
+ int n = workingPoints.Count - 8;
+ if (n < 1)
+ {
+ // 如果采样后点数太少,回退到原始方法
+ n = points.Count - 8;
+ workingPoints = points;
+ }
+
List filteredPoints = new List();
// 收集过滤后的点(跳过前 4 个和后 4 个点,用于计算直线方向)
- for (int i = 4; i < n + 4; i++)
+ int skipCount = Math.Min(4, n / 2); // 确保跳过数量不超过一半
+ for (int i = skipCount; i < n + skipCount && i < workingPoints.Count; i++)
{
- filteredPoints.Add(points[i]);
+ filteredPoints.Add(workingPoints[i]);
}
// 计算中心点(使用过滤后的点)
@@ -1244,7 +1277,8 @@ namespace Ink_Canvas
double maxProjection = double.MinValue;
// 计算所有点在直线方向上的投影
- foreach (Point p in points)
+ List pointsForProjection = Settings.Canvas.HighPrecisionLineStraighten ? workingPoints : points;
+ foreach (Point p in pointsForProjection)
{
// 相对于过滤点中心的投影
double projection = (p.X - centerX) * directionX + (p.Y - centerY) * directionY;
@@ -1453,6 +1487,43 @@ namespace Ink_Canvas
return points;
}
+ ///
+ /// 高精度模式
+ ///
+ private List SamplePointsByDistance(List points, double sampleInterval = 10.0)
+ {
+ if (points == null || points.Count < 2)
+ return points;
+
+ List sampledPoints = new List();
+ sampledPoints.Add(points[0]); // 总是包含起点
+
+ double accumulatedDistance = 0;
+ Point lastSampledPoint = points[0];
+
+ for (int i = 1; i < points.Count; i++)
+ {
+ double segmentDistance = GetDistance(lastSampledPoint, points[i]);
+ accumulatedDistance += segmentDistance;
+
+ // 当累积距离达到采样间隔时,添加当前点
+ if (accumulatedDistance >= sampleInterval)
+ {
+ sampledPoints.Add(points[i]);
+ lastSampledPoint = points[i];
+ accumulatedDistance = 0; // 重置累积距离
+ }
+ }
+
+ // 总是包含终点(如果还没有包含)
+ if (sampledPoints.Count == 0 || GetDistance(sampledPoints.Last(), points.Last()) > 1.0)
+ {
+ sampledPoints.Add(points.Last());
+ }
+
+ return sampledPoints;
+ }
+
// New method: Gets distance from point to a line defined by two points
private double DistanceFromLineToPoint(Point lineStart, Point lineEnd, Point point)
{
@@ -1467,11 +1538,66 @@ namespace Ink_Canvas
return distance;
}
+ ///
+ /// 判断一个 stroke 是否是直线(排除虚线和点线)
+ ///
+ /// 要检查的 stroke
+ /// 如果是直线返回 true,否则返回 false
+ private bool IsStraightLine(Stroke stroke)
+ {
+ if (stroke == null || stroke.StylusPoints.Count == 0)
+ return false;
+
+ int pointCount = stroke.StylusPoints.Count;
+
+ if (pointCount == 1)
+ return false;
+
+ // 最简单的直线:只有2个点
+ if (pointCount == 2)
+ {
+ Point p1 = stroke.StylusPoints[0].ToPoint();
+ Point p2 = stroke.StylusPoints[1].ToPoint();
+ double lineLength = GetDistance(p1, p2);
+
+ if (lineLength < 10)
+ return false;
+
+ return true;
+ }
+
+ if (pointCount > 3)
+ return false;
+
+ // 对于3个点的情况,检查它们是否基本在一条直线上
+ if (pointCount == 3)
+ {
+ Point p1 = stroke.StylusPoints[0].ToPoint();
+ Point p2 = stroke.StylusPoints[1].ToPoint();
+ Point p3 = stroke.StylusPoints[2].ToPoint();
+
+ double totalLength = GetDistance(p1, p3);
+ if (totalLength < 10)
+ return false;
+
+ // 计算点到直线的距离
+ // 使用 p1 和 p3 作为直线端点,检查 p2 是否在这条直线上
+ double distance = DistanceFromLineToPoint(p1, p3, p2);
+
+ // 如果点到直线的距离相对于线段长度很小,认为是直线
+ // 使用相对误差阈值(比如 1%)
+ if (totalLength > 0 && distance / totalLength < 0.01)
+ return true;
+
+ return false;
+ }
+
+ return false;
+ }
+
// New method: Attempts to snap endpoints to existing stroke endpoints
private Point[] GetSnappedEndpoints(Point start, Point end)
{
- // 如果端点吸附功能关闭,直接返回null
- // 这里不再返回原始点,因为调用此方法的地方会判断返回值是否为null
if (!Settings.Canvas.LineEndpointSnapping)
return null;
@@ -1488,6 +1614,10 @@ namespace Ink_Canvas
{
if (stroke.StylusPoints.Count == 0) continue;
+ // 只对直线进行端点吸附,跳过虚线和点线
+ if (!IsStraightLine(stroke))
+ continue;
+
// Get stroke endpoints
Point strokeStart = stroke.StylusPoints.First().ToPoint();
Point strokeEnd = stroke.StylusPoints.Last().ToPoint();
diff --git a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs
index 31525760..592d8aba 100644
--- a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs
+++ b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs
@@ -325,7 +325,7 @@ namespace Ink_Canvas
// 根据当前编辑模式设置不同的光标
if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
{
- inkCanvas.Cursor = Cursors.Cross;
+ inkCanvas.Cursor = Cursors.Arrow;
}
else if (inkCanvas.EditingMode == InkCanvasEditingMode.Ink)
{
@@ -533,13 +533,6 @@ namespace Ink_Canvas
if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
{
- // 橡皮状态下只return,保证橡皮状态可保持
- return;
- }
- if (inkCanvas.EditingMode == InkCanvasEditingMode.Select)
- {
- // 套索选状态下不直接return,允许触摸事件继续处理
- dec.Add(e.TouchDevice.Id);
return;
}
if (drawingShapeMode != 0)
@@ -556,6 +549,11 @@ namespace Ink_Canvas
return;
}
+ if (inkCanvas.EditingMode == InkCanvasEditingMode.Select)
+ {
+ dec.Add(e.TouchDevice.Id);
+ return;
+ }
if (inkCanvas.EditingMode == InkCanvasEditingMode.Ink)
{
return;
@@ -571,171 +569,30 @@ namespace Ink_Canvas
}
}
- // 手掌擦相关变量
- private bool isPalmEraserActive;
- private InkCanvasEditingMode palmEraserLastEditingMode = InkCanvasEditingMode.Ink;
- private bool palmEraserLastIsHighlighter;
- private bool palmEraserWasEnabledBeforeMultiTouch;
-
public double GetTouchBoundWidth(TouchEventArgs e)
{
var args = e.GetTouchPoint(null).Bounds;
- if (!Settings.Advanced.IsQuadIR) return args.Width;
- else return Math.Sqrt(args.Width * args.Height); // 四边红外
+ 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;
}
private void inkCanvas_PreviewTouchDown(object sender, TouchEventArgs e)
{
- // 检查触摸是否发生在浮动栏区域,如果是则允许事件传播到浮动栏按钮
- var touchPoint = e.GetTouchPoint(this);
- var floatingBarBounds = ViewboxFloatingBar.TransformToAncestor(this).TransformBounds(
- new Rect(0, 0, ViewboxFloatingBar.ActualWidth, ViewboxFloatingBar.ActualHeight));
-
- // 如果触摸发生在浮动栏区域,不阻止事件传播,让浮动栏按钮能够接收触摸事件
- if (floatingBarBounds.Contains(touchPoint.Position))
- {
- // 不设置 ViewboxFloatingBar.IsHitTestVisible = false,让浮动栏按钮能够接收触摸事件
- return;
- }
-
- // 橡皮状态下不做任何切换,直接return,保证橡皮可持续
- if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint
- || inkCanvas.EditingMode == InkCanvasEditingMode.EraseByStroke)
- {
- 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;
- }
- // 第二笔时不更新iniP,保持第一笔的起点
- }
- 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);
-
- // Palm Eraser 逻辑
- if (Settings.Canvas.EnablePalmEraser && !isPalmEraserActive)
- {
- 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)
- {
- // 记录当前编辑模式和高光状态
- palmEraserLastEditingMode = inkCanvas.EditingMode;
- palmEraserLastIsHighlighter = drawingAttributes.IsHighlighter;
-
- // 动态调整橡皮大小
- 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;
- }
- }
- }
- }
-
- // 设备1个的时候,记录中心点
+ //设备1个的时候,记录中心点
if (dec.Count == 1)
{
- touchPoint = e.GetTouchPoint(inkCanvas);
+ var touchPoint = e.GetTouchPoint(inkCanvas);
centerPoint = touchPoint.Position;
- if (drawingShapeMode != 0)
- {
- // 对于双曲线绘制,第一笔时记录起点,第二笔时不更新起点
- if (drawingShapeMode == 24 || drawingShapeMode == 25)
- {
- // 双曲线绘制:第一笔记录起点,第二笔保持第一笔的起点
- if (drawMultiStepShapeCurrentStep == 0)
- {
- iniP = touchPoint.Position;
- }
- // 第二笔时不更新iniP,保持第一笔的起点
- }
- else
- {
- // 其他图形正常记录起点
- iniP = touchPoint.Position;
- }
- }
-
- // 记录第一根手指点击时的 StrokeCollection
+ //记录第一根手指点击时的 StrokeCollection
lastTouchDownStrokeCollection = inkCanvas.Strokes.Clone();
}
//设备两个及两个以上,将画笔功能关闭
@@ -744,61 +601,25 @@ namespace Ink_Canvas
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;
- System.Threading.Tasks.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;
- if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint
- && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByStroke
- && drawingShapeMode == 0)
- {
- inkCanvas.EditingMode = InkCanvasEditingMode.None;
- }
+ inkCanvas.EditingMode = InkCanvasEditingMode.None;
}
}
private void inkCanvas_PreviewTouchMove(object sender, TouchEventArgs e)
{
-
- // 如果手掌擦激活,更新橡皮擦反馈位置
- if (isPalmEraserActive)
- {
- var touchPoint = e.GetTouchPoint(inkCanvas);
- EraserOverlay_PointerMove(sender, touchPoint.Position);
- }
}
private void inkCanvas_PreviewTouchUp(object sender, TouchEventArgs e)
{
- // 橡皮状态下不做任何切换,直接return,保证橡皮可持续
- if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint && !isPalmEraserActive)
- {
- return;
- }
inkCanvas.ReleaseAllTouchCaptures();
ViewboxFloatingBar.IsHitTestVisible = true;
BlackboardUIGridForInkReplay.IsHitTestVisible = true;
- // Palm Eraser 逻辑
+ //手势完成后切回之前的状态
+ if (dec.Count > 1)
+ if (inkCanvas.EditingMode == InkCanvasEditingMode.None)
+ inkCanvas.EditingMode = lastInkCanvasEditingMode;
dec.Remove(e.TouchDevice.Id);
// 重置多触控点定时器状态
@@ -807,17 +628,30 @@ namespace Ink_Canvas
isMultiTouchTimerActive = false;
}
+ if (dec.Count == 0)
+ {
+ isSingleFingerDragMode = 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 (drawingShapeMode != 0)
{
isTouchDown = false;
ViewboxFloatingBar.IsHitTestVisible = true;
BlackboardUIGridForInkReplay.IsHitTestVisible = true;
- // 对于双曲线等需要多步绘制的图形,触摸抬手时应该进入下一步
if (drawingShapeMode == 24 || drawingShapeMode == 25)
{
- // 双曲线绘制:触摸抬手时进入下一步,但不自动触发鼠标抬起事件
- // 让用户继续绘制第二笔
if (drawMultiStepShapeCurrentStep == 0)
{
// 第一笔完成,进入第二笔
@@ -836,7 +670,6 @@ namespace Ink_Canvas
}
else
{
- // 其他单步绘制的图形,触摸抬手时完成绘制
var mouseArgs = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left)
{
RoutedEvent = MouseLeftButtonUpEvent,
@@ -846,82 +679,6 @@ 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)
- {
- // 当所有触摸点都抬起时,确保正确恢复编辑模式
- // 这对于从橡皮擦切换到笔后恢复多指手势功能很重要
- if (inkCanvas.EditingMode == InkCanvasEditingMode.None &&
- lastInkCanvasEditingMode != InkCanvasEditingMode.None &&
- lastInkCanvasEditingMode != InkCanvasEditingMode.EraseByPoint)
- {
- inkCanvas.EditingMode = lastInkCanvasEditingMode;
- }
-
- if (isPalmEraserActive)
- {
- LogHelper.WriteLogToFile("Palm eraser force recovery - all touch points cleared");
-
- // 恢复高光状态
- drawingAttributes.IsHighlighter = palmEraserLastIsHighlighter;
-
- // 恢复编辑模式
- try
- {
- if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
- {
- switch (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 force recovered to mode: {palmEraserLastEditingMode}");
- }
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"Palm eraser force recovery failed: {ex.Message}, forcing to Ink mode", LogHelper.LogType.Error);
- inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
- }
-
- // 如果手掌擦还在激活状态但触摸点已清空,强制重置状态
- isPalmEraserActive = false;
- inkCanvas.IsHitTestVisible = true;
- inkCanvas.IsManipulationEnabled = true;
-
- ViewboxFloatingBar.IsHitTestVisible = true;
- BlackboardUIGridForInkReplay.IsHitTestVisible = true;
-
- DisableEraserOverlay();
- if (Settings.Canvas.IsShowCursor)
- {
- inkCanvas.ForceCursor = true;
- inkCanvas.UseCustomCursor = true;
- }
-
- LogHelper.WriteLogToFile("Palm eraser force recovery completed");
- }
- }
- }
inkCanvas.Opacity = 1;
if (dec.Count == 0)
@@ -943,61 +700,37 @@ namespace Ink_Canvas
private void Main_Grid_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
- if (e.Manipulators.Count() != 0) return;
- if (drawingShapeMode == 0
- && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint
- && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByStroke
- && inkCanvas.EditingMode != InkCanvasEditingMode.Select)
+ if (e.Manipulators.Count() == 0)
{
- inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
- lastInkCanvasEditingMode = InkCanvasEditingMode.Ink;
+ if (dec.Count > 0)
+ {
+ dec.Clear();
+ }
+ isSingleFingerDragMode = false;
+
+ if (drawingShapeMode == 0
+ && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByPoint
+ && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByStroke
+ && inkCanvas.EditingMode != InkCanvasEditingMode.Select)
+ {
+ inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
+ lastInkCanvasEditingMode = InkCanvasEditingMode.Ink;
+ }
}
}
private void Main_Grid_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
- // 手掌擦时禁止移动/缩放
- if (inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint)
- return;
- // 三指及以上禁止缩放
- bool disableScale = dec.Count >= 3;
-
- if (isInMultiTouchMode) return;
-
- if (dec.Count == 0 && (isSingleFingerDragMode || isInMultiTouchMode))
- {
- ResetTouchStates();
- return;
- }
-
- // 如果是单指拖动选中的墨迹,允许处理
- if (dec.Count == 1 && inkCanvas.GetSelectedStrokes().Count > 0)
- {
- var md = e.DeltaManipulation;
- var trans = md.Translation; // 获得位移矢量
-
- if (trans.X != 0 || trans.Y != 0)
- {
- var m = new Matrix();
- m.Translate(trans.X, trans.Y); // 移动
-
- var strokes = inkCanvas.GetSelectedStrokes();
- foreach (var stroke in strokes)
- {
- stroke.Transform(m, false);
- }
-
- // 更新选择框位置
- updateBorderStrokeSelectionControlLocation();
- }
- return;
- }
-
- if (!Settings.Gesture.IsEnableTwoFingerGesture) return;
- if ((dec.Count >= 2 && (Settings.PowerPointSettings.IsEnableTwoFingerGestureInPresentationMode ||
- StackPanelPPTControls.Visibility != Visibility.Visible ||
- StackPanelPPTButtons.Visibility == Visibility.Collapsed)) ||
- isSingleFingerDragMode)
+ if (isInMultiTouchMode || !Settings.Gesture.IsEnableTwoFingerGesture) return;
+
+ bool hasMultipleManipulators = e.Manipulators.Count() >= 2;
+ bool shouldUseTwoFingerGesture = (dec.Count >= 2 && hasMultipleManipulators &&
+ (Settings.PowerPointSettings.IsEnableTwoFingerGestureInPresentationMode ||
+ StackPanelPPTControls.Visibility != Visibility.Visible ||
+ StackPanelPPTButtons.Visibility == Visibility.Collapsed)) ||
+ isSingleFingerDragMode;
+
+ if (shouldUseTwoFingerGesture)
{
var md = e.DeltaManipulation;
var trans = md.Translation; // 获得位移矢量
@@ -1007,20 +740,23 @@ namespace Ink_Canvas
if (Settings.Gesture.IsEnableTwoFingerTranslate)
m.Translate(trans.X, trans.Y); // 移动
+ // 计算中心点(用于缩放和旋转)
+ var fe = e.Source as FrameworkElement;
+ var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
+ center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
+
if (Settings.Gesture.IsEnableTwoFingerGestureTranslateOrRotation)
{
var rotate = md.Rotation; // 获得旋转角度
- var scale = md.Scale; // 获得缩放倍数
-
- // Find center of element and then transform to get current location of center
- var fe = e.Source as FrameworkElement;
- var center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
- center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
if (Settings.Gesture.IsEnableTwoFingerRotation)
m.RotateAt(rotate, center.X, center.Y); // 旋转
- if (Settings.Gesture.IsEnableTwoFingerZoom && !disableScale)
- m.ScaleAt(scale.X, scale.Y, center.X, center.Y); // 缩放
+ }
+
+ if (Settings.Gesture.IsEnableTwoFingerZoom)
+ {
+ var scale = md.Scale; // 获得缩放倍数
+ m.ScaleAt(scale.X, scale.Y, center.X, center.Y); // 缩放
}
var strokes = inkCanvas.GetSelectedStrokes();
@@ -1043,6 +779,13 @@ namespace Ink_Canvas
break;
}
+ if (!Settings.Gesture.IsEnableTwoFingerZoom) continue;
+ try
+ {
+ stroke.DrawingAttributes.Width *= md.Scale.X;
+ stroke.DrawingAttributes.Height *= md.Scale.Y;
+ }
+ catch { }
}
}
else
@@ -1165,69 +908,6 @@ namespace Ink_Canvas
LogHelper.WriteLogToFile($"应用媒体元素变换失败: {ex.Message}", LogHelper.LogType.Error);
}
}
-
- // 退出多指书写模式,恢复InkCanvas的TouchDown事件绑定
- private void ExitMultiTouchModeIfNeeded()
- {
- 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
- && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByStroke
- && drawingShapeMode == 0)
- {
- inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
- }
- // 保存非笔画元素(如图片)
- var preservedElements = PreserveNonStrokeElements();
- inkCanvas.Children.Clear();
- // 恢复非笔画元素
- RestoreNonStrokeElements(preservedElements);
- isInMultiTouchMode = false;
- // 关闭多指书写时,恢复手掌擦开关
- if (palmEraserWasEnabledBeforeMultiTouch)
- {
- Settings.Canvas.EnablePalmEraser = true;
- if (ToggleSwitchEnablePalmEraser != null)
- ToggleSwitchEnablePalmEraser.IsOn = true;
- }
- }
- }
-
- // 进入多指书写模式,绑定Main_Grid_TouchDown
- private void EnterMultiTouchModeIfNeeded()
- {
- 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
- && inkCanvas.EditingMode != InkCanvasEditingMode.EraseByStroke
- && drawingShapeMode == 0)
- {
- inkCanvas.EditingMode = InkCanvasEditingMode.None;
- }
- // 保存非笔画元素(如图片)
- var preservedElements = PreserveNonStrokeElements();
- inkCanvas.Children.Clear();
- // 恢复非笔画元素
- RestoreNonStrokeElements(preservedElements);
- isInMultiTouchMode = true;
- // 启用多指书写时,自动禁用手掌擦
- palmEraserWasEnabledBeforeMultiTouch = Settings.Canvas.EnablePalmEraser;
- Settings.Canvas.EnablePalmEraser = false;
- if (ToggleSwitchEnablePalmEraser != null)
- ToggleSwitchEnablePalmEraser.IsOn = false;
- }
- }
-
-
}
}
+
diff --git a/Ink Canvas/Resources/Settings.cs b/Ink Canvas/Resources/Settings.cs
index 5ef12f77..27a54c41 100644
--- a/Ink Canvas/Resources/Settings.cs
+++ b/Ink Canvas/Resources/Settings.cs
@@ -602,6 +602,9 @@ namespace Ink_Canvas
[JsonProperty("enableUIAccessTopMost")]
public bool EnableUIAccessTopMost { get; set; } = false;
+
+ [JsonProperty("windowMode")]
+ public bool WindowMode { get; set; } = true;
}
public class InkToShape
diff --git a/Ink Canvas/Windows/NewStyleRollCallWindow.cs b/Ink Canvas/Windows/NewStyleRollCallWindow.cs
index adc03650..ae7a5042 100644
--- a/Ink Canvas/Windows/NewStyleRollCallWindow.cs
+++ b/Ink Canvas/Windows/NewStyleRollCallWindow.cs
@@ -598,13 +598,52 @@ namespace Ink_Canvas
historyData.NameProbabilities = new Dictionary();
}
+ // 过滤掉已选择的人员
+ var candidateNames = availableNames.Where(name => !alreadySelected.Contains(name)).ToList();
+ if (candidateNames.Count == 0) return null;
+ if (candidateNames.Count == 1) return candidateNames[0];
+
+ // 检查极差:当极差达到3时,从被抽选次数最少的人中抽选
+ if (historyData.NameFrequency != null && historyData.NameFrequency.Count > 0)
+ {
+ // 获取所有候选人员的被抽选次数
+ var candidateFrequencies = new Dictionary();
+ foreach (string name in candidateNames)
+ {
+ int count = historyData.NameFrequency.ContainsKey(name) ? historyData.NameFrequency[name] : 0;
+ candidateFrequencies[name] = count;
+ }
+
+ // 计算极差(最大值 - 最小值)
+ if (candidateFrequencies.Count > 0)
+ {
+ int maxCount = candidateFrequencies.Values.Max();
+ int minCount = candidateFrequencies.Values.Min();
+ int range = maxCount - minCount;
+
+ // 当极差达到3时,只从被抽选次数最少的人中抽选
+ if (range >= 3)
+ {
+ var leastSelectedNames = candidateFrequencies
+ .Where(kvp => kvp.Value == minCount)
+ .Select(kvp => kvp.Key)
+ .ToList();
+
+ if (leastSelectedNames.Count > 0)
+ {
+ // 只从被抽选次数最少的人中随机选择
+ int randomIndex = random.Next(0, leastSelectedNames.Count);
+ return leastSelectedNames[randomIndex];
+ }
+ }
+ }
+ }
+
// 获取每个人员的概率
var nameProbabilities = new Dictionary();
- foreach (string name in availableNames)
+ foreach (string name in candidateNames)
{
- if (alreadySelected.Contains(name)) continue;
-
// 获取基础概率
double baseProbability = GetNameProbability(name);
diff --git a/Ink Canvas/Windows/TimerControl.xaml.cs b/Ink Canvas/Windows/TimerControl.xaml.cs
index 4ea97948..857dd325 100644
--- a/Ink Canvas/Windows/TimerControl.xaml.cs
+++ b/Ink Canvas/Windows/TimerControl.xaml.cs
@@ -70,7 +70,7 @@ namespace Ink_Canvas.Windows
}
///
- /// 刷新主题(供外部调用)
+ /// 刷新主题
///
public void RefreshTheme()
{
@@ -1505,6 +1505,72 @@ namespace Ink_Canvas.Windows
private void HandleTimerCompletion()
{
+ // 计时器结束时,如果显示的是最小化视图,恢复到主窗口视图
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ var mainWindow = Application.Current.MainWindow as MainWindow;
+ if (mainWindow != null)
+ {
+ var timerContainer = mainWindow.FindName("TimerContainer") as FrameworkElement;
+ var minimizedContainer = mainWindow.FindName("MinimizedTimerContainer") as FrameworkElement;
+
+ // 如果最小化视图可见,恢复到主窗口视图
+ if (minimizedContainer != null && minimizedContainer.Visibility == Visibility.Visible)
+ {
+ HideMinimizedRequested?.Invoke(this, EventArgs.Empty);
+ }
+ }
+ });
+
+ // 重置计时器状态
+ ResetTimerState();
+ }
+
+ ///
+ /// 重置计时器状态
+ ///
+ public void ResetTimerState()
+ {
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ // 停止计时器
+ if (isTimerRunning)
+ {
+ timer.Stop();
+ isTimerRunning = false;
+ isPaused = false;
+
+ if (hideTimer != null)
+ {
+ hideTimer.Stop();
+ }
+ }
+
+ // 重置时间到默认值
+ hour = 0;
+ minute = 5;
+ second = 0;
+
+ // 更新显示
+ UpdateDigitDisplays();
+ SetColonDisplay(false);
+
+ // 重置图标
+ if (StartPauseIcon != null)
+ {
+ StartPauseIcon.Data = Geometry.Parse(PlayIconData);
+ }
+
+ // 重置状态标志
+ isOvertimeMode = false;
+ hasPlayedProgressiveReminder = false;
+
+ // 禁用全屏按钮
+ if (FullscreenBtn != null)
+ {
+ FullscreenBtn.IsEnabled = false;
+ }
+ });
}
private void HideTimer_Elapsed(object sender, ElapsedEventArgs e)