Improve code readability

This commit is contained in:
ChanginJolly 2024-05-01 18:23:32 +08:00
parent 050b091ed9
commit 9703fe9fbf
42 changed files with 6955 additions and 7244 deletions

File diff suppressed because one or more lines are too long

View File

@ -159,13 +159,31 @@
<Compile Include="Helpers\AutoUpdateHelper.cs" /> <Compile Include="Helpers\AutoUpdateHelper.cs" />
<Compile Include="Helpers\DelAutoSavedFiles.cs" /> <Compile Include="Helpers\DelAutoSavedFiles.cs" />
<Compile Include="Helpers\ForegroundWindowInfo.cs" /> <Compile Include="Helpers\ForegroundWindowInfo.cs" />
<Compile Include="ChangeLogWindow.xaml.cs"> <Compile Include="MainWindow_cs\MainWindow_BoardIcons.cs" />
<Compile Include="MainWindow_cs\MainWindow_FloatingBarIcons.cs" />
<Compile Include="MainWindow_cs\MainWindow_AutoTheme.cs" />
<Compile Include="MainWindow_cs\MainWindow_SelectionGestures&amp;FloatingControl.cs" />
<Compile Include="MainWindow_cs\MainWindow_Hotkeys.cs" />
<Compile Include="MainWindow_cs\MainWindow_Notification.cs" />
<Compile Include="MainWindow_cs\MainWindow_BoardControls.cs" />
<Compile Include="MainWindow_cs\MainWindow_AutoStart.cs" />
<Compile Include="MainWindow_cs\MainWindow_TouchEvents.cs" />
<Compile Include="MainWindow_cs\MainWindow_SettingsToLoad.cs" />
<Compile Include="MainWindow_cs\MainWindow_SimulatePenPressure&amp;InkToShape.cs" />
<Compile Include="MainWindow_cs\MainWindow_Screenshot.cs" />
<Compile Include="MainWindow_cs\MainWindow_Save&amp;OpenStrokes.cs" />
<Compile Include="MainWindow_cs\MainWindow_Settings.cs" />
<Compile Include="MainWindow_cs\MainWindow_PPT.cs" />
<Compile Include="MainWindow_cs\MainWindow_Timer.cs" />
<Compile Include="MainWindow_cs\MainWindow_TimeMachine.cs" />
<Compile Include="MainWindow_cs\MainWindow_ShapeDrawing.cs" />
<Compile Include="Windows\ChangeLogWindow.xaml.cs">
<DependentUpon>ChangeLogWindow.xaml</DependentUpon> <DependentUpon>ChangeLogWindow.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="OperatingGuideWindow.xaml.cs"> <Compile Include="Windows\OperatingGuideWindow.xaml.cs">
<DependentUpon>OperatingGuideWindow.xaml</DependentUpon> <DependentUpon>OperatingGuideWindow.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="CycleProcessBar.xaml.cs"> <Compile Include="Windows\CycleProcessBar.xaml.cs">
<DependentUpon>CycleProcessBar.xaml</DependentUpon> <DependentUpon>CycleProcessBar.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Helpers\AnimationsHelper.cs" /> <Compile Include="Helpers\AnimationsHelper.cs" />
@ -176,31 +194,31 @@
<Compile Include="Helpers\TimeMachine.cs" /> <Compile Include="Helpers\TimeMachine.cs" />
<Compile Include="Helpers\Converters.cs" /> <Compile Include="Helpers\Converters.cs" />
<Compile Include="Helpers\WinTabWindowsChecker.cs" /> <Compile Include="Helpers\WinTabWindowsChecker.cs" />
<Compile Include="NamesInputWindow.xaml.cs"> <Compile Include="Windows\NamesInputWindow.xaml.cs">
<DependentUpon>NamesInputWindow.xaml</DependentUpon> <DependentUpon>NamesInputWindow.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="RandWindow.xaml.cs"> <Compile Include="Windows\RandWindow.xaml.cs">
<DependentUpon>RandWindow.xaml</DependentUpon> <DependentUpon>RandWindow.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="YesOrNoNotificationWindow.xaml.cs"> <Compile Include="Windows\YesOrNoNotificationWindow.xaml.cs">
<DependentUpon>YesOrNoNotificationWindow.xaml</DependentUpon> <DependentUpon>YesOrNoNotificationWindow.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Settings.cs" /> <Compile Include="Resources\Settings.cs" />
<Compile Include="SettingsPage.xaml.cs"> <Compile Include="Windows\SettingsPage.xaml.cs">
<DependentUpon>SettingsPage.xaml</DependentUpon> <DependentUpon>SettingsPage.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="CountdownTimerWindow.xaml.cs"> <Compile Include="Windows\CountdownTimerWindow.xaml.cs">
<DependentUpon>CountdownTimerWindow.xaml</DependentUpon> <DependentUpon>CountdownTimerWindow.xaml</DependentUpon>
</Compile> </Compile>
<Page Include="ChangeLogWindow.xaml"> <Page Include="Windows\ChangeLogWindow.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="OperatingGuideWindow.xaml"> <Page Include="Windows\OperatingGuideWindow.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Page> </Page>
<Page Include="CycleProcessBar.xaml"> <Page Include="Windows\CycleProcessBar.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Page> </Page>
@ -217,11 +235,11 @@
<DependentUpon>MainWindow.xaml</DependentUpon> <DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Page Include="NamesInputWindow.xaml"> <Page Include="Windows\NamesInputWindow.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="RandWindow.xaml"> <Page Include="Windows\RandWindow.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
@ -245,15 +263,15 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="YesOrNoNotificationWindow.xaml"> <Page Include="Windows\YesOrNoNotificationWindow.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="SettingsPage.xaml"> <Page Include="Windows\SettingsPage.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="CountdownTimerWindow.xaml"> <Page Include="Windows\CountdownTimerWindow.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
@ -493,5 +511,6 @@
<ItemGroup> <ItemGroup>
<Resource Include="Resources\Icons-Fluent\ic_fluent_control_button_24_regular.png" /> <Resource Include="Resources\Icons-Fluent\ic_fluent_control_button_24_regular.png" />
</ItemGroup> </ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View File

