diff --git a/Ink Canvas/Helpers/WinRtHandwritingRecognizer.cs b/Ink Canvas/Helpers/WinRtHandwritingRecognizer.cs index 6b90f765..62863ccc 100644 --- a/Ink Canvas/Helpers/WinRtHandwritingRecognizer.cs +++ b/Ink Canvas/Helpers/WinRtHandwritingRecognizer.cs @@ -722,64 +722,60 @@ namespace Ink_Canvas.Helpers var m = new Matrix(scale, 0, 0, scale, tx, ty); geom.Transform = new MatrixTransform(m); - return StrokesFromOutlinedGeometry(geom, templateDa, 0.35); + + var filled = FilledGlyphStroke.TryCreate(geom, templateDa); + if (filled == null) + return list; + + list.Add(filled); + return list; + } + } + + /// + /// 把字形几何作为「实心填充」绘制的笔画。仍是 WPF ,可被 InkCanvas 选择/移动/删除, + /// 但渲染时直接 DrawGeometry(brush, null, geom),不再走 StylusPoints 描边路径。 + /// + internal sealed class FilledGlyphStroke : Stroke + { + private readonly Geometry _geometry; + + private FilledGlyphStroke(StylusPointCollection pts, Geometry geometry, DrawingAttributes da) + : base(pts) + { + _geometry = geometry; + if (da != null) + DrawingAttributes = da.Clone(); } - private static List StrokesFromOutlinedGeometry(Geometry geometry, DrawingAttributes da, double tolerance) + public static FilledGlyphStroke TryCreate(Geometry geometry, DrawingAttributes templateDa) { - var list = new List(); - if (geometry == null || geometry.IsEmpty() || da == null) - return list; + if (geometry == null || geometry.IsEmpty()) + return null; - Geometry outlined; - try + var b = geometry.Bounds; + if (b.IsEmpty || b.Width < 0.5 || b.Height < 0.5) + return null; + + // StylusPoints 用 bounds 四角,保证命中测试 / 选区 / 包围盒计算正常。 + var pts = new StylusPointCollection { - outlined = geometry.GetOutlinedPathGeometry(tolerance, ToleranceType.Absolute); - } - catch - { - return list; - } + new StylusPoint(b.Left, b.Top, 0.5f), + new StylusPoint(b.Right, b.Top, 0.5f), + new StylusPoint(b.Right, b.Bottom, 0.5f), + new StylusPoint(b.Left, b.Bottom, 0.5f), + }; - if (outlined == null || outlined.IsEmpty()) - return list; + return new FilledGlyphStroke(pts, geometry, templateDa); + } - Geometry flat; - try - { - flat = outlined.GetFlattenedPathGeometry(tolerance, ToleranceType.Absolute); - } - catch - { - return list; - } + protected override void DrawCore(DrawingContext drawingContext, DrawingAttributes drawingAttributes) + { + if (drawingContext == null || _geometry == null) + return; - if (!(flat is PathGeometry pg)) - return list; - - foreach (var fig in pg.Figures) - { - var pts = new StylusPointCollection(); - pts.Add(new StylusPoint(fig.StartPoint.X, fig.StartPoint.Y, 0.5f)); - foreach (var seg in fig.Segments) - { - switch (seg) - { - case LineSegment ls: - pts.Add(new StylusPoint(ls.Point.X, ls.Point.Y, 0.5f)); - break; - case PolyLineSegment pls: - foreach (var p in pls.Points) - pts.Add(new StylusPoint(p.X, p.Y, 0.5f)); - break; - } - } - - if (pts.Count >= 2) - list.Add(new Stroke(pts) { DrawingAttributes = da.Clone() }); - } - - return list; + var color = drawingAttributes != null ? drawingAttributes.Color : Colors.Black; + drawingContext.DrawGeometry(new SolidColorBrush(color), null, _geometry); } } diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 0a15ca5f..0519f955 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -3418,7 +3418,11 @@ - + + + + + diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs index e2e9e1a3..ac91c1cd 100644 --- a/Ink Canvas/MainWindow_cs/MW_PPT.cs +++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs @@ -2269,9 +2269,15 @@ namespace Ink_Canvas if (Settings.PowerPointSettings.EnablePPTButtonEnhancedPreview && bar != null) { - if (bar.IsPreviewExpanded) + // 侧边条点击时,把增强预览重定向到同侧的底部条上展开 + var targetBar = ResolvePreviewTargetBar(bar); + if (targetBar == null) { - bar.IsPreviewExpanded = false; + _pptManager.TryShowSlideNavigation(); + } + else if (targetBar.IsPreviewExpanded) + { + targetBar.IsPreviewExpanded = false; } else { @@ -2292,9 +2298,9 @@ namespace Ink_Canvas Thumbnail = s.Thumbnail }); } - bar.PreviewItems = items; - bar.CurrentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0; - bar.IsPreviewExpanded = true; + targetBar.PreviewItems = items; + targetBar.CurrentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0; + targetBar.IsPreviewExpanded = true; } } } @@ -2332,6 +2338,35 @@ namespace Ink_Canvas finally { if (bar != null) bar.IsPreviewExpanded = false; } } + /// + /// 选择承载增强预览的底部条: + /// - 来自侧边条的点击重定向到同侧底部条; + /// - 若同侧底部条不可用,退化到任意可用的底部条; + /// - 来自底部条的点击保持原行为。 + /// + private Controls.PptNavBar ResolvePreviewTargetBar(Controls.PptNavBar source) + { + if (source == null) return null; + switch (source.Direction) + { + case Controls.PptNavBar.NavDirection.LeftSide: + return PickVisibleBar(LeftBottomPanelForPPTNavigation, RightBottomPanelForPPTNavigation) ?? source; + case Controls.PptNavBar.NavDirection.RightSide: + return PickVisibleBar(RightBottomPanelForPPTNavigation, LeftBottomPanelForPPTNavigation) ?? source; + default: + return source; + } + } + + private static Controls.PptNavBar PickVisibleBar(params Controls.PptNavBar[] candidates) + { + foreach (var c in candidates) + { + if (c != null && c.Visibility == Visibility.Visible) return c; + } + return null; + } + private sealed class PptEnhancedPreviewItem { public int SlideNumber { get; set; } diff --git a/Ink Canvas/Properties/Strings.en-US.resx b/Ink Canvas/Properties/Strings.en-US.resx index ad3535a9..07cbdacb 100644 --- a/Ink Canvas/Properties/Strings.en-US.resx +++ b/Ink Canvas/Properties/Strings.en-US.resx @@ -1864,7 +1864,7 @@ Finger mode BoundsWidth - EdgeGestureUtil is newly introduced in ICC to temporarily block edge gestures when using touch (e.g., on Windows 10: swipe from the left edge to Task View, from the right edge to Action Center; on Windows 11: swipe up from the bottom to open Start). It works by using + EdgeGestureUtil is newly introduced in ICC to temporarily block edge gestures when using touch (e.g., on Windows 10: swipe from the left edge to Task View, from the right edge to Action Center; on Windows 11: swipe up from the bottom to open Start). It works by using System.EdgeGesture.DisableTouchWhenFullscreen (When the app window is active and in full-screen mode (or an owned window is active), prevents edge gesture behavior.) If anything is abnormal, turn this option off; it should take effect immediately. (Not available on Windows 7/8.) (When the app window is active and in full-screen mode (or an owned window is active), prevents edge gesture behavior.) If anything is abnormal, turn this option off; it should take effect immediately. (Not available on Windows 7/8.) diff --git a/Ink Canvas/Properties/Strings.resx b/Ink Canvas/Properties/Strings.resx index 5b56d8f4..9be513c4 100644 --- a/Ink Canvas/Properties/Strings.resx +++ b/Ink Canvas/Properties/Strings.resx @@ -1907,7 +1907,7 @@ 手指模式 BoundsWidth - EdgeGestureUtil是icc最新引入的可以暂时阻止在使用触摸时触发边缘手势(如Windows10环境下,屏幕左边缘滑动进入任务视图,右边缘滑动弹出通知中心;Windows11环境下,底部向上滑动打开开始菜单),其原理是使用了 + EdgeGestureUtil是icc最新引入的可以暂时阻止在使用触摸时触发边缘手势(如Windows10环境下,屏幕左边缘滑动进入任务视图,右边缘滑动弹出通知中心;Windows11环境下,底部向上滑动打开开始菜单),其原理是使用了 System.EdgeGesture.DisableTouchWhenFullscreen (当应用程序窗口处于活动状态且处于全屏模式 (或拥有的窗口) 处于活动状态时,防止边缘手势行为。)来实现的。如果有异常,请关闭该选项,该选项应该能够实时生效。(Win7和Win8用户该选项无法使用) (当应用程序窗口处于活动状态且处于全屏模式 (或拥有的窗口) 处于活动状态时,防止边缘手势行为。)来实现的。如果有异常,请关闭该选项,该选项应该能够实时生效。(Win7和Win8用户该选项无法使用) diff --git a/Ink Canvas/Windows/SettingsViews/Pages/AutomationPage.xaml b/Ink Canvas/Windows/SettingsViews/Pages/AutomationPage.xaml index a536648c..c8ba799c 100644 --- a/Ink Canvas/Windows/SettingsViews/Pages/AutomationPage.xaml +++ b/Ink Canvas/Windows/SettingsViews/Pages/AutomationPage.xaml @@ -302,7 +302,7 @@ diff --git a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs index e7b11cc9..9b831003 100644 --- a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs @@ -79,6 +79,7 @@ namespace Ink_Canvas.Windows.SettingsViews RegisterDpiChangedListener(); LoadPluginSettingsPages(); UpdateUpdateBadgeVisibility(); + _ = PreloadAllPagesAsync(); }; this.Closed += (sender, e) => @@ -694,6 +695,42 @@ namespace Ink_Canvas.Windows.SettingsViews return NavigationViewControl; } + private async System.Threading.Tasks.Task PreloadAllPagesAsync() + { + try + { + var tags = _pageTypes.Keys.ToList(); + foreach (var tag in tags) + { + if (_pages.ContainsKey(tag)) + continue; + if (!_pageTypes.TryGetValue(tag, out var type)) + continue; + if (type == typeof(PluginSettingsPage)) + continue; + + await Dispatcher.InvokeAsync(() => + { + try + { + if (_pages.ContainsKey(tag)) + return; + var page = Activator.CreateInstance(type); + _pages[tag] = page; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($"预加载设置页面 {tag} 失败: {ex.Message}"); + } + }, System.Windows.Threading.DispatcherPriority.Background); + } + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($"异步预加载设置页面时出错: {ex.Message}"); + } + } + public void UpdateUpdateBadgeVisibility() { try