Files
community/Ink Canvas/MainWindow_cs/MW_BoardControls.cs
T
2025-07-28 14:45:37 +08:00

266 lines
12 KiB
C#

using Ink_Canvas.Helpers;
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Ink;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
namespace Ink_Canvas {
public partial class MainWindow : Window {
private StrokeCollection[] strokeCollections = new StrokeCollection[101];
private bool[] whiteboadLastModeIsRedo = new bool[101];
private StrokeCollection lastTouchDownStrokeCollection = new StrokeCollection();
private int CurrentWhiteboardIndex = 1;
private int WhiteboardTotalCount = 1;
private 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 {
// 新增:提交所有图片元素到时间机器历史记录
foreach (var child in inkCanvas.Children)
{
if (child is Image img)
{
timeMachine.CommitElementInsertHistory(img);
}
}
var timeMachineHistory = timeMachine.ExportTimeMachineHistory();
TimeMachineHistories[CurrentWhiteboardIndex] = timeMachineHistory;
timeMachine.ClearStrokeHistory();
// 保存当前页图片信息
var elementInfos = new List<CanvasElementInfo>();
foreach (var child in inkCanvas.Children)
{
if (child is Image img && img.Source is BitmapImage bmp)
{
elementInfos.Add(new CanvasElementInfo
{
Type = "Image",
SourcePath = bmp.UriSource?.LocalPath ?? "",
Left = InkCanvas.GetLeft(img),
Top = InkCanvas.GetTop(img),
Width = img.Width,
Height = img.Height
});
}
}
var savePath = Settings.Automation.AutoSavedStrokesLocation;
if (!Directory.Exists(savePath)) Directory.CreateDirectory(savePath);
File.WriteAllText(System.IO.Path.Combine(savePath, $"elements_page{CurrentWhiteboardIndex}.json"), JsonConvert.SerializeObject(elementInfos, Formatting.Indented));
}
}
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) {
timeMachine.ImportTimeMachineHistory(TimeMachineHistories[0]);
foreach (var item in TimeMachineHistories[0]) ApplyHistoryToCanvas(item);
} else {
timeMachine.ImportTimeMachineHistory(TimeMachineHistories[CurrentWhiteboardIndex]);
// 新增:通过时间机器历史恢复图片
foreach (var item in TimeMachineHistories[CurrentWhiteboardIndex])
{
if (item.CommitType == TimeMachineHistoryType.ElementInsert)
{
inkCanvas.Children.Add(item.InsertedElement);
}
}
foreach (var item in TimeMachineHistories[CurrentWhiteboardIndex]) ApplyHistoryToCanvas(item);
// 恢复当前页图片信息
inkCanvas.Children.Clear();
var savePath = Settings.Automation.AutoSavedStrokesLocation;
var elementsFile = System.IO.Path.Combine(savePath, $"elements_page{CurrentWhiteboardIndex}.json");
if (File.Exists(elementsFile))
{
var elementInfos = JsonConvert.DeserializeObject<List<CanvasElementInfo>>(File.ReadAllText(elementsFile));
foreach (var info in elementInfos)
{
if (info.Type == "Image" && File.Exists(info.SourcePath))
{
var img = new Image
{
Source = new BitmapImage(new Uri(info.SourcePath)),
Width = info.Width,
Height = info.Height,
Stretch = Enum.TryParse<Stretch>(info.Stretch, out var stretch) ? stretch : Stretch.Fill
};
InkCanvas.SetLeft(img, info.Left);
InkCanvas.SetTop(img, info.Top);
inkCanvas.Children.Add(img);
}
}
}
}
}
catch {
// ignored
}
}
private async void BtnWhiteBoardPageIndex_Click(object sender, EventArgs e) {
if (sender == BtnLeftPageListWB) {
if (BoardBorderLeftPageListView.Visibility == Visibility.Visible) {
AnimationsHelper.HideWithSlideAndFade(BoardBorderLeftPageListView);
} else {
AnimationsHelper.HideWithSlideAndFade(BoardBorderRightPageListView);
RefreshBlackBoardSidePageListView();
AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardBorderLeftPageListView);
await Task.Delay(1);
ScrollViewToVerticalTop(
(ListViewItem)BlackBoardLeftSidePageListView.ItemContainerGenerator.ContainerFromIndex(
CurrentWhiteboardIndex - 1), BlackBoardLeftSidePageListScrollViewer);
}
} else if (sender == BtnRightPageListWB)
{
if (BoardBorderRightPageListView.Visibility == Visibility.Visible) {
AnimationsHelper.HideWithSlideAndFade(BoardBorderRightPageListView);
} else {
AnimationsHelper.HideWithSlideAndFade(BoardBorderLeftPageListView);
RefreshBlackBoardSidePageListView();
AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardBorderRightPageListView);
await Task.Delay(1);
ScrollViewToVerticalTop(
(ListViewItem)BlackBoardRightSidePageListView.ItemContainerGenerator.ContainerFromIndex(
CurrentWhiteboardIndex - 1), BlackBoardRightSidePageListScrollViewer);
}
}
}
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) {
Trace.WriteLine("113223234");
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 (var i = WhiteboardTotalCount; i > CurrentWhiteboardIndex; i--)
TimeMachineHistories[i] = TimeMachineHistories[i - 1];
UpdateIndexInfoDisplay();
if (WhiteboardTotalCount >= 99) BtnWhiteBoardAdd.IsEnabled = false;
if (BlackBoardLeftSidePageListView.Visibility == Visibility.Visible) {
RefreshBlackBoardSidePageListView();
}
}
private void BtnWhiteBoardDelete_Click(object sender, RoutedEventArgs e) {
ClearStrokes(true);
if (CurrentWhiteboardIndex != WhiteboardTotalCount)
for (var 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 =
$"{CurrentWhiteboardIndex}/{WhiteboardTotalCount}";
bool isLastPage = CurrentWhiteboardIndex == WhiteboardTotalCount;
bool isMaxPage = WhiteboardTotalCount >= 99;
// 设置按钮文本
BtnLeftWhiteBoardSwitchNextLabel.Text = isLastPage ? "新页面" : "下一页";
BtnRightWhiteBoardSwitchNextLabel.Text = isLastPage ? "新页面" : "下一页";
// 始终允许点击“下一页/新页面”按钮(除非已达最大页数)
BtnWhiteBoardSwitchNext.IsEnabled = !isMaxPage;
// 保持按钮常亮(高亮)
BtnLeftWhiteBoardSwitchNextGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27));
BtnLeftWhiteBoardSwitchNextLabel.Opacity = 1;
BtnRightWhiteBoardSwitchNextGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27));
BtnRightWhiteBoardSwitchNextLabel.Opacity = 1;
BtnWhiteBoardSwitchPrevious.IsEnabled = true;
if (CurrentWhiteboardIndex == 1) {
BtnWhiteBoardSwitchPrevious.IsEnabled = false;
BtnLeftWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(127, 24, 24, 27));
BtnLeftWhiteBoardSwitchPreviousLabel.Opacity = 0.5;
BtnRightWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(127, 24, 24, 27));
BtnRightWhiteBoardSwitchPreviousLabel.Opacity = 0.5;
} else {
BtnLeftWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27));
BtnLeftWhiteBoardSwitchPreviousLabel.Opacity = 1;
BtnRightWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(Color.FromArgb(255, 24, 24, 27));
BtnRightWhiteBoardSwitchPreviousLabel.Opacity = 1;
}
BtnWhiteBoardDelete.IsEnabled = WhiteboardTotalCount != 1;
}
}
}