From c901c9c09676a44e83e5133c12771d6a6d37d067 Mon Sep 17 00:00:00 2001
From: zengwenjie <1663900244@qq.com>
Date: Thu, 25 Sep 2025 14:52:08 +0800
Subject: [PATCH] =?UTF-8?q?=E7=BC=96=E5=86=99VisualHelper?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
 .../Contract/Enums/DropPlacement.cs           |  15 +-
 .../Contract/Enums/LayoutDirection.cs         |  32 ++++
 .../{IDeedyInput.cs => IVisualInput.cs}       |   2 +-
 .../{IDeedyLayout.cs => IVisualLayout.cs}     |   4 +-
 .../{IDeedyViewer.cs => IVisualViewer.cs}     |   2 +-
 .../{DeedyLayout.cs => VisualLayout.cs}       |   6 +-
 .../Deedy.Activity/Helpers/VisualHelper.cs    | 141 ++++++++++++++++++
 .../Deedy.Activity/IVisualElement.cs          |   1 +
 8 files changed, 192 insertions(+), 11 deletions(-)
 create mode 100644 DeedyDesigner/Deedy.Activity/Contract/Enums/LayoutDirection.cs
 rename DeedyDesigner/Deedy.Activity/DeedyVisual/{IDeedyInput.cs => IVisualInput.cs} (82%)
 rename DeedyDesigner/Deedy.Activity/DeedyVisual/{IDeedyLayout.cs => IVisualLayout.cs} (60%)
 rename DeedyDesigner/Deedy.Activity/DeedyVisual/{IDeedyViewer.cs => IVisualViewer.cs} (83%)
 rename DeedyDesigner/Deedy.Activity/DeedyVisual/{DeedyLayout.cs => VisualLayout.cs} (96%)
diff --git a/DeedyDesigner/Deedy.Activity/Contract/Enums/DropPlacement.cs b/DeedyDesigner/Deedy.Activity/Contract/Enums/DropPlacement.cs
index 4f0bd65..aa900c9 100644
--- a/DeedyDesigner/Deedy.Activity/Contract/Enums/DropPlacement.cs
+++ b/DeedyDesigner/Deedy.Activity/Contract/Enums/DropPlacement.cs
@@ -11,25 +11,30 @@ namespace Deedy.Activity
     /// 
     public enum DropPlacement : int
     {
+        UnDragged = 0,
         /// 
         /// 不确定的
         /// 
-        Uncertain=0,
+        Uncertain = 1,
         /// 
         /// 拒绝放置
         /// 
-        Rejected = 0,
+        Rejected = 2,
         /// 
         /// 在节点前
         /// 
-        BeforeMe = 1,
+        BeforeMe = 3,
         /// 
         /// 在节点内
         /// 
-        WithinMe = 2,
+        WithinMe = 4,
         /// 
         /// 在节点后
         /// 
-        BehindMe = 3,
+        BehindMe = 5,
+        /// 
+        /// 替换自身
+        /// 
+        ReplaceMe = 6,
     }
 }
diff --git a/DeedyDesigner/Deedy.Activity/Contract/Enums/LayoutDirection.cs b/DeedyDesigner/Deedy.Activity/Contract/Enums/LayoutDirection.cs
new file mode 100644
index 0000000..ff83439
--- /dev/null
+++ b/DeedyDesigner/Deedy.Activity/Contract/Enums/LayoutDirection.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Deedy.Activity
+{
+    public enum LayoutDirection
+    {
+        /// 
+        /// 不可布局
+        /// 
+        Cannot,
+        /// 
+        /// 只有唯一子节点
+        /// 
+        Decorator,
+        /// 
+        /// 上下叠放
+        /// 
+        Stacked,
+        /// 
+        /// 从左向右
+        /// 
+        Horizontal,
+        /// 
+        /// 从上到下
+        /// 
+        Vertical,
+    }
+}
diff --git a/DeedyDesigner/Deedy.Activity/DeedyVisual/IDeedyInput.cs b/DeedyDesigner/Deedy.Activity/DeedyVisual/IVisualInput.cs
similarity index 82%
rename from DeedyDesigner/Deedy.Activity/DeedyVisual/IDeedyInput.cs
rename to DeedyDesigner/Deedy.Activity/DeedyVisual/IVisualInput.cs
index a200261..4e1d9a2 100644
--- a/DeedyDesigner/Deedy.Activity/DeedyVisual/IDeedyInput.cs
+++ b/DeedyDesigner/Deedy.Activity/DeedyVisual/IVisualInput.cs
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
 
 namespace Deedy.Activity
 {
-    public interface IDeedyInput
+    public interface IVisualInput
     {
     }
 }