@ -1158,7 +1158,7 @@
<TextBlock Name="TextBlockNotice" Text="测试文本" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="16"/> <TextBlock Name="TextBlockNotice" Text="测试文本" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="16"/>
</Border> </Border>
</Grid> </Grid>
<!--// Old UI //-->
<Viewbox Name="ViewBoxStackPanelMain" Visibility="Visible" Margin="10,10,10,55" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="46"> <Viewbox Name="ViewBoxStackPanelMain" Visibility="Visible" Margin="10,10,10,55" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="46">
<StackPanel Name="StackPanelMain" Width="46"> <StackPanel Name="StackPanelMain" Width="46">
<StackPanel Name="StackPanelControl"> <StackPanel Name="StackPanelControl">

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,36 @@
using IWshRuntimeLibrary;
using System;
using System.Windows;
namespace Ink_Canvas {
public partial class MainWindow : Window {
public static bool StartAutomaticallyCreate(string exeName) {
try {
WshShell shell = new WshShell();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\" + exeName + ".lnk");
//设置快捷方式的目标所在的位置(源程序完整路径)
shortcut.TargetPath = System.Windows.Forms.Application.ExecutablePath;
//应用程序的工作目录
//当用户没有指定一个具体的目录时,快捷方式的目标应用程序将使用该属性所指定的目录来装载或保存文件。
shortcut.WorkingDirectory = System.Environment.CurrentDirectory;
//目标应用程序窗口类型(1.Normal window普通窗口,3.Maximized最大化窗口,7.Minimized最小化)
shortcut.WindowStyle = 1;
//快捷方式的描述
shortcut.Description = exeName + "_Ink";
//设置快捷键(如果有必要的话.)
//shortcut.Hotkey = "CTRL+ALT+D";
shortcut.Save();
return true;
} catch (Exception) { }
return false;
}
public static bool StartAutomaticallyDel(string exeName) {
try {
System.IO.File.Delete(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\" + exeName + ".lnk");
return true;
} catch (Exception) { }
return false;
}
}
}

View File

@ -0,0 +1,76 @@
using Microsoft.Win32;
using iNKORE.UI.WPF.Modern;
using System;
using System.Windows;
using System.Windows.Media;
using Application = System.Windows.Application;
namespace Ink_Canvas {
public partial class MainWindow : Window {
Color FloatBarForegroundColor = Color.FromRgb(102, 102, 102);
private void SetTheme(string theme) {
if (theme == "Light") {
ResourceDictionary rd1 = new ResourceDictionary() { Source = new Uri("Resources/Styles/Light.xaml", UriKind.Relative) };
Application.Current.Resources.MergedDictionaries.Add(rd1);
ResourceDictionary rd2 = new ResourceDictionary() { Source = new Uri("Resources/DrawShapeImageDictionary.xaml", UriKind.Relative) };
Application.Current.Resources.MergedDictionaries.Add(rd2);
ResourceDictionary rd3 = new ResourceDictionary() { Source = new Uri("Resources/SeewoImageDictionary.xaml", UriKind.Relative) };
Application.Current.Resources.MergedDictionaries.Add(rd3);
ResourceDictionary rd4 = new ResourceDictionary() { Source = new Uri("Resources/IconImageDictionary.xaml", UriKind.Relative) };
Application.Current.Resources.MergedDictionaries.Add(rd4);
ThemeManager.SetRequestedTheme(window, ElementTheme.Light);
FloatBarForegroundColor = (Color)Application.Current.FindResource("FloatBarForegroundColor");
} else if (theme == "Dark") {
ResourceDictionary rd1 = new ResourceDictionary() { Source = new Uri("Resources/Styles/Dark.xaml", UriKind.Relative) };
Application.Current.Resources.MergedDictionaries.Add(rd1);
ResourceDictionary rd2 = new ResourceDictionary() { Source = new Uri("Resources/DrawShapeImageDictionary.xaml", UriKind.Relative) };
Application.Current.Resources.MergedDictionaries.Add(rd2);
ResourceDictionary rd3 = new ResourceDictionary() { Source = new Uri("Resources/SeewoImageDictionary.xaml", UriKind.Relative) };
Application.Current.Resources.MergedDictionaries.Add(rd3);
ResourceDictionary rd4 = new ResourceDictionary() { Source = new Uri("Resources/IconImageDictionary.xaml", UriKind.Relative) };
Application.Current.Resources.MergedDictionaries.Add(rd4);
ThemeManager.SetRequestedTheme(window, ElementTheme.Dark);
FloatBarForegroundColor = (Color)Application.Current.FindResource("FloatBarForegroundColor");
}
}
private void SystemEvents_UserPreferenceChanged(object sender, Microsoft.Win32.UserPreferenceChangedEventArgs e) {
switch (Settings.Appearance.Theme) {
case 0:
SetTheme("Light");
break;
case 1:
SetTheme("Dark");
break;
case 2:
if (IsSystemThemeLight()) SetTheme("Light");
else SetTheme("Dark");
break;
}
}
private bool IsSystemThemeLight() {
bool light = false;
try {
RegistryKey registryKey = Registry.CurrentUser;
RegistryKey themeKey = registryKey.OpenSubKey("software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");
int keyValue = 0;
if (themeKey != null) {
keyValue = (int)themeKey.GetValue("SystemUsesLightTheme");
}
if (keyValue == 1) light = true;
} catch { }
return light;
}
}
}

View File

@ -0,0 +1,335 @@
using Ink_Canvas.Helpers;
using System;
using System.Windows;
using System.Windows.Ink;
using System.Windows.Media.Imaging;
namespace Ink_Canvas {
public partial class MainWindow : Window {
StrokeCollection[] strokeCollections = new StrokeCollection[101];
bool[] whiteboadLastModeIsRedo = new bool[101];
StrokeCollection lastTouchDownStrokeCollection = new StrokeCollection();
int CurrentWhiteboardIndex = 1;
int WhiteboardTotalCount = 1;
TimeMachineHistory[][] TimeMachineHistories = new TimeMachineHistory[101][]; //最多99页0用来存储非白板时的墨迹以便还原
private void SaveStrokes(bool isBackupMain = false) {
if (isBackupMain) {
var timeMachineHistory = timeMachine.ExportTimeMachineHistory();
TimeMachineHistories[0] = timeMachineHistory;
timeMachine.ClearStrokeHistory();
} else {
var timeMachineHistory = timeMachine.ExportTimeMachineHistory();
TimeMachineHistories[CurrentWhiteboardIndex] = timeMachineHistory;
timeMachine.ClearStrokeHistory();
}
}
private void ClearStrokes(bool isErasedByCode) {
_currentCommitType = CommitReason.ClearingCanvas;
if (isErasedByCode) _currentCommitType = CommitReason.CodeInput;
inkCanvas.Strokes.Clear();
_currentCommitType = CommitReason.UserInput;
}
private void RestoreStrokes(bool isBackupMain = false) {
try {
if (TimeMachineHistories[CurrentWhiteboardIndex] == null) return; //防止白板打开后不居中
if (isBackupMain) {
_currentCommitType = CommitReason.CodeInput;
timeMachine.ImportTimeMachineHistory(TimeMachineHistories[0]);
foreach (var item in TimeMachineHistories[0]) {
if (item.CommitType == TimeMachineHistoryType.UserInput) {
if (!item.StrokeHasBeenCleared) {
foreach (var strokes in item.CurrentStroke) {
if (!inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Add(strokes);
}
} else {
foreach (var strokes in item.CurrentStroke) {
if (inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Remove(strokes);
}
}
} else if (item.CommitType == TimeMachineHistoryType.ShapeRecognition) {
if (item.StrokeHasBeenCleared) {
foreach (var strokes in item.CurrentStroke) {
if (inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Remove(strokes);
}
foreach (var strokes in item.ReplacedStroke) {
if (!inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Add(strokes);
}
} else {
foreach (var strokes in item.CurrentStroke) {
if (!inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Add(strokes);
}
foreach (var strokes in item.ReplacedStroke) {
if (inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Remove(strokes);
}
}
} else if (item.CommitType == TimeMachineHistoryType.Rotate) {
if (item.StrokeHasBeenCleared) {
foreach (var strokes in item.CurrentStroke) {
if (inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Remove(strokes);
}
foreach (var strokes in item.ReplacedStroke) {
if (!inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Add(strokes);
}
} else {
foreach (var strokes in item.CurrentStroke) {
if (!inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Add(strokes);
}
foreach (var strokes in item.ReplacedStroke) {
if (inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Remove(strokes);
}
}
} else if (item.CommitType == TimeMachineHistoryType.Clear) {
if (!item.StrokeHasBeenCleared) {
if (item.CurrentStroke != null) {
foreach (var currentStroke in item.CurrentStroke) {
if (!inkCanvas.Strokes.Contains(currentStroke)) inkCanvas.Strokes.Add(currentStroke);
}
}
if (item.ReplacedStroke != null) {
foreach (var replacedStroke in item.ReplacedStroke) {
if (inkCanvas.Strokes.Contains(replacedStroke)) inkCanvas.Strokes.Remove(replacedStroke);
}
}
} else {
if (item.ReplacedStroke != null) {
foreach (var replacedStroke in item.ReplacedStroke) {
if (!inkCanvas.Strokes.Contains(replacedStroke)) inkCanvas.Strokes.Add(replacedStroke);
}
}
if (item.CurrentStroke != null) {
foreach (var currentStroke in item.CurrentStroke) {
if (inkCanvas.Strokes.Contains(currentStroke)) inkCanvas.Strokes.Remove(currentStroke);
}
}
}
}
_currentCommitType = CommitReason.UserInput;
}
} else {
_currentCommitType = CommitReason.CodeInput;
timeMachine.ImportTimeMachineHistory(TimeMachineHistories[CurrentWhiteboardIndex]);
foreach (var item in TimeMachineHistories[CurrentWhiteboardIndex]) {
if (item.CommitType == TimeMachineHistoryType.UserInput) {
if (!item.StrokeHasBeenCleared) {
foreach (var strokes in item.CurrentStroke) {
if (!inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Add(strokes);
}
} else {
foreach (var strokes in item.CurrentStroke) {
if (inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Remove(strokes);
}
}
} else if (item.CommitType == TimeMachineHistoryType.ShapeRecognition) {
if (item.StrokeHasBeenCleared) {
foreach (var strokes in item.CurrentStroke) {
if (inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Remove(strokes);
}
foreach (var strokes in item.ReplacedStroke) {
if (!inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Add(strokes);
}
} else {
foreach (var strokes in item.CurrentStroke) {
if (!inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Add(strokes);
}
foreach (var strokes in item.ReplacedStroke) {
if (inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Remove(strokes);
}
}
} else if (item.CommitType == TimeMachineHistoryType.Rotate) {
if (item.StrokeHasBeenCleared) {
foreach (var strokes in item.CurrentStroke) {
if (inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Remove(strokes);
}
foreach (var strokes in item.ReplacedStroke) {
if (!inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Add(strokes);
}
} else {
foreach (var strokes in item.CurrentStroke) {
if (!inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Add(strokes);
}
foreach (var strokes in item.ReplacedStroke) {
if (inkCanvas.Strokes.Contains(strokes))
inkCanvas.Strokes.Remove(strokes);
}
}
} else if (item.CommitType == TimeMachineHistoryType.Clear) {
if (!item.StrokeHasBeenCleared) {
if (item.CurrentStroke != null) {
foreach (var currentStroke in item.CurrentStroke) {
if (!inkCanvas.Strokes.Contains(currentStroke)) inkCanvas.Strokes.Add(currentStroke);
}
}
if (item.ReplacedStroke != null) {
foreach (var replacedStroke in item.ReplacedStroke) {
if (inkCanvas.Strokes.Contains(replacedStroke)) inkCanvas.Strokes.Remove(replacedStroke);
}
}
} else {
if (item.ReplacedStroke != null) {
foreach (var replacedStroke in item.ReplacedStroke) {
if (!inkCanvas.Strokes.Contains(replacedStroke)) inkCanvas.Strokes.Add(replacedStroke);
}
}
if (item.CurrentStroke != null) {
foreach (var currentStroke in item.CurrentStroke) {
if (inkCanvas.Strokes.Contains(currentStroke)) inkCanvas.Strokes.Remove(currentStroke);
}
}
}
}
}
_currentCommitType = CommitReason.UserInput;
}
} catch { }
}
private void BtnWhiteBoardSwitchPrevious_Click(object sender, EventArgs e) {
if (CurrentWhiteboardIndex <= 1) return;
SaveStrokes();
ClearStrokes(true);
CurrentWhiteboardIndex--;
RestoreStrokes();
UpdateIndexInfoDisplay();
}
private void BtnWhiteBoardSwitchNext_Click(object sender, EventArgs e) {
if (Settings.Automation.IsAutoSaveStrokesAtClear && inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) {
SaveScreenShot(true);
}
if (CurrentWhiteboardIndex >= WhiteboardTotalCount) {
BtnWhiteBoardAdd_Click(sender, e);
return;
}
SaveStrokes();
ClearStrokes(true);
CurrentWhiteboardIndex++;
RestoreStrokes();
UpdateIndexInfoDisplay();
}
private void BtnWhiteBoardAdd_Click(object sender, EventArgs e) {
if (WhiteboardTotalCount >= 99) return;
if (Settings.Automation.IsAutoSaveStrokesAtClear && inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber) {
SaveScreenShot(true);
}
SaveStrokes();
ClearStrokes(true);
WhiteboardTotalCount++;
CurrentWhiteboardIndex++;
if (CurrentWhiteboardIndex != WhiteboardTotalCount) {
for (int i = WhiteboardTotalCount; i > CurrentWhiteboardIndex; i--) {
TimeMachineHistories[i] = TimeMachineHistories[i - 1];
}
}
UpdateIndexInfoDisplay();
if (WhiteboardTotalCount >= 99) BtnWhiteBoardAdd.IsEnabled = false;
}
private void BtnWhiteBoardDelete_Click(object sender, RoutedEventArgs e) {
ClearStrokes(true);
if (CurrentWhiteboardIndex != WhiteboardTotalCount) {
for (int i = CurrentWhiteboardIndex; i <= WhiteboardTotalCount; i++) {
TimeMachineHistories[i] = TimeMachineHistories[i + 1];
}
} else {
CurrentWhiteboardIndex--;
}
WhiteboardTotalCount--;
RestoreStrokes();
UpdateIndexInfoDisplay();
if (WhiteboardTotalCount < 99) BtnWhiteBoardAdd.IsEnabled = true;
}
private void UpdateIndexInfoDisplay() {
TextBlockWhiteBoardIndexInfo.Text = string.Format("{0} / {1}", CurrentWhiteboardIndex, WhiteboardTotalCount);
if (CurrentWhiteboardIndex == WhiteboardTotalCount) {
BitmapImage newImageSource = new BitmapImage();
newImageSource.BeginInit();
newImageSource.UriSource = new Uri("/Resources/Icons-Fluent/ic_fluent_add_circle_24_regular.png", UriKind.RelativeOrAbsolute);
newImageSource.EndInit();
BoardLeftPannelNextPage.Source = newImageSource;
BoardRightPannelNextPage.Source = newImageSource;
BoardRightPannelNextPageTextBlock.Text = "加页";
BoardLeftPannelNextPageTextBlock.Text = "加页";
} else {
BitmapImage newImageSource = new BitmapImage();
newImageSource.BeginInit();
newImageSource.UriSource = new Uri("/Resources/Icons-Fluent/ic_fluent_arrow_circle_right_24_regular.png", UriKind.RelativeOrAbsolute);
newImageSource.EndInit();
BoardLeftPannelNextPage.Source = newImageSource;
BoardRightPannelNextPage.Source = newImageSource;
BoardRightPannelNextPageTextBlock.Text = "下一页";
BoardLeftPannelNextPageTextBlock.Text = "下一页";
}
if (CurrentWhiteboardIndex == 1) {
BtnWhiteBoardSwitchPrevious.IsEnabled = false;
} else {
BtnWhiteBoardSwitchPrevious.IsEnabled = true;
}
if (CurrentWhiteboardIndex == WhiteboardTotalCount) {
BtnWhiteBoardSwitchNext.IsEnabled = false;
} else {
BtnWhiteBoardSwitchNext.IsEnabled = true;
}
if (WhiteboardTotalCount == 1) {
BtnWhiteBoardDelete.IsEnabled = false;
} else {
BtnWhiteBoardDelete.IsEnabled = true;
}
}
}
}

View File

@ -0,0 +1,89 @@
using Ink_Canvas.Helpers;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
namespace Ink_Canvas {
public partial class MainWindow : Window {
private void BoardChangeBackgroundColorBtn_MouseUp(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Canvas.UsingWhiteboard = !Settings.Canvas.UsingWhiteboard;
SaveSettingsToFile();
if (Settings.Canvas.UsingWhiteboard) {
if (inkColor == 5) inkColor = 0;
} else {
if (inkColor == 0) inkColor = 5;
}
CheckColorTheme(true);
}
private void BoardEraserIcon_Click(object sender, RoutedEventArgs e) {
if (BoardEraser.Background.ToString() == "#FF679CF4") {
AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardDeleteIcon);
} else {
forceEraser = true;
forcePointEraser = true;
double k = 1;
switch (Settings.Canvas.EraserSize) {
case 0:
k = 0.5;
break;
case 1:
k = 0.8;
break;
case 3:
k = 1.25;
break;
case 4:
k = 1.8;
break;
}
inkCanvas.EraserShape = new EllipseStylusShape(k * 90, k * 90);
inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
drawingShapeMode = 0;
inkCanvas_EditingModeChanged(inkCanvas, null);
CancelSingleFingerDragMode();
HideSubPanels("eraser");
}
}
private void BoardEraserIconByStrokes_Click(object sender, RoutedEventArgs e) {
if (BoardEraserByStrokes.Background.ToString() == "#FF679CF4") {
AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardDeleteIcon);
} else {
forceEraser = true;
forcePointEraser = false;
inkCanvas.EraserShape = new EllipseStylusShape(5, 5);
inkCanvas.EditingMode = InkCanvasEditingMode.EraseByStroke;
drawingShapeMode = 0;
inkCanvas_EditingModeChanged(inkCanvas, null);
CancelSingleFingerDragMode();
HideSubPanels("eraserByStrokes");
}
}
private void BoardSymbolIconDelete_MouseUp(object sender, MouseButtonEventArgs e) {
PenIcon_Click(null, null);
SymbolIconDelete_MouseUp(sender, e);
}
private void BoardLaunchEasiCamera_MouseUp(object sender, MouseButtonEventArgs e) {
ImageBlackboard_MouseUp(null, null);
SoftwareLauncher.LaunchEasiCamera("希沃视频展台");
}
private void BoardLaunchDesmos_MouseUp(object sender, MouseButtonEventArgs e) {
HideSubPanelsImmediately();
ImageBlackboard_MouseUp(null, null);
Process.Start("https://www.desmos.com/calculator?lang=zh-CN");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,102 @@
using System.Windows;
using System.Windows.Input;
namespace Ink_Canvas {
public partial class MainWindow : Window {
private void Window_MouseWheel(object sender, MouseWheelEventArgs e) {
if (StackPanelPPTControls.Visibility != Visibility.Visible || currentMode != 0) return;
if (e.Delta >= 120) {
BtnPPTSlidesUp_Click(BtnPPTSlidesUp, null);
} else if (e.Delta <= -120) {
BtnPPTSlidesDown_Click(BtnPPTSlidesDown, null);
}
}
private void Main_Grid_PreviewKeyDown(object sender, KeyEventArgs e) {
if (StackPanelPPTControls.Visibility != Visibility.Visible || currentMode != 0) return;
if (e.Key == Key.Down || e.Key == Key.PageDown || e.Key == Key.Right || e.Key == Key.N || e.Key == Key.Space) {
BtnPPTSlidesDown_Click(BtnPPTSlidesDown, null);
}
if (e.Key == Key.Up || e.Key == Key.PageUp || e.Key == Key.Left || e.Key == Key.P) {
BtnPPTSlidesUp_Click(BtnPPTSlidesUp, null);
}
}
private void Window_KeyDown(object sender, KeyEventArgs e) {
if (e.Key == Key.Escape) {
KeyExit(null, null);
}
}
private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = true;
}
private void HotKey_Undo(object sender, ExecutedRoutedEventArgs e) {
try {
SymbolIconUndo_MouseUp(lastBorderMouseDownObject, null);
} catch { }
}
private void HotKey_Redo(object sender, ExecutedRoutedEventArgs e) {
try {
SymbolIconRedo_MouseUp(lastBorderMouseDownObject, null);
} catch { }
}
private void HotKey_Clear(object sender, ExecutedRoutedEventArgs e) {
SymbolIconDelete_MouseUp(lastBorderMouseDownObject, null);
}
private void KeyExit(object sender, ExecutedRoutedEventArgs e) {
BtnPPTSlideShowEnd_Click(BtnPPTSlideShowEnd, null);
}
private void KeyChangeToDrawTool(object sender, ExecutedRoutedEventArgs e) {
PenIcon_Click(lastBorderMouseDownObject, null);
}
private void KeyChangeToQuitDrawTool(object sender, ExecutedRoutedEventArgs e) {
if (currentMode != 0) {
ImageBlackboard_MouseUp(lastBorderMouseDownObject, null);
}
CursorIcon_Click(lastBorderMouseDownObject, null);
}
private void KeyChangeToSelect(object sender, ExecutedRoutedEventArgs e) {
if (StackPanelCanvasControls.Visibility == Visibility.Visible) {
SymbolIconSelect_MouseUp(lastBorderMouseDownObject, null);
}
}
private void KeyChangeToEraser(object sender, ExecutedRoutedEventArgs e) {
if (StackPanelCanvasControls.Visibility == Visibility.Visible) {
if (Eraser_Icon.Background != null) {
EraserIconByStrokes_Click(lastBorderMouseDownObject, null);
} else {
EraserIcon_Click(lastBorderMouseDownObject, null);
}
}
}
private void KeyChangeToBoard(object sender, ExecutedRoutedEventArgs e) {
ImageBlackboard_MouseUp(lastBorderMouseDownObject, null);
}
private void KeyCapture(object sender, ExecutedRoutedEventArgs e) {
SaveScreenShotToDesktop();
}
private void KeyDrawLine(object sender, ExecutedRoutedEventArgs e) {
if (StackPanelCanvasControls.Visibility == Visibility.Visible) {
BtnDrawLine_Click(lastMouseDownSender, e);
}
}
private void KeyHide(object sender, ExecutedRoutedEventArgs e) {
SymbolIconEmoji_MouseUp(null, null);
}
}
}

View File

@ -0,0 +1,32 @@
using Ink_Canvas.Helpers;
using System;
using System.Linq;
using System.Threading;
using System.Windows;
namespace Ink_Canvas {
public partial class MainWindow : Window {
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)?.ShowNotification(notice, isShowImmediately);
}
public void ShowNotification(string notice, bool isShowImmediately = true) {
lastNotificationShowTime = Environment.TickCount;
TextBlockNotice.Text = notice;
AnimationsHelper.ShowWithSlideFromBottomAndFade(GridNotifications);
new Thread(new ThreadStart(() => {
Thread.Sleep(notificationShowTime + 300);
if (Environment.TickCount - lastNotificationShowTime >= notificationShowTime) {
Application.Current.Dispatcher.Invoke(() => {
AnimationsHelper.HideWithSlideAndFade(GridNotifications);
});
}
})).Start();
}
}
}

View File

@ -0,0 +1,589 @@
using Ink_Canvas.Helpers;
using Microsoft.Office.Interop.PowerPoint;
using iNKORE.UI.WPF.Modern;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using Application = System.Windows.Application;
using File = System.IO.File;
using MessageBox = System.Windows.MessageBox;
using iNKORE.UI.WPF.Helpers;
namespace Ink_Canvas {
public partial class MainWindow : Window {
public static Microsoft.Office.Interop.PowerPoint.Application pptApplication = null;
public static Microsoft.Office.Interop.PowerPoint.Presentation presentation = null;
public static Microsoft.Office.Interop.PowerPoint.Slides slides = null;
public static Microsoft.Office.Interop.PowerPoint.Slide slide = null;
public static int slidescount = 0;
private void BtnCheckPPT_Click(object sender, RoutedEventArgs e) {
try {
pptApplication = (Microsoft.Office.Interop.PowerPoint.Application)Marshal.GetActiveObject("PowerPoint.Application");
//pptApplication.SlideShowWindows[1].View.Next();
if (pptApplication != null) {
//获得演示文稿对象
presentation = pptApplication.ActivePresentation;
pptApplication.SlideShowBegin += PptApplication_SlideShowBegin;
pptApplication.SlideShowNextSlide += PptApplication_SlideShowNextSlide;
pptApplication.SlideShowEnd += PptApplication_SlideShowEnd;
// 获得幻灯片对象集合
slides = presentation.Slides;
// 获得幻灯片的数量
slidescount = slides.Count;
memoryStreams = new MemoryStream[slidescount + 2];
// 获得当前选中的幻灯片
try {
// 在普通视图下这种方式可以获得当前选中的幻灯片对象
// 然而在阅读模式下,这种方式会出现异常
slide = slides[pptApplication.ActiveWindow.Selection.SlideRange.SlideNumber];
} catch {
// 在阅读模式下出现异常时,通过下面的方式来获得当前选中的幻灯片对象
slide = pptApplication.SlideShowWindows[1].View.Slide;
}
}
if (pptApplication == null) throw new Exception();
//BtnCheckPPT.Visibility = Visibility.Collapsed;
StackPanelPPTControls.Visibility = Visibility.Visible;
} catch {
//BtnCheckPPT.Visibility = Visibility.Visible;
StackPanelPPTControls.Visibility = Visibility.Collapsed;
BottomViewboxPPTSidesControl.Visibility = Visibility.Collapsed;
LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
MessageBox.Show("未找到幻灯片");
}
}
private void ToggleSwitchSupportWPS_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.PowerPointSettings.IsSupportWPS = ToggleSwitchSupportWPS.IsOn;
SaveSettingsToFile();
}
public static bool isWPSSupportOn => Settings.PowerPointSettings.IsSupportWPS;
public static bool IsShowingRestoreHiddenSlidesWindow = false;
private void TimerCheckPPT_Elapsed(object sender, ElapsedEventArgs e) {
if (IsShowingRestoreHiddenSlidesWindow) return;
try {
Process[] processes = Process.GetProcessesByName("wpp");
if (processes.Length > 0 && !isWPSSupportOn) {
return;
}
//使用下方提前创建 PowerPoint 实例,将导致 PowerPoint 不再有启动界面
//pptApplication = (Microsoft.Office.Interop.PowerPoint.Application)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("91493441-5A91-11CF-8700-00AA0060263B")));
//new ComAwareEventInfo(typeof(EApplication_Event), "SlideShowBegin").AddEventHandler(pptApplication, new EApplication_SlideShowBeginEventHandler(this.PptApplication_SlideShowBegin));
//new ComAwareEventInfo(typeof(EApplication_Event), "SlideShowEnd").AddEventHandler(pptApplication, new EApplication_SlideShowEndEventHandler(this.PptApplication_SlideShowEnd));
//new ComAwareEventInfo(typeof(EApplication_Event), "SlideShowNextSlide").AddEventHandler(pptApplication, new EApplication_SlideShowNextSlideEventHandler(this.PptApplication_SlideShowNextSlide));
//ConfigHelper.Instance.IsInitApplicationSuccessful = true;
pptApplication = (Microsoft.Office.Interop.PowerPoint.Application)Marshal.GetActiveObject("PowerPoint.Application");
if (pptApplication != null) {
timerCheckPPT.Stop();
//获得演示文稿对象
presentation = pptApplication.ActivePresentation;
pptApplication.PresentationClose += PptApplication_PresentationClose;
pptApplication.SlideShowBegin += PptApplication_SlideShowBegin;
pptApplication.SlideShowNextSlide += PptApplication_SlideShowNextSlide;
pptApplication.SlideShowEnd += PptApplication_SlideShowEnd;
// 获得幻灯片对象集合
slides = presentation.Slides;
// 获得幻灯片的数量
slidescount = slides.Count;
memoryStreams = new MemoryStream[slidescount + 2];
// 获得当前选中的幻灯片
try {
// 在普通视图下这种方式可以获得当前选中的幻灯片对象
// 然而在阅读模式下,这种方式会出现异常
slide = slides[pptApplication.ActiveWindow.Selection.SlideRange.SlideNumber];
} catch {
// 在阅读模式下出现异常时,通过下面的方式来获得当前选中的幻灯片对象
slide = pptApplication.SlideShowWindows[1].View.Slide;
}
}
if (pptApplication == null) return;
//BtnCheckPPT.Visibility = Visibility.Collapsed;
// 跳转到上次播放页
if (Settings.PowerPointSettings.IsNotifyPreviousPage)
Application.Current.Dispatcher.BeginInvoke(() => {
string folderPath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - Presentations\" + presentation.Name + "_" + presentation.Slides.Count;
try {
if (File.Exists(folderPath + "/Position")) {
if (int.TryParse(File.ReadAllText(folderPath + "/Position"), out var page)) {
if (page <= 0) return;
new YesOrNoNotificationWindow($"上次播放到了第 {page} 页, 是否立即跳转", () => {
if (pptApplication.SlideShowWindows.Count >= 1) {
// 如果已经播放了的话, 跳转
presentation.SlideShowWindow.View.GotoSlide(page);
} else {
presentation.Windows[1].View.GotoSlide(page);
}
}).ShowDialog();
}
}
} catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
}, DispatcherPriority.Normal);
//检查是否有隐藏幻灯片
if (Settings.PowerPointSettings.IsNotifyHiddenPage) {
bool isHaveHiddenSlide = false;
foreach (Slide slide in slides) {
if (slide.SlideShowTransition.Hidden == Microsoft.Office.Core.MsoTriState.msoTrue) {
isHaveHiddenSlide = true;
break;
}
}
Application.Current.Dispatcher.BeginInvoke(() => {
if (isHaveHiddenSlide && !IsShowingRestoreHiddenSlidesWindow) {
IsShowingRestoreHiddenSlidesWindow = true;
new YesOrNoNotificationWindow("检测到此演示文档中包含隐藏的幻灯片,是否取消隐藏?",
() => {
foreach (Slide slide in slides) {
if (slide.SlideShowTransition.Hidden ==
Microsoft.Office.Core.MsoTriState.msoTrue) {
slide.SlideShowTransition.Hidden =
Microsoft.Office.Core.MsoTriState.msoFalse;
}
}
}).ShowDialog();
}
BtnPPTSlideShow.Visibility = Visibility.Visible;
}, DispatcherPriority.Normal);
}
//如果检测到已经开始放映,则立即进入画板模式
if (pptApplication.SlideShowWindows.Count >= 1) {
PptApplication_SlideShowBegin(pptApplication.SlideShowWindows[1]);
}
} catch {
//StackPanelPPTControls.Visibility = Visibility.Collapsed;
Application.Current.Dispatcher.Invoke(() => {
BtnPPTSlideShow.Visibility = Visibility.Collapsed;
});
timerCheckPPT.Start();
}
}
private void PptApplication_PresentationClose(Presentation Pres) {
pptApplication.PresentationClose -= PptApplication_PresentationClose;
pptApplication.SlideShowBegin -= PptApplication_SlideShowBegin;
pptApplication.SlideShowNextSlide -= PptApplication_SlideShowNextSlide;
pptApplication.SlideShowEnd -= PptApplication_SlideShowEnd;
pptApplication = null;
timerCheckPPT.Start();
Application.Current.Dispatcher.Invoke(() => {
BtnPPTSlideShow.Visibility = Visibility.Collapsed;
BtnPPTSlideShowEnd.Visibility = Visibility.Collapsed;
});
}
bool isPresentationHaveBlackSpace = false;
private string pptName = null;
private void PptApplication_SlideShowBegin(SlideShowWindow Wn) {
if (Settings.Automation.IsAutoFoldInPPTSlideShow && !isFloatingBarFolded) {
FoldFloatingBar_MouseUp(null, null);
} else if (isFloatingBarFolded) {
UnFoldFloatingBar_MouseUp(null, null);
}
LogHelper.WriteLogToFile("PowerPoint Application Slide Show Begin", LogHelper.LogType.Event);
Application.Current.Dispatcher.Invoke(() => {
if (currentMode != 0) {
ImageBlackboard_MouseUp(null, null);
}
//调整颜色
double screenRatio = SystemParameters.PrimaryScreenWidth / SystemParameters.PrimaryScreenHeight;
if (Math.Abs(screenRatio - 16.0 / 9) <= -0.01) {
if (Wn.Presentation.PageSetup.SlideWidth / Wn.Presentation.PageSetup.SlideHeight < 1.65) {
isPresentationHaveBlackSpace = true;
//isButtonBackgroundTransparent = ToggleSwitchTransparentButtonBackground.IsOn;
if (BtnSwitchTheme.Content.ToString() == "深色") {
//Light
BtnExit.Foreground = Brushes.White;
//SymbolIconBtnColorBlackContent.Foreground = Brushes.White;
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Dark;
//BtnExit.Background = new SolidColorBrush(StringToColor("#AACCCCCC"));
} else {
//Dark
//BtnExit.Background = new SolidColorBrush(StringToColor("#AA555555"));
}
}
} else if (screenRatio == -256 / 135) {
}
lastDesktopInkColor = 1;
slidescount = Wn.Presentation.Slides.Count;
previousSlideID = 0;
memoryStreams = new MemoryStream[slidescount + 2];
pptName = Wn.Presentation.Name;
LogHelper.NewLog("Name: " + Wn.Presentation.Name);
LogHelper.NewLog("Slides Count: " + slidescount.ToString());
//检查是否有已有墨迹,并加载
if (Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint) {
if (Directory.Exists(Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - Presentations\" + Wn.Presentation.Name + "_" + Wn.Presentation.Slides.Count)) {
LogHelper.WriteLogToFile("Found saved strokes", LogHelper.LogType.Trace);
FileInfo[] files = new DirectoryInfo(Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - Presentations\" + Wn.Presentation.Name + "_" + Wn.Presentation.Slides.Count).GetFiles();
int count = 0;
foreach (FileInfo file in files) {
if (file.Name != "Position") {
int i = -1;
try {
i = int.Parse(System.IO.Path.GetFileNameWithoutExtension(file.Name));
memoryStreams[i] = new MemoryStream(File.ReadAllBytes(file.FullName));
memoryStreams[i].Position = 0;
count++;
} catch (Exception ex) {
LogHelper.WriteLogToFile(string.Format("Failed to load strokes on Slide {0}\n{1}", i, ex.ToString()), LogHelper.LogType.Error);
}
}
}
LogHelper.WriteLogToFile(string.Format("Loaded {0} saved strokes", count.ToString()));
}
}
StackPanelPPTControls.Visibility = Visibility.Visible;
if (Settings.PowerPointSettings.IsShowBottomPPTNavigationPanel) {
AnimationsHelper.ShowWithSlideFromBottomAndFade(BottomViewboxPPTSidesControl);
} else {
BottomViewboxPPTSidesControl.Visibility = Visibility.Collapsed;
}
if (Settings.PowerPointSettings.IsShowSidePPTNavigationPanel) {
AnimationsHelper.ShowWithScaleFromLeft(LeftSidePanelForPPTNavigation);
AnimationsHelper.ShowWithScaleFromRight(RightSidePanelForPPTNavigation);
} else {
LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
}
BtnPPTSlideShow.Visibility = Visibility.Collapsed;
BtnPPTSlideShowEnd.Visibility = Visibility.Visible;
ViewBoxStackPanelMain.Margin = new Thickness(10, 10, 10, 10);
if (Settings.Appearance.IsColorfulViewboxFloatingBar) {
ViewboxFloatingBar.Opacity = 0.8;
} else {
ViewboxFloatingBar.Opacity = 0.5;
}
if (Settings.PowerPointSettings.IsShowCanvasAtNewSlideShow && Main_Grid.Background == Brushes.Transparent) {
if (currentMode != 0) {
currentMode = 0;
GridBackgroundCover.Visibility = Visibility.Collapsed;
AnimationsHelper.HideWithSlideAndFade(BlackboardLeftSide);
AnimationsHelper.HideWithSlideAndFade(BlackboardCenterSide);
AnimationsHelper.HideWithSlideAndFade(BlackboardRightSide);
//SaveStrokes();
ClearStrokes(true);
if (BtnSwitchTheme.Content.ToString() == "浅色") {
BtnSwitch.Content = "黑板";
} else {
BtnSwitch.Content = "白板";
}
StackPanelPPTButtons.Visibility = Visibility.Visible;
}
BtnHideInkCanvas_Click(BtnHideInkCanvas, null);
}
ClearStrokes(true);
BorderFloatingBarMainControls.Visibility = Visibility.Visible;
if (Settings.PowerPointSettings.IsShowCanvasAtNewSlideShow) {
BorderPenColorRed_MouseUp(BorderPenColorRed, null);
}
isEnteredSlideShowEndEvent = false;
PptNavigationTextBlock.Text = $"{Wn.View.CurrentShowPosition}/{Wn.Presentation.Slides.Count}";
LogHelper.NewLog("PowerPoint Slide Show Loading process complete");
new Thread(new ThreadStart(() => {
Thread.Sleep(100);
Application.Current.Dispatcher.Invoke(() => {
ViewboxFloatingBarMarginAnimation(60);
});
})).Start();
});
}
bool isEnteredSlideShowEndEvent = false; //防止重复调用本函数导致墨迹保存失效
private async void PptApplication_SlideShowEnd(Presentation Pres) {
if (isFloatingBarFolded) UnFoldFloatingBar_MouseUp(null, null);
LogHelper.WriteLogToFile(string.Format("PowerPoint Slide Show End"), LogHelper.LogType.Event);
if (isEnteredSlideShowEndEvent) {
LogHelper.WriteLogToFile("Detected previous entrance, returning");
return;
}
isEnteredSlideShowEndEvent = true;
if (Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint) {
string folderPath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - Presentations\" + Pres.Name + "_" + Pres.Slides.Count;
if (!Directory.Exists(folderPath)) {
Directory.CreateDirectory(folderPath);
}
try {
File.WriteAllText(folderPath + "/Position", previousSlideID.ToString());
} catch { }
for (int i = 1; i <= Pres.Slides.Count; i++) {
if (memoryStreams[i] != null) {
try {
if (memoryStreams[i].Length > 8) {
byte[] srcBuf = new Byte[memoryStreams[i].Length];
int byteLength = memoryStreams[i].Read(srcBuf, 0, srcBuf.Length);
File.WriteAllBytes(folderPath + @"\" + i.ToString("0000") + ".icstk", srcBuf);
LogHelper.WriteLogToFile(string.Format("Saved strokes for Slide {0}, size={1}, byteLength={2}", i.ToString(), memoryStreams[i].Length, byteLength));
} else {
File.Delete(folderPath + @"\" + i.ToString("0000") + ".icstk");
}
} catch (Exception ex) {
LogHelper.WriteLogToFile(string.Format("Failed to save strokes for Slide {0}\n{1}", i, ex.ToString()), LogHelper.LogType.Error);
File.Delete(folderPath + @"\" + i.ToString("0000") + ".icstk");
}
}
}
}
Application.Current.Dispatcher.Invoke(() => {
isPresentationHaveBlackSpace = false;
if (BtnSwitchTheme.Content.ToString() == "深色") {
//Light
BtnExit.Foreground = Brushes.Black;
//SymbolIconBtnColorBlackContent.Foreground = Brushes.White;
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light;
} else {
//Dark
}
BtnPPTSlideShow.Visibility = Visibility.Visible;
BtnPPTSlideShowEnd.Visibility = Visibility.Collapsed;
StackPanelPPTControls.Visibility = Visibility.Collapsed;
BottomViewboxPPTSidesControl.Visibility = Visibility.Collapsed;
LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
ViewBoxStackPanelMain.Margin = new Thickness(10, 10, 10, 55);
if (currentMode != 0) {
currentMode = 0;
GridBackgroundCover.Visibility = Visibility.Collapsed;
AnimationsHelper.HideWithSlideAndFade(BlackboardLeftSide);
AnimationsHelper.HideWithSlideAndFade(BlackboardCenterSide);
AnimationsHelper.HideWithSlideAndFade(BlackboardRightSide);
//SaveStrokes();
ClearStrokes(true);
//RestoreStrokes(true);
if (BtnSwitchTheme.Content.ToString() == "浅色") {
BtnSwitch.Content = "黑板";
} else {
BtnSwitch.Content = "白板";
}
StackPanelPPTButtons.Visibility = Visibility.Visible;
}
ClearStrokes(true);
if (Main_Grid.Background != Brushes.Transparent) {
BtnHideInkCanvas_Click(BtnHideInkCanvas, null);
}
if (Settings.Appearance.IsColorfulViewboxFloatingBar) {
ViewboxFloatingBar.Opacity = 0.95;
} else {
ViewboxFloatingBar.Opacity = 1;
}
});
await Task.Delay(150);
ViewboxFloatingBarMarginAnimation(100);
}
int previousSlideID = 0;
MemoryStream[] memoryStreams = new MemoryStream[50];
private void PptApplication_SlideShowNextSlide(SlideShowWindow Wn) {
LogHelper.WriteLogToFile(string.Format("PowerPoint Next Slide (Slide {0})", Wn.View.CurrentShowPosition), LogHelper.LogType.Event);
if (Wn.View.CurrentShowPosition != previousSlideID) {
Application.Current.Dispatcher.Invoke(() => {
MemoryStream ms = new MemoryStream();
inkCanvas.Strokes.Save(ms);
ms.Position = 0;
memoryStreams[previousSlideID] = ms;
if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber && Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint && !_isPptClickingBtnTurned)
SaveScreenShot(true, Wn.Presentation.Name + "/" + Wn.View.CurrentShowPosition);
_isPptClickingBtnTurned = false;
ClearStrokes(true);
timeMachine.ClearStrokeHistory();
try {
if (memoryStreams[Wn.View.CurrentShowPosition] != null && memoryStreams[Wn.View.CurrentShowPosition].Length > 0) {
inkCanvas.Strokes.Add(new StrokeCollection(memoryStreams[Wn.View.CurrentShowPosition]));
}
} catch { }
PptNavigationTextBlock.Text = $"{Wn.View.CurrentShowPosition}/{Wn.Presentation.Slides.Count}";
});
previousSlideID = Wn.View.CurrentShowPosition;
}
}
private bool _isPptClickingBtnTurned = false;
private void BtnPPTSlidesUp_Click(object sender, RoutedEventArgs e) {
if (currentMode == 1) {
GridBackgroundCover.Visibility = Visibility.Collapsed;
AnimationsHelper.HideWithSlideAndFade(BlackboardLeftSide);
AnimationsHelper.HideWithSlideAndFade(BlackboardCenterSide);
AnimationsHelper.HideWithSlideAndFade(BlackboardRightSide);
currentMode = 0;
}
_isPptClickingBtnTurned = true;
if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
SaveScreenShot(true, pptApplication.SlideShowWindows[1].Presentation.Name + "/" + pptApplication.SlideShowWindows[1].View.CurrentShowPosition);
try {
new Thread(new ThreadStart(() => {
try {
pptApplication.SlideShowWindows[1].Activate();
} catch { }
try {
pptApplication.SlideShowWindows[1].View.Previous();
} catch { } // Without this catch{}, app will crash when click the pre-page button in the fir page in some special env.
})).Start();
} catch {
StackPanelPPTControls.Visibility = Visibility.Collapsed;
BottomViewboxPPTSidesControl.Visibility = Visibility.Collapsed;
LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
}
}
private void BtnPPTSlidesDown_Click(object sender, RoutedEventArgs e) {
if (currentMode == 1) {
GridBackgroundCover.Visibility = Visibility.Collapsed;
AnimationsHelper.HideWithSlideAndFade(BlackboardLeftSide);
AnimationsHelper.HideWithSlideAndFade(BlackboardCenterSide);
AnimationsHelper.HideWithSlideAndFade(BlackboardRightSide);
currentMode = 0;
}
_isPptClickingBtnTurned = true;
if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
SaveScreenShot(true, pptApplication.SlideShowWindows[1].Presentation.Name + "/" + pptApplication.SlideShowWindows[1].View.CurrentShowPosition);
try {
new Thread(new ThreadStart(() => {
try {
pptApplication.SlideShowWindows[1].Activate();
} catch { }
try {
pptApplication.SlideShowWindows[1].View.Next();
} catch { }
})).Start();
} catch {
StackPanelPPTControls.Visibility = Visibility.Collapsed;
BottomViewboxPPTSidesControl.Visibility = Visibility.Collapsed;
LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
}
}
private async void PPTNavigationBtn_Click(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
Main_Grid.Background = new SolidColorBrush(StringToColor("#01FFFFFF"));
CursorIcon_Click(null, null);
try {
pptApplication.SlideShowWindows[1].SlideNavigation.Visible = true;
} catch { }
// 控制居中
if (!isFloatingBarFolded) {
await Task.Delay(100);
ViewboxFloatingBarMarginAnimation(60);
}
}
private void BtnPPTSlideShow_Click(object sender, RoutedEventArgs e) {
new Thread(new ThreadStart(() => {
try {
presentation.SlideShowSettings.Run();
} catch { }
})).Start();
}
private async void BtnPPTSlideShowEnd_Click(object sender, RoutedEventArgs e) {
Application.Current.Dispatcher.Invoke(() => {
try {
MemoryStream ms = new MemoryStream();
inkCanvas.Strokes.Save(ms);
ms.Position = 0;
memoryStreams[pptApplication.SlideShowWindows[1].View.CurrentShowPosition] = ms;
timeMachine.ClearStrokeHistory();
} catch { }
});
new Thread(new ThreadStart(() => {
try {
pptApplication.SlideShowWindows[1].View.Exit();
} catch { }
})).Start();
HideSubPanels("cursor");
await Task.Delay(150);
ViewboxFloatingBarMarginAnimation(100);
}
private void GridPPTControlPrevious_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
BtnPPTSlidesUp_Click(BtnPPTSlidesUp, null);
}
private void GridPPTControlNext_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
BtnPPTSlidesDown_Click(BtnPPTSlidesDown, null);
}
private void ImagePPTControlEnd_MouseUp(object sender, MouseButtonEventArgs e) {
BtnPPTSlideShowEnd_Click(BtnPPTSlideShowEnd, null);
}
}
}

View File

@ -0,0 +1,92 @@
using Ink_Canvas.Helpers;
using Microsoft.Win32;
using System;
using System.IO;
using System.Windows;
using System.Windows.Ink;
using System.Windows.Input;
using File = System.IO.File;
namespace Ink_Canvas {
public partial class MainWindow : Window {
private void SymbolIconSaveStrokes_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender || inkCanvas.Visibility != Visibility.Visible) return;
AnimationsHelper.HideWithSlideAndFade(BorderTools);
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
GridNotifications.Visibility = Visibility.Collapsed;
SaveInkCanvasStrokes(true, true);
}
private void SaveInkCanvasStrokes(bool newNotice = true, bool saveByUser = false) {
try {
string savePath = Settings.Automation.AutoSavedStrokesLocation
+ (saveByUser ? @"\User Saved - " : @"\Auto Saved - ")
+ (currentMode == 0 ? "Annotation Strokes" : "BlackBoard Strokes");
if (!Directory.Exists(savePath)) {
Directory.CreateDirectory(savePath);
}
string savePathWithName;
if (currentMode != 0) { // 黑板模式下
savePathWithName = savePath + @"\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff") + " Page-" + CurrentWhiteboardIndex + " StrokesCount-" + inkCanvas.Strokes.Count + ".icstk";
} else {
//savePathWithName = savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".icstk";
savePathWithName = savePath + @"\" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-fff") + ".icstk";
}
FileStream fs = new FileStream(savePathWithName, FileMode.Create);
inkCanvas.Strokes.Save(fs);
if (newNotice) {
ShowNotification("墨迹成功保存至 " + savePathWithName);
}
} catch (Exception Ex) {
ShowNotification("墨迹保存失败");
LogHelper.WriteLogToFile("墨迹保存失败 | " + Ex.ToString(), LogHelper.LogType.Error);
}
}
private void SymbolIconOpenStrokes_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
AnimationsHelper.HideWithSlideAndFade(BorderTools);
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.InitialDirectory = Settings.Automation.AutoSavedStrokesLocation;
openFileDialog.Title = "打开墨迹文件";
openFileDialog.Filter = "Ink Canvas Strokes File (*.icstk)|*.icstk";
if (openFileDialog.ShowDialog() == true) {
LogHelper.WriteLogToFile(string.Format("Strokes Insert: Name: {0}", openFileDialog.FileName), LogHelper.LogType.Event);
try {
var fileStreamHasNoStroke = false;
using (var fs = new FileStream(openFileDialog.FileName, FileMode.Open, FileAccess.Read)) {
var strokes = new StrokeCollection(fs);
fileStreamHasNoStroke = strokes.Count == 0;
if (!fileStreamHasNoStroke) {
ClearStrokes(true);
timeMachine.ClearStrokeHistory();
inkCanvas.Strokes.Add(strokes);
LogHelper.NewLog(string.Format("Strokes Insert: Strokes Count: {0}", inkCanvas.Strokes.Count.ToString()));
}
}
if (fileStreamHasNoStroke) {
using (var ms = new MemoryStream(File.ReadAllBytes(openFileDialog.FileName))) {
ms.Seek(0, SeekOrigin.Begin);
var strokes = new StrokeCollection(ms);
ClearStrokes(true);
timeMachine.ClearStrokeHistory();
inkCanvas.Strokes.Add(strokes);
LogHelper.NewLog(string.Format("Strokes Insert (2): Strokes Count: {0}", strokes.Count.ToString()));
}
}
if (inkCanvas.Visibility != Visibility.Visible) {
SymbolIconCursor_Click(sender, null);
}
} catch {
ShowNotification("墨迹打开失败");
}
}
}
}
}

View File

@ -0,0 +1,52 @@
using System;
using System.Drawing.Imaging;
using System.IO;
using System.Windows;
namespace Ink_Canvas {
public partial class MainWindow : Window {
private void SaveScreenShot(bool isHideNotification, string fileName = null) {
System.Drawing.Rectangle rc = System.Windows.Forms.SystemInformation.VirtualScreen;
var bitmap = new System.Drawing.Bitmap(rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (System.Drawing.Graphics memoryGrahics = System.Drawing.Graphics.FromImage(bitmap)) {
memoryGrahics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, System.Drawing.CopyPixelOperation.SourceCopy);
}
if (Settings.Automation.IsSaveScreenshotsInDateFolders) {
if (string.IsNullOrWhiteSpace(fileName)) fileName = DateTime.Now.ToString("HH-mm-ss");
string savePath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - Screenshots\{DateTime.Now.Date:yyyyMMdd}\{fileName}.png";
if (!Directory.Exists(Path.GetDirectoryName(savePath))) {
Directory.CreateDirectory(Path.GetDirectoryName(savePath));
}
bitmap.Save(savePath, ImageFormat.Png);
if (!isHideNotification) {
ShowNotification("截图成功保存至 " + savePath);
}
} else {
string savePath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - Screenshots";
if (!Directory.Exists(savePath)) {
Directory.CreateDirectory(savePath);
}
bitmap.Save(savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png", ImageFormat.Png);
if (!isHideNotification) {
ShowNotification("截图成功保存至 " + savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png");
}
}
if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) SaveInkCanvasStrokes(false, false);
}
private void SaveScreenShotToDesktop() {
System.Drawing.Rectangle rc = System.Windows.Forms.SystemInformation.VirtualScreen;
var bitmap = new System.Drawing.Bitmap(rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (System.Drawing.Graphics memoryGrahics = System.Drawing.Graphics.FromImage(bitmap)) {
memoryGrahics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, System.Drawing.CopyPixelOperation.SourceCopy);
}
string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
bitmap.Save(savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png", ImageFormat.Png);
ShowNotification("截图成功保存至【桌面" + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png】");
if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) SaveInkCanvasStrokes(false, false);
}
}
}

View File

@ -0,0 +1,357 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using Point = System.Windows.Point;
namespace Ink_Canvas {
public partial class MainWindow : Window {
#region Floating Control
object lastBorderMouseDownObject;
private void Border_MouseDown(object sender, MouseButtonEventArgs e) {
lastBorderMouseDownObject = sender;
}
bool isStrokeSelectionCloneOn = false;
private void BorderStrokeSelectionClone_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
if (isStrokeSelectionCloneOn) {
BorderStrokeSelectionClone.Background = Brushes.Transparent;
isStrokeSelectionCloneOn = false;
} else {
BorderStrokeSelectionClone.Background = new SolidColorBrush(StringToColor("#FF1ED760"));
isStrokeSelectionCloneOn = true;
}
}
private void BorderStrokeSelectionCloneToNewBoard_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
var strokes = inkCanvas.GetSelectedStrokes();
inkCanvas.Select(new StrokeCollection());
strokes = strokes.Clone();
BtnWhiteBoardAdd_Click(null, null);
inkCanvas.Strokes.Add(strokes);
}
private void BorderStrokeSelectionDelete_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
SymbolIconDelete_MouseUp(sender, e);
}
private void GridPenWidthDecrease_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
ChangeStrokeThickness(0.8);
}
private void GridPenWidthIncrease_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
ChangeStrokeThickness(1.25);
}
private void ChangeStrokeThickness(double multipler) {
foreach (Stroke stroke in inkCanvas.GetSelectedStrokes()) {
var newWidth = stroke.DrawingAttributes.Width * multipler;
var newHeight = stroke.DrawingAttributes.Height * multipler;
if (newWidth >= DrawingAttributes.MinWidth && newWidth <= DrawingAttributes.MaxWidth
&& newHeight >= DrawingAttributes.MinHeight && newHeight <= DrawingAttributes.MaxHeight) {
stroke.DrawingAttributes.Width = newWidth;
stroke.DrawingAttributes.Height = newHeight;
}
}
}
private void GridPenWidthRestore_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
foreach (Stroke stroke in inkCanvas.GetSelectedStrokes()) {
stroke.DrawingAttributes.Width = inkCanvas.DefaultDrawingAttributes.Width;
stroke.DrawingAttributes.Height = inkCanvas.DefaultDrawingAttributes.Height;
}
}
private void ImageFlipHorizontal_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
Matrix m = new Matrix();
// Find center of element and then transform to get current location of center
FrameworkElement fe = e.Source as FrameworkElement;
Point center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
// Update matrix to reflect translation/rotation
m.ScaleAt(-1, 1, center.X, center.Y); // 缩放
StrokeCollection targetStrokes = inkCanvas.GetSelectedStrokes();
StrokeCollection resultStrokes = targetStrokes.Clone();
foreach (Stroke stroke in resultStrokes) {
stroke.Transform(m, false);
}
_currentCommitType = CommitReason.Rotate;
inkCanvas.Strokes.Replace(targetStrokes, resultStrokes);
_currentCommitType = CommitReason.UserInput;
isProgramChangeStrokeSelection = true;
inkCanvas.Select(resultStrokes);
isProgramChangeStrokeSelection = false;
//updateBorderStrokeSelectionControlLocation();
}
private void ImageFlipVertical_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
Matrix m = new Matrix();
// Find center of element and then transform to get current location of center
FrameworkElement fe = e.Source as FrameworkElement;
Point center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
// Update matrix to reflect translation/rotation
m.ScaleAt(1, -1, center.X, center.Y); // 缩放
StrokeCollection targetStrokes = inkCanvas.GetSelectedStrokes();
StrokeCollection resultStrokes = targetStrokes.Clone();
foreach (Stroke stroke in resultStrokes) {
stroke.Transform(m, false);
}
_currentCommitType = CommitReason.Rotate;
inkCanvas.Strokes.Replace(targetStrokes, resultStrokes);
_currentCommitType = CommitReason.UserInput;
isProgramChangeStrokeSelection = true;
inkCanvas.Select(resultStrokes);
isProgramChangeStrokeSelection = false;
}
private void ImageRotate45_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
Matrix m = new Matrix();
// Find center of element and then transform to get current location of center
FrameworkElement fe = e.Source as FrameworkElement;
Point center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
// Update matrix to reflect translation/rotation
m.RotateAt(45, center.X, center.Y); // 旋转
StrokeCollection targetStrokes = inkCanvas.GetSelectedStrokes();
StrokeCollection resultStrokes = targetStrokes.Clone();
foreach (Stroke stroke in resultStrokes) {
stroke.Transform(m, false);
}
_currentCommitType = CommitReason.Rotate;
inkCanvas.Strokes.Replace(targetStrokes, resultStrokes);
_currentCommitType = CommitReason.UserInput;
isProgramChangeStrokeSelection = true;
inkCanvas.Select(resultStrokes);
isProgramChangeStrokeSelection = false;
}
private void ImageRotate90_MouseUp(object sender, MouseButtonEventArgs e) {
if (lastBorderMouseDownObject != sender) return;
Matrix m = new Matrix();
// Find center of element and then transform to get current location of center
FrameworkElement fe = e.Source as FrameworkElement;
Point center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
// Update matrix to reflect translation/rotation
m.RotateAt(90, center.X, center.Y); // 旋转
StrokeCollection targetStrokes = inkCanvas.GetSelectedStrokes();
StrokeCollection resultStrokes = targetStrokes.Clone();
foreach (Stroke stroke in resultStrokes) {
stroke.Transform(m, false);
}
_currentCommitType = CommitReason.Rotate;
inkCanvas.Strokes.Replace(targetStrokes, resultStrokes);
_currentCommitType = CommitReason.UserInput;
isProgramChangeStrokeSelection = true;
inkCanvas.Select(resultStrokes);
isProgramChangeStrokeSelection = false;
}
#endregion
bool isGridInkCanvasSelectionCoverMouseDown = false;
StrokeCollection StrokesSelectionClone = new StrokeCollection();
private void GridInkCanvasSelectionCover_MouseDown(object sender, MouseButtonEventArgs e) {
isGridInkCanvasSelectionCoverMouseDown = true;
}
private void GridInkCanvasSelectionCover_MouseUp(object sender, MouseButtonEventArgs e) {
if (isGridInkCanvasSelectionCoverMouseDown) {
isGridInkCanvasSelectionCoverMouseDown = false;
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
}
}
private void BtnSelect_Click(object sender, RoutedEventArgs e) {
forceEraser = true;
drawingShapeMode = 0;
inkCanvas.IsManipulationEnabled = false;
if (inkCanvas.EditingMode == InkCanvasEditingMode.Select) {
if (inkCanvas.GetSelectedStrokes().Count == inkCanvas.Strokes.Count) {
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
inkCanvas.EditingMode = InkCanvasEditingMode.Select;
} else {
StrokeCollection selectedStrokes = new StrokeCollection();
foreach (Stroke stroke in inkCanvas.Strokes) {
if (stroke.GetBounds().Width > 0 && stroke.GetBounds().Height > 0) {
selectedStrokes.Add(stroke);
}
}
inkCanvas.Select(selectedStrokes);
}
} else {
inkCanvas.EditingMode = InkCanvasEditingMode.Select;
}
}
double BorderStrokeSelectionControlWidth = 490.0;
double BorderStrokeSelectionControlHeight = 80.0;
bool isProgramChangeStrokeSelection = false;
private void inkCanvas_SelectionChanged(object sender, EventArgs e) {
if (isProgramChangeStrokeSelection) return;
if (inkCanvas.GetSelectedStrokes().Count == 0) {
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
} else {
GridInkCanvasSelectionCover.Visibility = Visibility.Visible;
BorderStrokeSelectionClone.Background = Brushes.Transparent;
isStrokeSelectionCloneOn = false;
updateBorderStrokeSelectionControlLocation();
}
}
private void updateBorderStrokeSelectionControlLocation() {
double borderLeft = (inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Right - BorderStrokeSelectionControlWidth) / 2;
double borderTop = inkCanvas.GetSelectionBounds().Bottom + 15;
if (borderLeft < 0) borderLeft = 0;
if (borderTop < 0) borderTop = 0;
if (Width - borderLeft < BorderStrokeSelectionControlWidth || double.IsNaN(borderLeft)) borderLeft = Width - BorderStrokeSelectionControlWidth;
if (Height - borderTop < BorderStrokeSelectionControlHeight || double.IsNaN(borderTop)) borderTop = Height - BorderStrokeSelectionControlHeight;
if (borderTop > 60) borderTop -= 60;
BorderStrokeSelectionControl.Margin = new Thickness(borderLeft, borderTop, 0, 0);
}
private void GridInkCanvasSelectionCover_ManipulationStarting(object sender, ManipulationStartingEventArgs e) {
e.Mode = ManipulationModes.All;
}
private void GridInkCanvasSelectionCover_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) {
}
private void GridInkCanvasSelectionCover_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) {
try {
if (dec.Count >= 1) {
ManipulationDelta md = e.DeltaManipulation;
Vector trans = md.Translation; // 获得位移矢量
double rotate = md.Rotation; // 获得旋转角度
Vector scale = md.Scale; // 获得缩放倍数
Matrix m = new Matrix();
// Find center of element and then transform to get current location of center
FrameworkElement fe = e.Source as FrameworkElement;
Point center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
center = new Point(inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Width / 2,
inkCanvas.GetSelectionBounds().Top + inkCanvas.GetSelectionBounds().Height / 2);
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
// Update matrix to reflect translation/rotation
m.Translate(trans.X, trans.Y); // 移动
m.ScaleAt(scale.X, scale.Y, center.X, center.Y); // 缩放
StrokeCollection strokes = inkCanvas.GetSelectedStrokes();
if (StrokesSelectionClone.Count != 0) {
strokes = StrokesSelectionClone;
} else if (Settings.Gesture.IsEnableTwoFingerRotationOnSelection) {
m.RotateAt(rotate, center.X, center.Y); // 旋转
}
foreach (Stroke stroke in strokes) {
stroke.Transform(m, false);
try {
stroke.DrawingAttributes.Width *= md.Scale.X;
stroke.DrawingAttributes.Height *= md.Scale.Y;
} catch { }
}
updateBorderStrokeSelectionControlLocation();
}
} catch { }
}
private void GridInkCanvasSelectionCover_TouchDown(object sender, TouchEventArgs e) {
}
private void GridInkCanvasSelectionCover_TouchUp(object sender, TouchEventArgs e) {
}
Point lastTouchPointOnGridInkCanvasCover = new Point(0, 0);
private void GridInkCanvasSelectionCover_PreviewTouchDown(object sender, TouchEventArgs e) {
dec.Add(e.TouchDevice.Id);
//设备1个的时候记录中心点
if (dec.Count == 1) {
TouchPoint touchPoint = e.GetTouchPoint(null);
centerPoint = touchPoint.Position;
lastTouchPointOnGridInkCanvasCover = touchPoint.Position;
if (isStrokeSelectionCloneOn) {
StrokeCollection strokes = inkCanvas.GetSelectedStrokes();
isProgramChangeStrokeSelection = true;
inkCanvas.Select(new StrokeCollection());
StrokesSelectionClone = strokes.Clone();
inkCanvas.Select(strokes);
isProgramChangeStrokeSelection = false;
inkCanvas.Strokes.Add(StrokesSelectionClone);
}
}
}
private void GridInkCanvasSelectionCover_PreviewTouchUp(object sender, TouchEventArgs e) {
dec.Remove(e.TouchDevice.Id);
if (dec.Count >= 1) return;
isProgramChangeStrokeSelection = false;
if (lastTouchPointOnGridInkCanvasCover == e.GetTouchPoint(null).Position) {
if (lastTouchPointOnGridInkCanvasCover.X < inkCanvas.GetSelectionBounds().Left ||
lastTouchPointOnGridInkCanvasCover.Y < inkCanvas.GetSelectionBounds().Top ||
lastTouchPointOnGridInkCanvasCover.X > inkCanvas.GetSelectionBounds().Right ||
lastTouchPointOnGridInkCanvasCover.Y > inkCanvas.GetSelectionBounds().Bottom) {
inkCanvas.Select(new StrokeCollection());
StrokesSelectionClone = new StrokeCollection();
}
} else if (inkCanvas.GetSelectedStrokes().Count == 0) {
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
StrokesSelectionClone = new StrokeCollection();
} else {
GridInkCanvasSelectionCover.Visibility = Visibility.Visible;
StrokesSelectionClone = new StrokeCollection();
}
}
}
}

View File

@ -0,0 +1,711 @@
using Ink_Canvas.Helpers;
using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using File = System.IO.File;
namespace Ink_Canvas {
public partial class MainWindow : Window {
#region Behavior
private void ToggleSwitchIsAutoUpdate_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Startup.IsAutoUpdate = ToggleSwitchIsAutoUpdate.IsOn;
ToggleSwitchIsAutoUpdateWithSilence.Visibility = ToggleSwitchIsAutoUpdate.IsOn ? Visibility.Visible : Visibility.Collapsed;
SaveSettingsToFile();
}
private void ToggleSwitchIsAutoUpdateWithSilence_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Startup.IsAutoUpdateWithSilence = ToggleSwitchIsAutoUpdateWithSilence.IsOn;
AutoUpdateTimePeriodBlock.Visibility = Settings.Startup.IsAutoUpdateWithSilence ? Visibility.Visible : Visibility.Collapsed;
SaveSettingsToFile();
}
private void ToggleSwitchIsAutoUpdateWithProxy_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Startup.IsAutoUpdateWithProxy = ToggleSwitchIsAutoUpdateWithProxy.IsOn;
AutoUpdateWithProxy_Title.Visibility = Settings.Startup.IsAutoUpdateWithProxy ? Visibility.Visible : Visibility.Collapsed;
SaveSettingsToFile();
}
private void AutoUpdateProxyTextBox_TextChanged(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Startup.AutoUpdateProxy = AutoUpdateProxyTextBox.Text;
SaveSettingsToFile();
}
private void BtnResetAutoUpdateProxyToGHProxy_Click(object sender, RoutedEventArgs e) {
AutoUpdateProxyTextBox.Text = "https://mirror.ghproxy.com/";
}
private async void BtnCheckAutoUpdateProxyReturnedData_Click(object sender, RoutedEventArgs e) {
string ProxyReturnedData = await AutoUpdateHelper.GetRemoteVersion(Settings.Startup.AutoUpdateProxy + "https://raw.githubusercontent.com/ChangSakura/Ink-Canvas/master/AutomaticUpdateVersionControl.txt");
ShowNotification(ProxyReturnedData);
}
private void AutoUpdateWithSilenceStartTimeComboBox_SelectionChanged(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Startup.AutoUpdateWithSilenceStartTime = (string)AutoUpdateWithSilenceStartTimeComboBox.SelectedItem;
SaveSettingsToFile();
}
private void AutoUpdateWithSilenceEndTimeComboBox_SelectionChanged(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Startup.AutoUpdateWithSilenceEndTime = (string)AutoUpdateWithSilenceEndTimeComboBox.SelectedItem;
SaveSettingsToFile();
}
private void ToggleSwitchRunAtStartup_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
if (ToggleSwitchRunAtStartup.IsOn) {
StartAutomaticallyDel("InkCanvas");
StartAutomaticallyCreate("Ink Canvas Annotation");
} else {
StartAutomaticallyDel("InkCanvas");
StartAutomaticallyDel("Ink Canvas Annotation");
}
}
private void ToggleSwitchFoldAtStartup_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Startup.IsFoldAtStartup = ToggleSwitchFoldAtStartup.IsOn;
SaveSettingsToFile();
}
private void ToggleSwitchSupportPowerPoint_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.PowerPointSettings.PowerPointSupport = ToggleSwitchSupportPowerPoint.IsOn;
SaveSettingsToFile();
if (Settings.PowerPointSettings.PowerPointSupport) {
timerCheckPPT.Start();
} else {
timerCheckPPT.Stop();
}
}
private void ToggleSwitchShowCanvasAtNewSlideShow_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.PowerPointSettings.IsShowCanvasAtNewSlideShow = ToggleSwitchShowCanvasAtNewSlideShow.IsOn;
SaveSettingsToFile();
}
#endregion
#region Startup
private void ToggleSwitchEnableNibMode_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
if (sender == ToggleSwitchEnableNibMode) {
ToggleSwitchBoardEnableNibMode.IsOn = ToggleSwitchEnableNibMode.IsOn;
} else {
ToggleSwitchEnableNibMode.IsOn = ToggleSwitchBoardEnableNibMode.IsOn;
}
Settings.Startup.IsEnableNibMode = ToggleSwitchEnableNibMode.IsOn;
if (Settings.Startup.IsEnableNibMode) {
BoundsWidth = Settings.Advanced.NibModeBoundsWidth;
} else {
BoundsWidth = Settings.Advanced.FingerModeBoundsWidth;
}
SaveSettingsToFile();
}
#endregion
#region Appearance
private void ToggleSwitchEnableDisPlayNibModeToggle_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Appearance.IsEnableDisPlayNibModeToggler = ToggleSwitchEnableDisPlayNibModeToggle.IsOn;
SaveSettingsToFile();
LoadSettings();
}
private void ToggleSwitchIsColorfulViewboxFloatingBar_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Appearance.IsColorfulViewboxFloatingBar = ToggleSwitchColorfulViewboxFloatingBar.IsOn;
SaveSettingsToFile();
LoadSettings();
}
private void ToggleSwitchEnableViewboxFloatingBarScaleTransform_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Appearance.EnableViewboxFloatingBarScaleTransform = ToggleSwitchEnableViewboxFloatingBarScaleTransform.IsOn;
SaveSettingsToFile();
LoadSettings();
}
private void ToggleSwitchEnableViewboxBlackBoardScaleTransform_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Appearance.EnableViewboxBlackBoardScaleTransform = ToggleSwitchEnableViewboxBlackBoardScaleTransform.IsOn;
SaveSettingsToFile();
LoadSettings();
}
private void ToggleSwitchShowButtonPPTNavigation_OnToggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.PowerPointSettings.IsShowPPTNavigation = ToggleSwitchShowButtonPPTNavigation.IsOn;
PptNavigationBtn.Visibility = Settings.PowerPointSettings.IsShowPPTNavigation ? Visibility.Visible : Visibility.Collapsed;
SaveSettingsToFile();
}
private void ToggleSwitchShowBottomPPTNavigationPanel_OnToggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.PowerPointSettings.IsShowBottomPPTNavigationPanel = ToggleSwitchShowBottomPPTNavigationPanel.IsOn;
if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) {
BottomViewboxPPTSidesControl.Visibility = Settings.PowerPointSettings.IsShowBottomPPTNavigationPanel ? Visibility.Visible : Visibility.Collapsed;
}
SaveSettingsToFile();
}
private void ToggleSwitchShowSidePPTNavigationPanel_OnToggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.PowerPointSettings.IsShowSidePPTNavigationPanel = ToggleSwitchShowSidePPTNavigationPanel.IsOn;
if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) {
LeftSidePanelForPPTNavigation.Visibility = Settings.PowerPointSettings.IsShowSidePPTNavigationPanel ? Visibility.Visible : Visibility.Collapsed;
RightSidePanelForPPTNavigation.Visibility = Settings.PowerPointSettings.IsShowSidePPTNavigationPanel ? Visibility.Visible : Visibility.Collapsed;
}
SaveSettingsToFile();
}
private void ToggleSwitchShowCursor_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Canvas.IsShowCursor = ToggleSwitchShowCursor.IsOn;
inkCanvas_EditingModeChanged(inkCanvas, null);
SaveSettingsToFile();
}
#endregion
#region Canvas
private void ComboBoxPenStyle_SelectionChanged(object sender, SelectionChangedEventArgs e) {
if (!isLoaded) return;
if (sender == ComboBoxPenStyle) {
Settings.Canvas.InkStyle = ComboBoxPenStyle.SelectedIndex;
BoardComboBoxPenStyle.SelectedIndex = ComboBoxPenStyle.SelectedIndex;
} else {
Settings.Canvas.InkStyle = BoardComboBoxPenStyle.SelectedIndex;
ComboBoxPenStyle.SelectedIndex = BoardComboBoxPenStyle.SelectedIndex;
}
SaveSettingsToFile();
}
private void ComboBoxEraserSize_SelectionChanged(object sender, SelectionChangedEventArgs e) {
if (!isLoaded) return;
Settings.Canvas.EraserSize = ComboBoxEraserSize.SelectedIndex;
SaveSettingsToFile();
}
private void InkWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) {
if (!isLoaded) return;
if (sender == BoardInkWidthSlider) InkWidthSlider.Value = ((Slider)sender).Value;
if (sender == InkWidthSlider) BoardInkWidthSlider.Value = ((Slider)sender).Value;
drawingAttributes.Height = ((Slider)sender).Value / 2;
drawingAttributes.Width = ((Slider)sender).Value / 2;
Settings.Canvas.InkWidth = ((Slider)sender).Value / 2;
SaveSettingsToFile();
}
private void ComboBoxHyperbolaAsymptoteOption_SelectionChanged(object sender, SelectionChangedEventArgs e) {
if (!isLoaded) return;
Settings.Canvas.HyperbolaAsymptoteOption = (OptionalOperation)ComboBoxHyperbolaAsymptoteOption.SelectedIndex;
SaveSettingsToFile();
}
#endregion
#region Automation
private void StartOrStoptimerCheckAutoFold() {
if (Settings.Automation.IsEnableAutoFold) {
timerCheckAutoFold.Start();
} else {
timerCheckAutoFold.Stop();
}
}
private void ToggleSwitchAutoFoldInEasiNote_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoFoldInEasiNote = ToggleSwitchAutoFoldInEasiNote.IsOn;
SaveSettingsToFile();
StartOrStoptimerCheckAutoFold();
}
private void ToggleSwitchAutoFoldInEasiNoteIgnoreDesktopAnno_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoFoldInEasiNoteIgnoreDesktopAnno = ToggleSwitchAutoFoldInEasiNoteIgnoreDesktopAnno.IsOn;
SaveSettingsToFile();
}
private void ToggleSwitchAutoFoldInEasiCamera_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoFoldInEasiCamera = ToggleSwitchAutoFoldInEasiCamera.IsOn;
SaveSettingsToFile();
StartOrStoptimerCheckAutoFold();
}
private void ToggleSwitchAutoFoldInEasiNote3C_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoFoldInEasiNote3C = ToggleSwitchAutoFoldInEasiNote3C.IsOn;
SaveSettingsToFile();
StartOrStoptimerCheckAutoFold();
}
private void ToggleSwitchAutoFoldInSeewoPincoTeacher_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoFoldInSeewoPincoTeacher = ToggleSwitchAutoFoldInSeewoPincoTeacher.IsOn;
SaveSettingsToFile();
StartOrStoptimerCheckAutoFold();
}
private void ToggleSwitchAutoFoldInHiteTouchPro_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoFoldInHiteTouchPro = ToggleSwitchAutoFoldInHiteTouchPro.IsOn;
SaveSettingsToFile();
StartOrStoptimerCheckAutoFold();
}
private void ToggleSwitchAutoFoldInHiteCamera_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoFoldInHiteCamera = ToggleSwitchAutoFoldInHiteCamera.IsOn;
SaveSettingsToFile();
StartOrStoptimerCheckAutoFold();
}
private void ToggleSwitchAutoFoldInWxBoardMain_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoFoldInWxBoardMain = ToggleSwitchAutoFoldInWxBoardMain.IsOn;
SaveSettingsToFile();
StartOrStoptimerCheckAutoFold();
}
private void ToggleSwitchAutoFoldInOldZyBoard_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoFoldInOldZyBoard = ToggleSwitchAutoFoldInOldZyBoard.IsOn;
SaveSettingsToFile();
StartOrStoptimerCheckAutoFold();
}
private void ToggleSwitchAutoFoldInMSWhiteboard_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoFoldInMSWhiteboard = ToggleSwitchAutoFoldInMSWhiteboard.IsOn;
SaveSettingsToFile();
StartOrStoptimerCheckAutoFold();
}
private void ToggleSwitchAutoFoldInPPTSlideShow_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoFoldInPPTSlideShow = ToggleSwitchAutoFoldInPPTSlideShow.IsOn;
SaveSettingsToFile();
StartOrStoptimerCheckAutoFold();
}
private void ToggleSwitchAutoKillPptService_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoKillPptService = ToggleSwitchAutoKillPptService.IsOn;
SaveSettingsToFile();
if (Settings.Automation.IsAutoKillEasiNote || Settings.Automation.IsAutoKillPptService) {
timerKillProcess.Start();
} else {
timerKillProcess.Stop();
}
}
private void ToggleSwitchAutoKillEasiNote_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoKillEasiNote = ToggleSwitchAutoKillEasiNote.IsOn;
SaveSettingsToFile();
if (Settings.Automation.IsAutoKillEasiNote || Settings.Automation.IsAutoKillPptService) {
timerKillProcess.Start();
} else {
timerKillProcess.Stop();
}
}
private void ToggleSwitchSaveScreenshotsInDateFolders_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsSaveScreenshotsInDateFolders = ToggleSwitchSaveScreenshotsInDateFolders.IsOn;
SaveSettingsToFile();
}
private void ToggleSwitchAutoSaveStrokesAtScreenshot_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoSaveStrokesAtScreenshot = ToggleSwitchAutoSaveStrokesAtScreenshot.IsOn;
ToggleSwitchAutoSaveStrokesAtClear.Header = ToggleSwitchAutoSaveStrokesAtScreenshot.IsOn ? "清屏时自动截图并保存墨迹" : "清屏时自动截图";
SaveSettingsToFile();
}
private void ToggleSwitchAutoSaveStrokesAtClear_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.IsAutoSaveStrokesAtClear = ToggleSwitchAutoSaveStrokesAtClear.IsOn;
SaveSettingsToFile();
}
private void ToggleSwitchHideStrokeWhenSelecting_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Canvas.HideStrokeWhenSelecting = ToggleSwitchHideStrokeWhenSelecting.IsOn;
SaveSettingsToFile();
}
private void ToggleSwitchAutoSaveStrokesInPowerPoint_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint = ToggleSwitchAutoSaveStrokesInPowerPoint.IsOn;
SaveSettingsToFile();
}
private void ToggleSwitchNotifyPreviousPage_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.PowerPointSettings.IsNotifyPreviousPage = ToggleSwitchNotifyPreviousPage.IsOn;
SaveSettingsToFile();
}
private void ToggleSwitchNotifyHiddenPage_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.PowerPointSettings.IsNotifyHiddenPage = ToggleSwitchNotifyHiddenPage.IsOn;
SaveSettingsToFile();
}
private void SideControlMinimumAutomationSlider_ValueChanged(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.MinimumAutomationStrokeNumber = (int)SideControlMinimumAutomationSlider.Value;
SaveSettingsToFile();
}
private void AutoSavedStrokesLocationTextBox_TextChanged(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.AutoSavedStrokesLocation = AutoSavedStrokesLocation.Text;
SaveSettingsToFile();
}
private void AutoSavedStrokesLocationButton_Click(object sender, RoutedEventArgs e) {
System.Windows.Forms.FolderBrowserDialog folderBrowser = new System.Windows.Forms.FolderBrowserDialog();
folderBrowser.ShowDialog();
if (folderBrowser.SelectedPath.Length > 0) AutoSavedStrokesLocation.Text = folderBrowser.SelectedPath;
}
private void SetAutoSavedStrokesLocationToDiskDButton_Click(object sender, RoutedEventArgs e) {
AutoSavedStrokesLocation.Text = @"D:\Ink Canvas";
}
private void SetAutoSavedStrokesLocationToDocumentFolderButton_Click(object sender, RoutedEventArgs e) {
AutoSavedStrokesLocation.Text = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Ink Canvas";
}
private void ToggleSwitchAutoDelSavedFiles_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.AutoDelSavedFiles = ToggleSwitchAutoDelSavedFiles.IsOn;
SaveSettingsToFile();
}
private void ComboBoxAutoDelSavedFilesDaysThreshold_SelectionChanged(object sender, SelectionChangedEventArgs e) {
if (!isLoaded) return;
Settings.Automation.AutoDelSavedFilesDaysThreshold = int.Parse(((ComboBoxItem)ComboBoxAutoDelSavedFilesDaysThreshold.SelectedItem).Content.ToString());
SaveSettingsToFile();
}
private void ToggleSwitchAutoSaveScreenShotInPowerPoint_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint = ToggleSwitchAutoSaveScreenShotInPowerPoint.IsOn;
SaveSettingsToFile();
}
#endregion
#region Gesture
private void ToggleSwitchEnableFingerGestureSlideShowControl_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.PowerPointSettings.IsEnableFingerGestureSlideShowControl = ToggleSwitchEnableFingerGestureSlideShowControl.IsOn;
SaveSettingsToFile();
}
private void ToggleSwitchAutoSwitchTwoFingerGesture_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Gesture.AutoSwitchTwoFingerGesture = ToggleSwitchAutoSwitchTwoFingerGesture.IsOn;
SaveSettingsToFile();
}
private void ToggleSwitchEnableTwoFingerZoom_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
if (sender == ToggleSwitchEnableTwoFingerZoom) {
BoardToggleSwitchEnableTwoFingerZoom.IsOn = ToggleSwitchEnableTwoFingerZoom.IsOn;
} else {
ToggleSwitchEnableTwoFingerZoom.IsOn = BoardToggleSwitchEnableTwoFingerZoom.IsOn;
}
Settings.Gesture.IsEnableTwoFingerZoom = ToggleSwitchEnableTwoFingerZoom.IsOn;
CheckEnableTwoFingerGestureBtnColorPrompt();
SaveSettingsToFile();
}
private void ToggleSwitchEnableTwoFingerTranslate_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
if (sender == ToggleSwitchEnableTwoFingerTranslate) {
BoardToggleSwitchEnableTwoFingerTranslate.IsOn = ToggleSwitchEnableTwoFingerTranslate.IsOn;
} else {
ToggleSwitchEnableTwoFingerTranslate.IsOn = BoardToggleSwitchEnableTwoFingerTranslate.IsOn;
}
Settings.Gesture.IsEnableTwoFingerTranslate = ToggleSwitchEnableTwoFingerTranslate.IsOn;
CheckEnableTwoFingerGestureBtnColorPrompt();
SaveSettingsToFile();
}
private void ToggleSwitchEnableTwoFingerRotation_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
if (sender == ToggleSwitchEnableTwoFingerRotation) {
BoardToggleSwitchEnableTwoFingerRotation.IsOn = ToggleSwitchEnableTwoFingerRotation.IsOn;
} else {
ToggleSwitchEnableTwoFingerRotation.IsOn = BoardToggleSwitchEnableTwoFingerRotation.IsOn;
}
Settings.Gesture.IsEnableTwoFingerRotation = ToggleSwitchEnableTwoFingerRotation.IsOn;
Settings.Gesture.IsEnableTwoFingerRotationOnSelection = ToggleSwitchEnableTwoFingerRotationOnSelection.IsOn;
CheckEnableTwoFingerGestureBtnColorPrompt();
SaveSettingsToFile();
}
private void ToggleSwitchEnableTwoFingerGestureInPresentationMode_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.PowerPointSettings.IsEnableTwoFingerGestureInPresentationMode = ToggleSwitchEnableTwoFingerGestureInPresentationMode.IsOn;
SaveSettingsToFile();
}
#endregion
#region Reset
public static void SetSettingsToRecommendation() {
bool AutoDelSavedFilesDays = Settings.Automation.AutoDelSavedFiles;
int AutoDelSavedFilesDaysThreshold = Settings.Automation.AutoDelSavedFilesDaysThreshold;
Settings = new Settings();
Settings.Advanced.IsSpecialScreen = true;
Settings.Advanced.IsQuadIR = false;
Settings.Advanced.TouchMultiplier = 0.3;
Settings.Advanced.NibModeBoundsWidth = 5;
Settings.Advanced.FingerModeBoundsWidth = 20;
Settings.Advanced.EraserBindTouchMultiplier = true;
Settings.Advanced.IsLogEnabled = true;
Settings.Advanced.IsSecondConfimeWhenShutdownApp = false;
Settings.Appearance.IsEnableDisPlayNibModeToggler = false;
Settings.Appearance.IsColorfulViewboxFloatingBar = false;
Settings.Appearance.EnableViewboxFloatingBarScaleTransform = true;
Settings.Appearance.EnableViewboxBlackBoardScaleTransform = false;
Settings.Appearance.IsTransparentButtonBackground = true;
Settings.Appearance.IsShowExitButton = true;
Settings.Appearance.IsShowEraserButton = true;
Settings.Appearance.IsShowHideControlButton = false;
Settings.Appearance.IsShowLRSwitchButton = false;
Settings.Appearance.IsShowModeFingerToggleSwitch = true;
Settings.Appearance.Theme = 0;
Settings.Automation.IsAutoFoldInEasiNote = true;
Settings.Automation.IsAutoFoldInEasiNoteIgnoreDesktopAnno = true;
Settings.Automation.IsAutoFoldInEasiCamera = true;
Settings.Automation.IsAutoFoldInEasiNote3C = false;
Settings.Automation.IsAutoFoldInSeewoPincoTeacher = false;
Settings.Automation.IsAutoFoldInHiteTouchPro = false;
Settings.Automation.IsAutoFoldInHiteCamera = false;
Settings.Automation.IsAutoFoldInWxBoardMain = false;
Settings.Automation.IsAutoFoldInOldZyBoard = false;
Settings.Automation.IsAutoFoldInMSWhiteboard = false;
Settings.Automation.IsAutoFoldInPPTSlideShow = false;
Settings.Automation.IsAutoKillPptService = false;
Settings.Automation.IsAutoKillEasiNote = false;
Settings.Automation.IsSaveScreenshotsInDateFolders = false;
Settings.Automation.IsAutoSaveStrokesAtScreenshot = true;
Settings.Automation.IsAutoSaveStrokesAtClear = true;
Settings.Automation.IsAutoClearWhenExitingWritingMode = false;
Settings.Automation.MinimumAutomationStrokeNumber = 0;
Settings.Automation.AutoDelSavedFiles = AutoDelSavedFilesDays;
Settings.Automation.AutoDelSavedFilesDaysThreshold = AutoDelSavedFilesDaysThreshold;
Settings.PowerPointSettings.IsShowPPTNavigation = true;
Settings.PowerPointSettings.IsShowBottomPPTNavigationPanel = false;
Settings.PowerPointSettings.IsShowSidePPTNavigationPanel = true;
Settings.PowerPointSettings.PowerPointSupport = true;
Settings.PowerPointSettings.IsShowCanvasAtNewSlideShow = false;
Settings.PowerPointSettings.IsNoClearStrokeOnSelectWhenInPowerPoint = true;
Settings.PowerPointSettings.IsShowStrokeOnSelectInPowerPoint = false;
Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint = true;
Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint = true;
Settings.PowerPointSettings.IsNotifyPreviousPage = false;
Settings.PowerPointSettings.IsNotifyHiddenPage = false;
Settings.PowerPointSettings.IsEnableTwoFingerGestureInPresentationMode = false;
Settings.PowerPointSettings.IsEnableFingerGestureSlideShowControl = false;
Settings.PowerPointSettings.IsSupportWPS = true;
Settings.Canvas.InkWidth = 2.5;
Settings.Canvas.IsShowCursor = false;
Settings.Canvas.InkStyle = 0;
Settings.Canvas.EraserSize = 1;
Settings.Canvas.EraserType = 0;
Settings.Canvas.HideStrokeWhenSelecting = false;
Settings.Canvas.UsingWhiteboard = false;
Settings.Canvas.HyperbolaAsymptoteOption = 0;
Settings.Gesture.AutoSwitchTwoFingerGesture = true;
Settings.Gesture.IsEnableTwoFingerTranslate = true;
Settings.Gesture.IsEnableTwoFingerZoom = false;
Settings.Gesture.IsEnableTwoFingerRotation = false;
Settings.Gesture.IsEnableTwoFingerRotationOnSelection = false;
Settings.InkToShape.IsInkToShapeEnabled = true;
Settings.Startup.IsEnableNibMode = false;
Settings.Startup.IsAutoUpdate = true;
Settings.Startup.IsAutoUpdateWithSilence = true;
Settings.Startup.IsAutoUpdateWithProxy = true;
Settings.Startup.AutoUpdateProxy = "https://mirror.ghproxy.com/";
Settings.Startup.AutoUpdateWithSilenceStartTime = "18:20";
Settings.Startup.AutoUpdateWithSilenceEndTime = "07:40";
Settings.Startup.IsFoldAtStartup = false;
}
private void BtnResetToSuggestion_Click(object sender, RoutedEventArgs e) {
try {
isLoaded = false;
SetSettingsToRecommendation();
SaveSettingsToFile();
LoadSettings();
isLoaded = true;
ToggleSwitchRunAtStartup.IsOn = true;
} catch { }
ShowNotification("设置已重置为默认推荐设置~");
}
private async void SpecialVersionResetToSuggestion_Click() {
await Task.Delay(1000);
try {
isLoaded = false;
SetSettingsToRecommendation();
Settings.Automation.AutoDelSavedFiles = true;
Settings.Automation.AutoDelSavedFilesDaysThreshold = 15;
SetAutoSavedStrokesLocationToDiskDButton_Click(null, null);
SaveSettingsToFile();
LoadSettings();
isLoaded = true;
} catch { }
}
#endregion
#region Ink To Shape
private void ToggleSwitchEnableInkToShape_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.InkToShape.IsInkToShapeEnabled = ToggleSwitchEnableInkToShape.IsOn;
SaveSettingsToFile();
}
#endregion
#region Advanced
private void ToggleSwitchIsSpecialScreen_OnToggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Advanced.IsSpecialScreen = ToggleSwitchIsSpecialScreen.IsOn;
TouchMultiplierSlider.Visibility = ToggleSwitchIsSpecialScreen.IsOn ? Visibility.Visible : Visibility.Collapsed;
SaveSettingsToFile();
}
private void TouchMultiplierSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) {
if (!isLoaded) return;
Settings.Advanced.TouchMultiplier = e.NewValue;
SaveSettingsToFile();
}
private void BorderCalculateMultiplier_TouchDown(object sender, TouchEventArgs e) {
var args = e.GetTouchPoint(null).Bounds;
double value;
if (!Settings.Advanced.IsQuadIR) value = args.Width;
else value = Math.Sqrt(args.Width * args.Height); //四边红外
TextBlockShowCalculatedMultiplier.Text = (5 / (value * 1.1)).ToString();
}
private void ToggleSwitchEraserBindTouchMultiplier_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Advanced.EraserBindTouchMultiplier = ToggleSwitchEraserBindTouchMultiplier.IsOn;
SaveSettingsToFile();
}
private void NibModeBoundsWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) {
if (!isLoaded) return;
Settings.Advanced.NibModeBoundsWidth = (int)e.NewValue;
if (Settings.Startup.IsEnableNibMode) {
BoundsWidth = Settings.Advanced.NibModeBoundsWidth;
} else {
BoundsWidth = Settings.Advanced.FingerModeBoundsWidth;
}
SaveSettingsToFile();
}
private void FingerModeBoundsWidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) {
if (!isLoaded) return;
Settings.Advanced.FingerModeBoundsWidth = (int)e.NewValue;
if (Settings.Startup.IsEnableNibMode) {
BoundsWidth = Settings.Advanced.NibModeBoundsWidth;
} else {
BoundsWidth = Settings.Advanced.FingerModeBoundsWidth;
}
SaveSettingsToFile();
}
private void ToggleSwitchIsQuadIR_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Advanced.IsQuadIR = ToggleSwitchIsQuadIR.IsOn;
SaveSettingsToFile();
}
private void ToggleSwitchIsLogEnabled_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Advanced.IsLogEnabled = ToggleSwitchIsLogEnabled.IsOn;
SaveSettingsToFile();
}
private void ToggleSwitchIsSecondConfimeWhenShutdownApp_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.Advanced.IsSecondConfimeWhenShutdownApp = ToggleSwitchIsSecondConfimeWhenShutdownApp.IsOn;
SaveSettingsToFile();
}
#endregion
public static void SaveSettingsToFile() {
string text = JsonConvert.SerializeObject(Settings, Formatting.Indented);
try {
File.WriteAllText(App.RootPath + settingsFileName, text);
} catch { }
}
private void SCManipulationBoundaryFeedback(object sender, ManipulationBoundaryFeedbackEventArgs e) {
e.Handled = true;
}
private void HyperlinkSourceToPresentRepository_Click(object sender, RoutedEventArgs e) {
Process.Start("https://github.com/ChangSakura/Ink-Canvas");
HideSubPanels();
}
private void HyperlinkSourceToOringinalRepository_Click(object sender, RoutedEventArgs e) {
Process.Start("https://github.com/WXRIW/Ink-Canvas");
HideSubPanels();
}
}
}

