Files
community/Ink Canvas/MainWindow.xaml.cs
T
2025-06-12 10:13:47 +08:00

347 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Ink_Canvas.Helpers;
using iNKORE.UI.WPF.Modern;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Media;
using System.Diagnostics;
using File = System.IO.File;
using MessageBox = System.Windows.MessageBox;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Windows.Controls.Primitives;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Win32;
using System.Windows.Input;
namespace Ink_Canvas {
public partial class MainWindow : Window {
#region Window Initialization
public MainWindow() {
/*
处于画板模式内:Topmost == false / currentMode != 0
处于 PPT 放映内:BtnPPTSlideShowEnd.Visibility
*/
InitializeComponent();
BlackboardLeftSide.Visibility = Visibility.Collapsed;
BlackboardCenterSide.Visibility = Visibility.Collapsed;
BlackboardRightSide.Visibility = Visibility.Collapsed;
BorderTools.Visibility = Visibility.Collapsed;
BorderSettings.Visibility = Visibility.Collapsed;
LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
BorderSettings.Margin = new Thickness(0, 0, 0, 0);
TwoFingerGestureBorder.Visibility = Visibility.Collapsed;
BoardTwoFingerGestureBorder.Visibility = Visibility.Collapsed;
BorderDrawShape.Visibility = Visibility.Collapsed;
BoardBorderDrawShape.Visibility = Visibility.Collapsed;
GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed;
//if (!App.StartArgs.Contains("-o"))
ViewBoxStackPanelMain.Visibility = Visibility.Collapsed;
ViewBoxStackPanelShapes.Visibility = Visibility.Collapsed;
var workingArea = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea;
ViewboxFloatingBar.Margin = new Thickness(
(workingArea.Width - 284) / 2,
workingArea.Bottom - 60 - workingArea.Top,
-2000, -200);
ViewboxFloatingBarMarginAnimation(100, true);
try {
if (File.Exists("debug.ini")) Label.Visibility = Visibility.Visible;
}
catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
try {
if (File.Exists("Log.txt")) {
var fileInfo = new FileInfo("Log.txt");
var fileSizeInKB = fileInfo.Length / 1024;
if (fileSizeInKB > 512)
try {
File.Delete("Log.txt");
LogHelper.WriteLogToFile(
"The Log.txt file has been successfully deleted. Original file size: " + fileSizeInKB +
" KB", LogHelper.LogType.Info);
}
catch (Exception ex) {
LogHelper.WriteLogToFile(
ex + " | Can not delete the Log.txt file. File size: " + fileSizeInKB + " KB",
LogHelper.LogType.Error);
}
}
}
catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
InitTimers();
timeMachine.OnRedoStateChanged += TimeMachine_OnRedoStateChanged;
timeMachine.OnUndoStateChanged += TimeMachine_OnUndoStateChanged;
inkCanvas.Strokes.StrokesChanged += StrokesOnStrokesChanged;
Microsoft.Win32.SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged;
try {
if (File.Exists("SpecialVersion.ini")) SpecialVersionResetToSuggestion_Click();
}
catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
CheckColorTheme(true);
CheckPenTypeUIState();
}
#endregion
#region Ink Canvas Functions
private System.Windows.Media.Color Ink_DefaultColor = Colors.Red;
private DrawingAttributes drawingAttributes;
private void loadPenCanvas() {
try {
//drawingAttributes = new DrawingAttributes();
drawingAttributes = inkCanvas.DefaultDrawingAttributes;
drawingAttributes.Color = Ink_DefaultColor;
drawingAttributes.Height = 2.5;
drawingAttributes.Width = 2.5;
drawingAttributes.IsHighlighter = false;
drawingAttributes.FitToCurve = Settings.Canvas.FitToCurve;
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
inkCanvas.Gesture += InkCanvas_Gesture;
}
catch { }
}
//ApplicationGesture lastApplicationGesture = ApplicationGesture.AllGestures;
private DateTime lastGestureTime = DateTime.Now;
private void InkCanvas_Gesture(object sender, InkCanvasGestureEventArgs e) {
var gestures = e.GetGestureRecognitionResults();
try {
foreach (var gest in gestures)
//Trace.WriteLine(string.Format("Gesture: {0}, Confidence: {1}", gest.ApplicationGesture, gest.RecognitionConfidence));
if (StackPanelPPTControls.Visibility == Visibility.Visible) {
if (gest.ApplicationGesture == ApplicationGesture.Left)
BtnPPTSlidesDown_Click(BtnPPTSlidesDown, null);
if (gest.ApplicationGesture == ApplicationGesture.Right)
BtnPPTSlidesUp_Click(BtnPPTSlidesUp, null);
}
}
catch { }
}
private void inkCanvas_EditingModeChanged(object sender, RoutedEventArgs e) {
var inkCanvas1 = sender as InkCanvas;
if (inkCanvas1 == null) return;
// 修复“显示画笔光标”选项不可用的问题
if (Settings.Canvas.IsShowCursor) {
inkCanvas1.UseCustomCursor = true;
// 修复触屏和数位笔时光标不显示:只要有输入设备悬停、捕获,或有任何Stylus设备连接就显示
if ((inkCanvas1.EditingMode == InkCanvasEditingMode.Ink || drawingShapeMode != 0)
&& (inkCanvas1.IsStylusDirectlyOver || inkCanvas1.IsMouseDirectlyOver || inkCanvas1.IsStylusCaptured || inkCanvas1.IsMouseCaptured
|| Stylus.CurrentStylusDevice != null))
inkCanvas1.ForceCursor = true;
else
inkCanvas1.ForceCursor = false;
} else {
inkCanvas1.UseCustomCursor = false;
inkCanvas1.ForceCursor = false;
}
if (inkCanvas1.EditingMode == InkCanvasEditingMode.Ink) forcePointEraser = !forcePointEraser;
}
#endregion Ink Canvas
#region Definations and Loading
public static Settings Settings = new Settings();
public static string settingsFileName = "Settings.json";
private bool isLoaded = false;
private void Window_Loaded(object sender, RoutedEventArgs e) {
loadPenCanvas();
//加载设置
LoadSettings(true);
// HasNewUpdateWindow hasNewUpdateWindow = new HasNewUpdateWindow();
if (Environment.Is64BitProcess) GroupBoxInkRecognition.Visibility = Visibility.Collapsed;
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light;
SystemEvents_UserPreferenceChanged(null, null);
//TextBlockVersion.Text = Assembly.GetExecutingAssembly().GetName().Version.ToString();
LogHelper.WriteLogToFile("Ink Canvas Loaded", LogHelper.LogType.Event);
isLoaded = true;
BlackBoardLeftSidePageListView.ItemsSource = blackBoardSidePageListViewObservableCollection;
BlackBoardRightSidePageListView.ItemsSource = blackBoardSidePageListViewObservableCollection;
BtnLeftWhiteBoardSwitchPreviousGeometry.Brush =
new SolidColorBrush(System.Windows.Media.Color.FromArgb(127, 24, 24, 27));
BtnLeftWhiteBoardSwitchPreviousLabel.Opacity = 0.5;
BtnRightWhiteBoardSwitchPreviousGeometry.Brush =
new SolidColorBrush(System.Windows.Media.Color.FromArgb(127, 24, 24, 27));
BtnRightWhiteBoardSwitchPreviousLabel.Opacity = 0.5;
BtnWhiteBoardSwitchPrevious.IsEnabled = CurrentWhiteboardIndex != 1;
BorderInkReplayToolBox.Visibility = Visibility.Collapsed;
// 提前加载IA库,优化第一笔等待时间
if (Settings.InkToShape.IsInkToShapeEnabled && !Environment.Is64BitProcess) {
var strokeEmpty = new StrokeCollection();
InkRecognizeHelper.RecognizeShape(strokeEmpty);
}
SystemEvents.DisplaySettingsChanged += SystemEventsOnDisplaySettingsChanged;
// 自动收纳到侧边栏
if (Settings.Startup.IsFoldAtStartup)
{
FoldFloatingBar_MouseUp(null, null);
}
// 恢复崩溃后操作设置
if (App.CrashAction == App.CrashActionType.SilentRestart)
RadioCrashSilentRestart.IsChecked = true;
else
RadioCrashNoAction.IsChecked = true;
}
private void SystemEventsOnDisplaySettingsChanged(object sender, EventArgs e) {
if (!Settings.Advanced.IsEnableResolutionChangeDetection) return;
ShowNotification($"检测到显示器信息变化,变为{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height}");
new Thread(() => {
var isFloatingBarOutsideScreen = false;
var isInPPTPresentationMode = false;
Dispatcher.Invoke(() => {
isFloatingBarOutsideScreen = IsOutsideOfScreenHelper.IsOutsideOfScreen(ViewboxFloatingBar);
isInPPTPresentationMode = BtnPPTSlideShowEnd.Visibility == Visibility.Visible;
});
if (isFloatingBarOutsideScreen) dpiChangedDelayAction.DebounceAction(3000, null, () => {
if (!isFloatingBarFolded)
{
if (isInPPTPresentationMode) ViewboxFloatingBarMarginAnimation(60);
else ViewboxFloatingBarMarginAnimation(100, true);
}
});
}).Start();
}
public DelayAction dpiChangedDelayAction = new DelayAction();
private void MainWindow_OnDpiChanged(object sender, DpiChangedEventArgs e)
{
if (e.OldDpi.DpiScaleX != e.NewDpi.DpiScaleX && e.OldDpi.DpiScaleY != e.NewDpi.DpiScaleY && Settings.Advanced.IsEnableDPIChangeDetection)
{
ShowNotification($"系统DPI发生变化,从 {e.OldDpi.DpiScaleX}x{e.OldDpi.DpiScaleY} 变化为 {e.NewDpi.DpiScaleX}x{e.NewDpi.DpiScaleY}");
new Thread(() => {
var isFloatingBarOutsideScreen = false;
var isInPPTPresentationMode = false;
Dispatcher.Invoke(() => {
isFloatingBarOutsideScreen = IsOutsideOfScreenHelper.IsOutsideOfScreen(ViewboxFloatingBar);
isInPPTPresentationMode = BtnPPTSlideShowEnd.Visibility == Visibility.Visible;
});
if (isFloatingBarOutsideScreen) dpiChangedDelayAction.DebounceAction(3000,null, () => {
if (!isFloatingBarFolded)
{
if (isInPPTPresentationMode) ViewboxFloatingBarMarginAnimation(60);
else ViewboxFloatingBarMarginAnimation(100, true);
}
});
}).Start();
}
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
LogHelper.WriteLogToFile("Ink Canvas closing", LogHelper.LogType.Event);
if (!CloseIsFromButton && Settings.Advanced.IsSecondConfirmWhenShutdownApp) {
e.Cancel = true;
if (MessageBox.Show("是否继续关闭 InkCanvasForClass,这将丢失当前未保存的墨迹。", "InkCanvasForClass",
MessageBoxButton.OKCancel, MessageBoxImage.Warning) == MessageBoxResult.OK)
if (MessageBox.Show("真的狠心关闭 InkCanvasForClass吗?", "InkCanvasForClass", MessageBoxButton.OKCancel,
MessageBoxImage.Error) == MessageBoxResult.OK)
if (MessageBox.Show("是否取消关闭 InkCanvasForClass", "InkCanvasForClass", MessageBoxButton.OKCancel,
MessageBoxImage.Error) != MessageBoxResult.OK)
e.Cancel = false;
}
if (e.Cancel) LogHelper.WriteLogToFile("Ink Canvas closing cancelled", LogHelper.LogType.Event);
}
[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
private void MainWindow_OnSizeChanged(object sender, SizeChangedEventArgs e) {
if (Settings.Advanced.IsEnableForceFullScreen) {
if (isLoaded) ShowNotification(
$"检测到窗口大小变化,已自动恢复到全屏:{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height}(缩放比例为{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height / SystemParameters.PrimaryScreenHeight}");
WindowState = WindowState.Maximized;
MoveWindow(new WindowInteropHelper(this).Handle, 0, 0,
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, true);
}
}
private void Window_Closed(object sender, EventArgs e) {
SystemEvents.DisplaySettingsChanged -= SystemEventsOnDisplaySettingsChanged;
LogHelper.WriteLogToFile("Ink Canvas closed", LogHelper.LogType.Event);
}
private async void AutoUpdate() {
AvailableLatestVersion = await AutoUpdateHelper.CheckForUpdates();
if (AvailableLatestVersion != null) {
var IsDownloadSuccessful = false;
IsDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFileAndSaveStatus(AvailableLatestVersion);
if (IsDownloadSuccessful) {
if (!Settings.Startup.IsAutoUpdateWithSilence) {
if (MessageBox.Show("InkCanvasForClass 新版本安装包已下载完成,是否立即更新?",
"InkCanvasForClass New Version Available", MessageBoxButton.YesNo,
MessageBoxImage.Question) ==
MessageBoxResult.Yes) AutoUpdateHelper.InstallNewVersionApp(AvailableLatestVersion, false);
} else {
timerCheckAutoUpdateWithSilence.Start();
}
}
} else {
AutoUpdateHelper.DeleteUpdatesFolder();
}
}
// 新增:崩溃后操作设置按钮事件
private void RadioCrashAction_Checked(object sender, RoutedEventArgs e)
{
if (RadioCrashSilentRestart != null && RadioCrashSilentRestart.IsChecked == true)
{
App.CrashAction = App.CrashActionType.SilentRestart;
}
else if (RadioCrashNoAction != null && RadioCrashNoAction.IsChecked == true)
{
App.CrashAction = App.CrashActionType.NoAction;
}
// 可选:保存到配置文件
// SaveSettingsToFile();
}
#endregion Definations and Loading
}
}