From cd7a801400ec6be990ba568ded85182d7ab6efe3 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 31 Aug 2025 00:39:40 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=98=E6=9C=AA=E5=AE=8C=E6=88=90=E7=9A=84?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=B7=A5=E5=85=B7=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow.xaml | 106 ++++++ .../MainWindow_cs/MW_ElementsControls.cs | 306 +++++++++++++++++- 2 files changed, 408 insertions(+), 4 deletions(-) diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index dc8c2a44..c00ff977 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -3443,6 +3443,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs b/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs index c23719af..cbfb5a81 100644 --- a/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs +++ b/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs @@ -154,6 +154,12 @@ namespace Ink_Canvas // 使用鼠标拖动的完整实现机制 ApplyMouseDragTransform(element, currentPoint, dragStartPoint); + // 如果是图片元素,更新工具栏位置 + if (element is Image && BorderImageSelectionControl?.Visibility == Visibility.Visible) + { + UpdateImageSelectionToolbarPosition(element); + } + dragStartPoint = currentPoint; e.Handled = true; } @@ -181,6 +187,12 @@ namespace Ink_Canvas // 使用触摸拖动的完整实现 ApplyTouchManipulationTransform(element, e); + // 如果是图片元素,更新工具栏位置 + if (element is Image && BorderImageSelectionControl?.Visibility == Visibility.Visible) + { + UpdateImageSelectionToolbarPosition(element); + } + e.Handled = true; } } @@ -247,8 +259,37 @@ namespace Ink_Canvas currentSelectedElement = element; isElementSelected = true; - // 去除选中效果,避免蓝色底边问题 - // 可以通过其他方式(如状态变量)来跟踪选中状态 + // 根据元素类型显示不同的选择工具栏 + if (element is Image) + { + // 显示图片选择工具栏并设置位置 + if (BorderImageSelectionControl != null) + { + // 计算工具栏位置 + UpdateImageSelectionToolbarPosition(element); + BorderImageSelectionControl.Visibility = Visibility.Visible; + } + + // 隐藏笔画选择工具栏 + if (BorderStrokeSelectionControl != null) + { + BorderStrokeSelectionControl.Visibility = Visibility.Collapsed; + } + } + else + { + // 显示笔画选择工具栏 + if (BorderStrokeSelectionControl != null) + { + BorderStrokeSelectionControl.Visibility = Visibility.Visible; + } + + // 隐藏图片选择工具栏 + if (BorderImageSelectionControl != null) + { + BorderImageSelectionControl.Visibility = Visibility.Collapsed; + } + } // 确保选择框不显示,避免蓝色边框 if (GridInkCanvasSelectionCover != null) @@ -272,6 +313,17 @@ namespace Ink_Canvas // 去除选中效果 isElementSelected = false; + // 隐藏所有选择工具栏 + if (BorderImageSelectionControl != null) + { + BorderImageSelectionControl.Visibility = Visibility.Collapsed; + } + + if (BorderStrokeSelectionControl != null) + { + BorderStrokeSelectionControl.Visibility = Visibility.Collapsed; + } + // 确保选择框隐藏 if (GridInkCanvasSelectionCover != null) { @@ -676,9 +728,9 @@ namespace Ink_Canvas /// 克隆图片 /// /// 要克隆的图片 - private void CloneImage(Image image) + private Image CloneImage(Image image) { - if (image == null) return; + if (image == null) return null; try { @@ -707,6 +759,8 @@ namespace Ink_Canvas // 记录错误但不中断程序 System.Diagnostics.Debug.WriteLine($"克隆图片时发生错误: {ex.Message}"); } + + return null; } /// @@ -932,5 +986,249 @@ namespace Ink_Canvas inkCanvas.EditingMode = InkCanvasEditingMode.None; } } + + // 更新图片选择工具栏位置 + private void UpdateImageSelectionToolbarPosition(FrameworkElement element) + { + try + { + if (BorderImageSelectionControl == null || element == null) return; + + // 获取元素在画布中的位置 + double elementLeft = InkCanvas.GetLeft(element); + double elementTop = InkCanvas.GetTop(element); + double elementWidth = element.ActualWidth; + double elementHeight = element.ActualHeight; + + // 如果元素位置未设置,使用默认值 + if (double.IsNaN(elementLeft)) elementLeft = 0; + if (double.IsNaN(elementTop)) elementTop = 0; + + // 计算工具栏位置(显示在图片下方) + double toolbarLeft = elementLeft + (elementWidth / 2) - (BorderImageSelectionControl.ActualWidth / 2); + double toolbarTop = elementTop + elementHeight + 10; // 图片下方10像素 + + // 确保工具栏不超出画布边界 + double maxLeft = inkCanvas.ActualWidth - BorderImageSelectionControl.ActualWidth; + double maxTop = inkCanvas.ActualHeight - BorderImageSelectionControl.ActualHeight; + + toolbarLeft = Math.Max(0, Math.Min(toolbarLeft, maxLeft)); + toolbarTop = Math.Max(0, Math.Min(toolbarTop, maxTop)); + + // 设置工具栏位置 + BorderImageSelectionControl.Margin = new Thickness(toolbarLeft, toolbarTop, 0, 0); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"更新图片选择工具栏位置失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + #region Image Selection Toolbar Event Handlers + + // 图片克隆功能 + private void BorderImageClone_MouseUp(object sender, MouseButtonEventArgs e) + { + try + { + if (currentSelectedElement is Image originalImage) + { + // 创建克隆图片 + Image clonedImage = CloneImage(originalImage); + + // 添加到画布 + inkCanvas.Children.Add(clonedImage); + + // 初始化变换 + InitializeElementTransform(clonedImage); + + // 绑定事件 + BindElementEvents(clonedImage); + + // 记录历史 + timeMachine.CommitElementInsertHistory(clonedImage); + + LogHelper.WriteLogToFile($"图片克隆完成: {clonedImage.Name}"); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"图片克隆失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + // 图片克隆到新页面 + private void BorderImageCloneToNewBoard_MouseUp(object sender, MouseButtonEventArgs e) + { + try + { + if (currentSelectedElement is Image originalImage) + { + // 创建克隆图片 + Image clonedImage = CloneImage(originalImage); + + // 这里可以添加切换到新页面的逻辑 + // 暂时先添加到当前页面 + inkCanvas.Children.Add(clonedImage); + + // 初始化变换 + InitializeElementTransform(clonedImage); + + // 绑定事件 + BindElementEvents(clonedImage); + + // 记录历史 + timeMachine.CommitElementInsertHistory(clonedImage); + + LogHelper.WriteLogToFile($"图片克隆到新页面完成: {clonedImage.Name}"); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"图片克隆到新页面失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + // 图片左旋转 + private void BorderImageRotateLeft_MouseUp(object sender, MouseButtonEventArgs e) + { + try + { + if (currentSelectedElement != null) + { + ApplyRotateTransform(currentSelectedElement, -45); + LogHelper.WriteLogToFile($"图片左旋转完成"); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"图片左旋转失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + // 图片右旋转 + private void BorderImageRotateRight_MouseUp(object sender, MouseButtonEventArgs e) + { + try + { + if (currentSelectedElement != null) + { + ApplyRotateTransform(currentSelectedElement, 45); + LogHelper.WriteLogToFile($"图片右旋转完成"); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"图片右旋转失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + // 图片缩放减小 + private void GridImageScaleDecrease_MouseUp(object sender, MouseButtonEventArgs e) + { + try + { + if (currentSelectedElement != null) + { + var elementCenter = new Point(currentSelectedElement.ActualWidth / 2, currentSelectedElement.ActualHeight / 2); + ApplyScaleTransform(currentSelectedElement, 0.9, elementCenter); + LogHelper.WriteLogToFile($"图片缩放减小完成"); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"图片缩放减小失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + // 图片缩放增大 + private void GridImageScaleIncrease_MouseUp(object sender, MouseButtonEventArgs e) + { + try + { + if (currentSelectedElement != null) + { + var elementCenter = new Point(currentSelectedElement.ActualWidth / 2, currentSelectedElement.ActualHeight / 2); + ApplyScaleTransform(currentSelectedElement, 1.1, elementCenter); + LogHelper.WriteLogToFile($"图片缩放增大完成"); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"图片缩放增大失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + // 图片删除 + private void BorderImageDelete_MouseUp(object sender, MouseButtonEventArgs e) + { + try + { + if (currentSelectedElement != null) + { + // 记录删除历史 + timeMachine.CommitElementRemoveHistory(currentSelectedElement); + + // 从画布中移除 + inkCanvas.Children.Remove(currentSelectedElement); + + // 清除选中状态 + UnselectElement(currentSelectedElement); + currentSelectedElement = null; + + LogHelper.WriteLogToFile($"图片删除完成"); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"图片删除失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + // 克隆图片的辅助方法 + private Image CreateClonedImage(Image originalImage) + { + try + { + Image clonedImage = new Image(); + + // 复制图片源 + if (originalImage.Source is BitmapSource bitmapSource) + { + clonedImage.Source = bitmapSource; + } + + // 复制属性 + clonedImage.Width = originalImage.Width; + clonedImage.Height = originalImage.Height; + clonedImage.Stretch = originalImage.Stretch; + clonedImage.StretchDirection = originalImage.StretchDirection; + + // 复制位置 + double left = InkCanvas.GetLeft(originalImage); + double top = InkCanvas.GetTop(originalImage); + InkCanvas.SetLeft(clonedImage, left + 20); // 稍微偏移位置 + InkCanvas.SetTop(clonedImage, top + 20); + + // 复制变换 + if (originalImage.RenderTransform is TransformGroup originalTransformGroup) + { + clonedImage.RenderTransform = originalTransformGroup.Clone(); + } + + // 设置名称 + string timestamp = "img_" + DateTime.Now.ToString("yyyyMMdd_HH_mm_ss_fff"); + clonedImage.Name = timestamp; + + return clonedImage; + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"克隆图片失败: {ex.Message}", LogHelper.LogType.Error); + return null; + } + } + + #endregion } }