View File

@ -0,0 +1,449 @@
using Ink_Canvas.Helpers;
using Newtonsoft.Json;
using System;
using System.Reflection;
using System.Windows;
using System.Windows.Media;
using File = System.IO.File;
namespace Ink_Canvas {
public partial class MainWindow : Window {
private void LoadSettings(bool isStartup = false) {
AppVersionTextBlock.Text = Assembly.GetExecutingAssembly().GetName().Version.ToString();
try {
if (File.Exists(App.RootPath + settingsFileName)) {
try {
string text = File.ReadAllText(App.RootPath + settingsFileName);
Settings = JsonConvert.DeserializeObject<Settings>(text);
} catch { }
} else {
BtnResetToSuggestion_Click(null, null);
}
} catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
// Startup
if (isStartup) {
CursorIcon_Click(null, null);
}
try {
if (File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\Ink Canvas Annotation.lnk")) {
ToggleSwitchRunAtStartup.IsOn = true;
}
} catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
if (Settings.Startup != null) {
if (isStartup) {
if (Settings.Automation.AutoDelSavedFiles) {
DelAutoSavedFiles.DeleteFilesOlder(Settings.Automation.AutoSavedStrokesLocation, Settings.Automation.AutoDelSavedFilesDaysThreshold);
}
if (Settings.Startup.IsFoldAtStartup) {
FoldFloatingBar_MouseUp(Fold_Icon, null);
}
}
if (Settings.Startup.IsEnableNibMode) {
ToggleSwitchEnableNibMode.IsOn = true;
ToggleSwitchBoardEnableNibMode.IsOn = true;
BoundsWidth = Settings.Advanced.NibModeBoundsWidth;
} else {
ToggleSwitchEnableNibMode.IsOn = false;
ToggleSwitchBoardEnableNibMode.IsOn = false;
BoundsWidth = Settings.Advanced.FingerModeBoundsWidth;
}
if (Settings.Startup.IsAutoUpdate) {
ToggleSwitchIsAutoUpdate.IsOn = true;
AutoUpdate();
}
ToggleSwitchIsAutoUpdateWithProxy.IsOn = Settings.Startup.IsAutoUpdateWithProxy;
AutoUpdateWithProxy_Title.Visibility = Settings.Startup.IsAutoUpdateWithProxy ? Visibility.Visible : Visibility.Collapsed;
AutoUpdateProxyTextBox.Text = Settings.Startup.AutoUpdateProxy;
ToggleSwitchIsAutoUpdateWithSilence.Visibility = Settings.Startup.IsAutoUpdate ? Visibility.Visible : Visibility.Collapsed;
if (Settings.Startup.IsAutoUpdateWithSilence) {
ToggleSwitchIsAutoUpdateWithSilence.IsOn = true;
}
AutoUpdateTimePeriodBlock.Visibility = Settings.Startup.IsAutoUpdateWithSilence ? Visibility.Visible : Visibility.Collapsed;
AutoUpdateWithSilenceTimeComboBox.InitializeAutoUpdateWithSilenceTimeComboBoxOptions(AutoUpdateWithSilenceStartTimeComboBox, AutoUpdateWithSilenceEndTimeComboBox);
AutoUpdateWithSilenceStartTimeComboBox.SelectedItem = Settings.Startup.AutoUpdateWithSilenceStartTime;
AutoUpdateWithSilenceEndTimeComboBox.SelectedItem = Settings.Startup.AutoUpdateWithSilenceEndTime;
ToggleSwitchFoldAtStartup.IsOn = Settings.Startup.IsFoldAtStartup;
} else {
Settings.Startup = new Startup();
}
// Appearance
if (Settings.Appearance != null) {
if (!Settings.Appearance.IsEnableDisPlayNibModeToggler) {
NibModeSimpleStackPanel.Visibility = Visibility.Collapsed;
BoardNibModeSimpleStackPanel.Visibility = Visibility.Collapsed;
} else {
NibModeSimpleStackPanel.Visibility = Visibility.Visible;
BoardNibModeSimpleStackPanel.Visibility = Visibility.Visible;
}
if (Settings.Appearance.IsColorfulViewboxFloatingBar) // 浮动工具栏背景色
{
LinearGradientBrush gradientBrush = new LinearGradientBrush();
gradientBrush.StartPoint = new Point(0, 0);
gradientBrush.EndPoint = new Point(1, 1);
GradientStop blueStop = new GradientStop(Color.FromArgb(0x95, 0x80, 0xB0, 0xFF), 0);
GradientStop greenStop = new GradientStop(Color.FromArgb(0x95, 0xC0, 0xFF, 0xC0), 1);
gradientBrush.GradientStops.Add(blueStop);
gradientBrush.GradientStops.Add(greenStop);
EnableTwoFingerGestureBorder.Background = gradientBrush;
BorderFloatingBarMainControls.Background = gradientBrush;
BorderFloatingBarMoveControls.Background = gradientBrush;
BorderFloatingBarExitPPTBtn.Background = gradientBrush;
ToggleSwitchColorfulViewboxFloatingBar.IsOn = true;
} else {
EnableTwoFingerGestureBorder.Background = (Brush)FindResource("FloatBarBackground");
BorderFloatingBarMainControls.Background = (Brush)FindResource("FloatBarBackground");
BorderFloatingBarMoveControls.Background = (Brush)FindResource("FloatBarBackground");
BorderFloatingBarExitPPTBtn.Background = (Brush)FindResource("FloatBarBackground");
ToggleSwitchColorfulViewboxFloatingBar.IsOn = false;
}
if (Settings.Appearance.EnableViewboxFloatingBarScaleTransform) // 浮动工具栏 UI 缩放 85%
{
ViewboxFloatingBarScaleTransform.ScaleX = 0.85;
ViewboxFloatingBarScaleTransform.ScaleY = 0.85;
ToggleSwitchEnableViewboxFloatingBarScaleTransform.IsOn = true;
} else {
ViewboxFloatingBarScaleTransform.ScaleX = 1;
ViewboxFloatingBarScaleTransform.ScaleY = 1;
ToggleSwitchEnableViewboxFloatingBarScaleTransform.IsOn = false;
}
if (Settings.Appearance.EnableViewboxBlackBoardScaleTransform) // 画板 UI 缩放 80%
{
ViewboxBlackboardLeftSideScaleTransform.ScaleX = 0.8;
ViewboxBlackboardLeftSideScaleTransform.ScaleY = 0.8;
ViewboxBlackboardCenterSideScaleTransform.ScaleX = 0.8;
ViewboxBlackboardCenterSideScaleTransform.ScaleY = 0.8;
ViewboxBlackboardRightSideScaleTransform.ScaleX = 0.8;
ViewboxBlackboardRightSideScaleTransform.ScaleY = 0.8;
ToggleSwitchEnableViewboxBlackBoardScaleTransform.IsOn = true;
} else {
ViewboxBlackboardLeftSideScaleTransform.ScaleX = 1;
ViewboxBlackboardLeftSideScaleTransform.ScaleY = 1;
ViewboxBlackboardCenterSideScaleTransform.ScaleX = 1;
ViewboxBlackboardCenterSideScaleTransform.ScaleY = 1;
ViewboxBlackboardRightSideScaleTransform.ScaleX = 1;
ViewboxBlackboardRightSideScaleTransform.ScaleY = 1;
ToggleSwitchEnableViewboxBlackBoardScaleTransform.IsOn = false;
}
if (Settings.Appearance.IsTransparentButtonBackground) {
BtnExit.Background = new SolidColorBrush(StringToColor("#7F909090"));
} else {
if (BtnSwitchTheme.Content.ToString() == "深色") {
//Light
BtnExit.Background = new SolidColorBrush(StringToColor("#FFCCCCCC"));
} else {
//Dark
BtnExit.Background = new SolidColorBrush(StringToColor("#FF555555"));
}
}
} else {
Settings.Appearance = new Appearance();
}
// PowerPointSettings
if (Settings.PowerPointSettings != null) {
PptNavigationBtn.Visibility = Settings.PowerPointSettings.IsShowPPTNavigation ? Visibility.Visible : Visibility.Collapsed;
ToggleSwitchShowButtonPPTNavigation.IsOn = Settings.PowerPointSettings.IsShowPPTNavigation;
ToggleSwitchShowBottomPPTNavigationPanel.IsOn = Settings.PowerPointSettings.IsShowBottomPPTNavigationPanel;
ToggleSwitchShowSidePPTNavigationPanel.IsOn = Settings.PowerPointSettings.IsShowSidePPTNavigationPanel;
if (Settings.PowerPointSettings.PowerPointSupport) {
ToggleSwitchSupportPowerPoint.IsOn = true;
timerCheckPPT.Start();
} else {
ToggleSwitchSupportPowerPoint.IsOn = false;
timerCheckPPT.Stop();
}
if (Settings.PowerPointSettings.IsShowCanvasAtNewSlideShow) {
ToggleSwitchShowCanvasAtNewSlideShow.IsOn = true;
} else {
ToggleSwitchShowCanvasAtNewSlideShow.IsOn = false;
}
if (Settings.PowerPointSettings.IsEnableTwoFingerGestureInPresentationMode) {
ToggleSwitchEnableTwoFingerGestureInPresentationMode.IsOn = true;
} else {
ToggleSwitchEnableTwoFingerGestureInPresentationMode.IsOn = false;
}
if (Settings.PowerPointSettings.IsEnableFingerGestureSlideShowControl) {
ToggleSwitchEnableFingerGestureSlideShowControl.IsOn = true;
} else {
ToggleSwitchEnableFingerGestureSlideShowControl.IsOn = false;
}
if (Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint) {
ToggleSwitchAutoSaveStrokesInPowerPoint.IsOn = true;
} else {
ToggleSwitchAutoSaveStrokesInPowerPoint.IsOn = false;
}
if (Settings.PowerPointSettings.IsNotifyPreviousPage) {
ToggleSwitchNotifyPreviousPage.IsOn = true;
} else {
ToggleSwitchNotifyPreviousPage.IsOn = false;
}
if (Settings.PowerPointSettings.IsNotifyHiddenPage) {
ToggleSwitchNotifyHiddenPage.IsOn = true;
} else {
ToggleSwitchNotifyHiddenPage.IsOn = false;
}
if (Settings.PowerPointSettings.IsSupportWPS) {
ToggleSwitchSupportWPS.IsOn = true;
} else {
ToggleSwitchSupportWPS.IsOn = false;
}
if (Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint) {
ToggleSwitchAutoSaveScreenShotInPowerPoint.IsOn = true;
} else {
ToggleSwitchAutoSaveScreenShotInPowerPoint.IsOn = false;
}
} else {
Settings.PowerPointSettings = new PowerPointSettings();
}
// Gesture
if (Settings.Gesture != null) {
if (Settings.Gesture.IsEnableTwoFingerZoom) {
ToggleSwitchEnableTwoFingerZoom.IsOn = true;
BoardToggleSwitchEnableTwoFingerZoom.IsOn = true;
} else {
ToggleSwitchEnableTwoFingerZoom.IsOn = false;
BoardToggleSwitchEnableTwoFingerZoom.IsOn = false;
}
if (Settings.Gesture.IsEnableTwoFingerTranslate) {
ToggleSwitchEnableTwoFingerTranslate.IsOn = true;
BoardToggleSwitchEnableTwoFingerTranslate.IsOn = true;
} else {
ToggleSwitchEnableTwoFingerTranslate.IsOn = false;
BoardToggleSwitchEnableTwoFingerTranslate.IsOn = false;
}
if (Settings.Gesture.IsEnableTwoFingerRotation) {
ToggleSwitchEnableTwoFingerRotation.IsOn = true;
BoardToggleSwitchEnableTwoFingerRotation.IsOn = true;
} else {
ToggleSwitchEnableTwoFingerRotation.IsOn = false;
BoardToggleSwitchEnableTwoFingerRotation.IsOn = false;
}
if (Settings.Gesture.AutoSwitchTwoFingerGesture) {
ToggleSwitchAutoSwitchTwoFingerGesture.IsOn = true;
} else {
ToggleSwitchAutoSwitchTwoFingerGesture.IsOn = false;
}
if (Settings.Gesture.IsEnableTwoFingerRotation) {
ToggleSwitchEnableTwoFingerRotation.IsOn = true;
} else {
ToggleSwitchEnableTwoFingerRotation.IsOn = false;
}
if (Settings.Gesture.IsEnableTwoFingerRotationOnSelection) {
ToggleSwitchEnableTwoFingerRotationOnSelection.IsOn = true;
} else {
ToggleSwitchEnableTwoFingerRotationOnSelection.IsOn = false;
}
if (Settings.Gesture.AutoSwitchTwoFingerGesture) {
if (Topmost) {
ToggleSwitchEnableTwoFingerTranslate.IsOn = false;
BoardToggleSwitchEnableTwoFingerTranslate.IsOn = false;
Settings.Gesture.IsEnableTwoFingerTranslate = false;
} else {
ToggleSwitchEnableTwoFingerTranslate.IsOn = true;
BoardToggleSwitchEnableTwoFingerTranslate.IsOn = true;
Settings.Gesture.IsEnableTwoFingerTranslate = true;
}
}
CheckEnableTwoFingerGestureBtnColorPrompt();
} else {
Settings.Gesture = new Gesture();
}
// Canvas
if (Settings.Canvas != null) {
drawingAttributes.Height = Settings.Canvas.InkWidth;
drawingAttributes.Width = Settings.Canvas.InkWidth;
InkWidthSlider.Value = Settings.Canvas.InkWidth * 2;
ComboBoxHyperbolaAsymptoteOption.SelectedIndex = (int)Settings.Canvas.HyperbolaAsymptoteOption;
if (Settings.Canvas.UsingWhiteboard) {
GridBackgroundCover.Background = new SolidColorBrush(StringToColor("#FFF2F2F2"));
} else {
GridBackgroundCover.Background = new SolidColorBrush(StringToColor("#FF1F1F1F"));
}
if (Settings.Canvas.IsShowCursor) {
ToggleSwitchShowCursor.IsOn = true;
inkCanvas.ForceCursor = true;
} else {
ToggleSwitchShowCursor.IsOn = false;
inkCanvas.ForceCursor = false;
}
ComboBoxPenStyle.SelectedIndex = Settings.Canvas.InkStyle;
BoardComboBoxPenStyle.SelectedIndex = Settings.Canvas.InkStyle;
ComboBoxEraserSize.SelectedIndex = Settings.Canvas.EraserSize;
if (Settings.Canvas.HideStrokeWhenSelecting) {
ToggleSwitchHideStrokeWhenSelecting.IsOn = true;
} else {
ToggleSwitchHideStrokeWhenSelecting.IsOn = false;
}
} else {
Settings.Canvas = new Canvas();
}
// Advanced
if (Settings.Advanced != null) {
TouchMultiplierSlider.Value = Settings.Advanced.TouchMultiplier;
FingerModeBoundsWidthSlider.Value = Settings.Advanced.FingerModeBoundsWidth;
NibModeBoundsWidthSlider.Value = Settings.Advanced.NibModeBoundsWidth;
if (Settings.Advanced.IsLogEnabled) {
ToggleSwitchIsLogEnabled.IsOn = true;
} else {
ToggleSwitchIsLogEnabled.IsOn = false;
}
if (Settings.Advanced.IsSecondConfimeWhenShutdownApp) {
ToggleSwitchIsSecondConfimeWhenShutdownApp.IsOn = true;
} else {
ToggleSwitchIsSecondConfimeWhenShutdownApp.IsOn = false;
}
if (Settings.Advanced.EraserBindTouchMultiplier) {
ToggleSwitchEraserBindTouchMultiplier.IsOn = true;
} else {
ToggleSwitchEraserBindTouchMultiplier.IsOn = false;
}
if (Settings.Advanced.IsSpecialScreen) {
ToggleSwitchIsSpecialScreen.IsOn = true;
} else {
ToggleSwitchIsSpecialScreen.IsOn = false;
}
TouchMultiplierSlider.Visibility = ToggleSwitchIsSpecialScreen.IsOn ? Visibility.Visible : Visibility.Collapsed;
ToggleSwitchIsQuadIR.IsOn = Settings.Advanced.IsQuadIR;
} else {
Settings.Advanced = new Advanced();
}
// InkToShape
if (Settings.InkToShape != null) {
if (Settings.InkToShape.IsInkToShapeEnabled) {
ToggleSwitchEnableInkToShape.IsOn = true;
} else {
ToggleSwitchEnableInkToShape.IsOn = false;
}
} else {
Settings.InkToShape = new InkToShape();
}
// RandSettings
if (Settings.RandSettings != null) {
} else {
Settings.RandSettings = new RandSettings();
}
// Automation
if (Settings.Automation != null) {
StartOrStoptimerCheckAutoFold();
if (Settings.Automation.IsAutoFoldInEasiNote) {
ToggleSwitchAutoFoldInEasiNote.IsOn = true;
} else {
ToggleSwitchAutoFoldInEasiNote.IsOn = false;
}
if (Settings.Automation.IsAutoFoldInEasiCamera) {
ToggleSwitchAutoFoldInEasiCamera.IsOn = true;
} else {
ToggleSwitchAutoFoldInEasiCamera.IsOn = false;
}
if (Settings.Automation.IsAutoFoldInEasiNote3C) {
ToggleSwitchAutoFoldInEasiNote3C.IsOn = true;
} else {
ToggleSwitchAutoFoldInEasiNote3C.IsOn = false;
}
if (Settings.Automation.IsAutoFoldInSeewoPincoTeacher) {
ToggleSwitchAutoFoldInSeewoPincoTeacher.IsOn = true;
} else {
ToggleSwitchAutoFoldInSeewoPincoTeacher.IsOn = false;
}
if (Settings.Automation.IsAutoFoldInHiteTouchPro) {
ToggleSwitchAutoFoldInHiteTouchPro.IsOn = true;
} else {
ToggleSwitchAutoFoldInHiteTouchPro.IsOn = false;
}
if (Settings.Automation.IsAutoFoldInHiteCamera) {
ToggleSwitchAutoFoldInHiteCamera.IsOn = true;
} else {
ToggleSwitchAutoFoldInHiteCamera.IsOn = false;
}
if (Settings.Automation.IsAutoFoldInWxBoardMain) {
ToggleSwitchAutoFoldInWxBoardMain.IsOn = true;
} else {
ToggleSwitchAutoFoldInWxBoardMain.IsOn = false;
}
if (Settings.Automation.IsAutoFoldInOldZyBoard) {
ToggleSwitchAutoFoldInOldZyBoard.IsOn = true;
} else {
ToggleSwitchAutoFoldInOldZyBoard.IsOn = false;
}
if (Settings.Automation.IsAutoFoldInMSWhiteboard) {
ToggleSwitchAutoFoldInMSWhiteboard.IsOn = true;
} else {
ToggleSwitchAutoFoldInMSWhiteboard.IsOn = false;
}
if (Settings.Automation.IsAutoFoldInPPTSlideShow) {
ToggleSwitchAutoFoldInPPTSlideShow.IsOn = true;
} else {
ToggleSwitchAutoFoldInPPTSlideShow.IsOn = false;
}
if (Settings.Automation.IsAutoKillEasiNote || Settings.Automation.IsAutoKillPptService) {
timerKillProcess.Start();
} else {
timerKillProcess.Stop();
}
if (Settings.Automation.IsAutoKillEasiNote) {
ToggleSwitchAutoKillEasiNote.IsOn = true;
} else {
ToggleSwitchAutoKillEasiNote.IsOn = false;
}
if (Settings.Automation.IsAutoKillPptService) {
ToggleSwitchAutoKillPptService.IsOn = true;
} else {
ToggleSwitchAutoKillPptService.IsOn = false;
}
if (Settings.Automation.IsAutoSaveStrokesAtClear) {
ToggleSwitchAutoSaveStrokesAtClear.IsOn = true;
} else {
ToggleSwitchAutoSaveStrokesAtClear.IsOn = false;
}
if (Settings.Automation.IsSaveScreenshotsInDateFolders) {
ToggleSwitchSaveScreenshotsInDateFolders.IsOn = true;
} else {
ToggleSwitchSaveScreenshotsInDateFolders.IsOn = false;
}
if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) {
ToggleSwitchAutoSaveStrokesAtScreenshot.IsOn = true;
} else {
ToggleSwitchAutoSaveStrokesAtScreenshot.IsOn = false;
}
SideControlMinimumAutomationSlider.Value = Settings.Automation.MinimumAutomationStrokeNumber;
AutoSavedStrokesLocation.Text = Settings.Automation.AutoSavedStrokesLocation;
ToggleSwitchAutoDelSavedFiles.IsOn = Settings.Automation.AutoDelSavedFiles;
ComboBoxAutoDelSavedFilesDaysThreshold.Text = Settings.Automation.AutoDelSavedFilesDaysThreshold.ToString();
} else {
Settings.Automation = new Automation();
}
// auto align
if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) {
ViewboxFloatingBarMarginAnimation(60);
} else {
ViewboxFloatingBarMarginAnimation(100);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,510 @@
using Ink_Canvas.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using Point = System.Windows.Point;
namespace Ink_Canvas {
public partial class MainWindow : Window {
StrokeCollection newStrokes = new StrokeCollection();
List<Circle> circles = new List<Circle>();
//此函数中的所有代码版权所有 WXRIW在其他项目中使用前必须提前联系wxriw@outlook.com谢谢
private void inkCanvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e) {
try {
inkCanvas.Opacity = 1;
if (Settings.InkToShape.IsInkToShapeEnabled && !Environment.Is64BitProcess) {
void InkToShapeProcess() {
try {
newStrokes.Add(e.Stroke);
if (newStrokes.Count > 4) newStrokes.RemoveAt(0);
for (int i = 0; i < newStrokes.Count; i++) {
if (!inkCanvas.Strokes.Contains(newStrokes[i])) newStrokes.RemoveAt(i--);
}
for (int i = 0; i < circles.Count; i++) {
if (!inkCanvas.Strokes.Contains(circles[i].Stroke)) circles.RemoveAt(i);
}
var strokeReco = new StrokeCollection();
var result = InkRecognizeHelper.RecognizeShape(newStrokes);
for (int i = newStrokes.Count - 1; i >= 0; i--) {
strokeReco.Add(newStrokes[i]);
var newResult = InkRecognizeHelper.RecognizeShape(strokeReco);
if (newResult.InkDrawingNode.GetShapeName() == "Circle" || newResult.InkDrawingNode.GetShapeName() == "Ellipse") {
result = newResult;
break;
}
//Label.Visibility = Visibility.Visible;
//Label.Content = circles.Count.ToString() + "\n" + newResult.InkDrawingNode.GetShapeName();
}
if (result.InkDrawingNode.GetShapeName() == "Circle") {
var shape = result.InkDrawingNode.GetShape();
if (shape.Width > 75) {
foreach (Circle circle in circles) {
//判断是否画同心圆
if (Math.Abs(result.Centroid.X - circle.Centroid.X) / shape.Width < 0.12 &&
Math.Abs(result.Centroid.Y - circle.Centroid.Y) / shape.Width < 0.12) {
result.Centroid = circle.Centroid;
break;
} else {
double d = (result.Centroid.X - circle.Centroid.X) * (result.Centroid.X - circle.Centroid.X) +
(result.Centroid.Y - circle.Centroid.Y) * (result.Centroid.Y - circle.Centroid.Y);
d = Math.Sqrt(d);
//判断是否画外切圆
double x = shape.Width / 2.0 + circle.R - d;
if (Math.Abs(x) / shape.Width < 0.1) {
double sinTheta = (result.Centroid.Y - circle.Centroid.Y) / d;
double cosTheta = (result.Centroid.X - circle.Centroid.X) / d;
double newX = result.Centroid.X + x * cosTheta;
double newY = result.Centroid.Y + x * sinTheta;
result.Centroid = new Point(newX, newY);
}
//判断是否画外切圆
x = Math.Abs(circle.R - shape.Width / 2.0) - d;
if (Math.Abs(x) / shape.Width < 0.1) {
double sinTheta = (result.Centroid.Y - circle.Centroid.Y) / d;
double cosTheta = (result.Centroid.X - circle.Centroid.X) / d;
double newX = result.Centroid.X + x * cosTheta;
double newY = result.Centroid.Y + x * sinTheta;
result.Centroid = new Point(newX, newY);
}
}
}
Point iniP = new Point(result.Centroid.X - shape.Width / 2, result.Centroid.Y - shape.Height / 2);
Point endP = new Point(result.Centroid.X + shape.Width / 2, result.Centroid.Y + shape.Height / 2);
var pointList = GenerateEllipseGeometry(iniP, endP);
var point = new StylusPointCollection(pointList);
var stroke = new Stroke(point) {
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
};
circles.Add(new Circle(result.Centroid, shape.Width / 2.0, stroke));
SetNewBackupOfStroke();
_currentCommitType = CommitReason.ShapeRecognition;
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
inkCanvas.Strokes.Add(stroke);
_currentCommitType = CommitReason.UserInput;
newStrokes = new StrokeCollection();
}
} else if (result.InkDrawingNode.GetShapeName().Contains("Ellipse")) {
var shape = result.InkDrawingNode.GetShape();
//var shape1 = result.InkDrawingNode.GetShape();
//shape1.Fill = Brushes.Gray;
//Canvas.Children.Add(shape1);
var p = result.InkDrawingNode.HotPoints;
double a = GetDistance(p[0], p[2]) / 2; //长半轴
double b = GetDistance(p[1], p[3]) / 2; //短半轴
if (a < b) {
double t = a;
a = b;
b = t;
}
result.Centroid = new Point((p[0].X + p[2].X) / 2, (p[0].Y + p[2].Y) / 2);
bool needRotation = true;
if (shape.Width > 75 || shape.Height > 75 && p.Count == 4) {
Point iniP = new Point(result.Centroid.X - shape.Width / 2, result.Centroid.Y - shape.Height / 2);
Point endP = new Point(result.Centroid.X + shape.Width / 2, result.Centroid.Y + shape.Height / 2);
foreach (Circle circle in circles) {
//判断是否画同心椭圆
if (Math.Abs(result.Centroid.X - circle.Centroid.X) / a < 0.2 &&
Math.Abs(result.Centroid.Y - circle.Centroid.Y) / a < 0.2) {
result.Centroid = circle.Centroid;
iniP = new Point(result.Centroid.X - shape.Width / 2, result.Centroid.Y - shape.Height / 2);
endP = new Point(result.Centroid.X + shape.Width / 2, result.Centroid.Y + shape.Height / 2);
//再判断是否与圆相切
if (Math.Abs(a - circle.R) / a < 0.2) {
if (shape.Width >= shape.Height) {
iniP.X = result.Centroid.X - circle.R;
endP.X = result.Centroid.X + circle.R;
iniP.Y = result.Centroid.Y - b;
endP.Y = result.Centroid.Y + b;
} else {
iniP.Y = result.Centroid.Y - circle.R;
endP.Y = result.Centroid.Y + circle.R;
iniP.X = result.Centroid.X - a;
endP.X = result.Centroid.X + a;
}
}
break;
} else if (Math.Abs(result.Centroid.X - circle.Centroid.X) / a < 0.2) {
double sinTheta = Math.Abs(circle.Centroid.Y - result.Centroid.Y) / circle.R;
double cosTheta = Math.Sqrt(1 - sinTheta * sinTheta);
double newA = circle.R * cosTheta;
if (circle.R * sinTheta / circle.R < 0.9 && a / b > 2 && Math.Abs(newA - a) / newA < 0.3) {
iniP.X = circle.Centroid.X - newA;
endP.X = circle.Centroid.X + newA;
iniP.Y = result.Centroid.Y - newA / 5;
endP.Y = result.Centroid.Y + newA / 5;
double topB = endP.Y - iniP.Y;
SetNewBackupOfStroke();
_currentCommitType = CommitReason.ShapeRecognition;
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
newStrokes = new StrokeCollection();
var _pointList = GenerateEllipseGeometry(iniP, endP, false, true);
var _point = new StylusPointCollection(_pointList);
var _stroke = new Stroke(_point) {
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
};
var _dashedLineStroke = GenerateDashedLineEllipseStrokeCollection(iniP, endP, true, false);
StrokeCollection strokes = new StrokeCollection()
{
_stroke,
_dashedLineStroke
};
inkCanvas.Strokes.Add(strokes);
_currentCommitType = CommitReason.UserInput;
return;
}
} else if (Math.Abs(result.Centroid.Y - circle.Centroid.Y) / a < 0.2) {
double cosTheta = Math.Abs(circle.Centroid.X - result.Centroid.X) / circle.R;
double sinTheta = Math.Sqrt(1 - cosTheta * cosTheta);
double newA = circle.R * sinTheta;
if (circle.R * sinTheta / circle.R < 0.9 && a / b > 2 && Math.Abs(newA - a) / newA < 0.3) {
iniP.X = result.Centroid.X - newA / 5;
endP.X = result.Centroid.X + newA / 5;
iniP.Y = circle.Centroid.Y - newA;
endP.Y = circle.Centroid.Y + newA;
needRotation = false;
}
}
}
//纠正垂直与水平关系
var newPoints = FixPointsDirection(p[0], p[2]);
p[0] = newPoints[0];
p[2] = newPoints[1];
newPoints = FixPointsDirection(p[1], p[3]);
p[1] = newPoints[0];
p[3] = newPoints[1];
var pointList = GenerateEllipseGeometry(iniP, endP);
var point = new StylusPointCollection(pointList);
var stroke = new Stroke(point) {
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
};
if (needRotation) {
Matrix m = new Matrix();
FrameworkElement fe = e.Source as FrameworkElement;
double tanTheta = (p[2].Y - p[0].Y) / (p[2].X - p[0].X);
double theta = Math.Atan(tanTheta);
m.RotateAt(theta * 180.0 / Math.PI, result.Centroid.X, result.Centroid.Y);
stroke.Transform(m, false);
}
SetNewBackupOfStroke();
_currentCommitType = CommitReason.ShapeRecognition;
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
inkCanvas.Strokes.Add(stroke);
_currentCommitType = CommitReason.UserInput;
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
newStrokes = new StrokeCollection();
}
} else if (result.InkDrawingNode.GetShapeName().Contains("Triangle")) {
var shape = result.InkDrawingNode.GetShape();
var p = result.InkDrawingNode.HotPoints;
if ((Math.Max(Math.Max(p[0].X, p[1].X), p[2].X) - Math.Min(Math.Min(p[0].X, p[1].X), p[2].X) >= 100 ||
Math.Max(Math.Max(p[0].Y, p[1].Y), p[2].Y) - Math.Min(Math.Min(p[0].Y, p[1].Y), p[2].Y) >= 100) && result.InkDrawingNode.HotPoints.Count == 3) {
//纠正垂直与水平关系
var newPoints = FixPointsDirection(p[0], p[1]);
p[0] = newPoints[0];
p[1] = newPoints[1];
newPoints = FixPointsDirection(p[0], p[2]);
p[0] = newPoints[0];
p[2] = newPoints[1];
newPoints = FixPointsDirection(p[1], p[2]);
p[1] = newPoints[0];
p[2] = newPoints[1];
var pointList = p.ToList();
//pointList.Add(p[0]);
var point = new StylusPointCollection(pointList);
var stroke = new Stroke(GenerateFakePressureTriangle(point)) {
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
};
SetNewBackupOfStroke();
_currentCommitType = CommitReason.ShapeRecognition;
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
inkCanvas.Strokes.Add(stroke);
_currentCommitType = CommitReason.UserInput;
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
newStrokes = new StrokeCollection();
}
} else if (result.InkDrawingNode.GetShapeName().Contains("Rectangle") ||
result.InkDrawingNode.GetShapeName().Contains("Diamond") ||
result.InkDrawingNode.GetShapeName().Contains("Parallelogram") ||
result.InkDrawingNode.GetShapeName().Contains("Square")) {
var shape = result.InkDrawingNode.GetShape();
var p = result.InkDrawingNode.HotPoints;
if ((Math.Max(Math.Max(Math.Max(p[0].X, p[1].X), p[2].X), p[3].X) - Math.Min(Math.Min(Math.Min(p[0].X, p[1].X), p[2].X), p[3].X) >= 100 ||
Math.Max(Math.Max(Math.Max(p[0].Y, p[1].Y), p[2].Y), p[3].Y) - Math.Min(Math.Min(Math.Min(p[0].Y, p[1].Y), p[2].Y), p[3].Y) >= 100) && result.InkDrawingNode.HotPoints.Count == 4) {
//纠正垂直与水平关系
var newPoints = FixPointsDirection(p[0], p[1]);
p[0] = newPoints[0];
p[1] = newPoints[1];
newPoints = FixPointsDirection(p[1], p[2]);
p[1] = newPoints[0];
p[2] = newPoints[1];
newPoints = FixPointsDirection(p[2], p[3]);
p[2] = newPoints[0];
p[3] = newPoints[1];
newPoints = FixPointsDirection(p[3], p[0]);
p[3] = newPoints[0];
p[0] = newPoints[1];
var pointList = p.ToList();
pointList.Add(p[0]);
var point = new StylusPointCollection(pointList);
var stroke = new Stroke(GenerateFakePressureRectangle(point)) {
DrawingAttributes = inkCanvas.DefaultDrawingAttributes.Clone()
};
SetNewBackupOfStroke();
_currentCommitType = CommitReason.ShapeRecognition;
inkCanvas.Strokes.Remove(result.InkDrawingNode.Strokes);
inkCanvas.Strokes.Add(stroke);
_currentCommitType = CommitReason.UserInput;
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
newStrokes = new StrokeCollection();
}
}
} catch { }
}
InkToShapeProcess();
}
foreach (StylusPoint stylusPoint in e.Stroke.StylusPoints) {
//LogHelper.WriteLogToFile(stylusPoint.PressureFactor.ToString(), LogHelper.LogType.Info);
// 检查是否是压感笔书写
//if (stylusPoint.PressureFactor != 0.5 && stylusPoint.PressureFactor != 0)
if ((stylusPoint.PressureFactor > 0.501 || stylusPoint.PressureFactor < 0.5) && stylusPoint.PressureFactor != 0) {
return;
}
}
try {
if (e.Stroke.StylusPoints.Count > 3) {
Random random = new Random();
double _speed = GetPointSpeed(e.Stroke.StylusPoints[random.Next(0, e.Stroke.StylusPoints.Count - 1)].ToPoint(), e.Stroke.StylusPoints[random.Next(0, e.Stroke.StylusPoints.Count - 1)].ToPoint(), e.Stroke.StylusPoints[random.Next(0, e.Stroke.StylusPoints.Count - 1)].ToPoint());
RandWindow.randSeed = (int)(_speed * 100000 * 1000);
}
} catch { }
switch (Settings.Canvas.InkStyle) {
case 1:
try {
StylusPointCollection stylusPoints = new StylusPointCollection();
int n = e.Stroke.StylusPoints.Count - 1;
string s = "";
for (int i = 0; i <= n; i++) {
double speed = GetPointSpeed(e.Stroke.StylusPoints[Math.Max(i - 1, 0)].ToPoint(), e.Stroke.StylusPoints[i].ToPoint(), e.Stroke.StylusPoints[Math.Min(i + 1, n)].ToPoint());
s += speed.ToString() + "\t";
StylusPoint point = new StylusPoint();
if (speed >= 0.25) {
point.PressureFactor = (float)(0.5 - 0.3 * (Math.Min(speed, 1.5) - 0.3) / 1.2);
} else if (speed >= 0.05) {
point.PressureFactor = (float)0.5;
} else {
point.PressureFactor = (float)(0.5 + 0.4 * (0.05 - speed) / 0.05);
}
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
e.Stroke.StylusPoints = stylusPoints;
} catch {
}
break;
case 0:
try {
StylusPointCollection stylusPoints = new StylusPointCollection();
int n = e.Stroke.StylusPoints.Count - 1;
double pressure = 0.1;
int x = 10;
if (n == 1) return;
if (n >= x) {
for (int i = 0; i < n - x; i++) {
StylusPoint point = new StylusPoint();
point.PressureFactor = (float)0.5;
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
for (int i = n - x; i <= n; i++) {
StylusPoint point = new StylusPoint();
point.PressureFactor = (float)((0.5 - pressure) * (n - i) / x + pressure);
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
} else {
for (int i = 0; i <= n; i++) {
StylusPoint point = new StylusPoint();
point.PressureFactor = (float)(0.4 * (n - i) / n + pressure);
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
}
e.Stroke.StylusPoints = stylusPoints;
} catch {
}
break;
case 3: //根据 mode == 0 改写,目前暂未完成
try {
StylusPointCollection stylusPoints = new StylusPointCollection();
int n = e.Stroke.StylusPoints.Count - 1;
double pressure = 0.1;
int x = 8;
if (lastTouchDownTime < lastTouchUpTime) {
double k = (lastTouchUpTime - lastTouchDownTime) / (n + 1); // 每个点之间间隔 k 毫秒
x = (int)(1000 / k); // 取 1000 ms 内的点
}
if (n >= x) {
for (int i = 0; i < n - x; i++) {
StylusPoint point = new StylusPoint();
point.PressureFactor = (float)0.5;
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
for (int i = n - x; i <= n; i++) {
StylusPoint point = new StylusPoint();
point.PressureFactor = (float)((0.5 - pressure) * (n - i) / x + pressure);
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
} else {
for (int i = 0; i <= n; i++) {
StylusPoint point = new StylusPoint();
point.PressureFactor = (float)(0.4 * (n - i) / n + pressure);
point.X = e.Stroke.StylusPoints[i].X;
point.Y = e.Stroke.StylusPoints[i].Y;
stylusPoints.Add(point);
}
}
e.Stroke.StylusPoints = stylusPoints;
} catch {
}
break;
}
} catch { }
}
private void SetNewBackupOfStroke() {
lastTouchDownStrokeCollection = inkCanvas.Strokes.Clone();
int whiteboardIndex = CurrentWhiteboardIndex;
if (currentMode == 0) {
whiteboardIndex = 0;
}
strokeCollections[whiteboardIndex] = lastTouchDownStrokeCollection;
}
public double GetDistance(Point point1, Point point2) {
return Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) + (point1.Y - point2.Y) * (point1.Y - point2.Y));
}
public double GetPointSpeed(Point point1, Point point2, Point point3) {
return (Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) + (point1.Y - point2.Y) * (point1.Y - point2.Y))
+ Math.Sqrt((point3.X - point2.X) * (point3.X - point2.X) + (point3.Y - point2.Y) * (point3.Y - point2.Y)))
/ 20;
}
public Point[] FixPointsDirection(Point p1, Point p2) {
if (Math.Abs(p1.X - p2.X) / Math.Abs(p1.Y - p2.Y) > 8) {
//水平
double x = Math.Abs(p1.Y - p2.Y) / 2;
if (p1.Y > p2.Y) {
p1.Y -= x;
p2.Y += x;
} else {
p1.Y += x;
p2.Y -= x;
}
} else if (Math.Abs(p1.Y - p2.Y) / Math.Abs(p1.X - p2.X) > 8) {
//垂直
double x = Math.Abs(p1.X - p2.X) / 2;
if (p1.X > p2.X) {
p1.X -= x;
p2.X += x;
} else {
p1.X += x;
p2.X -= x;
}
}
return new Point[2] { p1, p2 };
}
public StylusPointCollection GenerateFakePressureTriangle(StylusPointCollection points) {
var newPoint = new StylusPointCollection();
newPoint.Add(new StylusPoint(points[0].X, points[0].Y, (float)0.4));
var cPoint = GetCenterPoint(points[0], points[1]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[1].X, points[1].Y, (float)0.4));
newPoint.Add(new StylusPoint(points[1].X, points[1].Y, (float)0.4));
cPoint = GetCenterPoint(points[1], points[2]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[2].X, points[2].Y, (float)0.4));
newPoint.Add(new StylusPoint(points[2].X, points[2].Y, (float)0.4));
cPoint = GetCenterPoint(points[2], points[0]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[0].X, points[0].Y, (float)0.4));
return newPoint;
}
public StylusPointCollection GenerateFakePressureRectangle(StylusPointCollection points) {
var newPoint = new StylusPointCollection();
newPoint.Add(new StylusPoint(points[0].X, points[0].Y, (float)0.4));
var cPoint = GetCenterPoint(points[0], points[1]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[1].X, points[1].Y, (float)0.4));
newPoint.Add(new StylusPoint(points[1].X, points[1].Y, (float)0.4));
cPoint = GetCenterPoint(points[1], points[2]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[2].X, points[2].Y, (float)0.4));
newPoint.Add(new StylusPoint(points[2].X, points[2].Y, (float)0.4));
cPoint = GetCenterPoint(points[2], points[3]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[3].X, points[3].Y, (float)0.4));
newPoint.Add(new StylusPoint(points[3].X, points[3].Y, (float)0.4));
cPoint = GetCenterPoint(points[3], points[0]);
newPoint.Add(new StylusPoint(cPoint.X, cPoint.Y, (float)0.8));
newPoint.Add(new StylusPoint(points[0].X, points[0].Y, (float)0.4));
return newPoint;
}
public Point GetCenterPoint(Point point1, Point point2) {
return new Point((point1.X + point2.X) / 2, (point1.Y + point2.Y) / 2);
}
public StylusPoint GetCenterPoint(StylusPoint point1, StylusPoint point2) {
return new StylusPoint((point1.X + point2.X) / 2, (point1.Y + point2.Y) / 2);
}
}
}

