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

125 lines
4.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
namespace AIStudio.Wpf.DiagramDesigner.Controls
{
public class RotateThumb : Thumb
{
private Point centerPoint;
private Vector startVector;
private double initialAngle;
private Canvas designerCanvas;
private DesignerItemViewModelBase designerItem;
public RotateThumb()
{
DragDelta += RotateThumb_DragDelta;
DragStarted += RotateThumb_DragStarted;
DragCompleted += RotateThumb_DragCompleted;
}
public IDiagramViewModel DiagramViewModel
{
get
{
return (this.DataContext as SelectableDesignerItemViewModelBase)?.Root;
}
}
private List<SelectableDesignerItemViewModelBase> designerItems;
private void RotateThumb_DragStarted(object sender, DragStartedEventArgs e)
{
this.designerItem = this.DataContext as DesignerItemViewModelBase;
if (this.designerItem != null)
{
designerItems = designerItem.Root.SelectedItems.ToList();
DiagramViewModel.DoCommandManager.BeginDo = true;
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
{
item.SetOldValue(this.designerItem.Angle, nameof(this.designerItem.Angle));
}
this.designerCanvas = GetDesignerCanvas(this);
if (this.designerCanvas != null)
{
this.centerPoint =
new Point(this.designerItem.Left + this.designerItem.ItemWidth * 0.5,
this.designerItem.Top + this.designerItem.ItemHeight * 0.5);
Point startPoint = Mouse.GetPosition(this.designerCanvas);
this.startVector = Point.Subtract(startPoint, this.centerPoint);
this.initialAngle = this.designerItem.Angle;
}
e.Handled = true;
}
else
{
designerItems = null;
}
}
private void RotateThumb_DragCompleted(object sender, DragCompletedEventArgs e)
{
this.designerItem = this.DataContext as DesignerItemViewModelBase;
if (this.designerItems != null)
{
Dictionary<DesignerItemViewModelBase, Tuple<double, double>> infos =
designerItems.OfType<DesignerItemViewModelBase>().ToDictionary(p => p,
p => new Tuple<double, double>(p.GetOldValue<double>(nameof(p.Angle)), p.Angle));
DiagramViewModel.DoCommandManager.BeginDo = false;
DiagramViewModel.DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var info in infos)
{
info.Key.Angle = info.Value.Item2;
}
},
() => {
foreach (var info in infos)
{
info.Key.Angle = info.Value.Item1;
}
});
e.Handled = true;
}
}
private void RotateThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
if (this.designerItems != null && this.designerCanvas != null)
{
Point currentPoint = Mouse.GetPosition(this.designerCanvas);
Vector deltaVector = Point.Subtract(currentPoint, this.centerPoint);
double angle = Vector.AngleBetween(this.startVector, deltaVector);
foreach (DesignerItemViewModelBase item in designerItems.OfType<DesignerItemViewModelBase>())
{
item.Angle = this.initialAngle + Math.Round(angle, 0);
}
e.Handled = true;
}
}
private DesignerCanvas GetDesignerCanvas(DependencyObject element)
{
while (element != null && !(element is DesignerCanvas))
element = VisualTreeHelper.GetParent(element);
return element as DesignerCanvas;
}
}
}