diff --git a/DeedyDesigner/Deedy.Activity/DeedyVisual/IDeedyLayout.cs b/DeedyDesigner/Deedy.Activity/DeedyVisual/IVisualLayout.cs
similarity index 60%
rename from DeedyDesigner/Deedy.Activity/DeedyVisual/IDeedyLayout.cs
rename to DeedyDesigner/Deedy.Activity/DeedyVisual/IVisualLayout.cs
index 5d0911c..cb84d8b 100644
--- a/DeedyDesigner/Deedy.Activity/DeedyVisual/IDeedyLayout.cs
+++ b/DeedyDesigner/Deedy.Activity/DeedyVisual/IVisualLayout.cs
@@ -6,8 +6,8 @@ using System.Threading.Tasks;
 
 namespace Deedy.Activity
 {
-    public interface IDeedyLayout : IContainerElement
+    public interface IVisualLayout : IContainerElement
     {
-        
+        LayoutDirection LayoutDirection { get; }
     }
 }
diff --git a/DeedyDesigner/Deedy.Activity/DeedyVisual/IDeedyViewer.cs b/DeedyDesigner/Deedy.Activity/DeedyVisual/IVisualViewer.cs
similarity index 83%
rename from DeedyDesigner/Deedy.Activity/DeedyVisual/IDeedyViewer.cs
rename to DeedyDesigner/Deedy.Activity/DeedyVisual/IVisualViewer.cs
index dd0379c..3a1074e 100644
--- a/DeedyDesigner/Deedy.Activity/DeedyVisual/IDeedyViewer.cs
+++ b/DeedyDesigner/Deedy.Activity/DeedyVisual/IVisualViewer.cs
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
 
 namespace Deedy.Activity
 {
-    public class IDeedyViewer
+    public class IVisualViewer
     {
     }
 }
