You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
3.9 KiB
150 lines
3.9 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using System.Text; |
|
using System.Windows; |
|
using System.Windows.Input; |
|
using SharpDevelop.XamlDesigner.Extensibility; |
|
using SharpDevelop.XamlDesigner.Extensibility.Attributes; |
|
using SharpDevelop.XamlDesigner.Dom; |
|
|
|
namespace SharpDevelop.XamlDesigner.Placement |
|
{ |
|
class MoveOperation |
|
{ |
|
public PlacementContainer PrimaryContainer; |
|
public PreviewContainer SecondaryContainer; |
|
public PlacementInfo[] PlacementInfos; |
|
public bool Copy; |
|
public Point StartPoint; |
|
public Point EndPoint; |
|
public DesignView DesignView; |
|
|
|
public MoveOperation(DesignItem newItem, Point startPoint) |
|
{ |
|
DesignView = newItem.Context.DesignView; |
|
StartPoint = DesignView.TransformScrolledToZoomed.Transform(startPoint); |
|
|
|
newItem.View.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); |
|
var size = newItem.View.DesiredSize; |
|
var p = new Point(StartPoint.X - size.Width / 2, StartPoint.Y - size.Height / 2); |
|
|
|
this.PlacementInfos = new PlacementInfo() { |
|
Item = newItem, |
|
OriginalBounds = new Rect(p, size) |
|
}.AsArray(); |
|
|
|
PrimaryContainer = DesignView.SeparatedContainer; |
|
PrimaryContainer.Enter(this); |
|
|
|
Begin(); |
|
} |
|
|
|
public MoveOperation(IEnumerable<DesignItem> items, Point startPoint) |
|
{ |
|
this.PlacementInfos = items.Select(t => new PlacementInfo() { |
|
Item = t, |
|
OriginalBounds = t.GetLayoutSlot() |
|
}).ToArray(); |
|
|
|
this.StartPoint = startPoint; |
|
this.DesignView = items.First().Context.DesignView; |
|
|
|
Begin(); |
|
} |
|
|
|
public IEnumerable<DesignItem> Items |
|
{ |
|
get { return PlacementInfos.Select(f => f.Item); } |
|
} |
|
|
|
public void MoveTo(Point endPoint) |
|
{ |
|
this.EndPoint = DesignView.TransformScrolledToZoomed.Transform(endPoint); |
|
|
|
DesignItem newParent = null; |
|
DesignItem currentParent = PrimaryContainer == null ? null : PrimaryContainer.ContainerItem; |
|
|
|
foreach (var hit in DesignView.HitTest(endPoint).Except(Items)) { |
|
if (hit == currentParent || hit.CanAdd(Items, Copy)) { |
|
newParent = hit; |
|
break; |
|
} |
|
} |
|
|
|
PlacementContainer newContainer = null; |
|
if (newParent == null) { |
|
newContainer = DesignView.SeparatedContainer; |
|
} |
|
else { |
|
newContainer = PlacementContainer.GetContainer(newParent); |
|
if (newContainer == null) { |
|
var containerType = MetadataStore.GetAttributes<ContainerTypeAttribute>(newParent.Type).First().ContainerType; |
|
newContainer = Activator.CreateInstance(containerType) as PlacementContainer; |
|
PlacementContainer.SetContainer(newParent, newContainer); |
|
} |
|
} |
|
|
|
var newPositionalContainer = newContainer as PositionalContainer; |
|
|
|
if (newPositionalContainer != null) { |
|
if (newPositionalContainer != PrimaryContainer) { |
|
newPositionalContainer.BeforeLeavePreviousContainer(this); |
|
PrimaryContainer.Leave(this); |
|
PrimaryContainer = newPositionalContainer; |
|
PrimaryContainer.Enter(this); |
|
} |
|
} |
|
|
|
if (newContainer != SecondaryContainer) { |
|
if (SecondaryContainer != null) { |
|
SecondaryContainer.Leave(this); |
|
} |
|
SecondaryContainer = newContainer as PreviewContainer; |
|
if (SecondaryContainer != null) { |
|
SecondaryContainer.Enter(this); |
|
} |
|
} |
|
|
|
var delta = EndPoint - StartPoint; |
|
var transformToContainer = PrimaryContainer.TransformToContainer(); |
|
|
|
foreach (var info in PlacementInfos) { |
|
var newBounds = info.OriginalBounds; |
|
newBounds.Offset(delta); |
|
info.NewBoundsInContainer = transformToContainer.TransformBounds(newBounds); |
|
} |
|
|
|
PrimaryContainer.OnMove(this); |
|
|
|
if (SecondaryContainer != null) { |
|
SecondaryContainer.OnMove(this); |
|
} |
|
} |
|
|
|
public void Abort() |
|
{ |
|
End(); |
|
} |
|
|
|
public void Commit() |
|
{ |
|
End(); |
|
} |
|
|
|
void Begin() |
|
{ |
|
this.DesignView.Context.AdornerManager.OnBeginMove(Items); |
|
this.Copy = Keyboard.IsKeyDown(Key.LeftCtrl); |
|
} |
|
|
|
void End() |
|
{ |
|
PrimaryContainer.Leave(this); |
|
if (SecondaryContainer != null) { |
|
SecondaryContainer.Leave(this); |
|
} |
|
DesignView.Context.AdornerManager.OnEndMove(Items); |
|
} |
|
} |
|
}
|
|
|