Merge branch 'net6' of https://github.com/InkCanvasForClass/community into net6
This commit is contained in:
@@ -722,64 +722,60 @@ namespace Ink_Canvas.Helpers
|
|||||||
|
|
||||||
var m = new Matrix(scale, 0, 0, scale, tx, ty);
|
var m = new Matrix(scale, 0, 0, scale, tx, ty);
|
||||||
geom.Transform = new MatrixTransform(m);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把字形几何作为「实心填充」绘制的笔画。仍是 WPF <see cref="Stroke"/>,可被 InkCanvas 选择/移动/删除,
|
||||||
|
/// 但渲染时直接 DrawGeometry(brush, null, geom),不再走 StylusPoints 描边路径。
|
||||||
|
/// </summary>
|
||||||
|
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<Stroke> StrokesFromOutlinedGeometry(Geometry geometry, DrawingAttributes da, double tolerance)
|
public static FilledGlyphStroke TryCreate(Geometry geometry, DrawingAttributes templateDa)
|
||||||
{
|
{
|
||||||
var list = new List<Stroke>();
|
if (geometry == null || geometry.IsEmpty())
|
||||||
if (geometry == null || geometry.IsEmpty() || da == null)
|
return null;
|
||||||
return list;
|
|
||||||
|
|
||||||
Geometry outlined;
|
var b = geometry.Bounds;
|
||||||
try
|
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);
|
new StylusPoint(b.Left, b.Top, 0.5f),
|
||||||
}
|
new StylusPoint(b.Right, b.Top, 0.5f),
|
||||||
catch
|
new StylusPoint(b.Right, b.Bottom, 0.5f),
|
||||||
{
|
new StylusPoint(b.Left, b.Bottom, 0.5f),
|
||||||
return list;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
if (outlined == null || outlined.IsEmpty())
|
return new FilledGlyphStroke(pts, geometry, templateDa);
|
||||||
return list;
|
}
|
||||||
|
|
||||||
Geometry flat;
|
protected override void DrawCore(DrawingContext drawingContext, DrawingAttributes drawingAttributes)
|
||||||
try
|
{
|
||||||
{
|
if (drawingContext == null || _geometry == null)
|
||||||
flat = outlined.GetFlattenedPathGeometry(tolerance, ToleranceType.Absolute);
|
return;
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(flat is PathGeometry pg))
|
var color = drawingAttributes != null ? drawingAttributes.Color : Colors.Black;
|
||||||
return list;
|
drawingContext.DrawGeometry(new SolidColorBrush(color), null, _geometry);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3418,7 +3418,11 @@
|
|||||||
<controls:QuickPanelButton IconSource="{DynamicResource QuickPanelBlackboardIcon}" Label="{i18n:I18n Key=QuickPanel_Whiteboard}" ButtonMouseUp="ImageBlackboard_MouseUp" />
|
<controls:QuickPanelButton IconSource="{DynamicResource QuickPanelBlackboardIcon}" Label="{i18n:I18n Key=QuickPanel_Whiteboard}" ButtonMouseUp="ImageBlackboard_MouseUp" />
|
||||||
<controls:QuickPanelButton x:Name="BtnExitPptFromSidebarRight" IconSource="{DynamicResource QuickPanelEndSlideshowIcon}" Label="{i18n:I18n Key=QuickPanel_ExitShow}" LabelFontSize="7" Visibility="Collapsed" ButtonMouseUp="ExitPPTSlideShow_MouseUp" />
|
<controls:QuickPanelButton x:Name="BtnExitPptFromSidebarRight" IconSource="{DynamicResource QuickPanelEndSlideshowIcon}" Label="{i18n:I18n Key=QuickPanel_ExitShow}" LabelFontSize="7" Visibility="Collapsed" ButtonMouseUp="ExitPPTSlideShow_MouseUp" />
|
||||||
<controls:QuickPanelButton IconSource="{DynamicResource QuickPanelEyeIcon}" Label="{i18n:I18n Key=QuickPanel_Show}" ButtonMouseUp="UnFoldFloatingBar_MouseUp" />
|
<controls:QuickPanelButton IconSource="{DynamicResource QuickPanelEyeIcon}" Label="{i18n:I18n Key=QuickPanel_Show}" ButtonMouseUp="UnFoldFloatingBar_MouseUp" />
|
||||||
<controls:QuickPanelButton IconSource="{DynamicResource QuickPanelChevronLeftIcon}" ButtonMouseUp="HideQuickPanel_MouseUp" />
|
<controls:QuickPanelButton IconSource="{DynamicResource QuickPanelChevronLeftIcon}" ButtonMouseUp="HideQuickPanel_MouseUp" RenderTransformOrigin="0.5,0.5">
|
||||||
|
<controls:QuickPanelButton.RenderTransform>
|
||||||
|
<RotateTransform Angle="180" />
|
||||||
|
</controls:QuickPanelButton.RenderTransform>
|
||||||
|
</controls:QuickPanelButton>
|
||||||
</ikw:SimpleStackPanel>
|
</ikw:SimpleStackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
|
|||||||
@@ -2269,9 +2269,15 @@ namespace Ink_Canvas
|
|||||||
|
|
||||||
if (Settings.PowerPointSettings.EnablePPTButtonEnhancedPreview && bar != null)
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -2292,9 +2298,9 @@ namespace Ink_Canvas
|
|||||||
Thumbnail = s.Thumbnail
|
Thumbnail = s.Thumbnail
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
bar.PreviewItems = items;
|
targetBar.PreviewItems = items;
|
||||||
bar.CurrentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
|
targetBar.CurrentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
|
||||||
bar.IsPreviewExpanded = true;
|
targetBar.IsPreviewExpanded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2332,6 +2338,35 @@ namespace Ink_Canvas
|
|||||||
finally { if (bar != null) bar.IsPreviewExpanded = false; }
|
finally { if (bar != null) bar.IsPreviewExpanded = false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 选择承载增强预览的底部条:
|
||||||
|
/// - 来自侧边条的点击重定向到同侧底部条;
|
||||||
|
/// - 若同侧底部条不可用,退化到任意可用的底部条;
|
||||||
|
/// - 来自底部条的点击保持原行为。
|
||||||
|
/// </summary>
|
||||||
|
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
|
private sealed class PptEnhancedPreviewItem
|
||||||
{
|
{
|
||||||
public int SlideNumber { get; set; }
|
public int SlideNumber { get; set; }
|
||||||
|
|||||||
@@ -1864,7 +1864,7 @@
|
|||||||
<value>Finger mode BoundsWidth</value>
|
<value>Finger mode BoundsWidth</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Advanced_EdgeGestureUtilHint_Part1" xml:space="preserve">
|
<data name="Advanced_EdgeGestureUtilHint_Part1" xml:space="preserve">
|
||||||
<value>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</value>
|
<value>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.)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Advanced_EdgeGestureUtilHint_Part2" xml:space="preserve">
|
<data name="Advanced_EdgeGestureUtilHint_Part2" xml:space="preserve">
|
||||||
<value>(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.)</value>
|
<value>(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.)</value>
|
||||||
|
|||||||
@@ -1907,7 +1907,7 @@
|
|||||||
<value>手指模式 BoundsWidth</value>
|
<value>手指模式 BoundsWidth</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Advanced_EdgeGestureUtilHint_Part1" xml:space="preserve">
|
<data name="Advanced_EdgeGestureUtilHint_Part1" xml:space="preserve">
|
||||||
<value>EdgeGestureUtil是icc最新引入的可以暂时阻止在使用触摸时触发边缘手势(如Windows10环境下,屏幕左边缘滑动进入任务视图,右边缘滑动弹出通知中心;Windows11环境下,底部向上滑动打开开始菜单),其原理是使用了</value>
|
<value>EdgeGestureUtil是icc最新引入的可以暂时阻止在使用触摸时触发边缘手势(如Windows10环境下,屏幕左边缘滑动进入任务视图,右边缘滑动弹出通知中心;Windows11环境下,底部向上滑动打开开始菜单),其原理是使用了 System.EdgeGesture.DisableTouchWhenFullscreen (当应用程序窗口处于活动状态且处于全屏模式 (或拥有的窗口) 处于活动状态时,防止边缘手势行为。)来实现的。如果有异常,请关闭该选项,该选项应该能够实时生效。(Win7和Win8用户该选项无法使用)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Advanced_EdgeGestureUtilHint_Part2" xml:space="preserve">
|
<data name="Advanced_EdgeGestureUtilHint_Part2" xml:space="preserve">
|
||||||
<value>(当应用程序窗口处于活动状态且处于全屏模式 (或拥有的窗口) 处于活动状态时,防止边缘手势行为。)来实现的。如果有异常,请关闭该选项,该选项应该能够实时生效。(Win7和Win8用户该选项无法使用)</value>
|
<value>(当应用程序窗口处于活动状态且处于全屏模式 (或拥有的窗口) 处于活动状态时,防止边缘手势行为。)来实现的。如果有异常,请关闭该选项,该选项应该能够实时生效。(Win7和Win8用户该选项无法使用)</value>
|
||||||
|
|||||||
@@ -302,7 +302,7 @@
|
|||||||
<TextBlock Text="{i18n:I18n Key=AutoSave_Title}" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"/>
|
<TextBlock Text="{i18n:I18n Key=AutoSave_Title}" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"/>
|
||||||
|
|
||||||
<controls:LabeledSettingsCard x:Name="CardSaveScreenshotsInDateFolders"
|
<controls:LabeledSettingsCard x:Name="CardSaveScreenshotsInDateFolders"
|
||||||
Header="{i18n:I18n Key=Storage_AutoSaveInkOnScreenshot}"
|
Header="{i18n:I18n Key=Storage_ScreenshotsByDateFolder}"
|
||||||
Icon="{x:Static ui:SegoeFluentIcons.Folder}"
|
Icon="{x:Static ui:SegoeFluentIcons.Folder}"
|
||||||
Toggled="ToggleSwitchSaveScreenshotsInDateFolders_Toggled"/>
|
Toggled="ToggleSwitchSaveScreenshotsInDateFolders_Toggled"/>
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ namespace Ink_Canvas.Windows.SettingsViews
|
|||||||
RegisterDpiChangedListener();
|
RegisterDpiChangedListener();
|
||||||
LoadPluginSettingsPages();
|
LoadPluginSettingsPages();
|
||||||
UpdateUpdateBadgeVisibility();
|
UpdateUpdateBadgeVisibility();
|
||||||
|
_ = PreloadAllPagesAsync();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Closed += (sender, e) =>
|
this.Closed += (sender, e) =>
|
||||||
@@ -694,6 +695,42 @@ namespace Ink_Canvas.Windows.SettingsViews
|
|||||||
return NavigationViewControl;
|
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()
|
public void UpdateUpdateBadgeVisibility()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
Reference in New Issue
Block a user