diff --git a/DeedyDesigner/Deedy.Activity/DeedyVisual/DeedyLayout.cs b/DeedyDesigner/Deedy.Activity/DeedyVisual/VisualLayout.cs
similarity index 96%
rename from DeedyDesigner/Deedy.Activity/DeedyVisual/DeedyLayout.cs
rename to DeedyDesigner/Deedy.Activity/DeedyVisual/VisualLayout.cs
index 821e159..155cc57 100644
--- a/DeedyDesigner/Deedy.Activity/DeedyVisual/DeedyLayout.cs
+++ b/DeedyDesigner/Deedy.Activity/DeedyVisual/VisualLayout.cs
@@ -10,10 +10,10 @@ using System.Windows;
 
 namespace Deedy.Activity
 {
-    public class DeedyLayout : IDeedyLayout
+    public class VisualLayout : IVisualLayout
     {
         public ExpandoMapping ExpandoMapping { get; set; } = new ExpandoMapping();
-        public DeedyLayout() { }
+        public VisualLayout() { }
         public string Class { get; protected internal set; } = "";
         public string Title { get; set; } = "";
         public string Remark { get; set; } = "";
@@ -29,6 +29,8 @@ namespace Deedy.Activity
 
         public ParamDefineCollection ParamsMapping { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
 
+        public LayoutDirection LayoutDirection => throw new NotImplementedException();
+
         public event PropertyChangedEventHandler? PropertyChanged;
 
         /// 
diff --git a/DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs b/DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs
index 625f3cd..1b7fa78 100644
--- a/DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs
+++ b/DeedyDesigner/Deedy.Activity/Helpers/VisualHelper.cs
@@ -3,10 +3,151 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using System.Windows.Media;
+using System.Windows;
 
 namespace Deedy.Activity.Helpers
 {
+    /// 
+    /// 辅助可视化单元进行相关操作
+    /// 
     public static partial class Helper
     {
+        /// 
+        /// 辅助可视化单元进行拖放装饰器绘制操作
+        /// 
+        /// 要绘制的「UIElement」元素
+        /// 「UIElement」元素的绘图上下文
+        /// 拖放操作的放置位置
+        /// 父级布局的布局方向
+        public static void Help_DrawDropAdorner(this UIElement ui, DrawingContext dc, DropPlacement dropPlacement, LayoutDirection parentLayout)
+        {
+            if (ui == null || dc == null || dropPlacement == DropPlacement.UnDragged) return;
+            Pen pen = new Pen(Brushes.Red, 3);
+            pen.Freeze();
+
+            switch (dropPlacement)
+            {
+                case DropPlacement.Rejected:
+                    {
+                        
+                    }
+                    break;
+                case DropPlacement.Uncertain:
+                    {
+                        
+                    }
+                    break;
+                case DropPlacement.BeforeMe:
+                    {
+                        if (parentLayout == LayoutDirection.Horizontal)
+                        {
+                        }
+                        else if (parentLayout == LayoutDirection.Vertical)
+                        {
+                        }
+                        else if (parentLayout == LayoutDirection.Stacked)
+                        {
+                        }
+                        else { }
+                    }
+                    break;
+                case DropPlacement.BehindMe:
+                    {
+                        if (parentLayout == LayoutDirection.Horizontal)
+                        {
+                        }
+                        else if (parentLayout == LayoutDirection.Vertical)
+                        {
+                        }
+                        else if (parentLayout == LayoutDirection.Stacked)
+                        {
+                        }
+                        else { }
+                    }
+                    break;
+                case DropPlacement.WithinMe:
+                    {
+                    }
+                    break;
+                case DropPlacement.ReplaceMe:
+                    {
+                    }
+                    break;
+                default: break;                 //DropPlacement.UnDragged;不需要绘制任何图样
+            }
+        }
+        /// 
+        /// 检查拖放操作的模式
+        /// 
+        /// 要检查的「UIElement」元素
+        /// 检查点位置
+        /// 检查后的拖放位置;其中不包括「DropPlacement.UnDragged」与「DropPlacement.Uncertain」
+        /// 
+        /// 「DropPlacement.UnDragged」= 未在拖放状态
+        /// 「DropPlacement.Uncertain」= 拖放内容不是可视化元素
+        /// ··以上两种情况需要在调用此方法前进行判定
+        /// 
+        public static DropPlacement Help_CheckDropPlacement(this UIElement ui, Point point)
+        {
+            DropPlacement result = DropPlacement.UnDragged;
+            if (ui != null)
+            {
+                Size size = ui.RenderSize;
+                double horRuler = size.Width / 3;
+                if (horRuler > 20) horRuler = 20;
+                double verRuler = size.Height / 3;
+                if (verRuler > 20) verRuler = 20;
+                LayoutDirection direction = LayoutDirection.Cannot;
+                if (ui is IVisualLayout layout)
+                {
+                    if (ui is FrameworkElement fe && fe.Parent is IVisualLayout parentLayout)
+                    {
+                        direction = parentLayout.LayoutDirection;
+                        if (direction == LayoutDirection.Decorator)
+                        {
+                            if (point.X < horRuler
+                                || point.Y < verRuler
+                                || size.Width - point.X < horRuler
+                                || size.Height - point.Y < verRuler)
+                                result = DropPlacement.ReplaceMe;
+                            else result = DropPlacement.WithinMe;
+                        }
+                        else if (direction == LayoutDirection.Cannot)
+                            result = DropPlacement.WithinMe;
+                        else
+                        {
+                            if (point.X < horRuler || point.Y < verRuler)
+                                result = DropPlacement.BeforeMe;
+                            else if (size.Width - point.X < horRuler || size.Height - point.Y < verRuler)
+                                result = DropPlacement.BehindMe;
+                            else result = DropPlacement.WithinMe;
+                        }
+                    }
+                    else result = DropPlacement.WithinMe;
+                }
+                else
+                {
+                    if (ui is FrameworkElement fe && fe.Parent is IVisualLayout parentLayout)
+                    {
+                        direction = parentLayout.LayoutDirection;
+                        if (direction == LayoutDirection.Decorator)
+                            result = DropPlacement.ReplaceMe;
+                        else if (direction == LayoutDirection.Cannot)
+                            result = DropPlacement.Rejected;
+                        else
+                        {
+                            if (point.X < horRuler || point.Y < verRuler)
+                                result = DropPlacement.BeforeMe;
+                            else if (size.Width - point.X < horRuler || size.Height - point.Y < verRuler)
+                                result = DropPlacement.BehindMe;
+                            else result = DropPlacement.Rejected;
+                        }
+                    }
+                    else result = DropPlacement.Rejected;
+                }
+            }
+            return result;
+        }
     }
 }
diff --git a/DeedyDesigner/Deedy.Activity/IVisualElement.cs b/DeedyDesigner/Deedy.Activity/IVisualElement.cs
index da79d96..7a10490 100644
--- a/DeedyDesigner/Deedy.Activity/IVisualElement.cs
+++ b/DeedyDesigner/Deedy.Activity/IVisualElement.cs
@@ -8,5 +8,6 @@ namespace Deedy.Activity
 {
     public interface IVisualElement : IElement
     {
+        DropPlacement DropPlacement { get; }
     }
 }