fix:图片墨迹保存问题
This commit is contained in:
@@ -24,14 +24,91 @@ namespace Ink_Canvas {
|
||||
|
||||
// 保存每页白板图片信息
|
||||
private void SaveStrokes(bool isBackupMain = false) {
|
||||
// 确保画布上的所有UI元素都被保存到时间机器历史记录中
|
||||
var currentHistory = timeMachine.ExportTimeMachineHistory();
|
||||
var elementsInHistory = new HashSet<UIElement>();
|
||||
|
||||
// 收集已经在历史记录中的元素
|
||||
if (currentHistory != null) {
|
||||
foreach (var h in currentHistory) {
|
||||
if (h.CommitType == TimeMachineHistoryType.ElementInsert &&
|
||||
h.InsertedElement != null &&
|
||||
!h.StrokeHasBeenCleared) {
|
||||
elementsInHistory.Add(h.InsertedElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查画布上的所有UI元素,确保它们都在历史记录中
|
||||
var missingElements = 0;
|
||||
foreach (UIElement child in inkCanvas.Children) {
|
||||
if (child is Image || child is MediaElement) {
|
||||
if (!elementsInHistory.Contains(child)) {
|
||||
timeMachine.CommitElementInsertHistory(child);
|
||||
missingElements++;
|
||||
LogHelper.WriteLogToFile($"SaveStrokes: 补充保存遗漏的UI元素 {child.GetType().Name}", LogHelper.LogType.Trace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (missingElements > 0) {
|
||||
LogHelper.WriteLogToFile($"SaveStrokes: 总共补充保存了 {missingElements} 个遗漏的UI元素", LogHelper.LogType.Trace);
|
||||
}
|
||||
|
||||
// 确保画布上的所有墨迹都被保存
|
||||
if (inkCanvas.Strokes.Count > 0) {
|
||||
// 检查是否有墨迹没有在时间机器历史记录中
|
||||
var strokesInHistory = new HashSet<Stroke>();
|
||||
if (currentHistory != null) {
|
||||
foreach (var h in currentHistory) {
|
||||
if (h.CommitType == TimeMachineHistoryType.UserInput &&
|
||||
h.CurrentStroke != null &&
|
||||
!h.StrokeHasBeenCleared) {
|
||||
foreach (Stroke stroke in h.CurrentStroke) {
|
||||
strokesInHistory.Add(stroke);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 收集没有在历史记录中的墨迹
|
||||
var missingStrokes = new StrokeCollection();
|
||||
foreach (Stroke stroke in inkCanvas.Strokes) {
|
||||
if (!strokesInHistory.Contains(stroke)) {
|
||||
missingStrokes.Add(stroke);
|
||||
}
|
||||
}
|
||||
|
||||
if (missingStrokes.Count > 0) {
|
||||
timeMachine.CommitStrokeUserInputHistory(missingStrokes);
|
||||
LogHelper.WriteLogToFile($"SaveStrokes: 补充保存了 {missingStrokes.Count} 个遗漏的墨迹", LogHelper.LogType.Trace);
|
||||
}
|
||||
}
|
||||
|
||||
if (isBackupMain) {
|
||||
var timeMachineHistory = timeMachine.ExportTimeMachineHistory();
|
||||
TimeMachineHistories[0] = timeMachineHistory;
|
||||
timeMachine.ClearStrokeHistory();
|
||||
|
||||
// 调试信息
|
||||
var elementCount = timeMachineHistory?.Count(h => h.CommitType == TimeMachineHistoryType.ElementInsert && !h.StrokeHasBeenCleared) ?? 0;
|
||||
var strokeHistoryCount = timeMachineHistory?.Count(h => h.CommitType == TimeMachineHistoryType.UserInput && !h.StrokeHasBeenCleared) ?? 0;
|
||||
var currentCanvasElements = inkCanvas.Children.Count;
|
||||
var currentCanvasStrokes = inkCanvas.Strokes.Count;
|
||||
var selectedElement = selectedUIElement?.GetType().Name ?? "无";
|
||||
LogHelper.WriteLogToFile($"SaveStrokes(备份主页面): 保存了 {elementCount} 个UI元素, {strokeHistoryCount} 个墨迹历史, 当前画布有 {currentCanvasElements} 个元素, {currentCanvasStrokes} 个墨迹, 选中元素: {selectedElement}", LogHelper.LogType.Trace);
|
||||
} else {
|
||||
var timeMachineHistory = timeMachine.ExportTimeMachineHistory();
|
||||
TimeMachineHistories[CurrentWhiteboardIndex] = timeMachineHistory;
|
||||
timeMachine.ClearStrokeHistory();
|
||||
|
||||
// 调试信息
|
||||
var elementCount = timeMachineHistory?.Count(h => h.CommitType == TimeMachineHistoryType.ElementInsert && !h.StrokeHasBeenCleared) ?? 0;
|
||||
var strokeHistoryCount = timeMachineHistory?.Count(h => h.CommitType == TimeMachineHistoryType.UserInput && !h.StrokeHasBeenCleared) ?? 0;
|
||||
var currentCanvasElements = inkCanvas.Children.Count;
|
||||
var currentCanvasStrokes = inkCanvas.Strokes.Count;
|
||||
var selectedElement = selectedUIElement?.GetType().Name ?? "无";
|
||||
LogHelper.WriteLogToFile($"SaveStrokes(页面{CurrentWhiteboardIndex}): 保存了 {elementCount} 个UI元素, {strokeHistoryCount} 个墨迹历史, 当前画布有 {currentCanvasElements} 个元素, {currentCanvasStrokes} 个墨迹, 选中元素: {selectedElement}", LogHelper.LogType.Trace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,17 +131,29 @@ namespace Ink_Canvas {
|
||||
try {
|
||||
var targetIndex = isBackupMain ? 0 : CurrentWhiteboardIndex;
|
||||
|
||||
// 先清空当前画布的所有内容(墨迹和图片)
|
||||
// 这里必须清除图片,因为页面切换时需要完全重置画布状态
|
||||
// 先清空当前画布的墨迹
|
||||
inkCanvas.Strokes.Clear();
|
||||
|
||||
// 保存当前的UI元素,稍后会被ApplyHistoryToCanvas正确处理
|
||||
var currentElements = new List<UIElement>();
|
||||
for (int i = inkCanvas.Children.Count - 1; i >= 0; i--)
|
||||
{
|
||||
currentElements.Add(inkCanvas.Children[i]);
|
||||
}
|
||||
inkCanvas.Children.Clear();
|
||||
LogHelper.WriteLogToFile($"RestoreStrokes: 清空了 {currentElements.Count} 个当前UI元素", LogHelper.LogType.Trace);
|
||||
|
||||
// 如果历史记录为空,直接返回(新页面或空页面)
|
||||
if (TimeMachineHistories[targetIndex] == null) {
|
||||
timeMachine.ClearStrokeHistory();
|
||||
LogHelper.WriteLogToFile($"RestoreStrokes({(isBackupMain ? "备份主页面" : $"页面{CurrentWhiteboardIndex}")}): 历史记录为空", LogHelper.LogType.Trace);
|
||||
return;
|
||||
}
|
||||
|
||||
var targetHistory = TimeMachineHistories[targetIndex];
|
||||
var elementCount = targetHistory?.Count(h => h.CommitType == TimeMachineHistoryType.ElementInsert && !h.StrokeHasBeenCleared) ?? 0;
|
||||
LogHelper.WriteLogToFile($"RestoreStrokes({(isBackupMain ? "备份主页面" : $"页面{CurrentWhiteboardIndex}")}): 准备恢复 {elementCount} 个UI元素", LogHelper.LogType.Trace);
|
||||
|
||||
if (isBackupMain) {
|
||||
timeMachine.ImportTimeMachineHistory(TimeMachineHistories[0]);
|
||||
foreach (var item in TimeMachineHistories[0]) ApplyHistoryToCanvas(item);
|
||||
@@ -73,9 +162,19 @@ namespace Ink_Canvas {
|
||||
// 通过时间机器历史恢复所有内容(墨迹和图片)
|
||||
foreach (var item in TimeMachineHistories[CurrentWhiteboardIndex]) ApplyHistoryToCanvas(item);
|
||||
}
|
||||
|
||||
// 恢复后检查实际的UI元素数量
|
||||
var actualElementCount = inkCanvas.Children.Count;
|
||||
LogHelper.WriteLogToFile($"RestoreStrokes({(isBackupMain ? "备份主页面" : $"页面{CurrentWhiteboardIndex}")}): 实际恢复了 {actualElementCount} 个UI元素", LogHelper.LogType.Trace);
|
||||
|
||||
// 确保选中状态被清除,因为我们切换了页面
|
||||
if (selectedUIElement != null) {
|
||||
DeselectUIElement();
|
||||
LogHelper.WriteLogToFile($"RestoreStrokes: 清除了选中状态", LogHelper.LogType.Trace);
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// ignored
|
||||
catch (Exception ex) {
|
||||
LogHelper.WriteLogToFile($"RestoreStrokes失败: {ex.Message}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Ink_Canvas.Helpers;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Ink_Canvas
|
||||
@@ -28,17 +29,10 @@ namespace Ink_Canvas
|
||||
string timestamp = "img_" + DateTime.Now.ToString("yyyyMMdd_HH_mm_ss_fff");
|
||||
image.Name = timestamp;
|
||||
|
||||
// 新缩放逻辑:最大宽高为画布一半,并居中
|
||||
double maxWidth = inkCanvas.ActualWidth / 2;
|
||||
double maxHeight = inkCanvas.ActualHeight / 2;
|
||||
double scaleX = maxWidth / image.Width;
|
||||
double scaleY = maxHeight / image.Height;
|
||||
double scale = Math.Min(1, Math.Min(scaleX, scaleY));
|
||||
image.Width = image.Width * scale;
|
||||
image.Height = image.Height * scale;
|
||||
InkCanvas.SetLeft(image, (inkCanvas.ActualWidth - image.Width) / 2);
|
||||
InkCanvas.SetTop(image, (inkCanvas.ActualHeight - image.Height) / 2);
|
||||
CenterAndScaleElement(image);
|
||||
|
||||
InkCanvas.SetLeft(image, 0);
|
||||
InkCanvas.SetTop(image, 0);
|
||||
inkCanvas.Children.Add(image);
|
||||
|
||||
// 添加鼠标事件处理,使图片可以被选择
|
||||
@@ -46,6 +40,7 @@ namespace Ink_Canvas
|
||||
image.IsManipulationEnabled = true;
|
||||
|
||||
timeMachine.CommitElementInsertHistory(image);
|
||||
LogHelper.WriteLogToFile($"图片插入: {image.Name}, 当前画布UI元素数量: {inkCanvas.Children.Count}", LogHelper.LogType.Trace);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,6 +114,8 @@ namespace Ink_Canvas
|
||||
|
||||
if (mediaElement != null)
|
||||
{
|
||||
CenterAndScaleElement(mediaElement);
|
||||
|
||||
InkCanvas.SetLeft(mediaElement, 0);
|
||||
InkCanvas.SetTop(mediaElement, 0);
|
||||
inkCanvas.Children.Add(mediaElement);
|
||||
@@ -256,5 +253,27 @@ namespace Ink_Canvas
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void CenterAndScaleElement(FrameworkElement element)
|
||||
{
|
||||
double maxWidth = SystemParameters.PrimaryScreenWidth / 2;
|
||||
double maxHeight = SystemParameters.PrimaryScreenHeight / 2;
|
||||
|
||||
double scaleX = maxWidth / element.Width;
|
||||
double scaleY = maxHeight / element.Height;
|
||||
double scale = Math.Min(scaleX, scaleY);
|
||||
|
||||
TransformGroup transformGroup = new TransformGroup();
|
||||
transformGroup.Children.Add(new ScaleTransform(scale, scale));
|
||||
|
||||
double canvasWidth = inkCanvas.ActualWidth;
|
||||
double canvasHeight = inkCanvas.ActualHeight;
|
||||
double centerX = (canvasWidth - element.Width * scale) / 2;
|
||||
double centerY = (canvasHeight - element.Height * scale) / 2;
|
||||
|
||||
transformGroup.Children.Add(new TranslateTransform(centerX, centerY));
|
||||
|
||||
element.RenderTransform = transformGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1789,11 +1789,11 @@ namespace Ink_Canvas {
|
||||
|
||||
// 总是恢复备份墨迹,不管是否在PPT模式
|
||||
// PPT墨迹和白板墨迹应该分别管理,不应该互相影响
|
||||
RestoreStrokes();
|
||||
RestoreStrokes(true);
|
||||
LogHelper.WriteLogToFile($"退出白板模式,恢复备份墨迹。当前模式:{(BtnPPTSlideShowEnd.Visibility == Visibility.Visible ? "PPT放映" : "桌面")}", LogHelper.LogType.Trace);
|
||||
|
||||
// 退出白板时清空图片
|
||||
inkCanvas.Children.Clear();
|
||||
// 注释掉:退出白板时不应该清空图片,因为RestoreStrokes()已经恢复了正确的状态
|
||||
// inkCanvas.Children.Clear();
|
||||
|
||||
if (BtnSwitchTheme.Content.ToString() == "浅色") {
|
||||
BtnSwitch.Content = "黑板";
|
||||
@@ -1837,8 +1837,8 @@ namespace Ink_Canvas {
|
||||
RestoreStrokes(true);
|
||||
LogHelper.WriteLogToFile($"切换到桌面模式,恢复备份墨迹。当前模式:{(BtnPPTSlideShowEnd.Visibility == Visibility.Visible ? "PPT放映" : "桌面")}", LogHelper.LogType.Trace);
|
||||
|
||||
// 退出白板时清空图片
|
||||
inkCanvas.Children.Clear();
|
||||
// 注释掉:退出白板时不应该清空图片,因为RestoreStrokes()已经恢复了正确的状态
|
||||
// inkCanvas.Children.Clear();
|
||||
|
||||
if (BtnSwitchTheme.Content.ToString() == "浅色") {
|
||||
BtnSwitch.Content = "黑板";
|
||||
@@ -2044,17 +2044,10 @@ namespace Ink_Canvas {
|
||||
string timestamp = "img_" + DateTime.Now.ToString("yyyyMMdd_HH_mm_ss_fff");
|
||||
image.Name = timestamp;
|
||||
|
||||
// 新缩放逻辑:最大宽高为画布一半,并居中
|
||||
double maxWidth = inkCanvas.ActualWidth / 2;
|
||||
double maxHeight = inkCanvas.ActualHeight / 2;
|
||||
double scaleX = maxWidth / image.Width;
|
||||
double scaleY = maxHeight / image.Height;
|
||||
double scale = Math.Min(1, Math.Min(scaleX, scaleY));
|
||||
image.Width = image.Width * scale;
|
||||
image.Height = image.Height * scale;
|
||||
InkCanvas.SetLeft(image, (inkCanvas.ActualWidth - image.Width) / 2);
|
||||
InkCanvas.SetTop(image, (inkCanvas.ActualHeight - image.Height) / 2);
|
||||
CenterAndScaleElement(image);
|
||||
|
||||
InkCanvas.SetLeft(image, 0);
|
||||
InkCanvas.SetTop(image, 0);
|
||||
inkCanvas.Children.Add(image);
|
||||
|
||||
timeMachine.CommitElementInsertHistory(image);
|
||||
@@ -2062,6 +2055,5 @@ namespace Ink_Canvas {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
using Ink_Canvas.Helpers;
|
||||
using iNKORE.UI.WPF.Modern.Controls;
|
||||
using Point = System.Windows.Point;
|
||||
|
||||
@@ -587,6 +588,7 @@ namespace Ink_Canvas {
|
||||
}
|
||||
|
||||
selectedUIElement = element;
|
||||
LogHelper.WriteLogToFile($"SelectUIElement: 设置选中元素为 {element?.GetType().Name ?? "null"}", LogHelper.LogType.Trace);
|
||||
|
||||
if (element != null)
|
||||
{
|
||||
@@ -600,11 +602,13 @@ namespace Ink_Canvas {
|
||||
if (element is Image)
|
||||
{
|
||||
ShowImageToolbar();
|
||||
LogHelper.WriteLogToFile($"SelectUIElement: 显示图片工具栏", LogHelper.LogType.Trace);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 对于其他UI元素,显示拖拽手柄
|
||||
ShowResizeHandles();
|
||||
LogHelper.WriteLogToFile($"SelectUIElement: 显示拖拽手柄", LogHelper.LogType.Trace);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -867,6 +871,8 @@ namespace Ink_Canvas {
|
||||
|
||||
private void UIElement_MouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"UIElement_MouseDown: 编辑模式={inkCanvas.EditingMode}, 元素类型={sender.GetType().Name}", LogHelper.LogType.Trace);
|
||||
|
||||
if (inkCanvas.EditingMode == InkCanvasEditingMode.Select)
|
||||
{
|
||||
var element = sender as UIElement;
|
||||
@@ -875,9 +881,14 @@ namespace Ink_Canvas {
|
||||
// 切换到选择模式并选择这个元素
|
||||
inkCanvas.Select(new[] { element });
|
||||
SelectUIElement(element);
|
||||
LogHelper.WriteLogToFile($"UIElement_MouseDown: 选择了UI元素 {element.GetType().Name}", LogHelper.LogType.Trace);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.WriteLogToFile($"UIElement_MouseDown: 编辑模式不是Select,无法选择UI元素", LogHelper.LogType.Trace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -135,12 +135,51 @@ namespace Ink_Canvas {
|
||||
|
||||
if (item.StrokeHasBeenCleared) {
|
||||
// Undo: 移除元素
|
||||
if (item.InsertedElement != null && targetCanvas.Children.Contains(item.InsertedElement))
|
||||
if (item.InsertedElement != null && targetCanvas.Children.Contains(item.InsertedElement)) {
|
||||
targetCanvas.Children.Remove(item.InsertedElement);
|
||||
LogHelper.WriteLogToFile($"ApplyHistoryToCanvas: 移除UI元素 {item.InsertedElement.GetType().Name}", LogHelper.LogType.Trace);
|
||||
}
|
||||
} else {
|
||||
// Redo: 添加元素
|
||||
if (item.InsertedElement != null && !targetCanvas.Children.Contains(item.InsertedElement))
|
||||
if (item.InsertedElement != null) {
|
||||
// 确保元素不在画布上,如果在就先移除
|
||||
if (targetCanvas.Children.Contains(item.InsertedElement)) {
|
||||
targetCanvas.Children.Remove(item.InsertedElement);
|
||||
LogHelper.WriteLogToFile($"ApplyHistoryToCanvas: 先移除已存在的UI元素 {item.InsertedElement.GetType().Name}", LogHelper.LogType.Trace);
|
||||
}
|
||||
|
||||
// 确保元素没有其他父容器
|
||||
if (item.InsertedElement is FrameworkElement fe && fe.Parent != null) {
|
||||
if (fe.Parent is Panel parentPanel) {
|
||||
parentPanel.Children.Remove(fe);
|
||||
LogHelper.WriteLogToFile($"ApplyHistoryToCanvas: 从其他父容器移除UI元素 {item.InsertedElement.GetType().Name}", LogHelper.LogType.Trace);
|
||||
}
|
||||
}
|
||||
|
||||
targetCanvas.Children.Add(item.InsertedElement);
|
||||
LogHelper.WriteLogToFile($"ApplyHistoryToCanvas: 添加UI元素 {item.InsertedElement.GetType().Name}", LogHelper.LogType.Trace);
|
||||
|
||||
// 重新绑定事件处理器(仅对主画布)
|
||||
if (targetCanvas == inkCanvas) {
|
||||
if (item.InsertedElement is Image img) {
|
||||
img.MouseDown -= UIElement_MouseDown;
|
||||
img.MouseDown += UIElement_MouseDown;
|
||||
img.IsManipulationEnabled = true;
|
||||
|
||||
// 重新应用CenterAndScaleElement变换
|
||||
CenterAndScaleElement(img);
|
||||
LogHelper.WriteLogToFile($"ApplyHistoryToCanvas: 重新配置图片元素 {img.Name}", LogHelper.LogType.Trace);
|
||||
} else if (item.InsertedElement is MediaElement media) {
|
||||
media.MouseDown -= UIElement_MouseDown;
|
||||
media.MouseDown += UIElement_MouseDown;
|
||||
media.IsManipulationEnabled = true;
|
||||
|
||||
// 重新应用CenterAndScaleElement变换
|
||||
CenterAndScaleElement(media);
|
||||
LogHelper.WriteLogToFile($"ApplyHistoryToCanvas: 重新配置媒体元素 {media.Name}", LogHelper.LogType.Trace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user