Files
艾竹 d2e00c6149 block
2023-06-27 22:57:08 +08:00

221 lines
7.4 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner.Helpers;
namespace AIStudio.Wpf.DiagramDesigner
{
public class BlockItemsContainer : ContentControl
{
static BlockItemsContainer()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(BlockItemsContainer), new FrameworkPropertyMetadata(typeof(BlockItemsContainer)));
}
public static readonly DependencyProperty BorderProperty = DependencyProperty.Register(
nameof(Border), typeof(object), typeof(BlockItemsContainer), new PropertyMetadata(default(object)));
public object Border
{
get => GetValue(BorderProperty);
set => SetValue(BorderProperty, value);
}
public static readonly DependencyProperty BorderTemplateProperty = DependencyProperty.Register(
nameof(BorderTemplate), typeof(DataTemplate), typeof(BlockItemsContainer), new PropertyMetadata(default(DataTemplate)));
[Bindable(true), Category("Content")]
public DataTemplate BorderTemplate
{
get => (DataTemplate)GetValue(BorderTemplateProperty);
set => SetValue(BorderTemplateProperty, value);
}
public static readonly DependencyProperty BorderTemplateSelectorProperty = DependencyProperty.Register(
nameof(BorderTemplateSelector), typeof(DataTemplateSelector), typeof(BlockItemsContainer), new PropertyMetadata(default(DataTemplateSelector)));
[Bindable(true), Category("Content")]
public DataTemplateSelector BorderTemplateSelector
{
get => (DataTemplateSelector)GetValue(BorderTemplateSelectorProperty);
set => SetValue(BorderTemplateSelectorProperty, value);
}
public static readonly DependencyProperty BorderStringFormatProperty = DependencyProperty.Register(
nameof(BorderStringFormat), typeof(string), typeof(BlockItemsContainer), new PropertyMetadata(default(string)));
[Bindable(true), Category("Content")]
public string BorderStringFormat
{
get => (string)GetValue(BorderStringFormatProperty);
set => SetValue(BorderStringFormatProperty, value);
}
public static readonly DependencyProperty ParentPanelProperty =
DependencyProperty.Register(nameof(ParentPanel), typeof(FrameworkElement), typeof(BlockItemsContainer),
new FrameworkPropertyMetadata(null));
public FrameworkElement ParentPanel
{
get
{
return (FrameworkElement)GetValue(ParentPanelProperty);
}
set
{
SetValue(ParentPanelProperty, value);
}
}
public static readonly DependencyProperty GetOffSetFuncProperty =
DependencyProperty.Register(nameof(GetOffSetFunc),
typeof(Func<Point>),
typeof(BlockItemsContainer),
new FrameworkPropertyMetadata(null));
public Func<Point> GetOffSetFunc
{
get
{
return (Func<Point>)this.GetValue(GetOffSetFuncProperty);
}
set
{
this.SetValue(GetOffSetFuncProperty, value);
}
}
public Func<Point> GetOffSet
{
get
{
return new Func<Point>(() => this.TransformToAncestor(ParentPanel).Transform(new Point(0, 0)));
}
}
public BlockItemsContainerInfo Info
{
get
{
if (Border is BlockItemsContainerInfo itemsContainerInfo)
return itemsContainerInfo;
return this.DataContext as BlockItemsContainerInfo;
}
}
public BlockDesignerItemViewModel DragObject
{
get; private set;
}
public Point DragOffset
{
get; private set;
}
public Point? FirstPoint
{
get; private set;
}
public BlockItemsContainer()
{
}
public static List<BlockItemsContainer> Containers = new List<BlockItemsContainer>();
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
GetOffSetFunc = GetOffSet;
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
FirstPoint = e.GetPosition(this);
Containers.Add(this);
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (FirstPoint != null)
{
var currentPoint = e.GetPosition(this);
if (Math.Sqrt(Math.Pow(FirstPoint.Value.X - currentPoint.X, 2) + Math.Pow(FirstPoint.Value.Y - currentPoint.Y, 2)) > 5)
{
FirstPoint = null;
if (Info?.Children.Count > 0)
{
var borders = VisualHelper.FindVisualChildren<BlockGrid>(this);
foreach (var border in borders)
{
var itemsContainers = VisualHelper.TryFindParent<BlockItemsContainer>(border);
if (this != itemsContainers)
{
continue;
}
var point = border.TransformToAncestor(this).Transform(new Point(0, 0));
var rect = new Rect(point.X, point.Y, border.ActualWidth, border.ActualHeight);
if (rect.Contains(currentPoint))
{
DragObject = border.DataContext as BlockDesignerItemViewModel;
DragOffset = new Point(currentPoint.X - point.X, currentPoint.Y - point.Y);
break;
}
}
if (DragObject != null)
{
Containers.ForEach(p => p.FirstPoint = null);
DesignerCanvas canvas = GetDesignerCanvas(this);
if (canvas != null)
{
canvas.SourceItemsContainer = this;
e.Handled = true;
}
}
}
}
}
}
protected override void OnMouseUp(MouseButtonEventArgs e)
{
base.OnMouseUp(e);
FirstPoint = null;
Containers.Clear();
}
public ConnectorOrientation Orientation
{
get; set;
}
// iterate through visual tree to get parent DesignerCanvas
private DesignerCanvas GetDesignerCanvas(DependencyObject element)
{
while (element != null && !(element is DesignerCanvas))
element = VisualTreeHelper.GetParent(element);
return element as DesignerCanvas;
}
}
}