[update] Toast風格,其他細節修改和Bug修復

This commit is contained in:
Dubi906w 2024-07-28 22:04:21 +08:00
parent 87d93c29fd
commit 12ec3d7874
41 changed files with 1930 additions and 1187 deletions

View File

@ -1,2 +1,3 @@
/.vs
/.idea
custom-copyright-banner.png

View File

@ -15,6 +15,7 @@ using Window = System.Windows.Window;
using System.Windows.Shell;
using Ookii.Dialogs.Wpf;
using System.Diagnostics;
using Lierda.WPFHelper;
namespace Ink_Canvas
{
@ -36,7 +37,7 @@ namespace Ink_Canvas
private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
Ink_Canvas.MainWindow.ShowNewMessage("抱歉,出现未预期的异常,可能导致 InkCanvasForClass 运行不稳定。\n建议保存墨迹后重启应用。", true);
Ink_Canvas.MainWindow.ShowNewMessage("抱歉,出现未预期的异常,可能导致 InkCanvasForClass 运行不稳定。\n建议保存墨迹后重启应用。");
LogHelper.NewLog(e.Exception.ToString());
e.Handled = true;
}
@ -117,6 +118,9 @@ namespace Ink_Canvas
_taskbar = (TaskbarIcon)FindResource("TaskbarTrayIcon");
LierdaCracker cracker = new LierdaCracker();
cracker.Cracker();
StartArgs = e.Args;
}

View File

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Costura DisableCleanup="false" IncludeDebugSymbols="true" CreateTemporaryAssemblies="true"></Costura>
</Weavers>

