Browse Source

Path -> Support Extended. Points can now be modified.

pull/637/head
jkuehner 11 years ago
parent
commit
1adfe7d235
  1. 219
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PathHandlerExtension.cs
  2. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PointTrackerPlacementSupport.cs

219
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PathHandlerExtension.cs

@ -79,7 +79,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
private void SelectThumb(MultiPointResizeThumb mprt) private void SelectThumb(MultiPointResizeThumb mprt)
{ {
var points = GetPoints(); var points = GetPoints();
Point p = points[mprt.Index]; Point p = points[mprt.Index].Point;
_selectedThumbs.Add(mprt.Index, new Bounds { X = p.X, Y = p.Y }); _selectedThumbs.Add(mprt.Index, new Bounds { X = p.X, Y = p.Y });
mprt.IsPrimarySelection = false; mprt.IsPrimarySelection = false;
@ -162,7 +162,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
_isResizing = true; _isResizing = true;
} }
void ChangeOperation(List<Point> points) void ChangeOperation(List<PathPoint> points)
{ {
//this is for SharpDevelop built in undo functionality //this is for SharpDevelop built in undo functionality
if (operation != null) if (operation != null)
@ -170,8 +170,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
var info = operation.PlacedItems[0]; var info = operation.PlacedItems[0];
var result = info.OriginalBounds; var result = info.OriginalBounds;
IEnumerable<double> xs = points.Select(x => x.X); IEnumerable<double> xs = points.Select(x => x.Point.X);
IEnumerable<double> ys = points.Select(y => y.Y); IEnumerable<double> ys = points.Select(y => y.Point.Y);
result.X = (double)(info.Item.Properties.GetAttachedProperty(Canvas.LeftProperty).ValueOnInstance); result.X = (double)(info.Item.Properties.GetAttachedProperty(Canvas.LeftProperty).ValueOnInstance);
result.Y = (double)(info.Item.Properties.GetAttachedProperty(Canvas.TopProperty).ValueOnInstance); result.Y = (double)(info.Item.Properties.GetAttachedProperty(Canvas.TopProperty).ValueOnInstance);
result.Width = xs.Max() - xs.Min(); result.Width = xs.Max() - xs.Min();
@ -229,7 +229,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
Double theta; Double theta;
//if one point selected snapping angle is calculated in relation to previous point //if one point selected snapping angle is calculated in relation to previous point
if (_selectedThumbs.Count == 1 && mprt.Index > 0) { if (_selectedThumbs.Count == 1 && mprt.Index > 0) {
theta = (180 / Math.PI) * Math.Atan2(_selectedThumbs[mprt.Index].Y + dy - points[mprt.Index - 1].Y, _selectedThumbs[mprt.Index].X + dx - points[mprt.Index - 1].X); theta = (180 / Math.PI) * Math.Atan2(_selectedThumbs[mprt.Index].Y + dy - points[mprt.Index - 1].Point.Y, _selectedThumbs[mprt.Index].X + dx - points[mprt.Index - 1].Point.X);
} else { //if multiple points snapping angle is calculated in relation to mouse dragging angle } else { //if multiple points snapping angle is calculated in relation to mouse dragging angle
theta = (180 / Math.PI) * Math.Atan2(dy, dx); theta = (180 / Math.PI) * Math.Atan2(dy, dx);
} }
@ -238,45 +238,45 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
int? snapAngle = null; int? snapAngle = null;
//shift+alt gives a new point //shift+alt gives a new point
if ((Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) && (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))) // if ((Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) && (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)))
{ // {
//if dragging occurs on a point and that point is the only selected, a new node will be added. // //if dragging occurs on a point and that point is the only selected, a new node will be added.
//_isCtrlDragging is needed since this method is called for every x pixel that the mouse moves // //_isCtrlDragging is needed since this method is called for every x pixel that the mouse moves
//so it could be many thousands of times during a single dragging // //so it could be many thousands of times during a single dragging
if (!_isDragging && _selectedThumbs.Count == 1 && (Math.Abs(dx) > 0 || Math.Abs(dy) > 0)) // if (!_isDragging && _selectedThumbs.Count == 1 && (Math.Abs(dx) > 0 || Math.Abs(dy) > 0))
{ // {
//
//duplicate point that is selected // //duplicate point that is selected
Point p = points[mprt.Index]; // Point p = points[mprt.Index].Point;
//
//insert duplicate // //insert duplicate
points.Insert(mprt.Index, p); // points.Insert(mprt.Index, p);
//
//create adorner marker // //create adorner marker
CreateThumb(PlacementAlignment.BottomRight, Cursors.Cross, mprt.Index); // CreateThumb(PlacementAlignment.BottomRight, Cursors.Cross, mprt.Index);
//
//set index of all points that had a higher index than selected to +1 // //set index of all points that had a higher index than selected to +1
foreach (FrameworkElement rt in adornerPanel.Children) // foreach (FrameworkElement rt in adornerPanel.Children)
{ // {
if (rt is MultiPointResizeThumb) // if (rt is MultiPointResizeThumb)
{ // {
MultiPointResizeThumb t = rt as MultiPointResizeThumb; // MultiPointResizeThumb t = rt as MultiPointResizeThumb;
if (t.Index > mprt.Index) // if (t.Index > mprt.Index)
t.Index++; // t.Index++;
} // }
} // }
//
//set index of new point to old point index + 1 // //set index of new point to old point index + 1
mprt.Index = mprt.Index + 1; // mprt.Index = mprt.Index + 1;
ResetThumbs(); // ResetThumbs();
SelectThumb(mprt); // SelectThumb(mprt);
//
} // }
snapAngle = 10; // snapAngle = 10;
} // }
//snapping occurs when mouse is within 10 degrees from horizontal or vertical plane if shift is pressed //snapping occurs when mouse is within 10 degrees from horizontal or vertical plane if shift is pressed
else if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) /*else*/ if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{ {
snapAngle = 10; snapAngle = 10;
} }
@ -337,49 +337,124 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
#endregion #endregion
List<Point> GetPoints() List<PathPoint> GetPoints()
{ {
return GetPoints(this.ExtendedItem.View as Path); return GetPoints(this.ExtendedItem.View as Path);
} }
public static List<Point> GetPoints(Path path) public static List<PathPoint> GetPoints(Path path)
{ {
var retVal = new List<Point>(); var retVal = new List<PathPoint>();
AddGeometryPoints(retVal, path.Data);
var geometry = path.Data as PathGeometry;
if (geometry!=null) { return retVal;
var figure = geometry.Figures[0] as PathFigure; }
if (figure != null) {
retVal.Add(figure.StartPoint); private static void AddGeometryPoints(List<PathPoint> list, Geometry geometry)
foreach (var s in figure.Segments) { {
if (s is LineSegment) if (geometry is CombinedGeometry) {
retVal.Add(((LineSegment)s).Point); var g = geometry as CombinedGeometry;
else if (s is PolyLineSegment) AddGeometryPoints(list, g.Geometry1);
retVal.AddRange(((PolyLineSegment)s).Points); AddGeometryPoints(list, g.Geometry2);
else if (s is BezierSegment) { } else if (geometry is PathGeometry) {
retVal.Add(((BezierSegment)s).Point1); var g = geometry as PathGeometry;
retVal.Add(((BezierSegment)s).Point2); if (geometry!=null) {
retVal.Add(((BezierSegment)s).Point3); foreach(var figure in g.Figures) {
} list.Add(new PathPoint(figure.StartPoint, figure, PointType.StartPoint, (p) => figure.StartPoint = p));
else if (s is QuadraticBezierSegment) { foreach (var s in figure.Segments) {
retVal.Add(((QuadraticBezierSegment)s).Point1); if (s is LineSegment)
retVal.Add(((QuadraticBezierSegment)s).Point2); list.Add(new PathPoint(((LineSegment)s).Point, s, PointType.LineSegment, (p) => ((LineSegment)s).Point = p));
else if (s is PolyLineSegment) {
//list.AddRange(((PolyLineSegment)s).Points);
}
else if (s is BezierSegment) {
list.Add(new PathPoint(((BezierSegment)s).Point1, s, PointType.BezierSegment, (p) => ((BezierSegment)s).Point1 = p));
//list.Add(((BezierSegment)s).Point1);
//list.Add(((BezierSegment)s).Point2);
//list.Add(((BezierSegment)s).Point3);
}
else if (s is QuadraticBezierSegment) {
list.Add(new PathPoint(((QuadraticBezierSegment)s).Point1, s, PointType.QuadricBezierSegment, (p) => ((QuadraticBezierSegment)s).Point1 = p));
//list.Add(((QuadraticBezierSegment)s).Point1);
//list.Add(((QuadraticBezierSegment)s).Point2);
}
else if (s is ArcSegment)
list.Add(new PathPoint(((ArcSegment)s).Point, s, PointType.ArcSegment, (p) => ((ArcSegment)s).Point = p));
//list.Add(((ArcSegment)s).Point);
} }
else if (s is ArcSegment)
retVal.Add(((ArcSegment)s).Point);
} }
} }
} else if (geometry is RectangleGeometry) {
var g = geometry as RectangleGeometry;
list.Add(new PathPoint(g.Rect.TopLeft, geometry, PointType.RectangleGeometryP1, null)); //(p) => g.Rect.Left = p.X));
list.Add(new PathPoint(g.Rect.TopRight, geometry, PointType.RectangleGeometryP2, null)); //(p) => g.Rect.Width = p.X));
list.Add(new PathPoint(g.Rect.BottomLeft, geometry, PointType.RectangleGeometryP3, null)); //(p) => g.Rect.Top = p.Y));
list.Add(new PathPoint(g.Rect.BottomRight, geometry, PointType.RectangleGeometryP4, null)); //(p) => g.Rect.Height = p.Y));
// list.Add(new Point(g.Rect.Left, g.Rect.Top));
// list.Add(new Point(g.Rect.Left, g.Rect.Top + g.Rect.Height));
// list.Add(new Point(g.Rect.Left + g.Rect.Width, g.Rect.Top));
// list.Add(new Point(g.Rect.Left + g.Rect.Width, g.Rect.Top + g.Rect.Height));
} else if (geometry is EllipseGeometry) {
var g = geometry as EllipseGeometry;
list.Add(new PathPoint(g.Center, geometry, PointType.EllipseGeometryCenter, (p) => g.Center = p));
//list.Add(g.Center);
} else if (geometry is LineGeometry) {
var g = geometry as LineGeometry;
list.Add(new PathPoint(g.StartPoint, geometry, PointType.LineGeometryStart, (p) => g.StartPoint = p));
list.Add(new PathPoint(g.EndPoint, geometry, PointType.LineGeometryEnd, (p) => g.EndPoint = p));
//list.Add(g.StartPoint);
//list.Add(g.EndPoint);
} }
}
return retVal; public enum PointType{
StartPoint,
LineSegment,
BezierSegment,
ArcSegment,
QuadricBezierSegment,
LineGeometryStart,
LineGeometryEnd,
EllipseGeometryCenter,
RectangleGeometryP1,
RectangleGeometryP2,
RectangleGeometryP3,
RectangleGeometryP4,
}
public class PathPoint {
public PathPoint(Point point, Object @object, PointType pointType, Action<Point> setLambda)
{
this._point = point;
this._setLambda = setLambda;
this.Object = @object;
}
private Point _point;
Action<Point> _setLambda;
public Point Point {
get{return _point;}
set{_setLambda(value);}
}
public Point ReferencePoint {get; private set;}
public PointType Start {get; private set;}
public PointType End {get; private set;}
public object Object {get; private set;}
} }
List<Point> MovePoints(List<Point> pc, double displacementX, double displacementY, double theta, int? snapangle) //Should not return a List of Points, no a List of Point Object wich say what a Point is.
//For Example: a Center Point of a Circle, should now it's a Center point!
//When he is selected, he should show another drag point to change the radius!
//a Combined Gemoetry should show a Adorner to change the combination mode!
List<PathPoint> MovePoints(List<PathPoint> pc, double displacementX, double displacementY, double theta, int? snapangle)
{ {
//iterate all selected points //iterate all selected points
foreach (int i in _selectedThumbs.Keys) foreach (int i in _selectedThumbs.Keys)
{ {
Point p = pc[i]; Point p = pc[i].Point;
//x and y is calculated from the currentl point //x and y is calculated from the currentl point
double x = _selectedThumbs[i].X + displacementX; double x = _selectedThumbs[i].X + displacementX;
@ -394,19 +469,19 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
if (Math.Abs(theta) < snapangle || 180 - Math.Abs(theta) < snapangle) if (Math.Abs(theta) < snapangle || 180 - Math.Abs(theta) < snapangle)
{ {
//if one point selected use point before as snap point, else snap to movement //if one point selected use point before as snap point, else snap to movement
y = _selectedThumbs.Count == 1 ? pc[i - 1].Y : y - displacementY; y = _selectedThumbs.Count == 1 ? pc[i - 1].Point.Y : y - displacementY;
} }
else if (Math.Abs(90 - Math.Abs(theta)) < snapangle)//vertical snap else if (Math.Abs(90 - Math.Abs(theta)) < snapangle)//vertical snap
{ {
//if one point selected use point before as snap point, else snap to movement //if one point selected use point before as snap point, else snap to movement
x = _selectedThumbs.Count == 1 ? pc[i - 1].X : x - displacementX; x = _selectedThumbs.Count == 1 ? pc[i - 1].Point.X : x - displacementX;
} }
} }
} }
p.X = x; p.X = x;
p.Y = y; p.Y = y;
pc[i] = p; pc[i].Point = p;
} }
return pc; return pc;
} }

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PointTrackerPlacementSupport.cs

@ -74,7 +74,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
} else if (shape is Path) { } else if (shape is Path) {
var path = shape as Path; var path = shape as Path;
var points = PathHandlerExtension.GetPoints(path); var points = PathHandlerExtension.GetPoints(path);
p = points[Index]; p = points[Index].Point;
} }
var transform = shape.RenderedGeometry.Transform; var transform = shape.RenderedGeometry.Transform;

Loading…
Cancel
Save