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.
794 lines
29 KiB
794 lines
29 KiB
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team |
|
// |
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this |
|
// software and associated documentation files (the "Software"), to deal in the Software |
|
// without restriction, including without limitation the rights to use, copy, modify, merge, |
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons |
|
// to whom the Software is furnished to do so, subject to the following conditions: |
|
// |
|
// The above copyright notice and this permission notice shall be included in all copies or |
|
// substantial portions of the Software. |
|
// |
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE |
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|
// DEALINGS IN THE SOFTWARE. |
|
|
|
using System; |
|
using System.Windows.Markup; |
|
using ICSharpCode.WpfDesign.Extensions; |
|
using ICSharpCode.WpfDesign.Adorners; |
|
using ICSharpCode.WpfDesign.Designer.Controls; |
|
using System.Windows.Input; |
|
using System.Windows.Media; |
|
using System.Windows.Shapes; |
|
using System.Windows; |
|
using System.Windows.Controls; |
|
using System.Collections.Generic; |
|
using System.Diagnostics; |
|
using System.Linq; |
|
using ICSharpCode.WpfDesign.UIExtensions; |
|
using DragListener = ICSharpCode.WpfDesign.Designer.Controls.DragListener; |
|
using System.Windows.Data; |
|
using System.ComponentModel; |
|
using System.Globalization; |
|
|
|
namespace ICSharpCode.WpfDesign.Designer.Extensions |
|
{ |
|
/// <summary> |
|
/// Description of PathHandlerExtension. |
|
/// </summary> |
|
[ExtensionFor(typeof(Path))] |
|
internal class PathHandlerExtension : LineExtensionBase, IKeyDown, IKeyUp |
|
{ |
|
enum PathPartConvertType |
|
{ |
|
insertPoint, |
|
ToLineSegment, |
|
ToBezierSegment, |
|
ToQuadricBezierSegment, |
|
ToArcSegment, |
|
} |
|
|
|
//A modifieable Point on the Path |
|
protected class PathPoint : INotifyPropertyChanged |
|
{ |
|
public PathPoint(Point point, Object @object, Object parentObject, Action<Point> setLambda, Action save, Shape shape) |
|
{ |
|
this._point = point; |
|
this._setLambda = setLambda; |
|
this.Object = @object; |
|
this.ParentObject = parentObject; |
|
this._shape = shape; |
|
this._save = save; |
|
} |
|
|
|
private Point _point; |
|
Action<Point> _setLambda; |
|
Action _save; |
|
Shape _shape; |
|
|
|
public void Commit() { |
|
_save(); |
|
} |
|
|
|
|
|
public Point Point |
|
{ |
|
get { return _point; } |
|
set { |
|
if (_setLambda != null) |
|
{ |
|
_point = value; |
|
_setLambda(value); |
|
if (PropertyChanged != null) |
|
{ |
|
PropertyChanged(this, new PropertyChangedEventArgs("Point")); |
|
PropertyChanged(this, new PropertyChangedEventArgs("TranslatedPoint")); |
|
} |
|
} |
|
} |
|
} |
|
|
|
public Point TranslatedPoint |
|
{ |
|
get { |
|
if (_shape.RenderedGeometry.Transform == null) |
|
return Point; |
|
return _shape.RenderedGeometry.Transform.Transform(Point); |
|
} |
|
set { |
|
if (_shape.RenderedGeometry.Transform == null) |
|
Point = value; |
|
else |
|
Point = _shape.RenderedGeometry.Transform.Inverse.Transform(value); |
|
} |
|
} |
|
|
|
public PathPoint ParentPathPoint {get; set;} |
|
|
|
public Point ReferencePoint { get; private set; } |
|
|
|
public object Object { get; private set; } |
|
|
|
public object ParentObject { get; private set; } |
|
|
|
public int PolyLineIndex { get; set; } |
|
|
|
public PathPoint TargetPathPoint { get; set; } |
|
|
|
public event PropertyChangedEventHandler PropertyChanged; |
|
} |
|
|
|
//A Thumb wich displays the Point |
|
protected class PathThumb : PointThumb |
|
{ |
|
public PathThumb(int index, PathPoint pathpoint) : base() |
|
{ |
|
this.Index = index; |
|
this.PathPoint = pathpoint; |
|
var bnd = new Binding("TranslatedPoint") { Source = this.PathPoint, Mode=BindingMode.OneWay }; |
|
this.SetBinding(PointProperty, bnd); |
|
} |
|
|
|
public int Index { get; set; } |
|
|
|
public PathPoint PathPoint { get; set; } |
|
} |
|
|
|
//A Converter for the RealtiveTo Point (on PolyLineSegment, ...) |
|
protected class RelativeToPointConverter : IValueConverter |
|
{ |
|
PathPoint pathPoint; |
|
|
|
public RelativeToPointConverter(PathPoint pathPoint) |
|
{ |
|
this.pathPoint = pathPoint; |
|
} |
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
|
{ |
|
var pt = (Point)value; |
|
return pt - new Vector(pathPoint.TranslatedPoint.X, pathPoint.TranslatedPoint.Y); |
|
} |
|
|
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
|
{ |
|
throw new NotImplementedException(); |
|
} |
|
} |
|
|
|
private readonly Dictionary<int, Bounds> _selectedThumbs = new Dictionary<int, Bounds>(); |
|
#pragma warning disable 0414 // For future use, disable Warning CS0414: The field is assigned but its value is never used |
|
private bool _isDragging; |
|
#pragma warning restore 0414 |
|
ZoomControl _zoom; |
|
|
|
private List<PathPoint> pathPoints = null; |
|
|
|
protected virtual Control[] BuildMenu(PathPoint pathpoint) |
|
{ |
|
var menuList = new List<Control>(); |
|
MenuItem menuItem = null; |
|
|
|
if (pathpoint.TargetPathPoint == null && (pathpoint.Object is LineSegment || pathpoint.Object is PolyLineSegment || pathpoint.Object is BezierSegment || pathpoint.Object is QuadraticBezierSegment || pathpoint.Object is ArcSegment)) { |
|
menuItem = new MenuItem() { Header = "insert Point", HorizontalContentAlignment = HorizontalAlignment.Left, VerticalContentAlignment = VerticalAlignment.Center }; |
|
menuItem.Click += (s, e) => ConvertPart(((DependencyObject)s).TryFindParent<PathThumb>(), PathPartConvertType.insertPoint); |
|
menuList.Add(menuItem); |
|
menuItem = new MenuItem() { Header = "to Line Segment", HorizontalContentAlignment = HorizontalAlignment.Left, VerticalContentAlignment = VerticalAlignment.Center }; |
|
menuItem.Click += (s, e) => ConvertPart(((DependencyObject)s).TryFindParent<PathThumb>(), PathPartConvertType.ToLineSegment); |
|
menuList.Add(menuItem); |
|
menuItem = new MenuItem() {Header = "to Bezier Segment", HorizontalContentAlignment = HorizontalAlignment.Left, VerticalContentAlignment = VerticalAlignment.Center }; |
|
menuItem.Click += (s, e) => ConvertPart(((DependencyObject)s).TryFindParent<PathThumb>(), PathPartConvertType.ToBezierSegment); |
|
menuList.Add(menuItem); |
|
menuItem = new MenuItem() {Header = "to Quadric Bezier Segment", HorizontalContentAlignment = HorizontalAlignment.Left, VerticalContentAlignment = VerticalAlignment.Center }; |
|
menuItem.Click += (s, e) => ConvertPart(((DependencyObject)s).TryFindParent<PathThumb>(), PathPartConvertType.ToQuadricBezierSegment); |
|
menuList.Add(menuItem); |
|
menuItem = new MenuItem() { Header = "to Arc Segment", HorizontalContentAlignment = HorizontalAlignment.Left, VerticalContentAlignment = VerticalAlignment.Center }; |
|
menuItem.Click += (s, e) => ConvertPart(((DependencyObject)s).TryFindParent<PathThumb>(), PathPartConvertType.ToArcSegment); |
|
menuList.Add(menuItem); |
|
menuList.Add(new Separator()); |
|
menuItem = new MenuItem() { Header = "is Stroked", IsChecked = ((PathSegment)pathpoint.Object).IsStroked, HorizontalContentAlignment = HorizontalAlignment.Left, VerticalContentAlignment = VerticalAlignment.Center }; |
|
menuItem.Click += (s, e) => ChangeIsStroked(((DependencyObject)s).TryFindParent<PathThumb>(), (MenuItem)s); |
|
menuList.Add(menuItem); |
|
menuItem = new MenuItem() { Header = "is Smooth Join", IsChecked = ((PathSegment)pathpoint.Object).IsSmoothJoin, HorizontalContentAlignment = HorizontalAlignment.Left, VerticalContentAlignment = VerticalAlignment.Center }; |
|
menuList.Add(menuItem); |
|
} |
|
if (pathpoint.Object is ArcSegment) { |
|
menuItem = new MenuItem() { Header = "is large Arc", IsChecked = ((ArcSegment)pathpoint.Object).IsLargeArc, HorizontalContentAlignment = HorizontalAlignment.Left, VerticalContentAlignment = VerticalAlignment.Center }; |
|
menuList.Add(menuItem); |
|
menuItem = new MenuItem() { Header = "Rotation Angle", IsChecked = true, HorizontalContentAlignment = HorizontalAlignment.Left, VerticalContentAlignment = VerticalAlignment.Center }; |
|
menuList.Add(menuItem); |
|
menuItem = new MenuItem() { Header = "Clockwise SweepDirection", IsChecked = ((ArcSegment)pathpoint.Object).SweepDirection == SweepDirection.Clockwise, HorizontalContentAlignment = HorizontalAlignment.Left, VerticalContentAlignment = VerticalAlignment.Center }; |
|
menuList.Add(menuItem); |
|
} |
|
|
|
if (pathpoint.Object is PathFigure) { |
|
menuItem = new MenuItem() { Header = "is Closed", IsChecked = ((PathFigure)pathpoint.Object).IsClosed, HorizontalContentAlignment = HorizontalAlignment.Left, VerticalContentAlignment = VerticalAlignment.Center }; |
|
menuItem.Click += (s, e) => ChangeIsClosed(((DependencyObject)s).TryFindParent<PathThumb>(), (MenuItem)s); |
|
menuList.Add(menuItem); |
|
} |
|
|
|
if (!menuList.Any()) |
|
return null; |
|
|
|
return menuList.ToArray(); |
|
} |
|
|
|
#region thumb methods |
|
protected virtual PathThumb CreateThumb(PlacementAlignment alignment, Cursor cursor, int index, PathPoint pathpoint, Transform transform) |
|
{ |
|
var designerThumb = new PathThumb(index, pathpoint) {Cursor = cursor}; |
|
designerThumb.OperationMenu = BuildMenu(pathpoint); |
|
|
|
designerThumb.InnerRenderTransform = ((Transform)transform.Inverse); |
|
|
|
if (pathpoint.TargetPathPoint != null) { |
|
designerThumb.IsEllipse = true; |
|
designerThumb.Foreground = Brushes.Blue; |
|
|
|
var bnd = new Binding("TranslatedPoint") { Source = pathpoint.TargetPathPoint, Mode = BindingMode.OneWay, Converter = new RelativeToPointConverter(pathpoint) }; |
|
designerThumb.SetBinding(PathThumb.RelativeToPointProperty, bnd); |
|
} |
|
|
|
AdornerPanel.SetPlacement(designerThumb, designerThumb.AdornerPlacement); |
|
adornerPanel.Children.Add(designerThumb); |
|
|
|
DragListener drag = new DragListener(designerThumb); |
|
drag.Transform = transform; |
|
|
|
WeakEventManager<DesignerThumb, MouseButtonEventArgs>.AddHandler(designerThumb, "PreviewMouseLeftButtonDown", ResizeThumbOnMouseLeftButtonUp); |
|
|
|
drag.MouseDown += drag_MouseDown; |
|
drag.Started += drag_Started; |
|
drag.Changed += drag_Changed; |
|
drag.Completed += drag_Completed; |
|
return designerThumb; |
|
} |
|
|
|
private void ConvertPart(PathThumb senderThumb, PathPartConvertType convertType) |
|
{ |
|
if (senderThumb.PathPoint.ParentObject is PathFigure) |
|
{ |
|
var pathFigure = senderThumb.PathPoint.ParentObject as PathFigure; |
|
var pathSegment = senderThumb.PathPoint.Object as PathSegment; |
|
|
|
var idx = pathFigure.Segments.IndexOf(pathSegment); |
|
|
|
var point = senderThumb.PathPoint.Point; |
|
|
|
if (pathSegment is PolyLineSegment) { |
|
var poly = pathSegment as PolyLineSegment; |
|
var lst = poly.Points.Take(senderThumb.PathPoint.PolyLineIndex); |
|
var lst2 = poly.Points.Skip(senderThumb.PathPoint.PolyLineIndex + 1); |
|
var p = poly.Points[senderThumb.PathPoint.PolyLineIndex]; |
|
pathFigure.Segments.RemoveAt(idx); |
|
var p1 = new PolyLineSegment(); |
|
p1.Points.AddRange(lst); |
|
pathFigure.Segments.Insert(idx, p1); |
|
pathSegment = new LineSegment() {Point = p}; |
|
pathFigure.Segments.Insert(idx+1, pathSegment); |
|
var p2 = new PolyLineSegment(); |
|
p2.Points.AddRange(lst2); |
|
pathFigure.Segments.Insert(idx+2, p2); |
|
idx++; |
|
} else if (pathSegment is PolyBezierSegment) { |
|
//TODO |
|
} else if (pathSegment is PolyQuadraticBezierSegment) { |
|
//TODO |
|
} |
|
|
|
pathFigure.Segments.RemoveAt(idx); |
|
|
|
var midp = senderThumb.PathPoint.ParentPathPoint.Point - ((senderThumb.PathPoint.ParentPathPoint.Point - point) / 2); |
|
|
|
PathSegment newSegment = null; |
|
switch (convertType) |
|
{ |
|
case PathPartConvertType.ToBezierSegment: |
|
newSegment = new BezierSegment() { Point1 = midp - new Vector(40, 40), Point2 = midp + new Vector(-40, 40), Point3 = point }; |
|
break; |
|
case PathPartConvertType.ToQuadricBezierSegment: |
|
newSegment = new QuadraticBezierSegment() { Point1 = point - new Vector(40, 40), Point2 = point }; |
|
break; |
|
case PathPartConvertType.ToArcSegment: |
|
newSegment = new ArcSegment() { Point = point, Size = new Size(20, 20) }; |
|
break; |
|
case PathPartConvertType.insertPoint: |
|
pathFigure.Segments.Insert(idx, pathSegment); |
|
newSegment = new LineSegment() { Point = midp, }; |
|
break; |
|
default: |
|
newSegment = new LineSegment() { Point = point }; |
|
break; |
|
} |
|
|
|
pathFigure.Segments.Insert(idx, newSegment); |
|
} |
|
|
|
this.ExtendedItem.ReapplyAllExtensions(); |
|
} |
|
|
|
private void ChangeIsClosed(PathThumb senderThumb, MenuItem menuItem) |
|
{ |
|
var figure = senderThumb.PathPoint.Object as PathFigure; |
|
figure.IsClosed = !figure.IsClosed; |
|
menuItem.IsChecked = figure.IsClosed; |
|
} |
|
|
|
private void ChangeIsStroked(PathThumb senderThumb, MenuItem menuItem) |
|
{ |
|
var segment = senderThumb.PathPoint.Object as PathSegment; |
|
segment.IsStroked = !segment.IsStroked; |
|
menuItem.IsChecked = segment.IsStroked; |
|
} |
|
|
|
private void ResetThumbs() |
|
{ |
|
foreach (FrameworkElement rt in adornerPanel.Children) |
|
{ |
|
if (rt is DesignerThumb) |
|
(rt as DesignerThumb).IsPrimarySelection = true; |
|
} |
|
_selectedThumbs.Clear(); |
|
} |
|
|
|
private void SelectThumb(PathThumb mprt) |
|
{ |
|
CommitOrAbortKeyboardOperation(); |
|
|
|
var points = GetPoints(); |
|
Point p = points[mprt.Index].TranslatedPoint; |
|
_selectedThumbs.Add(mprt.Index, new Bounds { X = p.X, Y = p.Y }); |
|
|
|
mprt.IsPrimarySelection = false; |
|
} |
|
|
|
#endregion |
|
|
|
#region eventhandlers |
|
|
|
private void ResizeThumbOnMouseLeftButtonUp(object sender, MouseButtonEventArgs mouseButtonEventArgs) |
|
{ |
|
//get current thumb |
|
var mprt = sender as PathThumb; |
|
if (mprt != null) |
|
{ |
|
//if not keyboard ctrl is pressed and selected point is not previously selected, clear selection |
|
if (!_selectedThumbs.ContainsKey(mprt.Index) & !Keyboard.IsKeyDown(Key.LeftCtrl) & |
|
!Keyboard.IsKeyDown(Key.RightCtrl)) |
|
{ |
|
ResetThumbs(); |
|
} |
|
//add selected thumb, if ctrl pressed this could be all points in poly |
|
if (!_selectedThumbs.ContainsKey(mprt.Index)) |
|
SelectThumb(mprt); |
|
_isDragging = false; |
|
|
|
} |
|
} |
|
|
|
protected void drag_MouseDown(DragListener drag) |
|
{ |
|
|
|
} |
|
|
|
// TODO : Remove all hide/show extensions from here. |
|
protected void drag_Started(DragListener drag) |
|
{ |
|
//get current thumb |
|
var mprt = (drag.Target as PathThumb); |
|
if (mprt != null) |
|
{ |
|
SetOperation(); |
|
} |
|
} |
|
|
|
bool _isKeyboardMoveing; |
|
|
|
void SetOperation() |
|
{ |
|
var designPanel = ExtendedItem.Services.DesignPanel as DesignPanel; |
|
_zoom = designPanel.TryFindParent<ZoomControl>(); |
|
|
|
CommitOrAbortKeyboardOperation(); |
|
|
|
//Move a Virtual Design Item arround... (for Snaplines, raster, ...) |
|
//And Resfresh the Points after Positioning that Item! |
|
//if (resizeBehavior != null) |
|
operation = PlacementOperation.Start(extendedItemArray, PlacementType.MovePoint); |
|
// else |
|
// { |
|
// changeGroup = ExtendedItem.Context.OpenGroup("Resize", extendedItemArray); |
|
// } |
|
_isResizing = true; |
|
} |
|
|
|
void CommitOrAbortKeyboardOperation() |
|
{ |
|
if (operation != null) { |
|
if (!_isKeyboardMoveing) { |
|
var op = operation; |
|
operation = null; |
|
op.Abort(); |
|
} |
|
else |
|
CommitOperation(); |
|
} |
|
|
|
_isKeyboardMoveing = false; |
|
} |
|
void CommitOperation() |
|
{ |
|
if (operation != null) |
|
{ |
|
foreach (int i in _selectedThumbs.Keys) |
|
{ |
|
pathPoints[i].Commit(); |
|
} |
|
|
|
var op = operation; |
|
operation = null; |
|
op.Commit(); |
|
|
|
_isKeyboardMoveing = false; |
|
} |
|
// else |
|
// { |
|
// if (changeGroup != null) |
|
// changeGroup.Commit(); |
|
// changeGroup = null; |
|
// } |
|
_isResizing = false; |
|
|
|
//Invalidate(); |
|
} |
|
|
|
protected void drag_Changed(DragListener drag) |
|
{ |
|
var mprt = drag.Target as PathThumb; |
|
if (mprt != null) { |
|
_isDragging = true; |
|
MovePoints(drag.Delta.X, drag.Delta.Y); |
|
} |
|
} |
|
|
|
protected void drag_Completed(DragListener drag) |
|
{ |
|
var mprt = drag.Target as PathThumb; |
|
if (mprt != null) { |
|
if (operation != null && drag.IsCanceled) { |
|
operation.Abort(); |
|
} else if (drag.IsCanceled) { |
|
changeGroup.Abort(); |
|
} |
|
CommitOperation(); |
|
} |
|
} |
|
|
|
|
|
|
|
protected override void OnInitialized() |
|
{ |
|
base.OnInitialized(); |
|
|
|
pathPoints = GetPoints(); |
|
|
|
resizeThumbs = new List<DesignerThumb>(); |
|
|
|
var transform = this.ExtendedItem.GetCompleteAppliedTransformationToView(); |
|
|
|
for (int i = 0; i < pathPoints.Count; i++) { |
|
CreateThumb(PlacementAlignment.BottomRight, Cursors.Cross, i, pathPoints[i], transform); |
|
} |
|
|
|
Invalidate(); |
|
|
|
ResetThumbs(); |
|
_isDragging = false; |
|
|
|
extendedItemArray[0] = ExtendedItem; |
|
ExtendedItem.PropertyChanged += OnPropertyChanged; |
|
resizeBehavior = PlacementOperation.GetPlacementBehavior(extendedItemArray); |
|
UpdateAdornerVisibility(); |
|
|
|
this.ExtendedItem.Services.Selection.PrimarySelectionChanged += ExtendedItem_Services_Selection_PrimarySelectionChanged; |
|
} |
|
|
|
protected override void OnRemove() |
|
{ |
|
this.ExtendedItem.Services.Selection.PrimarySelectionChanged -= ExtendedItem_Services_Selection_PrimarySelectionChanged; |
|
base.OnRemove(); |
|
} |
|
|
|
void ExtendedItem_Services_Selection_PrimarySelectionChanged(object sender, EventArgs e) |
|
{ |
|
if (operation != null && _isKeyboardMoveing) { |
|
var newSelection = this.ExtendedItem.Services.Selection.SelectedItems.ToList(); |
|
CommitOrAbortKeyboardOperation(); |
|
this.ExtendedItem.Services.Selection.SetSelectedComponents(newSelection); |
|
} |
|
} |
|
|
|
#endregion |
|
|
|
List<PathPoint> GetPoints() |
|
{ |
|
return GetPoints(this.ExtendedItem); |
|
} |
|
|
|
protected List<PathPoint> GetPoints(DesignItem designItem) |
|
{ |
|
var retVal = new List<PathPoint>(); |
|
AddGeometryPoints(retVal, ((Path)designItem.View).Data, ((Path)designItem.View), () => designItem.Properties["Data"].SetValue(((Path)designItem.View).Data.ToString())); |
|
|
|
return retVal; |
|
} |
|
|
|
protected void AddGeometryPoints(List<PathPoint> list, Geometry geometry, Shape shape, Action saveDesignItem) |
|
{ |
|
if (geometry is CombinedGeometry) { |
|
var g = geometry as CombinedGeometry; |
|
var d = ExtendedItem.Services.Component.GetDesignItem(g); |
|
if (d != null) |
|
saveDesignItem = () => |
|
{ |
|
d.Properties["Geometry1"].SetValue(((CombinedGeometry)d.Component).Geometry1); |
|
d.Properties["Geometry2"].SetValue(((CombinedGeometry)d.Component).Geometry2); |
|
}; |
|
AddGeometryPoints(list, g.Geometry1, shape, saveDesignItem); |
|
AddGeometryPoints(list, g.Geometry2, shape, saveDesignItem); |
|
} else if (geometry is GeometryGroup) { |
|
var gg = geometry as GeometryGroup; |
|
foreach (var g in gg.Children.ToList()) { |
|
AddGeometryPoints(list, g, shape, saveDesignItem); |
|
} |
|
} else if (geometry is StreamGeometry) { |
|
var sg = geometry as StreamGeometry; |
|
var pg = sg.GetFlattenedPathGeometry().Clone(); |
|
var d = ExtendedItem.Services.Component.GetDesignItem(sg); |
|
if (d != null) |
|
saveDesignItem = () => |
|
{ |
|
d.ParentProperty.SetValue(Geometry.Parse(pg.ToString())); |
|
}; |
|
|
|
if (d != null) { |
|
if (!d.ParentProperty.IsCollection) |
|
((DependencyObject)d.ParentProperty.DesignItem.Component).SetValue(d.ParentProperty.DependencyProperty, pg); |
|
else { |
|
var collection = ((DependencyObject)d.ParentProperty.DesignItem.Component) as GeometryGroup; |
|
var i = collection.Children.IndexOf(geometry); |
|
collection.Children.RemoveAt(i); |
|
collection.Children.Insert(i, pg); |
|
} |
|
} |
|
else |
|
((Path)shape).Data = pg; |
|
AddGeometryPoints(list, pg, shape, saveDesignItem); |
|
} else if (geometry is PathGeometry) { |
|
var g = geometry as PathGeometry; |
|
var d = ExtendedItem.Services.Component.GetDesignItem(g); |
|
if (d != null) |
|
saveDesignItem = () => |
|
{ |
|
d.Properties["Figures"].SetValue(((PathGeometry)d.Component).Figures); |
|
}; |
|
if (geometry!=null) { |
|
foreach(var figure in g.Figures) { |
|
var dd = ExtendedItem.Services.Component.GetDesignItem(figure); |
|
if (dd != null) |
|
saveDesignItem = () => |
|
{ |
|
dd.Properties["StartPoint"].SetValue(((PathFigure)dd.Component).StartPoint); |
|
//dd.Properties["Segments"].SetValue(((PathFigure)dd.Component).Segments); |
|
}; |
|
list.Add(new PathPoint(figure.StartPoint, figure, null, (p) => figure.StartPoint = p, saveDesignItem, shape)); |
|
foreach (var s in figure.Segments) { |
|
var parentp = list.Last(); |
|
if (s is LineSegment) |
|
{ |
|
var ds = ExtendedItem.Services.Component.GetDesignItem(s); |
|
if (ds != null) |
|
saveDesignItem = () => |
|
{ |
|
ds.Properties["Point"].SetValue(((LineSegment)ds.Component).Point); |
|
}; |
|
list.Add(new PathPoint(((LineSegment)s).Point, s, figure, (p) => ((LineSegment)s).Point = p, saveDesignItem, shape) { ParentPathPoint = parentp }); |
|
} |
|
else if (s is PolyLineSegment) |
|
{ |
|
var ds = ExtendedItem.Services.Component.GetDesignItem(s); |
|
if (ds != null) |
|
saveDesignItem = () => |
|
{ |
|
ds.Properties["Points"].SetValue(((PolyLineSegment)ds.Component).Points); |
|
}; |
|
var poly = s as PolyLineSegment; |
|
for (int n = 0; n < poly.Points.Count; n++) |
|
{ |
|
var closure_n = n; |
|
list.Add(new PathPoint(poly.Points[closure_n], s, figure, (p) => poly.Points[closure_n] = p, saveDesignItem, shape) { PolyLineIndex = closure_n, ParentPathPoint = parentp }); |
|
parentp = list.Last(); |
|
} |
|
} |
|
else if (s is BezierSegment) |
|
{ |
|
var ds = ExtendedItem.Services.Component.GetDesignItem(s); |
|
if (ds != null) |
|
saveDesignItem = () => |
|
{ |
|
ds.Properties["Point1"].SetValue(((BezierSegment)ds.Component).Point1); |
|
ds.Properties["Point2"].SetValue(((BezierSegment)ds.Component).Point2); |
|
ds.Properties["Point3"].SetValue(((BezierSegment)ds.Component).Point3); |
|
}; |
|
var pathp = new PathPoint(((BezierSegment)s).Point3, s, figure, (p) => ((BezierSegment)s).Point3 = p, saveDesignItem, shape) { ParentPathPoint = parentp }; |
|
var previous = list.Last(); |
|
list.Add(new PathPoint(((BezierSegment)s).Point1, s, figure, (p) => ((BezierSegment)s).Point1 = p, saveDesignItem, shape) { TargetPathPoint = previous }); |
|
list.Add(new PathPoint(((BezierSegment)s).Point2, s, figure, (p) => ((BezierSegment)s).Point2 = p, saveDesignItem, shape) { TargetPathPoint = pathp }); |
|
list.Add(pathp); |
|
} |
|
else if (s is PolyBezierSegment) |
|
{ |
|
var ds = ExtendedItem.Services.Component.GetDesignItem(s); |
|
if (ds != null) |
|
saveDesignItem = () => |
|
{ |
|
ds.Properties["Points"].SetValue(((PolyBezierSegment)ds.Component).Points); |
|
}; |
|
var poly = s as PolyBezierSegment; |
|
for (int n = 0; n < poly.Points.Count; n+=3) |
|
{ |
|
var closure_n = n; |
|
var previous = list.Last(); |
|
var pathp = new PathPoint(poly.Points[closure_n+2], s, figure, (p) => poly.Points[closure_n+2] = p, saveDesignItem, shape) { PolyLineIndex = closure_n+2, ParentPathPoint = parentp }; |
|
list.Add(new PathPoint(poly.Points[closure_n], s, figure, (p) => poly.Points[closure_n] = p, saveDesignItem, shape) { PolyLineIndex = closure_n, TargetPathPoint = previous }); |
|
list.Add(new PathPoint(poly.Points[closure_n+1], s, figure, (p) => poly.Points[closure_n+1] = p, saveDesignItem, shape) { PolyLineIndex = closure_n+1, TargetPathPoint = pathp }); |
|
list.Add(pathp); |
|
parentp = pathp; |
|
} |
|
} |
|
else if (s is QuadraticBezierSegment) |
|
{ |
|
var ds = ExtendedItem.Services.Component.GetDesignItem(s); |
|
if (ds != null) |
|
saveDesignItem = () => |
|
{ |
|
ds.Properties["Point1"].SetValue(((QuadraticBezierSegment)ds.Component).Point1); |
|
ds.Properties["Point2"].SetValue(((QuadraticBezierSegment)ds.Component).Point2); |
|
}; |
|
var pathp = new PathPoint(((QuadraticBezierSegment)s).Point2, s, figure, (p) => ((QuadraticBezierSegment)s).Point2 = p, saveDesignItem, shape) { ParentPathPoint = parentp }; |
|
list.Add(new PathPoint(((QuadraticBezierSegment)s).Point1, s, figure, (p) => ((QuadraticBezierSegment)s).Point1 = p, saveDesignItem, shape) { TargetPathPoint = pathp }); |
|
list.Add(pathp); |
|
} |
|
else if (s is PolyQuadraticBezierSegment) |
|
{ |
|
var ds = ExtendedItem.Services.Component.GetDesignItem(s); |
|
if (ds != null) |
|
saveDesignItem = () => |
|
{ |
|
ds.Properties["Points"].SetValue(((PolyQuadraticBezierSegment)ds.Component).Points); |
|
}; |
|
var poly = s as PolyQuadraticBezierSegment; |
|
for (int n = 0; n < poly.Points.Count; n+=2) |
|
{ |
|
var closure_n = n; |
|
var previous = list.Last(); |
|
var pathp = new PathPoint(poly.Points[closure_n+1], s, figure, (p) => poly.Points[closure_n+1] = p, saveDesignItem, shape) { PolyLineIndex = closure_n+1, ParentPathPoint = parentp }; |
|
list.Add(new PathPoint(poly.Points[closure_n], s, figure, (p) => poly.Points[closure_n] = p, saveDesignItem, shape) { PolyLineIndex = closure_n, TargetPathPoint = pathp }); |
|
list.Add(pathp); |
|
parentp = pathp; |
|
} |
|
} |
|
else if (s is ArcSegment) |
|
{ |
|
var ds = ExtendedItem.Services.Component.GetDesignItem(s); |
|
if (ds != null) |
|
saveDesignItem = () => |
|
{ |
|
ds.Properties["Size"].SetValue(((ArcSegment)ds.Component).Size); |
|
}; |
|
var arc = ((ArcSegment)s); |
|
var pathp = new PathPoint(arc.Point, s, figure, (p) => arc.Point = p, saveDesignItem, shape) { ParentPathPoint = parentp }; |
|
list.Add(new PathPoint(arc.Point - new Vector(arc.Size.Width, arc.Size.Height), s, figure, (p) => arc.Size = new Size(Math.Abs(arc.Point.X - p.X), Math.Abs(arc.Point.Y - p.Y)), saveDesignItem, shape) { TargetPathPoint = pathp }); |
|
list.Add(pathp); |
|
} |
|
} |
|
} |
|
} |
|
} else if (geometry is RectangleGeometry) { |
|
var g = geometry as RectangleGeometry; |
|
list.Add(new PathPoint(g.Rect.TopLeft, geometry, null, null, saveDesignItem, shape)); //(p) => g.Rect.Left = p.X)); |
|
list.Add(new PathPoint(g.Rect.TopRight, geometry, null, null, saveDesignItem, shape)); //(p) => g.Rect.Width = p.X)); |
|
list.Add(new PathPoint(g.Rect.BottomLeft, geometry, null, null, saveDesignItem, shape)); //(p) => g.Rect.Top = p.Y)); |
|
list.Add(new PathPoint(g.Rect.BottomRight, geometry, null, null, saveDesignItem, shape)); //(p) => g.Rect.Height = p.Y)); |
|
} else if (geometry is EllipseGeometry) { |
|
var g = geometry as EllipseGeometry; |
|
var d = ExtendedItem.Services.Component.GetDesignItem(g); |
|
if (d != null) |
|
saveDesignItem = () => d.Properties["Center"].SetValue(((EllipseGeometry)d.Component).Center); |
|
list.Add(new PathPoint(g.Center, geometry, null, (p) => g.Center = p, saveDesignItem, shape)); |
|
} else if (geometry is LineGeometry) { |
|
var g = geometry as LineGeometry; |
|
var d = ExtendedItem.Services.Component.GetDesignItem(g); |
|
if (d != null) |
|
saveDesignItem = () => |
|
{ |
|
d.Properties["StartPoint"].SetValue(((LineGeometry)d.Component).StartPoint); |
|
d.Properties["EndPoint"].SetValue(((LineGeometry)d.Component).EndPoint); |
|
}; |
|
list.Add(new PathPoint(g.StartPoint, geometry, null, (p) => g.StartPoint = p, saveDesignItem, shape)); |
|
list.Add(new PathPoint(g.EndPoint, geometry, null, (p) => g.EndPoint = p, saveDesignItem, shape)); |
|
} |
|
} |
|
|
|
void MovePoints(double displacementX, double displacementY, bool useContainerBehavior = true) |
|
{ |
|
var relativeTo = new Vector(operation.PlacedItems[0].Bounds.TopLeft.X, operation.PlacedItems[0].Bounds.TopLeft.Y); |
|
|
|
//iterate all selected points |
|
foreach (int i in _selectedThumbs.Keys) { |
|
Point p = pathPoints[i].TranslatedPoint; |
|
|
|
//x and y is calculated from the currentl point |
|
double x = _selectedThumbs[i].X + displacementX; |
|
double y = _selectedThumbs[i].Y + displacementY; |
|
|
|
p.X = x; |
|
p.Y = y; |
|
|
|
if (useContainerBehavior) |
|
p = operation.CurrentContainerBehavior.PlacePoint(p + relativeTo) - relativeTo; |
|
|
|
pathPoints[i].TranslatedPoint = p; |
|
} |
|
} |
|
|
|
#region IKeyDown |
|
|
|
public bool InvokeDefaultAction |
|
{ |
|
get { return _selectedThumbs.Count == 0 || _selectedThumbs.Count == pathPoints.Count - 1; } |
|
} |
|
|
|
int _movingDistanceX; |
|
int _movingDistanceY; |
|
public void KeyDownAction(object sender, KeyEventArgs e) |
|
{ |
|
if (_selectedThumbs.Count > 0) { |
|
if (IsArrowKey(e.Key)) { |
|
if (operation == null) { |
|
SetOperation(); |
|
_isKeyboardMoveing = true; |
|
_movingDistanceX = 0; |
|
_movingDistanceY = 0; |
|
} |
|
} |
|
|
|
var dx1 = (e.Key == Key.Left) ? Keyboard.IsKeyDown(Key.LeftShift) ? - 10 : - 1 : 0; |
|
var dy1 = (e.Key == Key.Up) ? Keyboard.IsKeyDown(Key.LeftShift) ? - 10 : - 1 : 0; |
|
var dx2 = (e.Key == Key.Right) ? Keyboard.IsKeyDown(Key.LeftShift) ? + 10 : + 1 : 0; |
|
var dy2 = (e.Key == Key.Down) ? Keyboard.IsKeyDown(Key.LeftShift) ? + 10 : + 1 : 0; |
|
|
|
_movingDistanceX += (dx1 + dx2); |
|
_movingDistanceY += (dy1 + dy2); |
|
|
|
if (operation != null) |
|
MovePoints(_movingDistanceX, _movingDistanceY, false); |
|
} |
|
} |
|
|
|
public void KeyUpAction(object sender, KeyEventArgs e) |
|
{ |
|
// if (IsArrowKey(e.Key)) |
|
// CommitOperation(); |
|
} |
|
|
|
bool IsArrowKey(Key key) |
|
{ |
|
return (key == Key.Left || key == Key.Right || key == Key.Up || key == Key.Down); |
|
} |
|
#endregion |
|
} |
|
}
|
|
|