Files
aistudio-wpf-diagram/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs
2023-03-28 23:16:56 +08:00

136 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner.Controls
{
public class DragThumb : Thumb
{
public DragThumb()
{
base.DragDelta += new DragDeltaEventHandler(DragThumb_DragDelta);
base.DragStarted += DragThumb_DragStarted;
base.DragCompleted += DragThumb_DragCompleted;
}
public IDiagramViewModel DiagramViewModel
{
get
{
return (this.DataContext as SelectableDesignerItemViewModelBase)?.Root;
}
}
private List<SelectableDesignerItemViewModelBase> designerItems;
private bool drag;
private void DragThumb_DragStarted(object sender, DragStartedEventArgs e)
{
GetDesignerCanvas(this)?.Focus();
drag = false;
SelectableDesignerItemViewModelBase designerItem = this.DataContext as SelectableDesignerItemViewModelBase;
if (designerItem != null && designerItem.IsSelected)
{
// we only move DesignerItems
designerItems = designerItem.Root.SelectedItems.ToList();
if (designerItem is IGroupable groupable)
{
designerItems.AddRange(designerItem.Root.SelectionService.GetGroupMembers(groupable).OfType<SelectableDesignerItemViewModelBase>());
}
if (designerItem is ConnectionViewModel connector)
{
designerItems.Add(connector.SourceConnectorInfo.DataItem);
if (connector.IsFullConnection)
{
designerItems.Add(connector.SinkConnectorInfoFully.DataItem);
}
}
if (designerItem is PointDesignerItemViewModel)
{
designerItems = new List<SelectableDesignerItemViewModelBase> { designerItem };
}
designerItems = designerItems.Distinct().ToList();
DiagramViewModel.DoCommandManager.BeginDo = true;
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
{
item.SetOldValue(item.TopLeft, nameof(item.TopLeft));
}
e.Handled = true;
}
else
{
designerItems = null;
}
}
private void DragThumb_DragCompleted(object sender, DragCompletedEventArgs e)
{
if (drag == false)
{
DiagramViewModel.DoCommandManager.BeginDo = false;
return;
}
if (designerItems != null)
{
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
{
item.SetCellAlignment();
}
Dictionary<DesignerItemViewModelBase, Tuple<PointBase, PointBase>> infos =
designerItems.OfType<DesignerItemViewModelBase>().ToDictionary(p => p,
p => new Tuple<PointBase, PointBase>(p.GetOldValue<PointBase>(nameof(p.TopLeft)), p.TopLeft));
DiagramViewModel.DoCommandManager.BeginDo = false;
DiagramViewModel.DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var info in infos)
{
info.Key.TopLeft = info.Value.Item2;
}
},
() => {
foreach (var info in infos)
{
info.Key.TopLeft = info.Value.Item1;
}
});
e.Handled = true;
}
}
void DragThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
drag = true;
if (designerItems != null)
{
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
{
item.Left += e.HorizontalChange;
item.Top += e.VerticalChange;
}
e.Handled = true;
}
}
private DesignerCanvas GetDesignerCanvas(DependencyObject element)
{
while (element != null && !(element is DesignerCanvas))
element = VisualTreeHelper.GetParent(element);
return element as DesignerCanvas;
}
}
}