View File

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="Costura" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="IncludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeRuntimeReferences" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls if runtime assemblies are also embedded.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="UseRuntimeReferencePaths" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCompression" type="xs:boolean">
<xs:annotation>
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCleanup" type="xs:boolean">
<xs:annotation>
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ExcludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeRuntimeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -67,13 +67,6 @@ namespace Ink_Canvas.Helpers
//Recognizer 的实现
public enum RecognizeLanguage
{
SimplifiedChinese = 0x0804,
TraditionalChinese = 0x7c03,
English = 0x0809
}
public class ShapeRecognizeResult
{
public ShapeRecognizeResult(Point centroid, PointCollection hotPoints, AnalysisAlternate analysisAlternate, InkDrawingNode node)

View File

@ -6,7 +6,7 @@
<AssemblyName>InkCanvasForClass</AssemblyName>
<TargetFramework>net472</TargetFramework>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<AutoGenerateBindingRedirects>False</AutoGenerateBindingRedirects>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
@ -138,9 +138,19 @@
<None Include="app.manifest" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Costura.Fody" Version="5.7.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Fody" Version="6.8.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Hardcodet.NotifyIcon.Wpf" Version="1.1.0" />
<PackageReference Include="iNKORE.UI.WPF.Modern" Version="0.9.27" />
<PackageReference Include="MdXaml" Version="1.27.0" />
<PackageReference Include="JetBrains.Annotations" Version="2024.2.0" />
<PackageReference Include="Jint" Version="4.0.0" />
<PackageReference Include="Lierda.WPFHelper" Version="1.0.3" />
<PackageReference Include="Microsoft.Office.Interop.PowerPoint" Version="15.0.4420.1018" />
<PackageReference Include="MicrosoftOfficeCore" Version="15.0.0" />
</ItemGroup>
@ -184,6 +194,7 @@
<None Include="Resources\TimerDownNotice.wav" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\contributors.png" />
<Resource Include="Resources\Cursors\close-hand-cursor.cur" />
<Resource Include="Resources\Cursors\cursor-move.cur" />
<Resource Include="Resources\Cursors\cursor-resize-lr.cur" />
@ -192,13 +203,6 @@
<Resource Include="Resources\Cursors\cursor-resize-tb.cur" />
<Resource Include="Resources\Cursors\open-hand-cursor.cur" />
<Resource Include="Resources\Cursors\Pen.cur" />
<Resource Include="Resources\DeveloperAvatars\aaaaaaccd.jpg" />
<Resource Include="Resources\DeveloperAvatars\Alan-CRL.png" />
<Resource Include="Resources\DeveloperAvatars\NetheriteBowl.png" />
<Resource Include="Resources\DeveloperAvatars\NotYoojun.png" />
<Resource Include="Resources\DeveloperAvatars\RaspberryKan.jpg" />
<Resource Include="Resources\DeveloperAvatars\wwei.png" />
<Resource Include="Resources\DeveloperAvatars\yuwenhui2020.png" />
<Resource Include="Resources\icc.ico" />
<Resource Include="Resources\Icons-png\AdmoxBooth.png" />
<Resource Include="Resources\Icons-png\AdmoxWhiteboard.png" />
@ -246,11 +250,6 @@
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\DeveloperAvatars\ChangSakura.png" />
<Resource Include="Resources\DeveloperAvatars\clover-yan.png" />
<Resource Include="Resources\DeveloperAvatars\CN-Ironegg.jpg" />
<Resource Include="Resources\DeveloperAvatars\jiajiaxd.jpg" />
<Resource Include="Resources\DeveloperAvatars\kengwang.png" />
<Resource Include="Resources\DeveloperAvatars\STBBRD.png" />
<Resource Include="Resources\DeveloperAvatars\WXRIW.png" />
</ItemGroup>
<ItemGroup>
@ -495,6 +494,7 @@
</ItemGroup>
<ItemGroup>
<None Remove="MainWindow.xaml~RF6c3144.TMP" />
<None Remove="Resources\contributors.png" />
<None Remove="Resources\Cursors\close-hand-cursor.cur" />
<None Remove="Resources\Cursors\cursor-move.cur" />
<None Remove="Resources\Cursors\cursor-resize-lr.cur" />
@ -503,13 +503,6 @@
<None Remove="Resources\Cursors\cursor-resize-tb.cur" />
<None Remove="Resources\Cursors\open-hand-cursor.cur" />
<None Remove="Resources\Cursors\Pen.cur" />
<None Remove="Resources\DeveloperAvatars\aaaaaaccd.jpg" />
<None Remove="Resources\DeveloperAvatars\Alan-CRL.png" />
<None Remove="Resources\DeveloperAvatars\NetheriteBowl.png" />
<None Remove="Resources\DeveloperAvatars\NotYoojun.png" />
<None Remove="Resources\DeveloperAvatars\RaspberryKan.jpg" />
<None Remove="Resources\DeveloperAvatars\wwei.png" />
<None Remove="Resources\DeveloperAvatars\yuwenhui2020.png" />
<None Remove="Resources\icc.ico" />
<None Remove="Resources\Icons-png\AdmoxBooth.png" />
<None Remove="Resources\Icons-png\AdmoxWhiteboard.png" />
@ -587,6 +580,9 @@
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Update="custom-copyright-banner.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="v6\" />

View File

@ -8,6 +8,9 @@
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemGroup>
<Compile Update="MainWindow_cs\MW_Toast.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Popups\ColorPalette.xaml.cs">
<SubType>Code</SubType>
</Compile>
@ -22,6 +25,9 @@
<Page Update="MainWindow_cs\MW_Eraser.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="MainWindow_cs\MW_Toast.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Popups\ColorPalette.xaml">
<SubType>Designer</SubType>
</Page>

View File

@ -118,7 +118,7 @@
<Grid x:Name="Main_Grid">
<Popup Name="PenPaletteV2Popup" PopupAnimation="Fade" IsOpen="False" StaysOpen="True" AllowsTransparency="True" Placement="AbsolutePoint">
<Popup Name="PenPaletteV2Popup" PopupAnimation="Fade" IsOpen="False" StaysOpen="True" AllowsTransparency="True" Placement="Bottom">
<popups:ColorPalette x:Name="PenPaletteV2" Width="300" />
</Popup>
@ -130,7 +130,7 @@
<Label Name="Label" Visibility="Collapsed" Foreground="Gray" Content="0" />
<Grid Name="InkCanvasGridForInkReplay">
<helpers:RectangleSelectionViewer x:Name="RectangleSelection" />
<InkCanvas x:Name="inkCanvas" ForceCursor="False"
<inkCanvas:IccInkCanvas x:Name="inkCanvas" ForceCursor="False"
TouchUp="Main_Grid_TouchUp" TouchDown="Main_Grid_TouchDown"
TouchMove="inkCanvas_TouchMove"
ManipulationDelta="Main_Grid_ManipulationDelta"
@ -485,40 +485,6 @@
<helpers:DrawingVisualCanvas IsHitTestVisible="False" x:Name="EraserOverlay_DrawingVisual"/>
</Grid>
<Grid Visibility="Collapsed">
<Grid Visibility="{Binding ElementName=GridBackgroundCoverHolder, Path=Visibility}">
<Viewbox Margin="10" Height="50" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="5">
<Border Width="36" Height="36" CornerRadius="5"
Background="{DynamicResource FloatBarBackground}" BorderThickness="1"
BorderBrush="{DynamicResource FloatBarBorderBrush}">
<Grid Margin="6" MouseUp="GridPPTControlPrevious_MouseUp">
<Image
Source="{DynamicResource ResourceKey=SeewoImageSource.HorizontalPreviousSlideNormal}" />
</Grid>
</Border>
<Border Visibility="{Binding ElementName=PptNavigationBtn, Path=Visibility}" Width="36"
Height="36" CornerRadius="5" Background="{DynamicResource FloatBarBackground}"
BorderThickness="1" BorderBrush="{DynamicResource FloatBarBorderBrush}">
<Grid MouseUp="PPTNavigationBtn_MouseUp">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="{Binding ElementName=PptNavigationTextBlock, Path=Foreground}"
FontSize="{Binding ElementName=PptNavigationTextBlock, Path=FontSize}"
Text="{Binding ElementName=PptNavigationTextBlock, Path=Text}" />
</Grid>
</Border>
<Border Width="36" Height="36" CornerRadius="5"
Background="{DynamicResource FloatBarBackground}" BorderThickness="1"
BorderBrush="{DynamicResource FloatBarBorderBrush}">
<Grid Margin="6" MouseUp="GridPPTControlNext_MouseUp">
<Image
Source="{DynamicResource ResourceKey=SeewoImageSource.HorizontalNextSlideNormal}" />
</Grid>
</Border>
</ui:SimpleStackPanel>
</Viewbox>
</Grid>
</Grid>
<!--// BlackBoard 界面 //-->
<Grid Name="BlackboardUIGridForInkReplay">
<Grid Visibility="{Binding ElementName=GridBackgroundCoverHolder, Path=Visibility}">
@ -3015,14 +2981,8 @@
<!-- 通知弹窗 -->
<Grid Name="GridNotifications" Margin="0,110" Visibility="Collapsed" HorizontalAlignment="Center"
VerticalAlignment="Bottom">
<Border CornerRadius="6" MaxHeight="200" Padding="20 10" Background="White" Opacity="0.95"
BorderBrush="#b91c1c" BorderThickness="1.5">
<TextBlock Name="TextBlockNotice" Text="测试文本" VerticalAlignment="Center" HorizontalAlignment="Center"
FontSize="16" />
</Border>
</Grid>
<Grid Name="GridNotifications" Margin="0,110" Visibility="Visible" HorizontalAlignment="Center"
VerticalAlignment="Bottom"/>
<!--// Old UI //-->
<!--<Viewbox Name="ViewBoxStackPanelMain" Visibility="Collapsed" Margin="10,10,10,55" HorizontalAlignment="Right"
VerticalAlignment="Bottom" Width="46">
@ -3041,7 +3001,9 @@
Margin="0,10,0,0" Width="{Binding ElementName=StackPanelMain, Path=ActualWidth}"
Foreground="{Binding ElementName=BtnExit, Path=Foreground}"
Background="{Binding ElementName=BtnExit, Path=Background}" />
--><!-- Click="BtnSwitchTheme_Click" --><!--
-->
<!-- Click="BtnSwitchTheme_Click" -->
<!--
<Button Name="BtnSwitch" Content="背景" FontFamily="Microsoft YaHei UI"
Margin="0,10,0,0" Width="{Binding ElementName=StackPanelMain, Path=ActualWidth}"
@ -8164,6 +8126,7 @@
<TextBlock x:Name="AppVersionTextBlock" FontSize="18" FontWeight="Bold"
Text="5.X.X.X" />
</ui:SimpleStackPanel>
<Image Name="CustomCopyrightBanner"/>
<TextBlock
Text="# 使用和分发本软件前,请您应当且务必知晓相关开源协议,且您应当知晓本软件基于 https://github.com/WXRIW/Ink-Canvas 修改而成。"
TextWrapping="Wrap" Foreground="#a1a1aa" />
@ -8295,181 +8258,11 @@
</TextBlock>
<Line HorizontalAlignment="Center" X1="0" Y1="0" X2="400" Y2="0" Stroke="#3f3f46"
StrokeThickness="1" Margin="0,4,0,4" />
<TextBlock FontSize="18" FontWeight="Bold" Margin="0,0,0,4" Text="感谢下列贡献者:" />
<Grid Margin="8,0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<ui:SimpleStackPanel Grid.Column="0" Grid.Row="0" Orientation="Vertical">
<Image Source="/Resources/DeveloperAvatars/RaspberryKan.jpg"
VerticalAlignment="Center" HorizontalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality" Width="48"
Margin="0,0,0,6" Height="48">
<Image.Clip>
<EllipseGeometry Center="24,24" RadiusX="24" RadiusY="24" />
</Image.Clip>
</Image>
<TextBlock Margin="0,0,0,2" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="12" Foreground="White">
Raspberry Kan
</TextBlock>
</ui:SimpleStackPanel>
<ui:SimpleStackPanel Grid.Column="1" Grid.Row="0" Orientation="Vertical">
<Image Source="/Resources/DeveloperAvatars/kengwang.png"
VerticalAlignment="Center" HorizontalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality" Width="48"
Margin="0,0,0,6" Height="48">
<Image.Clip>
<EllipseGeometry Center="24,24" RadiusX="24" RadiusY="24" />
</Image.Clip>
</Image>
<TextBlock Margin="0,0,0,2" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="12" Foreground="White">
Kengwang
</TextBlock>
</ui:SimpleStackPanel>
<ui:SimpleStackPanel Grid.Column="2" Grid.Row="0" Orientation="Vertical">
<Image Source="/Resources/DeveloperAvatars/jiajiaxd.jpg"
VerticalAlignment="Center" HorizontalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality" Width="48"
Margin="0,0,0,6" Height="48">
<Image.Clip>
<EllipseGeometry Center="24,24" RadiusX="24" RadiusY="24" />
</Image.Clip>
</Image>
<TextBlock Margin="0,0,0,2" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="12" Foreground="White">
Charles Jia
</TextBlock>
</ui:SimpleStackPanel>
<ui:SimpleStackPanel Grid.Column="3" Grid.Row="0" Orientation="Vertical">
<Image Source="/Resources/DeveloperAvatars/clover-yan.png"
VerticalAlignment="Center" HorizontalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality" Width="48"
Margin="0,0,0,6" Height="48">
<Image.Clip>
<EllipseGeometry Center="24,24" RadiusX="24" RadiusY="24" />
</Image.Clip>
</Image>
<TextBlock Margin="0,0,0,2" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="12" Foreground="White">
clover_yan
</TextBlock>
</ui:SimpleStackPanel>
<ui:SimpleStackPanel Grid.Column="0" Grid.Row="1" Orientation="Vertical"
Margin="0,16,0,0">
<Image Source="/Resources/DeveloperAvatars/NetheriteBowl.png"
VerticalAlignment="Center" HorizontalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality" Width="48"
Margin="0,0,0,6" Height="48">
<Image.Clip>
<EllipseGeometry Center="24,24" RadiusX="24" RadiusY="24" />
</Image.Clip>
</Image>
<TextBlock Margin="0,0,0,2" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="12" Foreground="White">
Netherite_Bowl
</TextBlock>
</ui:SimpleStackPanel>
<ui:SimpleStackPanel Grid.Column="1" Grid.Row="1" Orientation="Vertical"
Margin="0,16,0,0">
<Image Source="/Resources/DeveloperAvatars/NotYoojun.png"
VerticalAlignment="Center" HorizontalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality" Width="48"
Margin="0,0,0,6" Height="48">
<Image.Clip>
<EllipseGeometry Center="24,24" RadiusX="24" RadiusY="24" />
</Image.Clip>
</Image>
<TextBlock Margin="0,0,0,2" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="12" Foreground="White">
Yoojun Zhou
</TextBlock>
</ui:SimpleStackPanel>
<ui:SimpleStackPanel Grid.Column="2" Grid.Row="1" Orientation="Vertical"
Margin="0,16,0,0">
<Image Source="/Resources/DeveloperAvatars/yuwenhui2020.png"
VerticalAlignment="Center" HorizontalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality" Width="48"
Margin="0,0,0,6" Height="48">
<Image.Clip>
<EllipseGeometry Center="24,24" RadiusX="24" RadiusY="24" />
</Image.Clip>
</Image>
<TextBlock Margin="0,0,0,2" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="12" Foreground="White">
YuWenHui2020
</TextBlock>
</ui:SimpleStackPanel>
<ui:SimpleStackPanel Grid.Column="3" Grid.Row="1" Orientation="Vertical"
Margin="0,16,0,0">
<Image Source="/Resources/DeveloperAvatars/STBBRD.png"
VerticalAlignment="Center" HorizontalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality" Width="48"
Margin="0,0,0,6" Height="48">
<Image.Clip>
<EllipseGeometry Center="24,24" RadiusX="24" RadiusY="24" />
</Image.Clip>
</Image>
<TextBlock Margin="0,0,0,2" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="12" Foreground="White">
ZongziTEK
</TextBlock>
</ui:SimpleStackPanel>
<ui:SimpleStackPanel Grid.Column="0" Grid.Row="2" Orientation="Vertical"
Margin="0,16,0,0">
<Image Source="/Resources/DeveloperAvatars/aaaaaaccd.jpg"
VerticalAlignment="Center" HorizontalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality" Width="48"
Margin="0,0,0,6" Height="48">
<Image.Clip>
<EllipseGeometry Center="24,24" RadiusX="24" RadiusY="24" />
</Image.Clip>
</Image>
<TextBlock Margin="0,0,0,2" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="12" Foreground="White">
Aesthed
</TextBlock>
</ui:SimpleStackPanel>
<ui:SimpleStackPanel Grid.Column="1" Grid.Row="2" Orientation="Vertical"
Margin="0,16,0,0">
<Image Source="/Resources/DeveloperAvatars/wwei.png"
VerticalAlignment="Center" HorizontalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality" Width="48"
Margin="0,0,0,6" Height="48">
<Image.Clip>
<EllipseGeometry Center="24,24" RadiusX="24" RadiusY="24" />
</Image.Clip>
</Image>
<TextBlock Margin="0,0,0,2" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="12" Foreground="White">
Wei
</TextBlock>
</ui:SimpleStackPanel>
<ui:SimpleStackPanel Grid.Column="2" Grid.Row="2" Orientation="Vertical"
Margin="0,16,0,0">
<Image Source="/Resources/DeveloperAvatars/Alan-CRL.png"
VerticalAlignment="Center" HorizontalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality" Width="48"
Margin="0,0,0,6" Height="48">
<Image.Clip>
<EllipseGeometry Center="24,24" RadiusX="24" RadiusY="24" />
</Image.Clip>
</Image>
<TextBlock Margin="0,0,0,2" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="12" Foreground="White">
Alan-CRL
</TextBlock>
</ui:SimpleStackPanel>
</Grid>
<TextBlock FontSize="18" FontWeight="Bold" Text="感谢下列贡献者和支持者:" />
<TextBlock
Text="# 排名不分先后"
TextWrapping="Wrap" Foreground="#a1a1aa" />
<Image Source="Resources/contributors.png"/>
<ui:SimpleStackPanel Spacing="3" Orientation="Vertical">
<TextBlock
Text="© 2024 Dubi906w(Kriastans) 版权所有" FontWeight="Bold"

View File

@ -21,6 +21,10 @@ using System.Text;
using System.Windows.Documents;
using Ink_Canvas.Popups;
using iNKORE.UI.WPF.Modern.Controls;
using System.Windows.Forms;
using Jint.Runtime;
using Button = System.Windows.Controls.Button;
using TextBox = System.Windows.Controls.TextBox;
namespace Ink_Canvas {
public partial class MainWindow : Window {
@ -197,7 +201,7 @@ namespace Ink_Canvas {
const uint MF_GRAYED = 0x00000001;
const uint SC_CLOSE = 0xF060;
private void Window_Loaded(object sender, RoutedEventArgs e) {
private async void Window_Loaded(object sender, RoutedEventArgs e) {
loadPenCanvas();
//加载设置
LoadSettings(true);
@ -246,11 +250,13 @@ namespace Ink_Canvas {
UpdateFloatingBarIconsLayout();
StylusInvertedListenerInit();
PenPaletteV2Init();
}
private void SystemEventsOnDisplaySettingsChanged(object sender, EventArgs e) {
if (!Settings.Advanced.IsEnableResolutionChangeDetection) return;
ShowNotificationAsync($"检测到显示器信息变化,变为{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height}");
ShowNotification($"检测到显示器信息变化,变为{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height}");
new Thread(() => {
var isFloatingBarOutsideScreen = false;
var isInPPTPresentationMode = false;
@ -270,11 +276,11 @@ namespace Ink_Canvas {
public DelayAction dpiChangedDelayAction = new DelayAction();
private void MainWindow_OnDpiChanged(object sender, DpiChangedEventArgs e)
private void MainWindow_OnDpiChanged(object sender, System.Windows.DpiChangedEventArgs e)
{
if (e.OldDpi.DpiScaleX != e.NewDpi.DpiScaleX && e.OldDpi.DpiScaleY != e.NewDpi.DpiScaleY && Settings.Advanced.IsEnableDPIChangeDetection)
{
ShowNotificationAsync($"系统DPI发生变化从 {e.OldDpi.DpiScaleX}x{e.OldDpi.DpiScaleY} 变化为 {e.NewDpi.DpiScaleX}x{e.NewDpi.DpiScaleY}");
ShowNotification($"系统DPI发生变化从 {e.OldDpi.DpiScaleX}x{e.OldDpi.DpiScaleY} 变化为 {e.NewDpi.DpiScaleX}x{e.NewDpi.DpiScaleY}");
new Thread(() => {
var isFloatingBarOutsideScreen = false;
@ -308,7 +314,7 @@ namespace Ink_Canvas {
private void MainWindow_OnSizeChanged(object sender, SizeChangedEventArgs e) {
if (Settings.Advanced.IsEnableForceFullScreen) {
if (isLoaded) ShowNotificationAsync(
if (isLoaded) ShowNotification(
$"检测到窗口大小变化,已自动恢复到全屏:{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height}(缩放比例为{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height / SystemParameters.PrimaryScreenHeight}");
WindowState = WindowState.Maximized;
MoveWindow(new WindowInteropHelper(this).Handle, 0, 0,

View File

@ -6,6 +6,7 @@ using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
@ -76,12 +77,12 @@ namespace Ink_Canvas {
if (currentMode != 0) CloseWhiteboardImmediately();
if (StackPanelCanvasControls.Visibility == Visibility.Visible)
if (foldFloatingBarByUser && inkCanvas.Strokes.Count > 2)
ShowNotificationAsync("正在清空墨迹并收纳至侧边栏,可进入批注模式后通过【撤销】功能来恢复原先墨迹。");
lastBorderMouseDownObject = sender;
CursorWithDelIcon_Click(sender, null);
ShowNotification("正在清空墨迹并收纳至侧边栏,可进入批注模式后通过【撤销】功能来恢复原先墨迹。");
CursorWithDelIcon_Click(null, null);
RectangleSelectionHitTestBorder.Visibility = Visibility.Collapsed;
});
await Task.Delay(10);
await Task.Delay(5);
await Dispatcher.InvokeAsync(() => {
LeftBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed;
@ -94,6 +95,7 @@ namespace Ink_Canvas {
SelectedMode = ICCToolsEnum.CursorMode;
ForceUpdateToolSelection(null);
SidePannelMarginAnimation(-10);
});
isFloatingBarChangingHideMode = false;
}

View File

@ -12,6 +12,7 @@ using System.Windows.Media;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Animation;
using Ink_Canvas.Popups;
namespace Ink_Canvas {
public partial class MainWindow : Window {
@ -694,5 +695,46 @@ namespace Ink_Canvas {
var b = (byte)"0123456789ABCDEF".IndexOf(c);
return b;
}
#region PenPaletteV2
private void PenPaletteV2Init() {
PenPaletteV2.ColorSelectionChanged += PenpaletteV2_ColorSelectionChanged;
PenPaletteV2.ColorModeChanged += PenpaletteV2_ColorModeChanged;
PenPaletteV2.CustomColorChanged += PenpaletteV2_CustomColorChanged;
PenPaletteV2.PaletteShouldCloseEvent += PenpaletteV2_PaletteShouldCloseEvent;
PenPaletteV2.PenModeChanged += PenpaletteV2_PenModeChanged;
PenPaletteV2.SelectedColor = ColorPalette.ColorPaletteColor.ColorRed;
}
private void PenpaletteV2_ColorSelectionChanged(object sender, ColorPalette.ColorSelectionChangedEventArgs e) {
if (e.TriggerMode == ColorPalette.TriggerMode.TriggeredByCode) return;
drawingAttributes.Color = PenPaletteV2.GetColor(e.NowColor, false, null);
}
private void PenpaletteV2_ColorModeChanged(object sender, ColorPalette.ColorModeChangedEventArgs e) {
if (e.TriggerMode == ColorPalette.TriggerMode.TriggeredByCode) return;
drawingAttributes.Color = PenPaletteV2.GetColor(PenPaletteV2.SelectedColor, false, null);
}
private void PenpaletteV2_CustomColorChanged(object sender, ColorPalette.CustomColorChangedEventArgs e) {
if (e.TriggerMode == ColorPalette.TriggerMode.TriggeredByCode) return;
if (PenPaletteV2.SelectedColor == ColorPalette.ColorPaletteColor.ColorCustom)
drawingAttributes.Color = e.NowColor??new Color();
}
private void PenpaletteV2_PaletteShouldCloseEvent(object sender, RoutedEventArgs e) {
PenPaletteV2Popup.IsOpen = false;
}
private void PenpaletteV2_PenModeChanged(object sender, ColorPalette.PenModeChangedEventArgs e) {
penType = e.NowMode == ColorPalette.PenMode.HighlighterMode ? 1 : 0;
drawingAttributes.Width = e.NowMode == ColorPalette.PenMode.HighlighterMode ? Settings.Canvas.HighlighterWidth / 2 : Settings.Canvas.InkWidth;
drawingAttributes.Height = e.NowMode == ColorPalette.PenMode.HighlighterMode ? Settings.Canvas.HighlighterWidth : Settings.Canvas.InkWidth;
drawingAttributes.StylusTip = e.NowMode == ColorPalette.PenMode.HighlighterMode ? StylusTip.Rectangle : StylusTip.Ellipse;
drawingAttributes.IsHighlighter = e.NowMode == ColorPalette.PenMode.HighlighterMode;
}
#endregion
}
}

View File

@ -318,20 +318,23 @@ namespace Ink_Canvas {
if (mode != null && autoAlignCenter) {
if (BorderFloatingBarExitPPTBtn.Visibility == Visibility.Visible) {
await Task.Delay(50);
await Task.Delay(1);
ViewboxFloatingBarMarginAnimation(60);
} else if (Topmost == true) //非黑板
{
await Task.Delay(50);
await Task.Delay(1);
ViewboxFloatingBarMarginAnimation(100, true);
} else //黑板
{
await Task.Delay(50);
await Task.Delay(1);
ViewboxFloatingBarMarginAnimation(60);
}
}
await Task.Delay(150);
// new popup
PenPaletteV2Popup.IsOpen = false;
await Task.Delay(10);
isHidingSubPanelsWhenInking = false;
}
@ -718,7 +721,7 @@ namespace Ink_Canvas {
SelectedMode = ICCToolsEnum.CursorMode;
ForceUpdateToolSelection(null);
await Task.Delay(50);
await Task.Delay(5);
if (BorderFloatingBarExitPPTBtn.Visibility == Visibility.Visible)
ViewboxFloatingBarMarginAnimation(60);
@ -1515,7 +1518,7 @@ namespace Ink_Canvas {
((Panel)lastBorderMouseDownObject).Background = new SolidColorBrush(Colors.Transparent);
if (sender == CursorWithDelFloatingBarBtn && lastBorderMouseDownObject != CursorWithDelFloatingBarBtn) return;
SymbolIconDelete_MouseUp(sender, null);
SymbolIconDelete_MouseUp(null, null);
CursorIcon_Click(null, null);
}

View File

@ -3,9 +3,14 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Input.StylusPlugIns;
using System.Windows.Media;
namespace Ink_Canvas
{

View File

@ -44,8 +44,7 @@ namespace Ink_Canvas
Point currentPoint = e.GetPosition(inkCanvas);
System.Windows.Vector delta = currentPoint - startPoint;
foreach (Stroke stroke in inkCanvas.Strokes)
{
foreach (Stroke stroke in inkCanvas.Strokes) {
stroke.Transform(new Matrix(1, 0, 0, 1, delta.X, delta.Y), false);
}

View File

@ -10,20 +10,17 @@ namespace Ink_Canvas
int lastNotificationShowTime = 0;
int notificationShowTime = 2500;
public static void ShowNewMessage(string notice, bool isShowImmediately = true) {
(Application.Current?.Windows.Cast<Window>().FirstOrDefault(window => window is MainWindow) as MainWindow)?.ShowNotificationAsync(notice, isShowImmediately);
public static void ShowNewMessage(string notice) {
(Application.Current?.Windows.Cast<Window>().FirstOrDefault(window => window is MainWindow) as MainWindow)?.ShowNotification(notice);
}
public async Task ShowNotificationAsync(string notice, bool isShowImmediately = true)
{
try
{
TextBlockNotice.Text = notice;
AnimationsHelper.ShowWithSlideFromBottomAndFade(GridNotifications);
await Task.Delay(2000);
AnimationsHelper.HideWithSlideAndFade(GridNotifications);
}
catch { }
public MW_Toast ShowNotification(string notice) {
var notification = new MW_Toast(MW_Toast.ToastType.Informative, notice, (self) => {
GridNotifications.Children.Remove(self);
});
GridNotifications.Children.Add(notification);
notification.ShowAnimatedWithAutoDispose(3000 + notice.Length * 10);
return notification;
}
}
}

View File

@ -35,10 +35,10 @@ namespace Ink_Canvas {
savePathWithName = savePath + @"\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff") + ".icstk";
var fs = new FileStream(savePathWithName, FileMode.Create);
inkCanvas.Strokes.Save(fs);
if (newNotice) ShowNotificationAsync("墨迹成功保存至 " + savePathWithName);
if (newNotice) ShowNotification("墨迹成功保存至 " + savePathWithName);
}
catch (Exception ex) {
ShowNotificationAsync("墨迹保存失败");
ShowNotification("墨迹保存失败");
LogHelper.WriteLogToFile("墨迹保存失败 | " + ex.ToString(), LogHelper.LogType.Error);
}
}
@ -81,7 +81,7 @@ namespace Ink_Canvas {
if (inkCanvas.Visibility != Visibility.Visible) SymbolIconCursor_Click(sender, null);
}
catch {
ShowNotificationAsync("墨迹打开失败");
ShowNotification("墨迹打开失败");
}
}
}

View File

@ -29,7 +29,7 @@ namespace Ink_Canvas
}
if (!isHideNotification)
{
ShowNotificationAsync("截图成功保存至 " + savePath);
ShowNotification("截图成功保存至 " + savePath);
}
}
@ -38,7 +38,7 @@ namespace Ink_Canvas
var bitmap = GetScreenshotBitmap();
string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
bitmap.Save(savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png", ImageFormat.Png);
ShowNotificationAsync("截图成功保存至【桌面" + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png】");
ShowNotification("截图成功保存至【桌面" + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png】");
if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) SaveInkCanvasStrokes(false, false);
}

View File

@ -1644,7 +1644,7 @@ namespace Ink_Canvas {
}
catch { }
ShowNotificationAsync("设置已重置为默认推荐设置~");
ShowNotification("设置已重置为默认推荐设置~");
}
private async void SpecialVersionResetToSuggestion_Click() {

View File

@ -1,11 +1,13 @@
using Hardcodet.Wpf.TaskbarNotification;
using Ink_Canvas.Helpers;
using Newtonsoft.Json;
using Ookii.Dialogs.Wpf;
using OSVersionExtension;
using System;
using System.Diagnostics;
using System.Reflection;
using System.Security.Principal;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
@ -18,6 +20,28 @@ using OperatingSystem = OSVersionExtension.OperatingSystem;
namespace Ink_Canvas {
public partial class MainWindow : System.Windows.Window {
private void DisplayWelcomePopup() {
if( TaskDialog.OSSupportsTaskDialogs ) {
var t = new Thread(() => {
using (TaskDialog dialog = new TaskDialog()) {
dialog.WindowTitle = "感谢使用 InkCanvasForClass!";
dialog.MainInstruction = "感谢您使用 InkCanvasForClass!";
dialog.Content =
"您需要知道的是该版本正处于开发阶段,可能会有无法预测的问题出现。出现任何问题以及未捕获的异常,请及时提供日志文件然后上报给开发者。";
dialog.Footer =
"加入 InkCanvasForClass 交流群 <a href=\"https://qm.qq.com/q/Dgzdt7RjQQ\">825759306</a>。";
dialog.FooterIcon = TaskDialogIcon.Information;
dialog.EnableHyperlinks = true;
TaskDialogButton okButton = new TaskDialogButton(ButtonType.Ok);
dialog.Buttons.Add(okButton);
TaskDialogButton button = dialog.Show();
}
});
t.Start();
}
}
private void LoadSettings(bool isStartup = false) {
AppVersionTextBlock.Text = Assembly.GetExecutingAssembly().GetName().Version.ToString();
try {
@ -29,6 +53,23 @@ namespace Ink_Canvas {
catch { }
} else {
BtnResetToSuggestion_Click(null, null);
DisplayWelcomePopup();
}
}
catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
try {
if (File.Exists(App.RootPath + "custom-copyright-banner.png")) {
try {
CustomCopyrightBanner.Visibility = Visibility.Visible;
CustomCopyrightBanner.Source =
new BitmapImage(new Uri($"file://{App.RootPath + "custom-copyright-banner.png"}"));
}
catch { }
} else {
CustomCopyrightBanner.Visibility = Visibility.Collapsed;
}
}
catch (Exception ex) {

View File

@ -45,10 +45,10 @@ namespace Ink_Canvas {
private TimeMachine timeMachine = new TimeMachine();
private void ApplyHistoryToCanvas(TimeMachineHistory item, InkCanvas applyCanvas = null) {
private void ApplyHistoryToCanvas(TimeMachineHistory item, IccInkCanvas applyCanvas = null) {
_currentCommitType = CommitReason.CodeInput;
var canvas = inkCanvas;
if (applyCanvas != null && applyCanvas is InkCanvas) {
if (applyCanvas != null && applyCanvas is IccInkCanvas) {
canvas = applyCanvas;
}
@ -136,7 +136,7 @@ namespace Ink_Canvas {
}
private StrokeCollection ApplyHistoriesToNewStrokeCollection(TimeMachineHistory[] items) {
InkCanvas fakeInkCanv = new InkCanvas() {
IccInkCanvas fakeInkCanv = new IccInkCanvas() {
Width = inkCanvas.ActualWidth,
Height = inkCanvas.ActualHeight,
EditingMode = InkCanvasEditingMode.None,
@ -159,12 +159,15 @@ namespace Ink_Canvas {
SymbolIconRedo.IsEnabled = status;
}
private bool _mouseGesturingPrevious = false;
private void StrokesOnStrokesChanged(object sender, StrokeCollectionChangedEventArgs e) {
if (!isHidingSubPanelsWhenInking) {
isHidingSubPanelsWhenInking = true;
HideSubPanels(); // 书写时自动隐藏二级菜单
}
foreach (var stroke in e?.Removed) {
stroke.StylusPointsChanged -= Stroke_StylusPointsChanged;
stroke.StylusPointsReplaced -= Stroke_StylusPointsReplaced;
@ -255,10 +258,12 @@ namespace Ink_Canvas {
}
private void Stroke_StylusPointsReplaced(object sender, StylusPointsReplacedEventArgs e) {
if (isMouseGesturing) return;
StrokeInitialHistory[sender as Stroke] = e.NewStylusPoints.Clone();
}
private void Stroke_StylusPointsChanged(object sender, EventArgs e) {
if (isMouseGesturing) return;
var selectedStrokes = inkCanvas.GetSelectedStrokes();
var count = selectedStrokes.Count;
if (count == 0) count = inkCanvas.Strokes.Count;

View File

@ -141,25 +141,25 @@ namespace Ink_Canvas {
if (arg.Contains("EasiNote")) {
Dispatcher.Invoke(() => {
ShowNotificationAsync("“希沃白板 5”已自动关闭");
ShowNotification("“希沃白板 5”已自动关闭");
});
}
if (arg.Contains("HiteAnnotation")) {
Dispatcher.Invoke(() => {
ShowNotificationAsync("“鸿合屏幕书写”已自动关闭");
ShowNotification("“鸿合屏幕书写”已自动关闭");
});
}
if (arg.Contains("Ink Canvas Annotation") || arg.Contains("Ink Canvas Artistry")) {
Dispatcher.Invoke(() => {
ShowNotificationAsync("“ICA”已自动关闭");
ShowNotification("“ICA”已自动关闭");
});
}
if (arg.Contains("\"Ink Canvas.exe\"")) {
Dispatcher.Invoke(() => {
ShowNotificationAsync("“Ink Canvas”已自动关闭");
ShowNotification("“Ink Canvas”已自动关闭");
});
}
@ -172,7 +172,7 @@ namespace Ink_Canvas {
if (arg.Contains("VcomTeach"))
{
Dispatcher.Invoke(() => {
ShowNotificationAsync("“优教授课端”已自动关闭");
ShowNotification("“优教授课端”已自动关闭");
});
}

View File

@ -0,0 +1,73 @@
<UserControl x:Class="Ink_Canvas.MW_Toast"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Ink_Canvas"
xmlns:modern="http://schemas.inkore.net/lib/ui/wpf/modern"
mc:Ignorable="d">
<UserControl.Resources>
<DrawingImage x:Key="ErrorIcon">
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
<GeometryDrawing Geometry="F1 M24,24z M0,0z M0,12C0,6.34315 0,3.51472 1.75736,1.75736 3.51472,0 6.34315,0 12,0 17.6569,0 20.4853,0 22.2426,1.75736 24,3.51472 24,6.34315 24,12 24,17.6569 24,20.4853 22.2426,22.2426 20.4853,24 17.6569,24 12,24 6.34315,24 3.51472,24 1.75736,22.2426 0,20.4853 0,17.6569 0,12z">
<GeometryDrawing.Brush>
<SolidColorBrush Color="#FF000000" Opacity="0.3" />
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Brush="#FFFFFFFF" Geometry="F0 M24,24z M0,0z M8.46967,8.46967C8.76256,8.17678,9.23744,8.17678,9.53033,8.46967L12,10.9394 14.4697,8.46969C14.7626,8.1768 15.2374,8.1768 15.5303,8.46969 15.8232,8.76259 15.8232,9.23746 15.5303,9.53035L13.0607,12 15.5303,14.4696C15.8232,14.7625 15.8232,15.2374 15.5303,15.5303 15.2374,15.8232 14.7625,15.8232 14.4696,15.5303L12,13.0607 9.53036,15.5303C9.23746,15.8232 8.76259,15.8232 8.4697,15.5303 8.1768,15.2374 8.1768,14.7626 8.4697,14.4697L10.9394,12 8.46967,9.53033C8.17678,9.23744,8.17678,8.76256,8.46967,8.46967z" />
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
<DrawingImage x:Key="WarningIcon">
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
<GeometryDrawing Geometry="F1 M24,24z M0,0z M0,12C0,6.34315 0,3.51472 1.75736,1.75736 3.51472,0 6.34315,0 12,0 17.6569,0 20.4853,0 22.2426,1.75736 24,3.51472 24,6.34315 24,12 24,17.6569 24,20.4853 22.2426,22.2426 20.4853,24 17.6569,24 12,24 6.34315,24 3.51472,24 1.75736,22.2426 0,20.4853 0,17.6569 0,12z">
<GeometryDrawing.Brush>
<SolidColorBrush Color="#FF000000" Opacity="0.3" />
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Brush="#FFFFFFFF" Geometry="F0 M24,24z M0,0z M12.75,7.5C12.75,7.08579 12.4142,6.75 12,6.75 11.5858,6.75 11.25,7.08579 11.25,7.5L11.25,12.5C11.25,12.9142 11.5858,13.25 12,13.25 12.4142,13.25 12.75,12.9142 12.75,12.5L12.75,7.5z M12,16.5C12.5523,16.5 13,16.0523 13,15.5 13,14.9477 12.5523,14.5 12,14.5 11.4477,14.5 11,14.9477 11,15.5 11,16.0523 11.4477,16.5 12,16.5z" />
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
<DrawingImage x:Key="InfoIcon">
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
<GeometryDrawing Geometry="F1 M24,24z M0,0z M0,12C0,6.34315 0,3.51472 1.75736,1.75736 3.51472,0 6.34315,0 12,0 17.6569,0 20.4853,0 22.2426,1.75736 24,3.51472 24,6.34315 24,12 24,17.6569 24,20.4853 22.2426,22.2426 20.4853,24 17.6569,24 12,24 6.34315,24 3.51472,24 1.75736,22.2426 0,20.4853 0,17.6569 0,12z">
<GeometryDrawing.Brush>
<SolidColorBrush Color="#FF000000" Opacity="0.3" />
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Brush="#FFFFFFFF" Geometry="F0 M24,24z M0,0z M12,7C12.5523,7 13,7.44772 13,8 13,8.55229 12.5523,9 12,9 11.4477,9 11,8.55229 11,8 11,7.44772 11.4477,7 12,7z M12.75,16C12.75,16.4142 12.4142,16.75 12,16.75 11.5858,16.75 11.25,16.4142 11.25,16L11.25,11C11.25,10.5858 11.5858,10.25 12,10.25 12.4142,10.25 12.75,10.5858 12.75,11L12.75,16z" />
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
<DrawingImage x:Key="SuccessIcon">
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
<GeometryDrawing Geometry="F1 M24,24z M0,0z M0,12C0,6.34315 0,3.51472 1.75736,1.75736 3.51472,0 6.34315,0 12,0 17.6569,0 20.4853,0 22.2426,1.75736 24,3.51472 24,6.34315 24,12 24,17.6569 24,20.4853 22.2426,22.2426 20.4853,24 17.6569,24 12,24 6.34315,24 3.51472,24 1.75736,22.2426 0,20.4853 0,17.6569 0,12z">
<GeometryDrawing.Brush>
<SolidColorBrush Color="#FF000000" Opacity="0.3" />
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Brush="#FFFFFFFF" Geometry="F0 M24,24z M0,0z M16.0303,8.96967C16.3232,9.26256,16.3232,9.73744,16.0303,10.0303L11.0303,15.0303C10.7374,15.3232,10.2626,15.3232,9.96967,15.0303L7.96967,13.0303C7.67678,12.7374 7.67678,12.2626 7.96967,11.9697 8.26256,11.6768 8.73744,11.6768 9.03033,11.9697L10.5,13.4393 14.9697,8.96967C15.2626,8.67678,15.7374,8.67678,16.0303,8.96967z" />
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</UserControl.Resources>
<Grid Name="ToastGrid" IsHitTestVisible="False" Opacity="1">
<Border Name="ToastBorder" BorderBrush="#F0863A" BorderThickness="1.5" CornerRadius="8" Padding="28,10" Height="56">
<Border.Background>
<LinearGradientBrush StartPoint="-1,-1" EndPoint="2,2" >
<GradientStop x:Name="GradientStop1" Color="#F6743E" Offset="0"/>
<GradientStop x:Name="GradientStop2" Color="#D42525" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<modern:SimpleStackPanel Orientation="Horizontal" Spacing="14">
<Image Name="ToastIconImage" Width="32" Height="32" VerticalAlignment="Center" Source="{StaticResource ErrorIcon}"/>
<TextBlock Name="ToastTextBlock" Foreground="White" VerticalAlignment="Center" Margin="0,-1,0,0" FontSize="17" Text="這是 InkCanvasForClass 新版Toast控件測試"></TextBlock>
</modern:SimpleStackPanel>
</Border>
</Grid>
</UserControl>

View File

@ -0,0 +1,162 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml.Linq;
namespace Ink_Canvas {
public partial class MW_Toast : UserControl {
private Tuple<Color, Color>[] gradientTuples = new Tuple<Color, Color>[] {
new Tuple<Color, Color>(Color.FromRgb(246, 116, 62),Color.FromRgb(212, 37, 37)),
new Tuple<Color, Color>(Color.FromRgb(248, 184, 6), Color.FromRgb(255, 140, 4)),
new Tuple<Color, Color>(Color.FromRgb(45, 130, 178), Color.FromRgb(50, 154, 187)),
new Tuple<Color, Color>(Color.FromRgb(50, 187, 113), Color.FromRgb(42, 157, 143))
};
private Color[] borderColors = new Color[] {
Color.FromRgb(240, 134, 58),
Color.FromRgb(255, 223, 141),
Color.FromRgb(123, 207, 237),
Color.FromRgb(67, 213, 144),
};
public enum ToastType {
Error,
Warning,
Informative,
Success
}
public DrawingImage[] tipIconDrawingImages;
private void UpdateToastStyle(ToastType type) {
ToastBorder.BorderBrush = new SolidColorBrush(borderColors[(int)type]);
GradientStop1.Color = gradientTuples[(int)type].Item1;
GradientStop2.Color = gradientTuples[(int)type].Item2;
ToastIconImage.Source = tipIconDrawingImages[(int)type];
}
private string _toastText = "InkCanvasForClass";
public string ToastText {
get => _toastText;
set {
_toastText = value;
ToastTextBlock.Text = _toastText;
}
}
private ToastType _toastType = ToastType.Error;
public ToastType Type {
get => _toastType;
set {
_toastType = value;
UpdateToastStyle(value);
}
}
private void Animate(double opacityFrom, double opacityTo, int durationMs, Action complete, EasingFunctionBase easing = null) {
var sb = new Storyboard();
var fadeInAnimation = new DoubleAnimation {
From = opacityFrom,
To = opacityTo,
Duration = TimeSpan.FromMilliseconds(durationMs)
};
Storyboard.SetTargetProperty(fadeInAnimation, new PropertyPath(UIElement.OpacityProperty));
if (easing != null) fadeInAnimation.EasingFunction = easing;
sb.Children.Add(fadeInAnimation);
sb.Completed += (sender, args) => {
if (complete != null) complete();
};
ToastGrid.Opacity = opacityFrom;
sb.Begin(ToastGrid);
}
public void ShowImmediately() {
ToastGrid.Opacity = 1;
}
public void ShowAnimated() {
HideImmediately();
Animate(0, 1, 200, null ,new CubicEase());
}
public void ShowAnimatedWithAutoDispose(int autoCloseMs=3000) {
var t = new Thread(() => {
_isDisplay = true;
Dispatcher.InvokeAsync(() => { ShowAnimated(); });
Thread.Sleep(autoCloseMs);
Dispatcher.InvokeAsync(() => {
Animate(1, 0, 200, (() => {
ShouldDisposeAction(this);
}), new CubicEase());
});
_isDisplay = false;
});
t.Start();
}
public void ShowImmediatelyWithAutoDispose(int autoCloseMs=3000) {
var t = new Thread(() => {
_isDisplay = true;
Dispatcher.InvokeAsync(() => { ToastGrid.Opacity = 1; });
Thread.Sleep(autoCloseMs);
Dispatcher.InvokeAsync(() => {
Animate(1, 0, 200, (() => {
ShouldDisposeAction(this);
}), new CubicEase());
});
_isDisplay = false;
});
t.Start();
}
public void HideImmediately() {
ToastGrid.Opacity = 0;
}
public void HideAnimated() {
Animate(1, 0, 200, null, new CubicEase());
}
public Action<MW_Toast> ShouldDisposeAction;
private bool _isDisplay = false;
public bool IsDisplay {
get => _isDisplay;
}
public MW_Toast(ToastType type, string text, Action<MW_Toast> shouldDisposeAction) {
InitializeComponent();
tipIconDrawingImages = new DrawingImage[] {
this.FindResource("ErrorIcon") as DrawingImage,
this.FindResource("WarningIcon") as DrawingImage,
this.FindResource("InfoIcon") as DrawingImage,
this.FindResource("SuccessIcon") as DrawingImage,
};
Type = type;
ToastText = text;
ToastGrid.Opacity = 0;
ShouldDisposeAction = shouldDisposeAction;
}
}
}

View File

@ -6,7 +6,8 @@
xmlns:local="clr-namespace:Ink_Canvas.Popups"
xmlns:modern="http://schemas.inkore.net/lib/ui/wpf/modern"
xmlns:colorPicker="clr-namespace:ColorPicker;assembly=ColorPicker"
mc:Ignorable="d" Width="300" Height="450" UseLayoutRounding="True">
xmlns:helpers="clr-namespace:Ink_Canvas.Helpers"
mc:Ignorable="d" Width="300" Height="462" UseLayoutRounding="True">
<UserControl.Resources>
<DrawingImage x:Key="CheckedLightIcon">
<DrawingImage.Drawing>
@ -22,19 +23,240 @@
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
<ContextMenu x:Key="InkRecognitionContextMenu" Placement="Relative" Closed="InkRecognitionContextMenu_Closed" Opened="InkRecognitionContextMenu_Opened">
<MenuItem IsCheckable="True" Name="EnableRecog" Checked="InkRecognitionContextMenuItem_Checked" Unchecked="InkRecognitionContextMenuItem_Checked" Header="启用墨迹转形状"/>
<Separator/>
<MenuItem IsCheckable="True" Name="RecogTri" Checked="InkRecognitionContextMenuItem_Checked" Unchecked="InkRecognitionContextMenuItem_Checked" Header="识别三角形"/>
<MenuItem IsCheckable="True" Name="RecogQua" Checked="InkRecognitionContextMenuItem_Checked" Unchecked="InkRecognitionContextMenuItem_Checked" Header="识别四边形"/>
<MenuItem IsCheckable="True" Name="RecogEll" Checked="InkRecognitionContextMenuItem_Checked" Unchecked="InkRecognitionContextMenuItem_Checked" Header="识别椭圆"/>
<MenuItem IsCheckable="True" Name="RecogPlg" Checked="InkRecognitionContextMenuItem_Checked" Unchecked="InkRecognitionContextMenuItem_Checked" Header="识别多边形"/>
<ContextMenu x:Key="InkRecognitionContextMenu" Placement="Absolute" Closed="InkRecognitionContextMenu_Closed" Opened="InkRecognitionContextMenu_Opened">
<MenuItem IsCheckable="True" Name="EnableRecog" Checked="InkRecognitionContextMenuItem_Checked" Unchecked="InkRecognitionContextMenuItem_Checked" Header="启用墨迹转形状" />
<Separator />
<MenuItem IsCheckable="True" Name="RecogTri" Checked="InkRecognitionContextMenuItem_Checked" Unchecked="InkRecognitionContextMenuItem_Checked" Header="识别三角形" />
<MenuItem IsCheckable="True" Name="RecogQua" Checked="InkRecognitionContextMenuItem_Checked" Unchecked="InkRecognitionContextMenuItem_Checked" Header="识别四边形" />
<MenuItem IsCheckable="True" Name="RecogEll" Checked="InkRecognitionContextMenuItem_Checked" Unchecked="InkRecognitionContextMenuItem_Checked" Header="识别椭圆" />
<MenuItem IsCheckable="True" Name="RecogPlg" Checked="InkRecognitionContextMenuItem_Checked" Unchecked="InkRecognitionContextMenuItem_Checked" Header="识别多边形" />
</ContextMenu>
<ContextMenu x:Key="SimulatePressureContextMenu" Placement="Relative" Closed="SimulatePressureContextMenu_Closed" Opened="SimulatePressureContextMenu_Opened">
<MenuItem IsCheckable="True" Name="PointSP" Checked="SimulatePressureContextMenuItem_Checked" Unchecked="SimulatePressureContextMenuItem_Checked" Header="点集笔锋"/>
<MenuItem IsCheckable="True" Name="VelocitySP" Checked="SimulatePressureContextMenuItem_Checked" Unchecked="SimulatePressureContextMenuItem_Checked" Header="速度笔锋"/>
<MenuItem IsCheckable="True" Name="NoneSP" Checked="SimulatePressureContextMenuItem_Checked" Unchecked="SimulatePressureContextMenuItem_Checked" Header="强制硬件压感"/>
<ContextMenu x:Key="SimulatePressureContextMenu" Placement="Absolute" Closed="SimulatePressureContextMenu_Closed" Opened="SimulatePressureContextMenu_Opened">
<MenuItem IsCheckable="True" Name="PointSP" Checked="SimulatePressureContextMenuItem_Checked" Unchecked="SimulatePressureContextMenuItem_Checked" Header="点集笔锋" />
<MenuItem IsCheckable="True" Name="VelocitySP" Checked="SimulatePressureContextMenuItem_Checked" Unchecked="SimulatePressureContextMenuItem_Checked" Header="速度笔锋" />
<MenuItem IsCheckable="True" Name="NoneSP" Checked="SimulatePressureContextMenuItem_Checked" Unchecked="SimulatePressureContextMenuItem_Checked" Header="强制硬件压感" />
</ContextMenu>
<DrawingImage x:Key="TransparentBackgroundImage">
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V144 H144 V0 H0 Z">
<DrawingGroup Opacity="1">
<DrawingGroup.ClipGeometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="0,0,144,144" />
</DrawingGroup.ClipGeometry>
<GeometryDrawing Brush="#FFFFFFFF">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="0,0,144,144" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="0,0,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="32,0,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="64,0,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="96,0,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="16,16,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="48,16,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="80,16,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="112,16,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="0,32,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="32,32,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="64,32,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="96,32,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="16,48,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="48,48,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="80,48,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="112,48,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="0,64,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="32,64,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="64,64,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="96,64,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="16,80,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="48,80,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="80,80,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="112,80,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="0,96,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="32,96,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="64,96,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="96,96,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="16,112,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="48,112,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="80,112,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="112,112,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="0,128,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="32,128,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="64,128,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="96,128,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="128,0,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="128,32,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="128,64,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="128,96,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FFD9D9D9">
<GeometryDrawing.Geometry>
<RectangleGeometry RadiusX="0" RadiusY="0" Rect="128,128,16,16" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
<DrawingImage x:Key="SwitchOnImage">
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V20 H53 V0 H0 Z">
@ -71,7 +293,7 @@
<Grid>
<Border Margin="8" Background="#f4f4f5" BorderBrush="#3b82f6" BorderThickness="2" CornerRadius="6">
<Border.Effect>
<DropShadowEffect BlurRadius="5" Opacity="0.2"/>
<DropShadowEffect BlurRadius="5" Opacity="0.2" />
</Border.Effect>
<Grid>
<modern:SimpleStackPanel Spacing="4" Margin="8,0" Height="40" VerticalAlignment="Top" Orientation="Horizontal">
@ -196,7 +418,8 @@
</Grid>
</Border>
</modern:SimpleStackPanel>
<Border Height="34" Width="34" CornerRadius="6" Background="#22dc2626" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,6,8,0">
<Border Name="CloseButtonBorder" MouseDown="CloseButtonBorder_MouseDown" MouseUp="CloseButtonBorder_MouseUp" MouseLeave="CloseButtonBorder_MouseLeave"
Height="34" Width="34" CornerRadius="6" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,6,8,0">
<Image Height="24" Width="24">
<Image.Source>
<DrawingImage>
@ -233,11 +456,11 @@
</Image>
</Button>
<Slider x:Name="HighlighterWidthSlider" Minimum="15"
Maximum="45" Width="172" Margin="0,-3,0,-3"
Maximum="45" Width="145" Margin="0,-3,31,-3"
FontFamily="Microsoft YaHei UI" FontSize="20" VerticalAlignment="Center"
IsSnapToTickEnabled="True" Value="20" HorizontalAlignment="Center"
TickFrequency="1" TickPlacement="None"/>
<Button Padding="3" HorizontalAlignment="Right">
TickFrequency="1" TickPlacement="None" />
<Button Padding="3" HorizontalAlignment="Right" Margin="0,0,30,0">
<Image Height="19" Width="19">
<Image.Source>
<DrawingImage>
@ -250,14 +473,25 @@
</Image.Source>
</Image>
</Button>
<Button Padding="3" HorizontalAlignment="Right">
<Image Height="19" Width="19">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V24 H24 V0 H0 Z">
<GeometryDrawing Brush="#FF000000" Geometry="F0 M24,24z M0,0z M19,6.304L19,3.99996C19,3.44768 19.4477,2.99996 20,2.99996 20.5523,2.99996 21,3.44768 21,3.99996L21,8.99996C21,9.55225,20.5523,9.99996,20,9.99996L15,9.99996C14.4477,9.99996 14,9.55225 14,8.99996 14,8.44768 14.4477,7.99996 15,7.99996L17.7723,7.99996C16.143,5.63455 13.162,4.47625 10.2568,5.2212 9.02629,5.53779 7.90511,6.18336 7.01353,7.08868 6.12187,7.99408 5.49349,9.12512 5.19579,10.3605 4.89808,11.5959 4.94228,12.889 5.32364,14.1012 5.705,15.3134 6.40914,16.3989 7.36053,17.2413 8.31193,18.0837 9.4747,18.6512 10.7241,18.883 11.9736,19.1148 13.2625,19.0021 14.4528,18.557 15.643,18.1119 16.6897,17.3512 17.4804,16.3565 18.2712,15.3618 18.7763,14.1706 18.9416,12.9106 19.0134,12.363 19.5155,11.9773 20.0631,12.0491 20.6107,12.1209 20.9964,12.6231 20.9246,13.1707 20.7121,14.7906 20.0627,16.3222 19.046,17.6011 18.0293,18.88 16.6836,19.8581 15.1533,20.4303 13.623,21.0026 11.9657,21.1475 10.3593,20.8494 8.7529,20.5514 7.25792,19.8217 6.03469,18.7386 4.81147,17.6555 3.90615,16.2599 3.41583,14.7014 2.92551,13.1429 2.86868,11.4803 3.25145,9.89195 3.63421,8.3036 4.44212,6.8494 5.58854,5.68532 6.73496,4.52123 8.17663,3.69118 9.75895,3.28417L9.75963,3.28399C13.2427,2.39068,16.8325,3.6344,19,6.304z" />
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Button>
</Grid>
<Line X1="0" Y1="0" X2="240" Y2="0" Margin="0,2" HorizontalAlignment="Center" Stroke="#a1a1aa"/>
<Grid Margin="14,0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Height="96" Background="#f4f4f5" BorderBrush="#d4d4d8" CornerRadius="3" BorderThickness="1" Margin="0,0,3,0">
<Line X1="0" Y1="0" X2="240" Y2="0" Margin="0,2" HorizontalAlignment="Center" Stroke="#a1a1aa" />
<Grid>
<modern:ScrollViewerEx PreviewMouseWheel="QuickActionsScrollViewer_PreviewMouseWheel" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Disabled" PanningMode="HorizontalOnly" Orientation="Horizontal" ManipulationBoundaryFeedback="SCManipulationBoundaryFeedback">
<modern:SimpleStackPanel Margin="14,0,14,0" Orientation="Horizontal" Spacing="6">
<Border Width="117" Height="96" Background="#f4f4f5" BorderBrush="#d4d4d8" CornerRadius="3" BorderThickness="1">
<Grid>
<modern:SimpleStackPanel Spacing="2" Orientation="Vertical" VerticalAlignment="Center">
<Image Height="28" Width="28">
@ -273,7 +507,7 @@
</Image>
<TextBlock FontSize="16" FontWeight="Bold" HorizontalAlignment="Center" Foreground="#27272a">墨迹纠正</TextBlock>
<Button Name="InkRecognitionToggleSwitchButton" Click="InkRecognitionToggleSwitchButton_Clicked" Style="{x:Null}" ClipToBounds="False" BorderBrush="Transparent" BorderThickness="0" Padding="0" Background="Transparent" HorizontalAlignment="Center" Margin="0,6,0,0">
<Image Name="InkRecognitionToggleSwitchImage" Height="20" Source="{StaticResource SwitchOnImage}"/>
<Image Name="InkRecognitionToggleSwitchImage" Height="20" Source="{StaticResource SwitchOnImage}" />
</Button>
</modern:SimpleStackPanel>
<Border Name="InkRecognitionMoreButton" MouseDown="InkRecognitionMoreButton_MouseDown" Height="26" Width="26" CornerRadius="3" Background="#2227272a" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,4,4,0">
@ -290,9 +524,8 @@
</Image>
</Border>
</Grid>
</Border>
<Border Grid.Column="1" Height="96" Background="#f4f4f5" BorderBrush="#d4d4d8" CornerRadius="3" BorderThickness="1" Margin="3,0,0,0">
<Border Width="117" Height="96" Background="#f4f4f5" BorderBrush="#d4d4d8" CornerRadius="3" BorderThickness="1">
<Grid>
<modern:SimpleStackPanel Spacing="2" Orientation="Vertical" VerticalAlignment="Center">
<Image Height="28" Width="28">
@ -308,7 +541,7 @@
</Image>
<TextBlock FontSize="16" FontWeight="Bold" HorizontalAlignment="Center" Foreground="#27272a">模拟笔锋</TextBlock>
<Button Name="SimulatePressureToggleSwitchButton" Click="SimulatePressureToggleSwitchButton_Clicked" Style="{x:Null}" ClipToBounds="False" BorderBrush="Transparent" BorderThickness="0" Padding="0" Background="Transparent" HorizontalAlignment="Center" Margin="0,6,0,0">
<Image Name="SimulatePressureToggleSwitchImage" Height="20" Source="{StaticResource SwitchOnImage}"/>
<Image Name="SimulatePressureToggleSwitchImage" Height="20" Source="{StaticResource SwitchOnImage}" />
</Button>
</modern:SimpleStackPanel>
<Border Name="SimulatePressureMoreButton" MouseDown="SimulatePressureMoreButton_MouseDown" Height="26" Width="26" CornerRadius="3" Background="#2227272a" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,4,4,0">
@ -325,46 +558,141 @@
</Image>
</Border>
</Grid>
</Border>
<Border Width="117" Height="96" Background="#f4f4f5" BorderBrush="#d4d4d8" CornerRadius="3" BorderThickness="1">
<Grid>
<modern:SimpleStackPanel Spacing="2" Orientation="Vertical" VerticalAlignment="Center">
<Image Height="28" Width="28">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V17 H17 V0 H0 Z">
<GeometryDrawing Brush="#18181b" Geometry="F0 M17,17z M0,0z M12.8619,1.53958C13.1164,1.27815 13.4627,1.12597 13.8273,1.11539 15.1066,1.07854 15.7644,2.63232 14.8476,3.52524L9.41539,8.9282C8.97043,8.07844,8.27949,7.3875,7.42973,6.94254L12.8619,1.53958z M5.01998,15.112C7.08804,15.1212 8.76457,13.4355 8.76457,11.3674 8.76457,9.29935 7.08806,7.62284 5.01998,7.62284 2.9519,7.62284 1.27539,9.29935 1.27539,11.3674L1.27539,15.112 5.01998,15.112z" />
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
<TextBlock FontSize="16" FontWeight="Bold" HorizontalAlignment="Center" Foreground="#27272a">圆形笔尖</TextBlock>
<Button Name="StylusTipShapeButton" Click="SimulatePressureToggleSwitchButton_Clicked" Style="{x:Null}" ClipToBounds="False" BorderBrush="Transparent" BorderThickness="0" Padding="0" Background="Transparent" HorizontalAlignment="Center" Margin="0,6,0,0">
<Image Name="StylusTipShapeToggleSwitchImage" Height="20" Source="{StaticResource SwitchOnImage}" />
</Button>
</modern:SimpleStackPanel>
</Grid>
</Border>
<Border Width="117" Height="96" Background="#f4f4f5" BorderBrush="#d4d4d8" CornerRadius="3" BorderThickness="1">
<Grid>
<modern:SimpleStackPanel Spacing="2" Orientation="Vertical" VerticalAlignment="Center">
<Image Height="28" Width="28">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup ClipGeometry="M0,0 V16 H16 V0 H0 Z">
<GeometryDrawing Brush="#18181b" Geometry="F1 M16,16z M0,0z M7.08831,3.6385C7.00086,3.6421 6.91445,3.65879 6.83196,3.68802 6.77659,3.70768 6.72335,3.73287 6.67303,3.76319 6.64829,3.7785 6.62434,3.79502 6.60125,3.81271 6.53072,3.86518 6.4685,3.92798 6.41668,3.99899 6.34819,4.09373 6.29938,4.20123 6.27313,4.31515 6.26659,4.34337 6.26146,4.3719 6.25775,4.40064 6.25359,4.43354 6.25131,4.46666 6.25091,4.49982L6.25091,8.87478 6.25091,11.8347 4.01729,10.717C3.82176,10.6189 3.59654,10.5975 3.38603,10.6571 3.17552,10.7168 2.99499,10.8531 2.88003,11.0393 2.76507,11.2255 2.72403,11.4479 2.76498,11.6629 2.80594,11.8778 2.92592,12.0696 3.10129,12.2004L6.58245,14.81 6.60125,14.8254C6.60969,14.8313 6.61824,14.8369 6.62688,14.8425 6.64029,14.852 6.65397,14.8611 6.66789,14.8698 6.67803,14.8757 6.68829,14.8814 6.69866,14.8868 6.71159,14.894 6.72469,14.9008 6.73796,14.9073 6.75369,14.9152 6.76965,14.9226 6.78582,14.9295 6.79655,14.9343 6.80737,14.9389 6.81829,14.9432 6.8363,14.9501 6.85454,14.9563 6.87297,14.962 6.88148,14.9645 6.89003,14.9668 6.89861,14.969 6.91333,14.9728 6.92815,14.9762 6.94304,14.9792 6.96003,14.9832 6.97712,14.9866 6.99431,14.9895 7.0017,14.9907 7.00911,14.9919 7.01653,14.993 7.04037,14.9957 7.06431,14.9975 7.0883,14.9982 7.10082,14.999 7.11336,14.9995 7.1259,14.9997L11.5009,14.9997C11.5009,14.9997 11.9023,15.0118 12.3297,14.7981 12.7572,14.5843 13.2508,13.9789 13.2508,13.2497L13.2508,9.74977C13.2509,9.55451 13.1857,9.36483 13.0655,9.21092 12.9454,9.05702 12.7772,8.94772 12.5878,8.90041L9.0878,8.02542C9.01847,8.00826,8.9473,7.99965,8.87589,7.99979L8.00089,7.99979 8.00089,4.49982C7.99966,4.41215 7.98526,4.32516 7.95817,4.24177 7.93084,4.15825 7.89109,4.07932 7.84025,4.00764 7.82373,3.984 7.80604,3.9612 7.78727,3.93931 7.73013,3.87272 7.6633,3.81511 7.58903,3.7684 7.56409,3.75345 7.53843,3.73976 7.51213,3.72737 7.48597,3.71407 7.45916,3.7021 7.4318,3.69149 7.40433,3.68156 7.37639,3.67299 7.34807,3.66585 7.31991,3.65816 7.29139,3.65188 7.26261,3.64704 7.20495,3.63832 7.14656,3.6356 7.08831,3.6385z" />
<GeometryDrawing Geometry="F1 M16,16z M0,0z M7.12594,1C5.20333,1 3.62598,2.57736 3.62598,4.49996 3.62598,5.78324 4.33688,6.90019 5.37596,7.50946L5.37596,4.49996C5.37596,3.54561 6.17159,2.74998 7.12594,2.74998 8.08029,2.74998 8.87592,3.54561 8.87592,4.49996L8.87592,7.12494C8.94734,7.1248,9.01851,7.13341,9.08784,7.15057L9.31171,7.20702C10.1054,6.56354 10.6259,5.59334 10.6259,4.49996 10.6259,2.57736 9.04855,1 7.12594,1z">
<GeometryDrawing.Brush>
<SolidColorBrush Color="#18181b" Opacity="0.5" />
</GeometryDrawing.Brush>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
<TextBlock FontSize="16" FontWeight="Bold" HorizontalAlignment="Center" Foreground="#27272a">手指模式</TextBlock>
<Button Name="FingerModeButton" Click="SimulatePressureToggleSwitchButton_Clicked" Style="{x:Null}" ClipToBounds="False" BorderBrush="Transparent" BorderThickness="0" Padding="0" Background="Transparent" HorizontalAlignment="Center" Margin="0,6,0,0">
<Image Name="FingerModeToggleSwitchImage" Height="20" Source="{StaticResource SwitchOnImage}" />
</Button>
</modern:SimpleStackPanel>
</Grid>
</Border>
</modern:SimpleStackPanel>
</modern:ScrollViewerEx>
<Border Width="14" HorizontalAlignment="Left">
<Border.Background>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#fafafa" Offset="0"/>
<GradientStop Color="#00ffffff" Offset="0.5"/>
<GradientStop Color="#00ffffff" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
</Border>
<Border Width="14" HorizontalAlignment="Right">
<Border.Background>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#fafafa" Offset="1"/>
<GradientStop Color="#00ffffff" Offset="0.5"/>
<GradientStop Color="#00ffffff" Offset="0"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
<Line X1="0" Y1="0" X2="240" Y2="0" Margin="0,2" HorizontalAlignment="Center" Stroke="#a1a1aa"/>
<Grid Margin="10,0,10,0" >
<Grid Margin="14,3,14,0" Height="5">
<modern:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="3">
<Border Height="5" Width="5" CornerRadius="2.5" Background="#d4d4d8"/>
<Border Height="5" Width="5" CornerRadius="2.5" Background="#27272a"/>
<Border Height="5" Width="5" CornerRadius="2.5" Background="#d4d4d8"/>
</modern:SimpleStackPanel>
</Grid>
<Line X1="0" Y1="0" X2="240" Y2="0" Margin="0,2" HorizontalAlignment="Center" Stroke="#a1a1aa" />
<Grid>
<Grid Margin="10,0,10,0">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Black" Grid.Row="0" Grid.Column="0" Margin="2" CornerRadius="3" Background="#09090b" BorderBrush="#5518181b" BorderThickness="1" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="White" Grid.Row="0" Grid.Column="1" Margin="2" CornerRadius="3" Background="#fafafa" BorderBrush="#5518181b" BorderThickness="1" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Red" Grid.Row="0" Grid.Column="2" Margin="2" CornerRadius="3" Background="#dc2626" BorderBrush="#5518181b" BorderThickness="1" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Orange" Grid.Row="0" Grid.Column="3" Margin="2" CornerRadius="3" Background="#ea580c" BorderBrush="#5518181b" BorderThickness="1" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Yellow" Grid.Row="0" Grid.Column="4" Margin="2" CornerRadius="3" Background="#facc15" BorderBrush="#5518181b" BorderThickness="1" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Lime" Grid.Row="1" Grid.Column="0" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#65a30d" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Green" Grid.Row="1" Grid.Column="1" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#16a34a" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Teal" Grid.Row="1" Grid.Column="2" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#0d9488" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Cyan" Grid.Row="1" Grid.Column="3" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#0284c7" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Blue" Grid.Row="1" Grid.Column="4" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#2563eb" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Indigo" Grid.Row="2" Grid.Column="0" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#4f46e5" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Purple" Grid.Row="2" Grid.Column="1" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#7c3aed" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Fuchsia" Grid.Row="2" Grid.Column="2" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#c026d3" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Pink" Grid.Row="2" Grid.Column="3" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#db2777" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Rose" Grid.Row="2" Grid.Column="4" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#e11d48" Width="42" Height="36"></Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Black" Grid.Row="0" Grid.Column="0" Margin="2" CornerRadius="3" Background="#09090b" BorderBrush="#5518181b" BorderThickness="1" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="White" Grid.Row="0" Grid.Column="1" Margin="2" CornerRadius="3" Background="#fafafa" BorderBrush="#5518181b" BorderThickness="1" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Red" Grid.Row="0" Grid.Column="2" Margin="2" CornerRadius="3" Background="#dc2626" BorderBrush="#5518181b" BorderThickness="1" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Orange" Grid.Row="0" Grid.Column="3" Margin="2" CornerRadius="3" Background="#ea580c" BorderBrush="#5518181b" BorderThickness="1" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Yellow" Grid.Row="0" Grid.Column="4" Margin="2" CornerRadius="3" Background="#facc15" BorderBrush="#5518181b" BorderThickness="1" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Lime" Grid.Row="1" Grid.Column="0" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#65a30d" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Green" Grid.Row="1" Grid.Column="1" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#16a34a" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Teal" Grid.Row="1" Grid.Column="2" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#0d9488" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Cyan" Grid.Row="1" Grid.Column="3" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#0284c7" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Blue" Grid.Row="1" Grid.Column="4" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#2563eb" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Indigo" Grid.Row="2" Grid.Column="0" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#4f46e5" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Purple" Grid.Row="2" Grid.Column="1" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#7c3aed" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Fuchsia" Grid.Row="2" Grid.Column="2" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#c026d3" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Pink" Grid.Row="2" Grid.Column="3" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#db2777" Width="42" Height="36">
</Border>
<Border MouseDown="ColorButton_MouseDown" MouseUp="ColorButton_MouseUp" MouseLeave="ColorButton_MouseLeave" Name="Rose" Grid.Row="2" Grid.Column="4" Margin="2,6,2,2" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1" Background="#e11d48" Width="42" Height="36">
</Border>
</Grid>
</Grid>
<Grid Margin="12,0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" HorizontalAlignment="Stretch" Margin="0,0,3,0">
<Button Click="RandomColorButton_Clicked" Grid.Column="0" HorizontalAlignment="Stretch" Margin="0,0,3,0">
<modern:SimpleStackPanel Orientation="Horizontal" Spacing="4">
<Image Height="19" Width="19">
<Image.Source>
@ -383,7 +711,7 @@
<Button Name="CustomColorButton" Click="CustomColorButton_Clicked" ClipToBounds="False" Grid.Column="1" HorizontalAlignment="Stretch" Margin="3,0,3,0">
<modern:SimpleStackPanel Orientation="Horizontal" Spacing="4">
<Border Name="CustomColorButtonColorBorder" VerticalAlignment="Center" Width="19" Height="19" Visibility="Collapsed" CornerRadius="3" BorderBrush="#5518181b" BorderThickness="1">
<Image HorizontalAlignment="Center" VerticalAlignment="Center" Name="CustomColorButtonColorBorderCheckIcon" Height="16" Width="16" Source="{StaticResource CheckedDarkIcon}"/>
<Image HorizontalAlignment="Center" VerticalAlignment="Center" Name="CustomColorButtonColorBorderCheckIcon" Height="16" Width="16" Source="{StaticResource CheckedDarkIcon}" />
</Border>
<Image Name="CustomColorButtonIcon" Height="19" Width="19">
<Image.Source>
@ -425,10 +753,10 @@
<modern:SimpleStackPanel Orientation="Vertical" Spacing="6">
<TextBlock FontSize="18" FontWeight="Bold" VerticalAlignment="Bottom" Foreground="#27272a" Margin="16,12,10,2" Text="自定义颜色"></TextBlock>
<Grid>
<colorPicker:SquarePicker Name="CustomColorPicker" ColorChanged="CustomColorPicker_ColorChanged" HorizontalAlignment="Center" Width="242" Height="242"/>
<colorPicker:SquarePicker Name="CustomColorPicker" ColorChanged="CustomColorPicker_ColorChanged" HorizontalAlignment="Center" Width="242" Height="242" />
</Grid>
<Grid Margin="12,2,12,0">
<Border Name="CustomColorHexBorder" HorizontalAlignment="Left" Width="32" Height="32" CornerRadius="3" BorderBrush="#6618181b" BorderThickness="1"/>
<Border Name="CustomColorHexBorder" HorizontalAlignment="Left" Width="32" Height="32" CornerRadius="3" BorderBrush="#6618181b" BorderThickness="1" />
<TextBox Name="CustomColorHexTextBox" Margin="36,0,0,0" HorizontalAlignment="Stretch" Text="#000000"></TextBox>
</Grid>
<Button Click="BackToPaletteButton_Clicked" HorizontalAlignment="Stretch" Margin="12,0">

View File

@ -24,6 +24,7 @@ using Ink_Canvas.Helpers;
using Color = System.Windows.Media.Color;
using Point = System.Windows.Point;
using Image = System.Windows.Controls.Image;
using System.Reflection;
namespace Ink_Canvas.Popups {
public partial class ColorPalette : UserControl {
@ -93,13 +94,37 @@ namespace Ink_Canvas.Popups {
public GeometryDrawing[] PenModeTabButtonIcons;
public TextBlock[] PenModeTabButtonTexts;
private void SCManipulationBoundaryFeedback(object sender, ManipulationBoundaryFeedbackEventArgs e) {
e.Handled = true;
}
private void QuickActionsScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
ScrollViewer scrollViewer = (ScrollViewer)sender;
if (e.Delta < 0) {
scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + 24);
} else {
scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset - 24);
}
e.Handled = true;
}
#region
/// <summary>
/// 內部變量,代表是否使用暗色配色方案
/// </summary>
private bool _usingDarkColors = true;
/// <summary>
/// 公共成員,讀取或修改是否使用暗色配色方案
/// </summary>
public bool UsingDarkColors {
get => _usingDarkColors;
set {
var pre = _usingDarkColors;
_usingDarkColors = value;
UpdateColorPaletteColorsAndColorModeChangeButton();
ColorModeChanged?.Invoke(this, new ColorModeChangedEventArgs()
{
IsPreviousUsedDarkColor = pre,
@ -109,20 +134,358 @@ namespace Ink_Canvas.Popups {
}
}
public class ColorModeChangedEventArgs : EventArgs
{
public bool IsPreviousUsedDarkColor { get; set; }
public bool IsNowUsingDarkColor { get; set; }
public TriggerMode TriggerMode { get; set; }
}
#endregion
#region
/// <summary>
/// 內部變量,代表當前選中的顏色
/// </summary>
private ColorPaletteColor _colorSelected = ColorPaletteColor.ColorRed;
/// <summary>
/// 公共成員,讀取或修改當前選中的顏色,實時生效
/// </summary>
public ColorPaletteColor SelectedColor {
get => _colorSelected;
set {
var pre = _colorSelected;
_colorSelected = value;
UpdateColorButtonsCheckedDisplayStatus();
UpdateCustomColorButtonCheckedDisplayStatus();
ColorSelectionChanged?.Invoke(this, new ColorSelectionChangedEventArgs {
PreviousColor = pre,
NowColor = value,
TriggerMode = TriggerMode.TriggeredByCode,
CustomColor = value == ColorPaletteColor.ColorCustom ? (Color)_customColor : new Color(),
});
}
}
public class ColorSelectionChangedEventArgs : EventArgs {
public ColorPaletteColor PreviousColor { get; set; }
public ColorPaletteColor NowColor { get; set; }
public TriggerMode TriggerMode { get; set; }
public Color CustomColor { get; set; }
}
#endregion
#region
private Color? _customColor = null;
public Color? CustomColor {
get => _customColor;
set {
var pre = _customColor;
_customColor = value;
CustomColorChanged?.Invoke(this, new CustomColorChangedEventArgs {
PreviousColor = pre,
NowColor = value,
TriggerMode = TriggerMode.TriggeredByCode,
});
}
}
public class CustomColorChangedEventArgs : EventArgs
{
public Color? PreviousColor { get; set; }
public Color? NowColor { get; set; }
public TriggerMode TriggerMode { get; set; }
}
#endregion
#region
/// <summary>
/// 按下的顏色按鈕,用於顏色按鈕鼠標事件
/// </summary>
private Border lastColorBtnDown;
#region
/// <summary>
/// 顏色按鈕的選中狀態更新函數,根據選中的顏色判斷對勾的前景色
/// </summary>
public void UpdateColorButtonsCheckedDisplayStatus() {
foreach (var bd in ColorPaletteColorButtonBorders) {
bd.Child = null;
}
UpdateCustomColorButtonCheckedDisplayStatus();
if (_colorSelected == ColorPaletteColor.ColorCustom) return;
var index = (int)_colorSelected;
var bdSel = ColorPaletteColorButtonBorders[index];
Image checkedImage = new Image();
checkedImage.Width = 24;
checkedImage.Height = 24;
var checkLight = this.FindResource("CheckedLightIcon");
var checkDark = this.FindResource("CheckedDarkIcon");
if (ColorUtilities.GetReverseForegroundColor(ColorUtilities.GetGrayLevel((_usingDarkColors?_darkColors:_lightColors)[(int)_colorSelected])) == Colors.Black) checkedImage.Source = checkDark as DrawingImage;
else checkedImage.Source = checkLight as DrawingImage;
bdSel.Child = checkedImage;
}
/// <summary>
/// 更新自定義顏色按鈕的選中狀態
/// </summary>
private void UpdateCustomColorButtonCheckedDisplayStatus() {
if (_customColor == null) {
CustomColorButtonColorBorder.Visibility = Visibility.Collapsed;
CustomColorButtonIcon.Visibility = Visibility.Visible;
} else {
CustomColorButtonColorBorder.Visibility = Visibility.Visible;
CustomColorButtonColorBorder.Background = new SolidColorBrush((Color)_customColor);
CustomColorButtonIcon.Visibility = Visibility.Collapsed;
if (_colorSelected == ColorPaletteColor.ColorCustom)
CustomColorButtonColorBorderCheckIcon.Visibility = Visibility.Visible;
else CustomColorButtonColorBorderCheckIcon.Visibility = Visibility.Collapsed;
CustomColorButtonColorBorderCheckIcon.Source =
this.FindResource(ColorUtilities.GetReverseForegroundColor(ColorUtilities.GetGrayLevel((Color)_customColor)) == Colors.White
? "CheckedLightIcon"
: "CheckedDarkIcon") as DrawingImage;
}
}
#endregion
#region
private void ColorButton_MouseDown(object sender, MouseButtonEventArgs e) {
lastColorBtnDown = sender as Border;
ColorBtnStoryboardScaleSmaller(sender);
}
private void ColorButton_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastColorBtnDown != sender) return;
lastColorBtnDown = null;
var border = (Border)sender;
var index = Array.IndexOf(ColorPaletteColorStrings, border.Name.ToLower());
var pre = _colorSelected;
_colorSelected = (ColorPaletteColor)index;
UpdateColorButtonsCheckedDisplayStatus();
ColorBtnStoryboardScaleLarger(sender);
ColorSelectionChanged?.Invoke(this, new ColorSelectionChangedEventArgs {
PreviousColor = pre,
NowColor = (ColorPaletteColor)index,
TriggerMode = TriggerMode.TriggeredByUser,
});
}
private void ColorButton_MouseLeave(object sender, MouseEventArgs e) {
if (lastColorBtnDown != null) {
var la = lastColorBtnDown as Border;
var st = la.RenderTransform as ScaleTransform;
if (st.ScaleX != 1 && st.ScaleY != 1) ColorBtnStoryboardScaleLarger(lastColorBtnDown);
}
lastColorBtnDown = null;
}
#endregion
#region Picker
private void UpdateCustomColorPickerDisplayStatus() {
if (_customColor == null) {
CustomColorHexTextBox.Text = "请在上方选择一个颜色";
CustomColorHexBorder.Background = new SolidColorBrush(Colors.Transparent);
} else {
CustomColorHexTextBox.Text = "#" + CustomColorPicker.SelectedColor.R.ToString("X2") + CustomColorPicker.SelectedColor.G.ToString("X2") + CustomColorPicker.SelectedColor.B.ToString("X2");
CustomColorHexBorder.Background = new SolidColorBrush(CustomColorPicker.SelectedColor);
}
}
private void CustomColorPicker_ColorChanged(object sender, RoutedEventArgs e) {
var cp = sender as SquarePicker;
var pre = _customColor;
_customColor = cp.SelectedColor;
Trace.WriteLine(_customColor);
if (_colorSelected != ColorPaletteColor.ColorCustom) {
var mode_pre = _colorSelected;
_colorSelected = ColorPaletteColor.ColorCustom;
ColorSelectionChanged?.Invoke(this, new ColorSelectionChangedEventArgs {
PreviousColor = mode_pre,
NowColor = _colorSelected,
TriggerMode = TriggerMode.TriggeredByUser,
CustomColor = cp.SelectedColor,
});
}
CustomColorChanged?.Invoke(this, new CustomColorChangedEventArgs {
PreviousColor = pre,
NowColor = _customColor,
TriggerMode = TriggerMode.TriggeredByUser,
});
UpdateCustomColorPickerDisplayStatus();
UpdateCustomColorButtonCheckedDisplayStatus();
UpdateColorButtonsCheckedDisplayStatus();
}
#endregion
#region Storyboard動畫邏輯
private void ColorBtnStoryBoardScaleAnimation(object sender, double from, double to) {
var border = sender as Border;
var sb = new Storyboard();
var scaleAnimationX = new DoubleAnimation() {
From = from,
To = to,
Duration = new Duration(TimeSpan.FromMilliseconds(100))
};
var scaleAnimationY = new DoubleAnimation() {
From = from,
To = to,
Duration = new Duration(TimeSpan.FromMilliseconds(100))
};
scaleAnimationY.EasingFunction = new CubicEase();
scaleAnimationX.EasingFunction = new CubicEase();
Storyboard.SetTargetProperty(scaleAnimationX,
new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleX)"));
Storyboard.SetTargetProperty(scaleAnimationY,
new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleY)"));
sb.Children.Add(scaleAnimationX);
sb.Children.Add(scaleAnimationY);
sb.Begin(border);
}
private void ColorBtnStoryboardScaleSmaller(object sender) {
ColorBtnStoryBoardScaleAnimation(sender, 1D, 0.9);
}
private void ColorBtnStoryboardScaleLarger(object sender) {
ColorBtnStoryBoardScaleAnimation(sender, 0.9, 1D);
}
#endregion
#region
/// <summary>
/// 根據是否使用暗色配色方案來更新顏色按鈕的背景顏色並更新切換按鈕的UI文字
/// </summary>
private void UpdateColorPaletteColorsAndColorModeChangeButton() {
foreach (var bd in ColorPaletteColorButtonBorders) {
bd.Background =
new SolidColorBrush((_usingDarkColors ? _darkColors : _lightColors)[
Array.IndexOf(ColorPaletteColorStrings, bd.Name.ToLower())]);
}
ChangedColorButtonsTransparentVisibility(_penModeSelected == PenMode.HighlighterMode);
var tb = ((SimpleStackPanel)ColorModeChangeButton.Content).Children.OfType<TextBlock>().Single();
tb.Text = _usingDarkColors ? "亮色" : "暗色";
}
private void ColorModeChangeButton_Clicked(object sender, RoutedEventArgs e) {
var pre = _usingDarkColors;
_usingDarkColors = !_usingDarkColors;
UpdateColorPaletteColorsAndColorModeChangeButton();
UpdateColorButtonsCheckedDisplayStatus();
ColorModeChanged?.Invoke(this, new ColorModeChangedEventArgs()
{
IsPreviousUsedDarkColor = pre,
IsNowUsingDarkColor = _usingDarkColors,
TriggerMode = TriggerMode.TriggeredByUser,
});
}
#endregion
#region GetRawColor
/// <summary>
/// 根據傳入的 <paramref name="color"/> 獲取對應的顏色
/// </summary>
/// <param name="color">傳入 <c>ColorPaletteColor</c></param>
/// <param name="doNotFollowPaletteColor">如果傳入<c>true</c>,則不會遵循調色板的亮色暗色配色方案,<paramref name="isDarkPalette"/> 則不能為<c>null</c>。</param>
/// <param name="isDarkPalette">指定是否使用暗色配色方案,如果為 <c>false</c>,使用亮色,如果在 <paramref name="doNotFollowPaletteColor"/> 為 <c>true</c> 的情況下傳入 <c>null</c> 會報錯。</param>
/// <returns>傳入的 <c>ColorPaletteColor</c> 對應的顏色</returns>
public Color GetColor(ColorPaletteColor color, bool doNotFollowPaletteColor, bool? isDarkPalette) {
if (doNotFollowPaletteColor && isDarkPalette == null) throw new ArgumentNullException(nameof(isDarkPalette),"指定了自訂的配色方案卻沒有傳入正確的 isDarkPalette。");
if (color == ColorPaletteColor.ColorCustom) return _customColor??new Color();
return (doNotFollowPaletteColor
? ((bool)isDarkPalette ? _darkColors : _lightColors)
: (_usingDarkColors ? _darkColors : _lightColors))[(int)color];
}
#endregion
#region
public static int StrictNext(int maxValue = int.MaxValue) {
return new Random(BitConverter.ToInt32(Guid.NewGuid().ToByteArray(), 0)).Next(maxValue);
}
private void RandomColorButton_Clicked(object sender, RoutedEventArgs e) {
var pre = _colorSelected;
_colorSelected = (ColorPaletteColor)StrictNext(14);
UpdateColorButtonsCheckedDisplayStatus();
UpdateCustomColorButtonCheckedDisplayStatus();
ColorSelectionChanged?.Invoke(this, new ColorSelectionChangedEventArgs {
PreviousColor = pre,
NowColor = _colorSelected,
TriggerMode = TriggerMode.TriggeredByUser,
});
}
#endregion
#region
private void ChangedColorButtonsTransparentVisibility(bool isTransparent) {
foreach (var bd in ColorPaletteColorButtonBorders) {
var ori_color = ((SolidColorBrush)bd.Background).Color;
if (isTransparent) ori_color.A = (byte)Math.Round(byte.MaxValue * 0.6,0);
else ori_color.A = byte.MaxValue;
bd.Background = new SolidColorBrush(ori_color);
}
}
#endregion
#endregion
#region
private void CustomColorButton_Clicked(object sender, RoutedEventArgs e) {
if (_customColor == null) {
CustomColorPanel.Visibility = Visibility.Visible;
} else {
if (_colorSelected == ColorPaletteColor.ColorCustom) CustomColorPanel.Visibility = Visibility.Visible;
else {
var pre = _colorSelected;
_colorSelected = ColorPaletteColor.ColorCustom;
ColorSelectionChanged?.Invoke(this, new ColorSelectionChangedEventArgs() {
PreviousColor = pre,
NowColor = _colorSelected,
TriggerMode = TriggerMode.TriggeredByUser,
CustomColor = (Color)_customColor,
});
UpdateColorButtonsCheckedDisplayStatus();
UpdateCustomColorButtonCheckedDisplayStatus();
UpdateCustomColorPickerDisplayStatus();
}
}
}
#endregion
#region
private bool _inkRecognition = true;
public bool InkRecognition {
get => _inkRecognition;
@ -138,16 +501,33 @@ namespace Ink_Canvas.Popups {
}
}
public class InkRecognitionChangedEventArgs : EventArgs {
public bool PreviousStatus { get; set; }
public bool NowStatus { get; set; }
public TriggerMode TriggerMode { get; set; }
public InkRecognitionOptions Options { get; set; }
}
#endregion
#region
private void InkRecognitionMoreButton_MouseDown(object sender, MouseButtonEventArgs e) {
var ircm = this.FindResource("InkRecognitionContextMenu") as ContextMenu;
var transform = InkRecognitionMoreButton.TransformToVisual(this);
var pt = transform.Transform(new Point(0, 0));
ircm.VerticalOffset = pt.Y-4;
ircm.HorizontalOffset = pt.X-4;
ircm.IsOpen = !ircm.IsOpen;
ircm.IsOpen = true;
ircm.StaysOpen = true;
}
private void UpdateInkRecognitionContextMenyDisplayStatus() {
#region
/// <summary>
/// 更新墨跡糾正菜單裡面菜單項的選中狀態根據_inkRecognition來做更新
/// </summary>
private void UpdateInkRecognitionContextMenuDisplayStatus() {
var ircm = (ContextMenu)this.FindResource("InkRecognitionContextMenu");
var enableRecog = ircm.Items[0] as MenuItem;
enableRecog.IsChecked = _inkRecognition;
@ -168,7 +548,7 @@ namespace Ink_Canvas.Popups {
Trace.WriteLine(mi.IsChecked);
_inkRecognition = mi.IsChecked;
UpdateInkRecognitionContextMenyDisplayStatus();
UpdateInkRecognitionContextMenuDisplayStatus();
InkRecognitionToggleSwitchImage.Source =
this.FindResource(_inkRecognition ? "SwitchOnImage" : "SwitchOffImage") as DrawingImage;
@ -179,7 +559,7 @@ namespace Ink_Canvas.Popups {
TriggerMode = TriggerMode.TriggeredByUser,
});
} else {
UpdateInkRecognitionContextMenyDisplayStatus();
UpdateInkRecognitionContextMenuDisplayStatus();
InkRecognitionChanged?.Invoke(this, new InkRecognitionChangedEventArgs
{
PreviousStatus = _inkRecognition,
@ -189,12 +569,26 @@ namespace Ink_Canvas.Popups {
}
}
private void InkRecognitionContextMenu_Closed(object sender, RoutedEventArgs e) {
InkRecognitionMoreButton.Background = new SolidColorBrush(Colors.Transparent);
UpdateInkRecognitionContextMenuDisplayStatus();
}
private void InkRecognitionContextMenu_Opened(object sender, RoutedEventArgs e) {
InkRecognitionMoreButton.Background = new SolidColorBrush(Color.FromArgb(34,39, 39, 42));
UpdateInkRecognitionContextMenuDisplayStatus();
}
#endregion
#region
private void InkRecognitionToggleSwitchButton_Clicked(object sender, RoutedEventArgs e) {
var pre = _inkRecognition;
_inkRecognition = !_inkRecognition;
InkRecognitionToggleSwitchImage.Source =
this.FindResource(_inkRecognition ? "SwitchOnImage" : "SwitchOffImage") as DrawingImage;
UpdateInkRecognitionContextMenyDisplayStatus();
UpdateInkRecognitionContextMenuDisplayStatus();
InkRecognitionChanged?.Invoke(this, new InkRecognitionChangedEventArgs
{
PreviousStatus = pre,
@ -203,16 +597,35 @@ namespace Ink_Canvas.Popups {
});
}
private void InkRecognitionContextMenu_Closed(object sender, RoutedEventArgs e) {
InkRecognitionMoreButton.Background = new SolidColorBrush(Colors.Transparent);
UpdateInkRecognitionContextMenyDisplayStatus();
#endregion
#endregion
#region
private bool isCloseButtonDown = false;
private void CloseButtonBorder_MouseDown(object sender, MouseButtonEventArgs e) {
isCloseButtonDown = true;
CloseButtonBorder.Background = new SolidColorBrush(Color.FromArgb(34, 220, 38, 38));
}
private void InkRecognitionContextMenu_Opened(object sender, RoutedEventArgs e) {
InkRecognitionMoreButton.Background = new SolidColorBrush(Color.FromArgb(34,39, 39, 42));
UpdateInkRecognitionContextMenyDisplayStatus();
private void CloseButtonBorder_MouseLeave(object sender, MouseEventArgs e) {
isCloseButtonDown = false;
CloseButtonBorder.Background = new SolidColorBrush(Colors.Transparent);
}
private void CloseButtonBorder_MouseUp(object sender, MouseButtonEventArgs e) {
if (!isCloseButtonDown) return;
CloseButtonBorder_MouseLeave(null, null);
PaletteShouldCloseEvent?.Invoke(this,new RoutedEventArgs());
}
#endregion
#region
public enum PenMode {
PenMode,
HighlighterMode,
@ -227,6 +640,9 @@ namespace Ink_Canvas.Popups {
{
var pre = _penModeSelected;
_penModeSelected = value;
UpdatePenModeButtonsCheckedDisplayStatus();
ChangedColorButtonsTransparentVisibility(_penModeSelected == PenMode.HighlighterMode);
PenModeChanged?.Invoke(this, new PenModeChangedEventArgs()
{
PreviousMode = pre,
@ -236,6 +652,55 @@ namespace Ink_Canvas.Popups {
}
}
public class PenModeChangedEventArgs : EventArgs
{
public PenMode PreviousMode { get; set; }
public PenMode NowMode { get; set; }
public TriggerMode TriggerMode { get; set; }
}
#endregion
#region
public void UpdatePenModeButtonsCheckedDisplayStatus() {
foreach (var bd in PenModeTabButtonBorders) {
bd.Background = new SolidColorBrush(Colors.Transparent);
}
foreach (var indicator in PenModeTabButtonIndicators) {
indicator.Visibility = Visibility.Hidden;
}
foreach (var gd in PenModeTabButtonIcons) {
gd.Brush = new SolidColorBrush(Color.FromRgb(63, 63, 70));
}
foreach (var text in PenModeTabButtonTexts) {
text.Foreground = new SolidColorBrush(Color.FromRgb(63, 63, 70));
text.FontWeight = FontWeights.Normal;
}
PenModeTabButtonBorders[(int)_penModeSelected].Background = new SolidColorBrush(Color.FromArgb(34, 59, 130, 246));
PenModeTabButtonIndicators[(int)_penModeSelected].Visibility = Visibility.Visible;
PenModeTabButtonIcons[(int)_penModeSelected].Brush = new SolidColorBrush(Color.FromRgb(37, 99, 235));
PenModeTabButtonTexts[(int)_penModeSelected].Foreground = new SolidColorBrush(Color.FromRgb(37, 99, 235));
PenModeTabButtonTexts[(int)_penModeSelected].FontWeight = FontWeights.Bold;
}
private void PenTabButton_MouseDown(object sender, MouseButtonEventArgs e) {
var pre = _penModeSelected;
_penModeSelected = (PenMode)Array.IndexOf(PenModeTabButtonBorders, (Border)sender);
UpdatePenModeButtonsCheckedDisplayStatus();
ChangedColorButtonsTransparentVisibility(_penModeSelected == PenMode.HighlighterMode);
PenModeChanged?.Invoke(this, new PenModeChangedEventArgs()
{
PreviousMode = pre,
NowMode = _penModeSelected,
TriggerMode = TriggerMode.TriggeredByUser,
});
}
#endregion
public enum TriggerMode {
TriggeredByUser,
TriggeredByCode
@ -334,210 +799,6 @@ namespace Ink_Canvas.Popups {
spcm.IsOpen = !spcm.IsOpen;
}
private Border lastColorBtnDown;
public void UpdateColorButtonsDisplayStatus() {
foreach (var bd in ColorPaletteColorButtonBorders) {
bd.Child = null;
}
UpdateCustomColorButtonDisplayStatus();
if (_colorSelected == ColorPaletteColor.ColorCustom) return;
var index = (int)_colorSelected;
var bdSel = ColorPaletteColorButtonBorders[index];
Image checkedImage = new Image();
checkedImage.Width = 24;
checkedImage.Height = 24;
var checkLight = this.FindResource("CheckedLightIcon");
var checkDark = this.FindResource("CheckedDarkIcon");
if (ColorUtilities.GetReverseForegroundColor(ColorUtilities.GetGrayLevel((_usingDarkColors?_darkColors:_lightColors)[(int)_colorSelected])) == Colors.Black) checkedImage.Source = checkDark as DrawingImage;
else checkedImage.Source = checkLight as DrawingImage;
bdSel.Child = checkedImage;
}
public void UpdatePenModeButtonsDisplayStatus() {
foreach (var bd in PenModeTabButtonBorders) {
bd.Background = new SolidColorBrush(Colors.Transparent);
}
foreach (var indicator in PenModeTabButtonIndicators) {
indicator.Visibility = Visibility.Hidden;
}
foreach (var gd in PenModeTabButtonIcons) {
gd.Brush = new SolidColorBrush(Color.FromRgb(63, 63, 70));
}
foreach (var text in PenModeTabButtonTexts) {
text.Foreground = new SolidColorBrush(Color.FromRgb(63, 63, 70));
text.FontWeight = FontWeights.Normal;
}
PenModeTabButtonBorders[(int)_penModeSelected].Background = new SolidColorBrush(Color.FromArgb(34, 59, 130, 246));
PenModeTabButtonIndicators[(int)_penModeSelected].Visibility = Visibility.Visible;
PenModeTabButtonIcons[(int)_penModeSelected].Brush = new SolidColorBrush(Color.FromRgb(37, 99, 235));
PenModeTabButtonTexts[(int)_penModeSelected].Foreground = new SolidColorBrush(Color.FromRgb(37, 99, 235));
PenModeTabButtonTexts[(int)_penModeSelected].FontWeight = FontWeights.Bold;
}
private void PenTabButton_MouseDown(object sender, MouseButtonEventArgs e) {
var pre = _penModeSelected;
_penModeSelected = (PenMode)Array.IndexOf(PenModeTabButtonBorders, (Border)sender);
UpdatePenModeButtonsDisplayStatus();
PenModeChanged?.Invoke(this, new PenModeChangedEventArgs()
{
PreviousMode = pre,
NowMode = _penModeSelected,
TriggerMode = TriggerMode.TriggeredByUser,
});
}
private void ColorButton_MouseDown(object sender, MouseButtonEventArgs e) {
lastColorBtnDown = sender as Border;
ColorBtnStoryboardScaleSmaller(sender);
}
private void ColorButton_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastColorBtnDown != sender) return;
lastColorBtnDown = null;
var border = (Border)sender;
var index = Array.IndexOf(ColorPaletteColorStrings, border.Name.ToLower());
var pre = _colorSelected;
_colorSelected = (ColorPaletteColor)index;
UpdateColorButtonsDisplayStatus();
ColorBtnStoryboardScaleLarger(sender);
ColorSelectionChanged?.Invoke(this, new ColorSelectionChangedEventArgs {
PreviousColor = pre,
NowColor = (ColorPaletteColor)index,
TriggerMode = TriggerMode.TriggeredByUser,
});
}
private void UpdateCustomColorPickerDisplayStatus() {
if (_customColor == null) {
CustomColorHexTextBox.Text = "请在上方选择一个颜色";
CustomColorHexBorder.Background = new SolidColorBrush(Colors.Transparent);
} else {
CustomColorHexTextBox.Text = "#" + CustomColorPicker.SelectedColor.R.ToString("X2") + CustomColorPicker.SelectedColor.G.ToString("X2") + CustomColorPicker.SelectedColor.B.ToString("X2");
CustomColorHexBorder.Background = new SolidColorBrush(CustomColorPicker.SelectedColor);
}
}
private void UpdateCustomColorButtonDisplayStatus() {
if (_customColor == null) {
CustomColorButtonColorBorder.Visibility = Visibility.Collapsed;
CustomColorButtonIcon.Visibility = Visibility.Visible;
} else {
CustomColorButtonColorBorder.Visibility = Visibility.Visible;
CustomColorButtonColorBorder.Background = new SolidColorBrush((Color)_customColor);
CustomColorButtonIcon.Visibility = Visibility.Collapsed;
if (_colorSelected == ColorPaletteColor.ColorCustom)
CustomColorButtonColorBorderCheckIcon.Visibility = Visibility.Visible;
else CustomColorButtonColorBorderCheckIcon.Visibility = Visibility.Collapsed;
CustomColorButtonColorBorderCheckIcon.Source =
this.FindResource(ColorUtilities.GetReverseForegroundColor(ColorUtilities.GetGrayLevel((Color)_customColor)) == Colors.White
? "CheckedLightIcon"
: "CheckedDarkIcon") as DrawingImage;
}
}
private void CustomColorPicker_ColorChanged(object sender, RoutedEventArgs e) {
var cp = sender as SquarePicker;
_customColor = cp.SelectedColor;
if (_colorSelected != ColorPaletteColor.ColorCustom) _colorSelected = ColorPaletteColor.ColorCustom;
UpdateCustomColorPickerDisplayStatus();
UpdateCustomColorButtonDisplayStatus();
UpdateColorButtonsDisplayStatus();
}
private void ColorBtnStoryBoardScaleAnimation(object sender, double from, double to) {
var border = sender as Border;
var sb = new Storyboard();
var scaleAnimationX = new DoubleAnimation() {
From = from,
To = to,
Duration = new Duration(TimeSpan.FromMilliseconds(100))
};
var scaleAnimationY = new DoubleAnimation() {
From = from,
To = to,
Duration = new Duration(TimeSpan.FromMilliseconds(100))
};
scaleAnimationY.EasingFunction = new CubicEase();
scaleAnimationX.EasingFunction = new CubicEase();
Storyboard.SetTargetProperty(scaleAnimationX,
new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleX)"));
Storyboard.SetTargetProperty(scaleAnimationY,
new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleY)"));
sb.Children.Add(scaleAnimationX);
sb.Children.Add(scaleAnimationY);
sb.Begin(border);
}
private void ColorBtnStoryboardScaleSmaller(object sender) {
ColorBtnStoryBoardScaleAnimation(sender, 1D, 0.9);
}
private void ColorBtnStoryboardScaleLarger(object sender) {
ColorBtnStoryBoardScaleAnimation(sender, 0.9, 1D);
}
private void ColorButton_MouseLeave(object sender, MouseEventArgs e) {
if (lastColorBtnDown != null) {
var la = lastColorBtnDown as Border;
var st = la.RenderTransform as ScaleTransform;
if (st.ScaleX != 1 && st.ScaleY != 1) ColorBtnStoryboardScaleLarger(lastColorBtnDown);
}
lastColorBtnDown = null;
}
public class ColorSelectionChangedEventArgs : EventArgs {
public ColorPaletteColor PreviousColor { get; set; }
public ColorPaletteColor NowColor { get; set; }
public TriggerMode TriggerMode { get; set; }
public Color CustomColor { get; set; }
}
public class ColorModeChangedEventArgs : EventArgs
{
public bool IsPreviousUsedDarkColor { get; set; }
public bool IsNowUsingDarkColor { get; set; }
public TriggerMode TriggerMode { get; set; }
}
private void UpdateColorPaletteColorsAndColorModeChangeButton() {
foreach (var bd in ColorPaletteColorButtonBorders) {
bd.Background =
new SolidColorBrush((_usingDarkColors ? _darkColors : _lightColors)[
Array.IndexOf(ColorPaletteColorStrings, bd.Name.ToLower())]);
}
var tb = ((SimpleStackPanel)ColorModeChangeButton.Content).Children.OfType<TextBlock>().Single();
tb.Text = _usingDarkColors ? "亮色" : "暗色";
}
private void ColorModeChangeButton_Clicked(object sender, RoutedEventArgs e) {
var pre = _usingDarkColors;
_usingDarkColors = !_usingDarkColors;
UpdateColorPaletteColorsAndColorModeChangeButton();
UpdateColorButtonsDisplayStatus();
ColorModeChanged?.Invoke(this, new ColorModeChangedEventArgs()
{
IsPreviousUsedDarkColor = pre,
IsNowUsingDarkColor = _usingDarkColors,
TriggerMode = TriggerMode.TriggeredByUser,
});
}
public class PenModeChangedEventArgs : EventArgs
{
public PenMode PreviousMode { get; set; }
public PenMode NowMode { get; set; }
public TriggerMode TriggerMode { get; set; }
}
public class PressureSimulationChangedEventArgs : EventArgs
{
@ -554,38 +815,44 @@ namespace Ink_Canvas.Popups {
public bool isRecognizePolygon;
}
private Color? _customColor = null;
private void CustomColorButton_Clicked(object sender, RoutedEventArgs e) {
if (_customColor == null) {
CustomColorPanel.Visibility = Visibility.Visible;
} else {
if (_colorSelected == ColorPaletteColor.ColorCustom) CustomColorPanel.Visibility = Visibility.Visible;
else {
_colorSelected = ColorPaletteColor.ColorCustom;
UpdateColorButtonsDisplayStatus();
UpdateCustomColorButtonDisplayStatus();
UpdateCustomColorPickerDisplayStatus();
}
}
}
private void BackToPaletteButton_Clicked(object sender, RoutedEventArgs e) {
CustomColorPanel.Visibility = Visibility.Collapsed;
}
public class InkRecognitionChangedEventArgs : EventArgs {
private bool _isDisplayQuickActions = true;
public bool IsDisplayQuickActions
{
get => _isDisplayQuickActions;
set
{
var pre = _isDisplayQuickActions;
_isDisplayQuickActions = value;
QuickActionsVisibilityChanged?.Invoke(this, new QuickActionsVisibilityChangedEventsArgs()
{
PreviousStatus = pre,
NowStatus = value,
TriggerMode = TriggerMode.TriggeredByCode,
});
}
}
public class QuickActionsVisibilityChangedEventsArgs : EventArgs {
public bool PreviousStatus { get; set; }
public bool NowStatus { get; set; }
public TriggerMode TriggerMode { get; set; }
public InkRecognitionOptions Options { get; set; }
}
public event EventHandler<ColorSelectionChangedEventArgs> ColorSelectionChanged;
public event EventHandler<CustomColorChangedEventArgs> CustomColorChanged;
public event EventHandler<PenModeChangedEventArgs> PenModeChanged;
public event EventHandler<InkRecognitionChangedEventArgs> InkRecognitionChanged;
public event EventHandler<PressureSimulationChangedEventArgs> PressureSimulationChanged;
public event EventHandler<ColorModeChangedEventArgs> ColorModeChanged;
public event EventHandler<QuickActionsVisibilityChangedEventsArgs> QuickActionsVisibilityChanged;
public event EventHandler<RoutedEventArgs> PaletteShouldCloseEvent;
public ColorPalette() {
InitializeComponent();
@ -609,9 +876,10 @@ namespace Ink_Canvas.Popups {
bd.RenderTransform = new ScaleTransform(1, 1);
}
UpdatePenModeButtonsDisplayStatus();
UpdateColorButtonsDisplayStatus();
UpdatePenModeButtonsCheckedDisplayStatus();
UpdateColorButtonsCheckedDisplayStatus();
UpdateColorPaletteColorsAndColorModeChangeButton();
ChangedColorButtonsTransparentVisibility(false);
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

View File

@ -1,59 +0,0 @@
<Window x:Class="Ink_Canvas.HasNewUpdateWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Ink_Canvas"
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
xmlns:mdxam="clr-namespace:MdXaml;assembly=MdXaml"
mc:Ignorable="d"
ui:WindowHelper.UseModernWindowStyle = "True"
ui:WindowHelper.SystemBackdropType="Mica"
ui:TitleBar.Height="36"
Title="InkCanvasForClass有新版本可用" Height="475" Width="800" ResizeMode="NoResize">
<Grid Background="#fafafa">
<ui:SimpleStackPanel VerticalAlignment="Stretch" Spacing="0">
<ui:SimpleStackPanel Orientation="Horizontal" Background="#2563eb" Margin="0,0,0,0">
<ui:SimpleStackPanel Orientation="Vertical" Width="685" Margin="24,18,0,12" Spacing="2">
<TextBlock Text="InkCanvasForClass 新版本来了!" FontSize="24" FontWeight="Bold" Foreground="White" TextAlignment="Left"/>
<TextBlock Text="希望您能喜欢我们的新版本 :-)" FontSize="20" TextAlignment="Left" Foreground="White"/>
</ui:SimpleStackPanel>
<Image Source="/Resources/Icons-fluent/party.png" Width="72" Height="72"/>
</ui:SimpleStackPanel>
<Border BorderBrush="#3f3f46" Background="White" BorderThickness="1" CornerRadius="4" Margin="24,12,24,0">
<ui:ScrollViewerEx Margin="0" VerticalScrollBarVisibility="Auto" Height="256" PanningMode="VerticalOnly">
<mdxam:MarkdownScrollViewer xml:space="preserve" Foreground="Black" MarkdownStyleName="GithubLike">
# InkCanvasForClass v5.0.2更新
你好旅行者们本次InkCanvasForClass更新带来了如下新功能供您探索
1. 全新设计的UI界面包括浮动工具栏和白板页面均经过重新设计更加现代化的UI让您在使用的过程中更加舒适。
2. 带来了实时修改橡皮大小和橡皮形状的菜单。您可以选择使用圆形橡皮,方形橡皮,和类似希沃白板的真实黑板擦(矩形)橡皮。
3. 白板页面支持显示当前时间和日期
4. 自动收纳新增对希沃轻白板、智绘教、鸿合屏幕书写等软件的支持,自动查杀新增对鸿合屏幕书写、希沃轻白板等软件的支持。
5. 为设置界面重写了全新的UI。
6. 重写了随机抽选模块,现在支持更丰富的抽选机制和自定义选项。
7. 修复了部分小Bug提升了整体的用户体验。
8. 带来了基于FitToCurve的笔迹平滑基于贝塞尔曲线平滑让墨迹线条更加优美好看。
</mdxam:MarkdownScrollViewer>
</ui:ScrollViewerEx>
</Border>
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="12" Margin="0,8,0,0">
<TextBlock Text="本次更新: 4.9.1 -> 5.9.1" FontWeight="Bold" FontSize="14" TextAlignment="Center"/>
<TextBlock Text="2024年8月4日发布更新" FontSize="14" TextAlignment="Center"/>
</ui:SimpleStackPanel>
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="12">
<Button Content="立刻更新" Foreground="White" HorizontalAlignment="Center" Margin="0,10,0,0">
<Button.Resources>
<SolidColorBrush x:Key="{x:Static ui:ThemeKeys.ButtonBackgroundKey}" Color="#15803d"/>
<SolidColorBrush x:Key="{x:Static ui:ThemeKeys.ButtonBackgroundPointerOverKey}" Color="#15803d"/>
<SolidColorBrush x:Key="{x:Static ui:ThemeKeys.ButtonBackgroundPressedKey}" Color="#166534"/>
</Button.Resources>
</Button>
<Button Content="下次更新" Foreground="Black" HorizontalAlignment="Center" Margin="0,10,0,0"/>
<Button Content="跳过该版本" HorizontalAlignment="Center" Foreground="#71717a" Margin="0,10,0,0"/>
</ui:SimpleStackPanel>
</ui:SimpleStackPanel>
</Grid>
</Window>

View File

@ -1,66 +0,0 @@
using Ink_Canvas.Helpers;
using iNKORE.UI.WPF.Modern.Controls.Helpers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Ink_Canvas
{
/// <summary>
/// HasNewUpdateWindow.xaml 的交互逻辑
/// </summary>
///
public partial class HasNewUpdateWindow : Window
{
[DllImport("dwmapi.dll")]
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
private const int DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19;
private const int DWMWA_USE_IMMERSIVE_DARK_MODE = 20;
private static bool UseImmersiveDarkMode(IntPtr handle, bool enabled)
{
if (IsWindows10OrGreater(17763))
{
var attribute = DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1;
if (IsWindows10OrGreater(18985))
{
attribute = DWMWA_USE_IMMERSIVE_DARK_MODE;
}
int useImmersiveDarkMode = enabled ? 1 : 0;
return DwmSetWindowAttribute(handle, (int)attribute, ref useImmersiveDarkMode, sizeof(int)) == 0;
}
return false;
}
private static bool IsWindows10OrGreater(int build = -1)
{
return Environment.OSVersion.Version.Major >= 10 && Environment.OSVersion.Version.Build >= build;
}
public HasNewUpdateWindow()
{
InitializeComponent();
AnimationsHelper.ShowWithFadeIn(this, 0.25);
Trace.WriteLine(new WindowInteropHelper(this).Handle);
UseImmersiveDarkMode(new WindowInteropHelper(this).Handle, true);
}
}
}

View File

@ -51,10 +51,10 @@ namespace InkCanvasForClassX.Libraries
public PerfectFreehandJint() {
// perfect-freehand
JintEngine.Execute("function neg(t){return[-t[0],-t[1]]}function add(t,n){return[t[0]+n[0],t[1]+n[1]]}function sub(t,n){return[t[0]-n[0],t[1]-n[1]]}function mul(t,n){return[t[0]*n,t[1]*n]}function div(t,n){return[t[0]/n,t[1]/n]}function per(t){return[t[1],-t[0]]}function dpr(t,n){return t[0]*n[0]+t[1]*n[1]}function isEqual(t,n){return t[0]===n[0]&&t[1]===n[1]}function len(t){return Math.hypot(t[0],t[1])}function len2(t){return t[0]*t[0]+t[1]*t[1]}function dist2(t,n){return len2(sub(t,n))}function uni(t){return div(t,len(t))}function dist(t,n){return Math.hypot(t[1]-n[1],t[0]-n[0])}function med(t,n){return mul(add(t,n),.5)}function rotAround(t,n,e){const r=Math.sin(e),u=Math.cos(e),i=t[0]-n[0],s=t[1]-n[1],o=i*r+s*u;return[i*u-s*r+n[0],o+n[1]]}function lrp(t,n,e){return add(t,mul(sub(n,t),e))}function prj(t,n,e){return add(t,mul(n,e))}function getStrokeRadius(t,n,e,r=(t=>t)){return t*r(.5-n*(.5-e))}function getStrokePoints(t,n={}){var e;const{streamline:r=.5,size:u=16,last:i=!1}=n;if(0===t.length)return[];const s=.15+.85*(1-r);let o=Array.isArray(t[0])?t:t.map((({x:t,y:n,pressure:e=.5})=>[t,n,e]));if(2===o.length){const t=o[1];o=o.slice(0,-1);for(let n=1;n<5;n++)o.push(lrp(o[0],t,n/4))}1===o.length&&(o=[...o,[...add(o[0],[1,1]),...o[0].slice(2)]]);const c=[{point:[o[0][0],o[0][1]],pressure:o[0][2]>=0?o[0][2]:.25,vector:[1,1],distance:0,runningLength:0}];let l=!1,p=0,a=c[0];const d=o.length-1;for(let t=1;t<o.length;t++){const n=i&&t===d?o[t].slice(0,2):lrp(a.point,o[t],s);if(isEqual(a.point,n))continue;const e=dist(n,a.point);if(p+=e,t<d&&!l){if(p<u)continue;l=!0}a={point:n,pressure:o[t][2]>=0?o[t][2]:.5,vector:uni(sub(a.point,n)),distance:e,runningLength:p},c.push(a)}return c[0].vector=(null===(e=c[1])||void 0===e?void 0:e.vector)||[0,0],c}const{min:min,PI:PI}=Math,RATE_OF_PRESSURE_CHANGE=.275,FIXED_PI=PI+1e-4;function getStrokeOutlinePoints(t,n={}){const{size:e=16,smoothing:r=.5,thinning:u=.5,simulatePressure:i=!0,easing:s=(t=>t),start:o={},end:c={},last:l=!1}=n,{cap:p=!0,easing:a=(t=>t*(2-t))}=o,{cap:d=!0,easing:h=(t=>--t*t*t+1)}=c;if(0===t.length||e<=0)return[];const f=t[t.length-1].runningLength,g=!1===o.taper?0:!0===o.taper?Math.max(e,f):o.taper,m=!1===c.taper?0:!0===c.taper?Math.max(e,f):c.taper,E=Math.pow(e*r,2),P=[],v=[];let I,_=t.slice(0,10).reduce(((t,n)=>{let r=n.pressure;if(i){const u=min(1,n.distance/e),i=min(1,1-u);r=min(1,t+u*RATE_OF_PRESSURE_CHANGE*(i-t))}return(t+r)/2}),t[0].pressure),A=getStrokeRadius(e,u,t[t.length-1].pressure,s),S=t[0].vector,b=t[0].point,R=b,M=b,F=R,k=!1;for(let n=0;n<t.length;n++){let{pressure:r}=t[n];const{point:o,vector:c,distance:l,runningLength:p}=t[n];if(n<t.length-1&&f-p<3)continue;if(u){if(i){const t=min(1,l/e),n=min(1,1-t);r=min(1,_+t*RATE_OF_PRESSURE_CHANGE*(n-_))}A=getStrokeRadius(e,u,r,s)}else A=e/2;void 0===I&&(I=A);const d=p<g?a(p/g):1,D=f-p<m?h((f-p)/m):1;A=Math.max(.01,A*Math.min(d,D));const X=(n<t.length-1?t[n+1]:t[n]).vector,y=n<t.length-1?dpr(c,X):1,O=null!==y&&y<0;if(dpr(c,S)<0&&!k||O){const t=mul(per(S),A);for(let n=1/13,e=0;e<=1;e+=n)M=rotAround(sub(o,t),o,FIXED_PI*e),P.push(M),F=rotAround(add(o,t),o,FIXED_PI*-e),v.push(F);b=M,R=F,O&&(k=!0);continue}if(k=!1,n===t.length-1){const t=mul(per(c),A);P.push(sub(o,t)),v.push(add(o,t));continue}const x=mul(per(lrp(X,c,y)),A);M=sub(o,x),(n<=1||dist2(b,M)>E)&&(P.push(M),b=M),F=add(o,x),(n<=1||dist2(R,F)>E)&&(v.push(F),R=F),_=r,S=c}const D=t[0].point.slice(0,2),X=t.length>1?t[t.length-1].point.slice(0,2):add(t[0].point,[1,1]),y=[],O=[];if(1===t.length){if(!g&&!m||l){const t=prj(D,uni(per(sub(D,X))),-(I||A)),n=[];for(let e=1/13,r=e;r<=1;r+=e)n.push(rotAround(t,D,2*FIXED_PI*r));return n}}else{if(g||m&&1===t.length);else if(p)for(let t=1/13,n=t;n<=1;n+=t){const t=rotAround(v[0],D,FIXED_PI*n);y.push(t)}else{const t=sub(P[0],v[0]),n=mul(t,.5),e=mul(t,.51);y.push(sub(D,n),sub(D,e),add(D,e),add(D,n))}const n=per(neg(t[t.length-1].vector));if(m||g&&1===t.length)O.push(X);else if(d){const t=prj(X,n,A);for(let n=1/29,e=n;e<1;e+=n)O.push(rotAround(t,X,3*FIXED_PI*e))}else O.push(add(X,mul(n,A)),add(X,mul(n,.99*A)),sub(X,mul(n,.99*A)),sub(X,mul(n,A)))}return P.concat(O,v.reverse(),y)}function getStroke(t,n={}){return getStrokeOutlinePoints(getStrokePoints(t,n),n)}");
JintEngine.Execute("\"use strict\";function neg(t){return[-t[0],-t[1]]}function add(t,n){return[t[0]+n[0],t[1]+n[1]]}function sub(t,n){return[t[0]-n[0],t[1]-n[1]]}function mul(t,n){return[t[0]*n,t[1]*n]}function div(t,n){return[t[0]/n,t[1]/n]}function per(t){return[t[1],-t[0]]}function dpr(t,n){return t[0]*n[0]+t[1]*n[1]}function isEqual(t,n){return t[0]===n[0]&&t[1]===n[1]}function len(t){return Math.hypot(t[0],t[1])}function len2(t){return t[0]*t[0]+t[1]*t[1]}function dist2(t,n){return len2(sub(t,n))}function uni(t){return div(t,len(t))}function dist(t,n){return Math.hypot(t[1]-n[1],t[0]-n[0])}function med(t,n){return mul(add(t,n),.5)}function rotAround(t,n,e){const r=Math.sin(e),u=Math.cos(e),i=t[0]-n[0],s=t[1]-n[1],o=i*r+s*u;return[i*u-s*r+n[0],o+n[1]]}function lrp(t,n,e){return add(t,mul(sub(n,t),e))}function prj(t,n,e){return add(t,mul(n,e))}function getStrokeRadius(t,n,e,r=(t=>t)){return t*r(.5-n*(.5-e))}function getStrokePoints(t,n={}){var e;const{streamline:r=.5,size:u=16,last:i=!1}=n;if(0===t.length)return[];const s=.15+.85*(1-r);let o=Array.isArray(t[0])?t:t.map((({x:t,y:n,pressure:e=.5})=>[t,n,e]));if(2===o.length){const t=o[1];o=o.slice(0,-1);for(let n=1;n<5;n++)o.push(lrp(o[0],t,n/4))}1===o.length&&(o=[...o,[...add(o[0],[1,1]),...o[0].slice(2)]]);const c=[{point:[o[0][0],o[0][1]],pressure:o[0][2]>=0?o[0][2]:.25,vector:[1,1],distance:0,runningLength:0}];let l=!1,p=0,a=c[0];const d=o.length-1;for(let t=1;t<o.length;t++){const n=i&&t===d?o[t].slice(0,2):lrp(a.point,o[t],s);if(isEqual(a.point,n))continue;const e=dist(n,a.point);if(p+=e,t<d&&!l){if(p<u)continue;l=!0}a={point:n,pressure:o[t][2]>=0?o[t][2]:.5,vector:uni(sub(a.point,n)),distance:e,runningLength:p},c.push(a)}return c[0].vector=(null===(e=c[1])||void 0===e?void 0:e.vector)||[0,0],c}const{min:min,PI:PI}=Math,RATE_OF_PRESSURE_CHANGE=.275,FIXED_PI=PI+1e-4;function getStrokeOutlinePoints(t,n={}){const{size:e=16,smoothing:r=.5,thinning:u=.5,simulatePressure:i=!0,easing:s=(t=>t),start:o={},end:c={},last:l=!1}=n,{cap:p=!0,easing:a=(t=>t*(2-t))}=o,{cap:d=!0,easing:h=(t=>--t*t*t+1)}=c;if(0===t.length||e<=0)return[];const f=t[t.length-1].runningLength,g=!1===o.taper?0:!0===o.taper?Math.max(e,f):o.taper,m=!1===c.taper?0:!0===c.taper?Math.max(e,f):c.taper,E=Math.pow(e*r,2),P=[],v=[];let I,_=t.slice(0,10).reduce(((t,n)=>{let r=n.pressure;if(i){const u=min(1,n.distance/e),i=min(1,1-u);r=min(1,t+u*RATE_OF_PRESSURE_CHANGE*(i-t))}return(t+r)/2}),t[0].pressure),A=getStrokeRadius(e,u,t[t.length-1].pressure,s),S=t[0].vector,b=t[0].point,R=b,M=b,F=R,k=!1;for(let n=0;n<t.length;n++){let{pressure:r}=t[n];const{point:o,vector:c,distance:l,runningLength:p}=t[n];if(n<t.length-1&&f-p<3)continue;if(u){if(i){const t=min(1,l/e),n=min(1,1-t);r=min(1,_+t*RATE_OF_PRESSURE_CHANGE*(n-_))}A=getStrokeRadius(e,u,r,s)}else A=e/2;void 0===I&&(I=A);const d=p<g?a(p/g):1,D=f-p<m?h((f-p)/m):1;A=Math.max(.01,A*Math.min(d,D));const X=(n<t.length-1?t[n+1]:t[n]).vector,y=n<t.length-1?dpr(c,X):1,O=null!==y&&y<0;if(dpr(c,S)<0&&!k||O){const t=mul(per(S),A);for(let n=1/13,e=0;e<=1;e+=n)M=rotAround(sub(o,t),o,FIXED_PI*e),P.push(M),F=rotAround(add(o,t),o,FIXED_PI*-e),v.push(F);b=M,R=F,O&&(k=!0);continue}if(k=!1,n===t.length-1){const t=mul(per(c),A);P.push(sub(o,t)),v.push(add(o,t));continue}const x=mul(per(lrp(X,c,y)),A);M=sub(o,x),(n<=1||dist2(b,M)>E)&&(P.push(M),b=M),F=add(o,x),(n<=1||dist2(R,F)>E)&&(v.push(F),R=F),_=r,S=c}const D=t[0].point.slice(0,2),X=t.length>1?t[t.length-1].point.slice(0,2):add(t[0].point,[1,1]),y=[],O=[];if(1===t.length){if(!g&&!m||l){const t=prj(D,uni(per(sub(D,X))),-(I||A)),n=[];for(let e=1/13,r=e;r<=1;r+=e)n.push(rotAround(t,D,2*FIXED_PI*r));return n}}else{if(g||m&&1===t.length);else if(p)for(let t=1/13,n=t;n<=1;n+=t){const t=rotAround(v[0],D,FIXED_PI*n);y.push(t)}else{const t=sub(P[0],v[0]),n=mul(t,.5),e=mul(t,.51);y.push(sub(D,n),sub(D,e),add(D,e),add(D,n))}const n=per(neg(t[t.length-1].vector));if(m||g&&1===t.length)O.push(X);else if(d){const t=prj(X,n,A);for(let n=1/29,e=n;e<1;e+=n)O.push(rotAround(t,X,3*FIXED_PI*e))}else O.push(add(X,mul(n,A)),add(X,mul(n,.99*A)),sub(X,mul(n,.99*A)),sub(X,mul(n,A)))}return P.concat(O,v.reverse(),y)}function getStroke(t,n={}){return getStrokeOutlinePoints(getStrokePoints(t,n),n)}");
// getSvgPathFromStroke
JintEngine.Execute(
"const average=(e,t)=>(e+t)/2;function getSvgPathFromStroke(e,t=!0){const o=e.length;if(o<4)return\"\";let r=e[0],a=e[1];const i=e[2];let F=`M${r[0].toFixed(2)},${r[1].toFixed(2)} Q${a[0].toFixed(2)},${a[1].toFixed(2)} ${average(a[0],i[0]).toFixed(2)},${average(a[1],i[1]).toFixed(2)} T`;for(let t=2,i=o-1;t<i;t++)r=e[t],a=e[t+1],F+=`${average(r[0],a[0]).toFixed(2)},${average(r[1],a[1]).toFixed(2)} `;return t&&(F+=\"Z\"),F}");
"\"use strict\";const average=(e,t)=>(e+t)/2;function getSvgPathFromStroke(e,t=!0){const o=e.length;if(o<4)return\"\";let r=e[0],a=e[1];const i=e[2];let F=`M${r[0].toFixed(2)},${r[1].toFixed(2)} Q${a[0].toFixed(2)},${a[1].toFixed(2)} ${average(a[0],i[0]).toFixed(2)},${average(a[1],i[1]).toFixed(2)} T`;for(let t=2,i=o-1;t<i;t++)r=e[t],a=e[t+1],F+=`${average(r[0],a[0]).toFixed(2)},${average(r[1],a[1]).toFixed(2)} `;return t&&(F+=\"Z\"),F}");
// getSvgPathStroke
JintEngine.Execute("function getSvgPathStroke(points,options,closed=true){return getSvgPathFromStroke(getStroke(points,options),closed)}");
}