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 @@ -79,7 +79,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
private void SelectThumb(MultiPointResizeThumb mprt)
{
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 });
mprt.IsPrimarySelection = false;
@ -162,7 +162,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -162,7 +162,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
_isResizing = true;
}
void ChangeOperation(List<Point> points)
void ChangeOperation(List<PathPoint> points)
{
//this is for SharpDevelop built in undo functionality
if (operation != null)
@ -170,8 +170,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -170,8 +170,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
var info = operation.PlacedItems[0];
var result = info.OriginalBounds;
IEnumerable<double> xs = points.Select(x => x.X);
IEnumerable<double> ys = points.Select(y => y.Y);
IEnumerable<double> xs = points.Select(x => x.Point.X);
IEnumerable<double> ys = points.Select(y => y.Point.Y);
result.X = (double)(info.Item.Properties.GetAttachedProperty(Canvas.LeftProperty).ValueOnInstance);
result.Y = (double)(info.Item.Properties.GetAttachedProperty(Canvas.TopProperty).ValueOnInstance);
result.Width = xs.Max() - xs.Min();
@ -229,7 +229,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -229,7 +229,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
Double theta;
//if one point selected snapping angle is calculated in relation to previous point
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
theta = (180 / Math.PI) * Math.Atan2(dy, dx);
}
@ -238,45 +238,45 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -238,45 +238,45 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
int? snapAngle = null;
//shift+alt gives a new point
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.
//_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
if (!_isDragging && _selectedThumbs.Count == 1 && (Math.Abs(dx) > 0 || Math.Abs(dy) > 0))
{
//duplicate point that is selected
Point p = points[mprt.Index];
//insert duplicate
points.Insert(mprt.Index, p);
//create adorner marker
CreateThumb(PlacementAlignment.BottomRight, Cursors.Cross, mprt.Index);
//set index of all points that had a higher index than selected to +1
foreach (FrameworkElement rt in adornerPanel.Children)
{
if (rt is MultiPointResizeThumb)
{
MultiPointResizeThumb t = rt as MultiPointResizeThumb;
if (t.Index > mprt.Index)
t.Index++;
}
}
//set index of new point to old point index + 1
mprt.Index = mprt.Index + 1;
ResetThumbs();
SelectThumb(mprt);
}
snapAngle = 10;
}
// 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.
// //_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
// if (!_isDragging && _selectedThumbs.Count == 1 && (Math.Abs(dx) > 0 || Math.Abs(dy) > 0))
// {
//
// //duplicate point that is selected
// Point p = points[mprt.Index].Point;
//
// //insert duplicate
// points.Insert(mprt.Index, p);
//
// //create adorner marker
// CreateThumb(PlacementAlignment.BottomRight, Cursors.Cross, mprt.Index);
//
// //set index of all points that had a higher index than selected to +1
// foreach (FrameworkElement rt in adornerPanel.Children)
// {
// if (rt is MultiPointResizeThumb)
// {
// MultiPointResizeThumb t = rt as MultiPointResizeThumb;
// if (t.Index > mprt.Index)
// t.Index++;
// }
// }
//
// //set index of new point to old point index + 1
// mprt.Index = mprt.Index + 1;
// ResetThumbs();
// SelectThumb(mprt);
//
// }
// snapAngle = 10;
// }
//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;
}
@ -337,49 +337,124 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -337,49 +337,124 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
#endregion
List<Point> GetPoints()
List<PathPoint> GetPoints()
{
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) {
var figure = geometry.Figures[0] as PathFigure;
if (figure != null) {
retVal.Add(figure.StartPoint);
foreach (var s in figure.Segments) {
if (s is LineSegment)
retVal.Add(((LineSegment)s).Point);
else if (s is PolyLineSegment)
retVal.AddRange(((PolyLineSegment)s).Points);
else if (s is BezierSegment) {
retVal.Add(((BezierSegment)s).Point1);
retVal.Add(((BezierSegment)s).Point2);
retVal.Add(((BezierSegment)s).Point3);
}
else if (s is QuadraticBezierSegment) {
retVal.Add(((QuadraticBezierSegment)s).Point1);
retVal.Add(((QuadraticBezierSegment)s).Point2);
return retVal;
}
private static void AddGeometryPoints(List<PathPoint> list, Geometry geometry)
{
if (geometry is CombinedGeometry) {
var g = geometry as CombinedGeometry;
AddGeometryPoints(list, g.Geometry1);
AddGeometryPoints(list, g.Geometry2);
} else if (geometry is PathGeometry) {
var g = geometry as PathGeometry;
if (geometry!=null) {
foreach(var figure in g.Figures) {
list.Add(new PathPoint(figure.StartPoint, figure, PointType.StartPoint, (p) => figure.StartPoint = p));
foreach (var s in figure.Segments) {
if (s is LineSegment)
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);
}
}
public enum PointType{
StartPoint,
LineSegment,
BezierSegment,
ArcSegment,
QuadricBezierSegment,
return retVal;
LineGeometryStart,
LineGeometryEnd,
EllipseGeometryCenter,
RectangleGeometryP1,
RectangleGeometryP2,
RectangleGeometryP3,
RectangleGeometryP4,
}
List<Point> MovePoints(List<Point> pc, double displacementX, double displacementY, double theta, int? snapangle)
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;}
}
//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
foreach (int i in _selectedThumbs.Keys)
{
Point p = pc[i];
Point p = pc[i].Point;
//x and y is calculated from the currentl point
double x = _selectedThumbs[i].X + displacementX;
@ -394,19 +469,19 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -394,19 +469,19 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
if (Math.Abs(theta) < snapangle || 180 - Math.Abs(theta) < snapangle)
{
//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
{
//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.Y = y;
pc[i] = p;
pc[i].Point = p;
}
return pc;
}

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

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

Loading…
Cancel
Save