2023-06-11 23:58:22 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.ComponentModel;
|
2023-06-15 22:44:12 +08:00
|
|
|
|
using System.Linq;
|
2023-06-11 23:58:22 +08:00
|
|
|
|
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 ItemsContainer : ContentControl
|
|
|
|
|
|
{
|
|
|
|
|
|
static ItemsContainer()
|
|
|
|
|
|
{
|
|
|
|
|
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(ItemsContainer), new FrameworkPropertyMetadata(typeof(ItemsContainer)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static readonly DependencyProperty BorderProperty = DependencyProperty.Register(
|
|
|
|
|
|
nameof(Border), typeof(object), typeof(ItemsContainer), 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(ItemsContainer), 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(ItemsContainer), 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(ItemsContainer), 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(ItemsContainer),
|
|
|
|
|
|
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(ItemsContainer),
|
|
|
|
|
|
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 ItemsContainerInfo Info
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Border is ItemsContainerInfo itemsContainerInfo)
|
|
|
|
|
|
return itemsContainerInfo;
|
|
|
|
|
|
|
|
|
|
|
|
return this.DataContext as ItemsContainerInfo;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public BlockDesignerItemViewModel DragObject
|
|
|
|
|
|
{
|
|
|
|
|
|
get; private set;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Point DragOffset
|
|
|
|
|
|
{
|
|
|
|
|
|
get; private set;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ItemsContainer()
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void OnApplyTemplate()
|
|
|
|
|
|
{
|
|
|
|
|
|
base.OnApplyTemplate();
|
|
|
|
|
|
|
|
|
|
|
|
GetOffSetFunc = GetOffSet;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Point? firstPoint;
|
|
|
|
|
|
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
base.OnMouseLeftButtonDown(e);
|
|
|
|
|
|
firstPoint = e.GetPosition(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)
|
|
|
|
|
|
{
|
2023-06-15 22:44:12 +08:00
|
|
|
|
firstPoint = null;
|
2023-06-11 23:58:22 +08:00
|
|
|
|
if (Info?.Children?.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
var borders = VisualHelper.FindVisualChildren<BlockBorder>(this);
|
2023-06-15 22:44:12 +08:00
|
|
|
|
BlockBorder innerblock = null;
|
|
|
|
|
|
BlockDesignerItemViewModel dragObject = null;
|
|
|
|
|
|
Point dragOffset = new Point();
|
2023-06-11 23:58:22 +08:00
|
|
|
|
foreach (var border in borders)
|
|
|
|
|
|
{
|
2023-06-15 22:44:12 +08:00
|
|
|
|
var itemsContainer = VisualHelper.TryFindParent<ItemsContainer>(border);
|
|
|
|
|
|
if (this != itemsContainer)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-06-11 23:58:22 +08:00
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
DesignerCanvas canvas = GetDesignerCanvas(this);
|
|
|
|
|
|
if (canvas != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
canvas.SourceItemsContainer = this;
|
2023-06-15 22:44:12 +08:00
|
|
|
|
e.Handled = true;
|
2023-06-11 23:58:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
protected override void OnMouseUp(MouseButtonEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
base.OnMouseUp(e);
|
|
|
|
|
|
|
|
|
|
|
|
firstPoint = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|