View File

@ -0,0 +1,76 @@
using Ink_Canvas.Helpers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
namespace Ink_Canvas {
public partial class MainWindow : Window {
private enum CommitReason {
UserInput,
CodeInput,
ShapeDrawing,
ShapeRecognition,
ClearingCanvas,
Rotate
}
private CommitReason _currentCommitType = CommitReason.UserInput;
private bool IsEraseByPoint => inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint;
private StrokeCollection ReplacedStroke;
private StrokeCollection AddedStroke;
private StrokeCollection CuboidStrokeCollection;
private TimeMachine timeMachine = new TimeMachine();
private void TimeMachine_OnUndoStateChanged(bool status) {
var result = status ? Visibility.Visible : Visibility.Collapsed;
BtnUndo.Visibility = result;
BtnUndo.IsEnabled = status;
}
private void TimeMachine_OnRedoStateChanged(bool status) {
var result = status ? Visibility.Visible : Visibility.Collapsed;
BtnRedo.Visibility = result;
BtnRedo.IsEnabled = status;
}
private void StrokesOnStrokesChanged(object sender, StrokeCollectionChangedEventArgs e) {
if (!isHidingSubPanelsWhenInking) {
isHidingSubPanelsWhenInking = true;
HideSubPanels(); // 书写时自动隐藏二级菜单
}
if (_currentCommitType == CommitReason.CodeInput || _currentCommitType == CommitReason.ShapeDrawing) return;
if (_currentCommitType == CommitReason.Rotate) {
timeMachine.CommitStrokeRotateHistory(e.Removed, e.Added);
return;
}
if ((e.Added.Count != 0 || e.Removed.Count != 0) && IsEraseByPoint) {
if (AddedStroke == null) AddedStroke = new StrokeCollection();
if (ReplacedStroke == null) ReplacedStroke = new StrokeCollection();
AddedStroke.Add(e.Added);
ReplacedStroke.Add(e.Removed);
return;
}
if (e.Added.Count != 0) {
if (_currentCommitType == CommitReason.ShapeRecognition) {
timeMachine.CommitStrokeShapeHistory(ReplacedStroke, e.Added);
ReplacedStroke = null;
return;
} else {
timeMachine.CommitStrokeUserInputHistory(e.Added);
return;
}
}
if (e.Removed.Count != 0) {
if (_currentCommitType == CommitReason.ShapeRecognition) {
ReplacedStroke = e.Removed;
return;
} else if (!IsEraseByPoint || _currentCommitType == CommitReason.ClearingCanvas) {
timeMachine.CommitStrokeEraseHistory(e.Removed);
return;
}
}
}
}
}

View File

@ -0,0 +1,119 @@
using Ink_Canvas.Helpers;
using System;
using System.Diagnostics;
using System.Timers;
using System.Windows;
using MessageBox = System.Windows.MessageBox;
namespace Ink_Canvas {
public partial class MainWindow : Window {
Timer timerCheckPPT = new Timer();
Timer timerKillProcess = new Timer();
Timer timerCheckAutoFold = new Timer();
string AvailableLatestVersion = null;
Timer timerCheckAutoUpdateWithSilence = new Timer();
bool isHidingSubPanelsWhenInking = false; // 避免书写时触发二次关闭二级菜单导致动画不连续
private void InitTimers() {
timerCheckPPT.Elapsed += TimerCheckPPT_Elapsed;
timerCheckPPT.Interval = 1000;
timerKillProcess.Elapsed += TimerKillProcess_Elapsed;
timerKillProcess.Interval = 5000;
timerCheckAutoFold.Elapsed += timerCheckAutoFold_Elapsed;
timerCheckAutoFold.Interval = 1500;
timerCheckAutoUpdateWithSilence.Elapsed += timerCheckAutoUpdateWithSilence_Elapsed;
timerCheckAutoUpdateWithSilence.Interval = 1000 * 60 * 10;
}
private void TimerKillProcess_Elapsed(object sender, ElapsedEventArgs e) {
try {
// 希沃相关: easinote swenserver RemoteProcess EasiNote.MediaHttpService smartnote.cloud EasiUpdate smartnote EasiUpdate3 EasiUpdate3Protect SeewoP2P CefSharp.BrowserSubprocess SeewoUploadService
string arg = "/F";
if (Settings.Automation.IsAutoKillPptService) {
Process[] processes = Process.GetProcessesByName("PPTService");
if (processes.Length > 0) {
arg += " /IM PPTService.exe";
}
processes = Process.GetProcessesByName("SeewoIwbAssistant");
if (processes.Length > 0) {
arg += " /IM SeewoIwbAssistant.exe" + " /IM Sia.Guard.exe";
}
}
if (Settings.Automation.IsAutoKillEasiNote) {
Process[] processes = Process.GetProcessesByName("EasiNote");
if (processes.Length > 0) {
arg += " /IM EasiNote.exe";
}
}
if (arg != "/F") {
Process p = new Process();
p.StartInfo = new ProcessStartInfo("taskkill", arg);
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.Start();
if (arg.Contains("EasiNote")) {
BtnSwitch_Click(BtnSwitch, null);
MessageBox.Show("“希沃白板 5”已自动关闭");
}
}
} catch { }
}
bool foldFloatingBarByUser = false, // 保持收纳操作不受自动收纳的控制
unfoldFloatingBarByUser = false; // 允许用户在希沃软件内进行展开操作
private void timerCheckAutoFold_Elapsed(object sender, ElapsedEventArgs e) {
if (isFloatingBarChangingHideMode) return;
try {
string windowProcessName = ForegroundWindowInfo.ProcessName();
string windowTitle = ForegroundWindowInfo.WindowTitle();
//LogHelper.WriteLogToFile("windowTitle | " + windowTitle + " | windowProcessName | " + windowProcessName);
if (Settings.Automation.IsAutoFoldInEasiNote && windowProcessName == "EasiNote" // 希沃白板
&& (!(windowTitle.Length == 0 && ForegroundWindowInfo.WindowRect().Height < 500) || !Settings.Automation.IsAutoFoldInEasiNoteIgnoreDesktopAnno)
|| Settings.Automation.IsAutoFoldInEasiCamera && windowProcessName == "EasiCamera" // 希沃视频展台
|| Settings.Automation.IsAutoFoldInEasiNote3C && windowProcessName == "EasiNote" // 希沃轻白板
|| Settings.Automation.IsAutoFoldInSeewoPincoTeacher && (windowProcessName == "BoardService" || windowProcessName == "seewoPincoTeacher") // 希沃品课
|| Settings.Automation.IsAutoFoldInHiteCamera && windowProcessName == "HiteCamera" // 鸿合视频展台
|| Settings.Automation.IsAutoFoldInHiteTouchPro && windowProcessName == "HiteTouchPro" // 鸿合白板
|| Settings.Automation.IsAutoFoldInWxBoardMain && windowProcessName == "WxBoardMain" // 文香白板
|| Settings.Automation.IsAutoFoldInMSWhiteboard && (windowProcessName == "MicrosoftWhiteboard" || windowProcessName == "msedgewebview2") // 微软白板
|| Settings.Automation.IsAutoFoldInOldZyBoard && // 中原旧白板
(WinTabWindowsChecker.IsWindowExisted("WhiteBoard - DrawingWindow")
|| WinTabWindowsChecker.IsWindowExisted("InstantAnnotationWindow"))) {
if (!unfoldFloatingBarByUser && !isFloatingBarFolded) {
FoldFloatingBar_MouseUp(null, null);
}
} else if (WinTabWindowsChecker.IsWindowExisted("幻灯片放映", false)) { // 处于幻灯片放映状态
if (!Settings.Automation.IsAutoFoldInPPTSlideShow && isFloatingBarFolded && !foldFloatingBarByUser) {
UnFoldFloatingBar_MouseUp(null, null);
}
} else {
if (isFloatingBarFolded && !foldFloatingBarByUser) {
UnFoldFloatingBar_MouseUp(null, null);
}
unfoldFloatingBarByUser = false;
}
} catch { }
}
private void timerCheckAutoUpdateWithSilence_Elapsed(object sender, ElapsedEventArgs e) {
Dispatcher.Invoke(() => {
try {
if ((!Topmost) || (inkCanvas.Strokes.Count > 0)) return;
} catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
});
try {
if (AutoUpdateWithSilenceTimeComboBox.CheckIsInSilencePeriod(Settings.Startup.AutoUpdateWithSilenceStartTime, Settings.Startup.AutoUpdateWithSilenceEndTime)) {
AutoUpdateHelper.InstallNewVersionApp(AvailableLatestVersion, true);
timerCheckAutoUpdateWithSilence.Stop();
}
} catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
}
}
}

View File

@ -0,0 +1,342 @@
using Ink_Canvas.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using Point = System.Windows.Point;
namespace Ink_Canvas {
public partial class MainWindow : Window {
#region Multi-Touch
bool isInMultiTouchMode = false;
private void BorderMultiTouchMode_MouseUp(object sender, MouseButtonEventArgs e) {
if (isInMultiTouchMode) {
inkCanvas.StylusDown -= MainWindow_StylusDown;
inkCanvas.StylusMove -= MainWindow_StylusMove;
inkCanvas.StylusUp -= MainWindow_StylusUp;
inkCanvas.TouchDown -= MainWindow_TouchDown;
inkCanvas.TouchDown += Main_Grid_TouchDown;
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
inkCanvas.Children.Clear();
isInMultiTouchMode = false;
//SymbolIconMultiTouchMode.Symbol = iNKORE.UI.WPF.Modern.Controls.Symbol.People;
} else {
inkCanvas.StylusDown += MainWindow_StylusDown;
inkCanvas.StylusMove += MainWindow_StylusMove;
inkCanvas.StylusUp += MainWindow_StylusUp;
inkCanvas.TouchDown -= Main_Grid_TouchDown;
inkCanvas.TouchDown += MainWindow_TouchDown;
inkCanvas.EditingMode = InkCanvasEditingMode.None;
inkCanvas.Children.Clear();
isInMultiTouchMode = true;
//SymbolIconMultiTouchMode.Symbol = iNKORE.UI.WPF.Modern.Controls.Symbol.Contact;
}
}
private void MainWindow_TouchDown(object sender, TouchEventArgs e) {
if (!isHidingSubPanelsWhenInking) {
isHidingSubPanelsWhenInking = true;
HideSubPanels(); // 书写时自动隐藏二级菜单
}
double boundWidth = e.GetTouchPoint(null).Bounds.Width;
if (boundWidth > 20) {
inkCanvas.EraserShape = new EllipseStylusShape(boundWidth * 0.75, boundWidth * 0.75);
TouchDownPointsList[e.TouchDevice.Id] = InkCanvasEditingMode.EraseByPoint;
inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
} else {
TouchDownPointsList[e.TouchDevice.Id] = InkCanvasEditingMode.None;
inkCanvas.EditingMode = InkCanvasEditingMode.None;
}
}
private void MainWindow_StylusDown(object sender, StylusDownEventArgs e) {
TouchDownPointsList[e.StylusDevice.Id] = InkCanvasEditingMode.None;
}
private void MainWindow_StylusUp(object sender, StylusEventArgs e) {
try {
inkCanvas.Strokes.Add(GetStrokeVisual(e.StylusDevice.Id).Stroke);
inkCanvas.Children.Remove(GetVisualCanvas(e.StylusDevice.Id));
inkCanvas_StrokeCollected(inkCanvas, new InkCanvasStrokeCollectedEventArgs(GetStrokeVisual(e.StylusDevice.Id).Stroke));
} catch (Exception ex) {
Label.Content = ex.ToString();
}
try {
StrokeVisualList.Remove(e.StylusDevice.Id);
VisualCanvasList.Remove(e.StylusDevice.Id);
TouchDownPointsList.Remove(e.StylusDevice.Id);
if (StrokeVisualList.Count == 0 || VisualCanvasList.Count == 0 || TouchDownPointsList.Count == 0) {
inkCanvas.Children.Clear();
StrokeVisualList.Clear();
VisualCanvasList.Clear();
TouchDownPointsList.Clear();
}
} catch { }
}
private void MainWindow_StylusMove(object sender, StylusEventArgs e) {
try {
if (GetTouchDownPointsList(e.StylusDevice.Id) != InkCanvasEditingMode.None) return;
try {
if (e.StylusDevice.StylusButtons[1].StylusButtonState == StylusButtonState.Down) return;
} catch { }
var strokeVisual = GetStrokeVisual(e.StylusDevice.Id);
var stylusPointCollection = e.GetStylusPoints(this);
foreach (var stylusPoint in stylusPointCollection) {
strokeVisual.Add(new StylusPoint(stylusPoint.X, stylusPoint.Y, stylusPoint.PressureFactor));
}
strokeVisual.Redraw();
} catch { }
}
private StrokeVisual GetStrokeVisual(int id) {
if (StrokeVisualList.TryGetValue(id, out var visual)) {
return visual;
}
var strokeVisual = new StrokeVisual(inkCanvas.DefaultDrawingAttributes.Clone());
StrokeVisualList[id] = strokeVisual;
StrokeVisualList[id] = strokeVisual;
var visualCanvas = new VisualCanvas(strokeVisual);
VisualCanvasList[id] = visualCanvas;
inkCanvas.Children.Add(visualCanvas);
return strokeVisual;
}
private VisualCanvas GetVisualCanvas(int id) {
if (VisualCanvasList.TryGetValue(id, out var visualCanvas)) {
return visualCanvas;
}
return null;
}
private InkCanvasEditingMode GetTouchDownPointsList(int id) {
if (TouchDownPointsList.TryGetValue(id, out var inkCanvasEditingMode)) {
return inkCanvasEditingMode;
}
return inkCanvas.EditingMode;
}
private Dictionary<int, InkCanvasEditingMode> TouchDownPointsList { get; } = new Dictionary<int, InkCanvasEditingMode>();
private Dictionary<int, StrokeVisual> StrokeVisualList { get; } = new Dictionary<int, StrokeVisual>();
private Dictionary<int, VisualCanvas> VisualCanvasList { get; } = new Dictionary<int, VisualCanvas>();
#endregion
int lastTouchDownTime = 0, lastTouchUpTime = 0;
Point iniP = new Point(0, 0);
bool isLastTouchEraser = false;
private bool forcePointEraser = true;
private void Main_Grid_TouchDown(object sender, TouchEventArgs e) {
if (!isHidingSubPanelsWhenInking) {
isHidingSubPanelsWhenInking = true;
HideSubPanels(); // 书写时自动隐藏二级菜单
}
if (NeedUpdateIniP()) {
iniP = e.GetTouchPoint(inkCanvas).Position;
}
if (drawingShapeMode == 9 && isFirstTouchCuboid == false) {
MouseTouchMove(iniP);
}
inkCanvas.Opacity = 1;
double boundsWidth = GetTouchBoundWidth(e);
var eraserMultiplier = 1d;
if (!Settings.Advanced.EraserBindTouchMultiplier && Settings.Advanced.IsSpecialScreen) eraserMultiplier = 1 / Settings.Advanced.TouchMultiplier;
if (boundsWidth > BoundsWidth) {
isLastTouchEraser = true;
if (drawingShapeMode == 0 && forceEraser) return;
if (boundsWidth > BoundsWidth * 2.5) {
double k = 1;
switch (Settings.Canvas.EraserSize) {
case 0:
k = 0.5;
break;
case 1:
k = 0.8;
break;
case 3:
k = 1.25;
break;
case 4:
k = 1.8;
break;
}
inkCanvas.EraserShape = new EllipseStylusShape(boundsWidth * 1.5 * k * eraserMultiplier * 0.75, boundsWidth * 1.5 * k * eraserMultiplier * 0.75);
inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
} else {
if (StackPanelPPTControls.Visibility == Visibility.Visible && inkCanvas.Strokes.Count == 0 && Settings.PowerPointSettings.IsEnableFingerGestureSlideShowControl) {
isLastTouchEraser = false;
inkCanvas.EditingMode = InkCanvasEditingMode.GestureOnly;
inkCanvas.Opacity = 0.1;
} else {
inkCanvas.EraserShape = new EllipseStylusShape(5, 5);
inkCanvas.EditingMode = InkCanvasEditingMode.EraseByStroke;
}
}
} else {
isLastTouchEraser = false;
inkCanvas.EraserShape = forcePointEraser ? new EllipseStylusShape(50, 50) : new EllipseStylusShape(5, 5);
if (forceEraser) return;
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
}
}
public double GetTouchBoundWidth(TouchEventArgs e) {
var args = e.GetTouchPoint(null).Bounds;
double value;
if (!Settings.Advanced.IsQuadIR) value = args.Width;
else value = Math.Sqrt(args.Width * args.Height); //四边红外
if (Settings.Advanced.IsSpecialScreen) value *= Settings.Advanced.TouchMultiplier;
return value;
}
//记录触摸设备ID
private List<int> dec = new List<int>();
//中心点
System.Windows.Point centerPoint;
InkCanvasEditingMode lastInkCanvasEditingMode = InkCanvasEditingMode.Ink;
bool isSingleFingerDragMode = false;
//防止衣服误触造成的墨迹消失
private void inkCanvas_PreviewTouchDown(object sender, TouchEventArgs e) {
dec.Add(e.TouchDevice.Id);
//设备1个的时候记录中心点
if (dec.Count == 1) {
TouchPoint touchPoint = e.GetTouchPoint(inkCanvas);
centerPoint = touchPoint.Position;
//记录第一根手指点击时的 StrokeCollection
lastTouchDownStrokeCollection = inkCanvas.Strokes.Clone();
}
//设备两个及两个以上,将画笔功能关闭
if (dec.Count > 1 || isSingleFingerDragMode || !Settings.Gesture.IsEnableTwoFingerGesture) {
if (isInMultiTouchMode || !Settings.Gesture.IsEnableTwoFingerGesture) return;
if (inkCanvas.EditingMode != InkCanvasEditingMode.None && inkCanvas.EditingMode != InkCanvasEditingMode.Select) {
lastInkCanvasEditingMode = inkCanvas.EditingMode;
inkCanvas.EditingMode = InkCanvasEditingMode.None;
}
}
}
private void inkCanvas_PreviewTouchUp(object sender, TouchEventArgs e) {
//手势完成后切回之前的状态
if (dec.Count > 1) {
if (inkCanvas.EditingMode == InkCanvasEditingMode.None) {
inkCanvas.EditingMode = lastInkCanvasEditingMode;
}
}
dec.Remove(e.TouchDevice.Id);
inkCanvas.Opacity = 1;
if (dec.Count == 0) {
if (lastTouchDownStrokeCollection.Count() != inkCanvas.Strokes.Count() &&
!(drawingShapeMode == 9 && !isFirstTouchCuboid)) {
int whiteboardIndex = CurrentWhiteboardIndex;
if (currentMode == 0) {
whiteboardIndex = 0;
}
strokeCollections[whiteboardIndex] = lastTouchDownStrokeCollection;
}
}
}
private void inkCanvas_ManipulationStarting(object sender, ManipulationStartingEventArgs e) {
e.Mode = ManipulationModes.All;
}
private void inkCanvas_ManipulationInertiaStarting(object sender, ManipulationInertiaStartingEventArgs e) {
}
private void Main_Grid_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) {
if (e.Manipulators.Count() == 0) {
if (forceEraser) return;
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
}
}
private void Main_Grid_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) {
if (isInMultiTouchMode || !Settings.Gesture.IsEnableTwoFingerGesture) return;
if ((dec.Count >= 2 && (Settings.PowerPointSettings.IsEnableTwoFingerGestureInPresentationMode || StackPanelPPTControls.Visibility != Visibility.Visible || StackPanelPPTButtons.Visibility == Visibility.Collapsed)) || isSingleFingerDragMode) {
ManipulationDelta md = e.DeltaManipulation;
Vector trans = md.Translation; // 获得位移矢量
Matrix m = new Matrix();
if (Settings.Gesture.IsEnableTwoFingerTranslate)
m.Translate(trans.X, trans.Y); // 移动
if (Settings.Gesture.IsEnableTwoFingerGestureTranslateOrRotation) {
double rotate = md.Rotation; // 获得旋转角度
Vector scale = md.Scale; // 获得缩放倍数
// Find center of element and then transform to get current location of center
FrameworkElement fe = e.Source as FrameworkElement;
Point center = new Point(fe.ActualWidth / 2, fe.ActualHeight / 2);
center = m.Transform(center); // 转换为矩阵缩放和旋转的中心点
if (Settings.Gesture.IsEnableTwoFingerRotation)
m.RotateAt(rotate, center.X, center.Y); // 旋转
if (Settings.Gesture.IsEnableTwoFingerZoom)
m.ScaleAt(scale.X, scale.Y, center.X, center.Y); // 缩放
}
StrokeCollection strokes = inkCanvas.GetSelectedStrokes();
if (strokes.Count != 0) {
foreach (Stroke stroke in strokes) {
stroke.Transform(m, false);
foreach (Circle circle in circles) {
if (stroke == circle.Stroke) {
circle.R = GetDistance(circle.Stroke.StylusPoints[0].ToPoint(), circle.Stroke.StylusPoints[circle.Stroke.StylusPoints.Count / 2].ToPoint()) / 2;
circle.Centroid = new Point((circle.Stroke.StylusPoints[0].X + circle.Stroke.StylusPoints[circle.Stroke.StylusPoints.Count / 2].X) / 2,
(circle.Stroke.StylusPoints[0].Y + circle.Stroke.StylusPoints[circle.Stroke.StylusPoints.Count / 2].Y) / 2);
break;
}
}
if (Settings.Gesture.IsEnableTwoFingerZoom) {
try {
stroke.DrawingAttributes.Width *= md.Scale.X;
stroke.DrawingAttributes.Height *= md.Scale.Y;
} catch { }
}
}
} else {
if (Settings.Gesture.IsEnableTwoFingerZoom) {
foreach (Stroke stroke in inkCanvas.Strokes) {
stroke.Transform(m, false);
try {
stroke.DrawingAttributes.Width *= md.Scale.X;
stroke.DrawingAttributes.Height *= md.Scale.Y;
} catch { }
};
} else {
foreach (Stroke stroke in inkCanvas.Strokes) {
stroke.Transform(m, false);
};
}
foreach (Circle circle in circles) {
circle.R = GetDistance(circle.Stroke.StylusPoints[0].ToPoint(), circle.Stroke.StylusPoints[circle.Stroke.StylusPoints.Count / 2].ToPoint()) / 2;
circle.Centroid = new Point(
(circle.Stroke.StylusPoints[0].X + circle.Stroke.StylusPoints[circle.Stroke.StylusPoints.Count / 2].X) / 2,
(circle.Stroke.StylusPoints[0].Y + circle.Stroke.StylusPoints[circle.Stroke.StylusPoints.Count / 2].Y) / 2
);
};
}
}
}
}
}

Binary file not shown.

View File

@ -49,5 +49,5 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("4.5.5.0")] [assembly: AssemblyVersion("4.5.6.0")]
[assembly: AssemblyFileVersion("4.5.5.0")] [assembly: AssemblyFileVersion("4.5.6.0")]