Browse Source

Better Path support...

pull/633/head
jogibear9988 11 years ago
parent
commit
3a9de7f816
  1. 6
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ControlStyles.xaml
  2. 14
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/Thumbs/DesignerThumb.cs
  3. 45
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/Thumbs/PointThumb.cs
  4. 5
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DefaultPlacementBehavior.cs
  5. 4
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DrawPathExtension.cs
  6. 12
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DrawPolyLineExtension.cs
  7. 254
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PathHandlerExtension.cs
  8. 12
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs
  9. 14
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementType.cs

6
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ControlStyles.xaml

@ -77,12 +77,14 @@
</Setter> </Setter>
</Style> </Style>
<Style TargetType="{x:Type Controls:PointThumb}"> <Style TargetType="{x:Type Controls:PointThumb}">
<Setter Property="Foreground" Value="Black" />
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:PointThumb}"> <ControlTemplate TargetType="{x:Type Controls:PointThumb}">
<Grid> <Grid>
<Rectangle Name="thumbRectangle" SnapsToDevicePixels="True" Stroke="Black" Fill="White" RadiusX="1.414" RadiusY="1.414" /> <Line HorizontalAlignment="Left" VerticalAlignment="Top" Stroke="{TemplateBinding Foreground}" StrokeThickness="1" StrokeDashArray="2 2" X1="3.5" Y1="3.5" X2="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=RelativeToPoint.X}" Y2="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=RelativeToPoint.Y}" Visibility="{Binding Path=RelativeToPoint, RelativeSource={RelativeSource TemplatedParent}, Converter={x:Static Converters:CollapsedWhenNull.Instance}}" />
<Ellipse Name="thumbElipse" Stroke="Blue" SnapsToDevicePixels="True" Fill="White" Visibility="Collapsed" /> <Rectangle HorizontalAlignment="Left" VerticalAlignment="Top" Width="7" Height="7" Name="thumbRectangle" SnapsToDevicePixels="True" Stroke="{TemplateBinding Foreground}" Fill="White" RadiusX="1.414" RadiusY="1.414" />
<Ellipse HorizontalAlignment="Left" VerticalAlignment="Top" Width="7" Height="7" Name="thumbElipse" Stroke="{TemplateBinding Foreground}" SnapsToDevicePixels="True" Fill="White" Visibility="Collapsed" />
<Menu Height="15" HorizontalAlignment="Left" Margin="0,-19,-19,0" VerticalAlignment="Top" Width="15" BorderThickness="0" Background="Transparent" Visibility="{Binding Path=OperationMenu, RelativeSource={RelativeSource TemplatedParent}, Converter={x:Static Converters:CollapsedWhenNull.Instance}}" > <Menu Height="15" HorizontalAlignment="Left" Margin="0,-19,-19,0" VerticalAlignment="Top" Width="15" BorderThickness="0" Background="Transparent" Visibility="{Binding Path=OperationMenu, RelativeSource={RelativeSource TemplatedParent}, Converter={x:Static Converters:CollapsedWhenNull.Instance}}" >
<MenuItem Height="15" Width="15" Padding="0" Background="Transparent" BorderThickness="1" ItemsSource="{TemplateBinding OperationMenu}"> <MenuItem Height="15" Width="15" Padding="0" Background="Transparent" BorderThickness="1" ItemsSource="{TemplateBinding OperationMenu}">
<MenuItem.Header> <MenuItem.Header>

14
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/Thumbs/DesignerThumb.cs

@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using ICSharpCode.WpfDesign.Designer.UIExtensions;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Controls.Primitives; using System.Windows.Controls.Primitives;
@ -43,7 +44,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
/// Dependency property for <see cref="OperationMenu"/>. /// Dependency property for <see cref="OperationMenu"/>.
/// </summary> /// </summary>
public static readonly DependencyProperty OperationMenuProperty = public static readonly DependencyProperty OperationMenuProperty =
DependencyProperty.Register("OperationMenu", typeof(MenuItem[]), typeof(DesignerThumb), new PropertyMetadata(null)); DependencyProperty.Register("OperationMenu", typeof(Control[]), typeof(DesignerThumb), new PropertyMetadata(null));
internal PlacementAlignment Alignment; internal PlacementAlignment Alignment;
@ -54,6 +55,13 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
DefaultStyleKeyProperty.OverrideMetadata(typeof(DesignerThumb), new FrameworkPropertyMetadata(typeof(DesignerThumb))); DefaultStyleKeyProperty.OverrideMetadata(typeof(DesignerThumb), new FrameworkPropertyMetadata(typeof(DesignerThumb)));
} }
public void ReDraw()
{
var parent = this.TryFindParent<FrameworkElement>();
if (parent != null)
parent.InvalidateArrange();
}
/// <summary> /// <summary>
/// Gets/Sets if the resize thumb is attached to the primary selection. /// Gets/Sets if the resize thumb is attached to the primary selection.
/// </summary> /// </summary>
@ -73,9 +81,9 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
/// <summary> /// <summary>
/// Gets/Sets the OperationMenu. /// Gets/Sets the OperationMenu.
/// </summary> /// </summary>
public MenuItem[] OperationMenu public Control[] OperationMenu
{ {
get { return (MenuItem[])GetValue(OperationMenuProperty); } get { return (Control[])GetValue(OperationMenuProperty); }
set { SetValue(OperationMenuProperty, value); } set { SetValue(OperationMenuProperty, value); }
} }
} }

45
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/Thumbs/PointThumb.cs

@ -19,6 +19,8 @@
using System.Windows; using System.Windows;
using ICSharpCode.WpfDesign.Adorners; using ICSharpCode.WpfDesign.Adorners;
using ICSharpCode.WpfDesign.Designer.Extensions; using ICSharpCode.WpfDesign.Designer.Extensions;
using System.Diagnostics;
using System.Windows.Data;
namespace ICSharpCode.WpfDesign.Designer.Controls namespace ICSharpCode.WpfDesign.Designer.Controls
{ {
@ -37,7 +39,36 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
public static readonly DependencyProperty IsEllipseProperty = public static readonly DependencyProperty IsEllipseProperty =
DependencyProperty.Register("IsEllipse", typeof(bool), typeof(PointThumb), new PropertyMetadata(false)); DependencyProperty.Register("IsEllipse", typeof(bool), typeof(PointThumb), new PropertyMetadata(false));
public Point Point
{
get { return (Point)GetValue(PointProperty); }
set { SetValue(PointProperty, value); }
}
// Using a DependencyProperty as the backing store for Point. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PointProperty =
DependencyProperty.Register("Point", typeof(Point), typeof(PointThumb), new PropertyMetadata(OnPointChanged));
private static void OnPointChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var pt = (PointThumb)d;
((PointPlacementSupport)pt.AdornerPlacement).p = (Point)e.NewValue;
var bndExpr = pt.GetBindingExpression(PointThumb.RelativeToPointProperty);
if (bndExpr != null)
bndExpr.UpdateTarget();
((PointThumb)d).ReDraw();
}
public Point RelativeToPoint
{
get { return (Point)GetValue(RelativeToPointProperty); }
set { SetValue(RelativeToPointProperty, value); }
}
// Using a DependencyProperty as the backing store for RelativeToPoint. This enables animation, styling, binding, etc...
public static readonly DependencyProperty RelativeToPointProperty =
DependencyProperty.Register("RelativeToPoint", typeof(Point), typeof(PointThumb), new PropertyMetadata(new Point(double.NaN, double.NaN)));
static PointThumb() static PointThumb()
{ {
//This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class. //This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
@ -48,13 +79,19 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
public PointThumb(Point point) public PointThumb(Point point)
{ {
this.AdornerPlacement = new PointPlacementSupport(point); this.AdornerPlacement = new PointPlacementSupport(point);
Point = point;
} }
public AdornerPlacement AdornerPlacement { get; private set; } public PointThumb()
{
this.AdornerPlacement = new PointPlacementSupport(Point);
}
public class PointPlacementSupport : AdornerPlacement public AdornerPlacement AdornerPlacement { get; private set; }
private class PointPlacementSupport : AdornerPlacement
{ {
private Point p; public Point p;
public PointPlacementSupport(Point point) public PointPlacementSupport(Point point)
{ {
this.p = point; this.p = point;
@ -63,7 +100,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
public override void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize) public override void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize)
{ {
double thumbsize = 7; double thumbsize = 7;
adorner.Arrange(new Rect(p.X - thumbsize / 2, p.Y - thumbsize / 2, thumbsize, thumbsize)); adorner.Arrange(new Rect(p.X - thumbsize / 2, p.Y - thumbsize / 2, adornedElementSize.Width, adornedElementSize.Height));
} }
} }
} }

5
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DefaultPlacementBehavior.cs

@ -87,8 +87,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
public virtual void SetPosition(PlacementInformation info) public virtual void SetPosition(PlacementInformation info)
{ {
if (info.Operation.Type != PlacementType.Move) if (info.Operation.Type != PlacementType.Move && info.Operation.Type != PlacementType.MovePoint)
ModelTools.Resize(info.Item, info.Bounds.Width, info.Bounds.Height); ModelTools.Resize(info.Item, info.Bounds.Width, info.Bounds.Height);
//if (info.Operation.Type == PlacementType.MovePoint)
// ModelTools.Resize(info.Item, info.Bounds.Width, info.Bounds.Height);
} }
public virtual bool CanLeaveContainer(PlacementOperation operation) public virtual bool CanLeaveContainer(PlacementOperation operation)

4
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DrawPathExtension.cs

@ -154,8 +154,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
if (services.Tool.CurrentTool is CreateComponentTool) { if (services.Tool.CurrentTool is CreateComponentTool) {
services.Tool.CurrentTool = services.Tool.PointerTool; services.Tool.CurrentTool = services.Tool.PointerTool;
} }
((DesignPanel) newLine.Services.DesignPanel).AdornerLayer.UpdateAdornersForElement(this.newLine.View, true); newLine.ReapplyAllExtensions();
base.OnStopped(); base.OnStopped();
} }

12
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DrawPolyLineExtension.cs

@ -155,18 +155,16 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
protected override void OnStopped() protected override void OnStopped()
{ {
if (changeGroup != null) if (changeGroup != null) {
{
changeGroup.Abort(); changeGroup.Abort();
changeGroup = null; changeGroup = null;
} }
if (services.Tool.CurrentTool is CreateComponentTool) if (services.Tool.CurrentTool is CreateComponentTool) {
{
services.Tool.CurrentTool = services.Tool.PointerTool; services.Tool.CurrentTool = services.Tool.PointerTool;
} }
((DesignPanel) newLine.Services.DesignPanel).AdornerLayer.UpdateAdornersForElement(this.newLine.View, true); newLine.ReapplyAllExtensions();
base.OnStopped(); base.OnStopped();
} }

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

@ -18,24 +18,21 @@
using System; using System;
using ICSharpCode.WpfDesign.Extensions; using ICSharpCode.WpfDesign.Extensions;
using ICSharpCode.WpfDesign;
using ICSharpCode.WpfDesign.Adorners; using ICSharpCode.WpfDesign.Adorners;
using ICSharpCode.WpfDesign.Designer;
using ICSharpCode.WpfDesign.Designer.Controls; using ICSharpCode.WpfDesign.Designer.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Shapes; using System.Windows.Shapes;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System;
using System.CodeDom;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Windows.Data;
using ICSharpCode.SharpDevelop.Widgets;
using ICSharpCode.WpfDesign.Designer.UIExtensions; using ICSharpCode.WpfDesign.Designer.UIExtensions;
using DragListener = ICSharpCode.WpfDesign.Designer.Controls.DragListener; using DragListener = ICSharpCode.WpfDesign.Designer.Controls.DragListener;
using System.Windows.Data;
using System.ComponentModel;
using System.Globalization;
namespace ICSharpCode.WpfDesign.Designer.Extensions namespace ICSharpCode.WpfDesign.Designer.Extensions
{ {
@ -47,12 +44,14 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
{ {
enum PathPartConvertType enum PathPartConvertType
{ {
insertPoint,
ToLineSegment, ToLineSegment,
ToBezierSegment, ToBezierSegment,
ToQuadricBezierSegment, ToQuadricBezierSegment,
ToArcSegment,
} }
protected class PathPoint protected class PathPoint : INotifyPropertyChanged
{ {
public PathPoint(Point point, Object @object, Object parentObject, Action<Point> setLambda) public PathPoint(Point point, Object @object, Object parentObject, Action<Point> setLambda)
{ {
@ -68,7 +67,15 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
public Point Point public Point Point
{ {
get { return _point; } get { return _point; }
set { _setLambda(value); } set {
if (_setLambda != null)
{
_point = value;
_setLambda(value);
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Point"));
}
}
} }
public Point ReferencePoint { get; private set; } public Point ReferencePoint { get; private set; }
@ -80,6 +87,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
public int PolyLineIndex { get; set; } public int PolyLineIndex { get; set; }
public PathPoint TargetPathPoint { get; set; } public PathPoint TargetPathPoint { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
} }
protected class PathThumb : PointThumb protected class PathThumb : PointThumb
@ -88,6 +97,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
{ {
this.Index = index; this.Index = index;
this.PathPoint = pathpoint; this.PathPoint = pathpoint;
var bnd = new Binding("Point") { Source = this.PathPoint, Mode=BindingMode.OneWay };
this.SetBinding(PointProperty, bnd);
} }
public int Index { get; set; } public int Index { get; set; }
@ -95,23 +106,57 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
public PathPoint PathPoint { get; set; } public PathPoint PathPoint { get; set; }
} }
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.Point.X - 3.5, pathPoint.Point.Y - 3.5);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
private readonly Dictionary<int, Bounds> _selectedThumbs = new Dictionary<int, Bounds>(); private readonly Dictionary<int, Bounds> _selectedThumbs = new Dictionary<int, Bounds>();
private bool _isDragging; private bool _isDragging;
ZoomControl _zoom; ZoomControl _zoom;
private MenuItem[] segmentContextMenu = null; private Control[] segmentContextMenu = null;
private Control[] arcSegmentContextMenu = null;
private List<PathPoint> pathPoints = null;
public PathHandlerExtension() public PathHandlerExtension()
{ {
var mnu0 = new MenuItem() { Header = "insert Point" };
var mnu1 = new MenuItem() { Header = "to Line Segment" }; var mnu1 = new MenuItem() { Header = "to Line Segment" };
mnu1.Click += (s, e) => ConvertPart(((DependencyObject)s).TryFindParent<PathThumb>(), PathPartConvertType.ToLineSegment); mnu1.Click += (s, e) => ConvertPart(((DependencyObject)s).TryFindParent<PathThumb>(), PathPartConvertType.ToLineSegment);
var mnu2 = new MenuItem() {Header = "to Bezier Segment"}; var mnu2 = new MenuItem() {Header = "to Bezier Segment"};
mnu2.Click += (s, e) => ConvertPart(((DependencyObject)s).TryFindParent<PathThumb>(), PathPartConvertType.ToBezierSegment); mnu2.Click += (s, e) => ConvertPart(((DependencyObject)s).TryFindParent<PathThumb>(), PathPartConvertType.ToBezierSegment);
var mnu3 = new MenuItem() {Header = "to Quadric Bezier Segment"}; var mnu3 = new MenuItem() {Header = "to Quadric Bezier Segment"};
mnu3.Click += (s, e) => ConvertPart(((DependencyObject)s).TryFindParent<PathThumb>(), PathPartConvertType.ToQuadricBezierSegment); mnu3.Click += (s, e) => ConvertPart(((DependencyObject)s).TryFindParent<PathThumb>(), PathPartConvertType.ToQuadricBezierSegment);
var mnu4 = new MenuItem() { Header = "to Arc Segment" };
mnu4.Click += (s, e) => ConvertPart(((DependencyObject)s).TryFindParent<PathThumb>(), PathPartConvertType.ToArcSegment);
segmentContextMenu = new[] {mnu1, mnu2, mnu3}; var mnu5 = new MenuItem() { Header = "is Stroked", IsChecked = true };
var mnu6 = new MenuItem() { Header = "is Smooth Join", IsChecked = true };
var mnu7 = new MenuItem() { Header = "is large Arc", IsChecked = true };
var mnu8 = new MenuItem() { Header = "Rotation Angle", IsChecked = true };
var mnu9 = new MenuItem() { Header = "SweepDirection", IsChecked = true };
segmentContextMenu = new Control[] {mnu0, new Separator(), mnu1, mnu2, mnu3, mnu4, new Separator(), mnu5, mnu6};
arcSegmentContextMenu = new Control[] { new Separator(), mnu7, mnu8, mnu9 };
} }
#region thumb methods #region thumb methods
@ -123,12 +168,17 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
var designerThumb = new PathThumb(point, index, pathpoint) {Cursor = cursor}; var designerThumb = new PathThumb(point, index, pathpoint) {Cursor = cursor};
if (pathpoint.Object is LineSegment || pathpoint.Object is PolyLineSegment || pathpoint.Object is BezierSegment || pathpoint.Object is QuadraticBezierSegment) { if (pathpoint.TargetPathPoint == null && (pathpoint.Object is LineSegment || pathpoint.Object is PolyLineSegment || pathpoint.Object is BezierSegment || pathpoint.Object is QuadraticBezierSegment || pathpoint.Object is ArcSegment)) {
designerThumb.OperationMenu = segmentContextMenu; designerThumb.OperationMenu = segmentContextMenu;
} }
if (pathpoint.TargetPathPoint != null) if (pathpoint.TargetPathPoint != null) {
designerThumb.IsEllipse = true; designerThumb.IsEllipse = true;
designerThumb.Foreground = Brushes.Blue;
var bnd = new Binding("Point") { Source = pathpoint.TargetPathPoint, Mode = BindingMode.OneWay, Converter = new RelativeToPointConverter(pathpoint) };
designerThumb.SetBinding(PathThumb.RelativeToPointProperty, bnd);
}
AdornerPanel.SetPlacement(designerThumb, designerThumb.AdornerPlacement); AdornerPanel.SetPlacement(designerThumb, designerThumb.AdornerPlacement);
adornerPanel.Children.Add(designerThumb); adornerPanel.Children.Add(designerThumb);
@ -144,7 +194,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
return designerThumb; return designerThumb;
} }
private static void ConvertPart(PathThumb senderThumb, PathPartConvertType convertType) private void ConvertPart(PathThumb senderThumb, PathPartConvertType convertType)
{ {
if (senderThumb.PathPoint.ParentObject is PathFigure) if (senderThumb.PathPoint.ParentObject is PathFigure)
{ {
@ -182,6 +232,9 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
case PathPartConvertType.ToQuadricBezierSegment: case PathPartConvertType.ToQuadricBezierSegment:
newSegment = new QuadraticBezierSegment() { Point1 = point - new Vector(40, 40), Point2 = point }; newSegment = new QuadraticBezierSegment() { Point1 = point - new Vector(40, 40), Point2 = point };
break; break;
case PathPartConvertType.ToArcSegment:
newSegment = new ArcSegment() { Point = point, Size = new Size(20, 20) };
break;
default: default:
newSegment = new LineSegment() { Point = point }; newSegment = new LineSegment() { Point = point };
break; break;
@ -189,6 +242,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
pathFigure.Segments.Insert(idx, newSegment); pathFigure.Segments.Insert(idx, newSegment);
} }
this.ExtendedItem.ReapplyAllExtensions();
} }
private void ResetThumbs() private void ResetThumbs()
@ -220,28 +275,26 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
var mprt = sender as PathThumb; var mprt = sender as PathThumb;
if (mprt != null) if (mprt != null)
{ {
//shift+ctrl will remove selected point ////shift+ctrl will remove selected point
if ((Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) && //if ((Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) &&
(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) // (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
{ //{
//unselect all points // //unselect all points
ResetThumbs(); // ResetThumbs();
var points = GetPoints();
// //iterate thumbs to lower index of remaining thumbs
//iterate thumbs to lower index of remaining thumbs // foreach (PathThumb m in adornerPanel.Children) {
foreach (PathThumb m in adornerPanel.Children) // if (m.Index > mprt.Index)
{ // m.Index--;
if (m.Index > mprt.Index) // }
m.Index--;
} // //remove point and thumb
// pathPoints.RemoveAt(mprt.Index);
//remove point and thumb // adornerPanel.Children.Remove(mprt);
points.RemoveAt(mprt.Index);
adornerPanel.Children.Remove(mprt); // Invalidate();
//}
Invalidate(); //else
}
else
{ {
//if not keyboard ctrl is pressed and selected point is not previously selected, clear selection //if not keyboard ctrl is pressed and selected point is not previously selected, clear selection
if (!_selectedThumbs.ContainsKey(mprt.Index) & !Keyboard.IsKeyDown(Key.LeftCtrl) & if (!_selectedThumbs.ContainsKey(mprt.Index) & !Keyboard.IsKeyDown(Key.LeftCtrl) &
@ -279,7 +332,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
_zoom = designPanel.TryFindParent<ZoomControl>(); _zoom = designPanel.TryFindParent<ZoomControl>();
if (resizeBehavior != null) if (resizeBehavior != null)
operation = PlacementOperation.Start(extendedItemArray, PlacementType.Resize); operation = PlacementOperation.Start(extendedItemArray, PlacementType.MovePoint);
else else
{ {
changeGroup = ExtendedItem.Context.OpenGroup("Resize", extendedItemArray); changeGroup = ExtendedItem.Context.OpenGroup("Resize", extendedItemArray);
@ -337,8 +390,6 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
protected void drag_Changed(DragListener drag) protected void drag_Changed(DragListener drag)
{ {
var points = GetPoints();
var mprt = drag.Target as PathThumb; var mprt = drag.Target as PathThumb;
if (mprt != null) if (mprt != null)
{ {
@ -350,72 +401,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
dx = drag.Delta.X * (1 / _zoom.CurrentZoom); dx = drag.Delta.X * (1 / _zoom.CurrentZoom);
dy = drag.Delta.Y * (1 / _zoom.CurrentZoom); dy = drag.Delta.Y * (1 / _zoom.CurrentZoom);
} }
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].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);
}
//snappingAngle is used for snapping function to horizontal or vertical plane in line drawing, and is activated by pressing ctrl or shift button
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].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 MultiPathThumb)
// {
// MultiPathThumb t = rt as MultiPathThumb;
// 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))
{
snapAngle = 10;
}
//snapping occurs within 45 degree intervals that is line will always be horizontal or vertical if alt is pressed
else if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
{
snapAngle = 45;
}
_isDragging = true; _isDragging = true;
points = MovePoints(points, dx, dy, theta, snapAngle); MovePoints(pathPoints, dx, dy);
} }
ChangeOperation(points); ChangeOperation(pathPoints);
(drag.Target as DesignerThumb).InvalidateArrange();
} }
protected void drag_Completed(DragListener drag) protected void drag_Completed(DragListener drag)
@ -441,12 +431,12 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
{ {
base.OnInitialized(); base.OnInitialized();
var points = GetPoints(); pathPoints = GetPoints();
resizeThumbs = new List<DesignerThumb>(); resizeThumbs = new List<DesignerThumb>();
for (int i = 0; i < points.Count; i++) for (int i = 0; i < pathPoints.Count; i++)
{ {
CreateThumb(PlacementAlignment.BottomRight, Cursors.Cross, i, points[i]); CreateThumb(PlacementAlignment.BottomRight, Cursors.Cross, i, pathPoints[i]);
} }
Invalidate(); Invalidate();
@ -481,6 +471,12 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
var g = geometry as CombinedGeometry; var g = geometry as CombinedGeometry;
AddGeometryPoints(list, g.Geometry1); AddGeometryPoints(list, g.Geometry1);
AddGeometryPoints(list, g.Geometry2); AddGeometryPoints(list, g.Geometry2);
} else if (geometry is GeometryGroup)
{
var gg = geometry as GeometryGroup;
foreach (var g in gg.Children) {
AddGeometryPoints(list, g);
}
} else if (geometry is PathGeometry) { } else if (geometry is PathGeometry) {
var g = geometry as PathGeometry; var g = geometry as PathGeometry;
if (geometry!=null) { if (geometry!=null) {
@ -489,27 +485,36 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
foreach (var s in figure.Segments) { foreach (var s in figure.Segments) {
if (s is LineSegment) if (s is LineSegment)
list.Add(new PathPoint(((LineSegment)s).Point, s, figure, (p) => ((LineSegment)s).Point = p)); list.Add(new PathPoint(((LineSegment)s).Point, s, figure, (p) => ((LineSegment)s).Point = p));
else if (s is PolyLineSegment) { else if (s is PolyLineSegment)
{
var poly = s as PolyLineSegment; var poly = s as PolyLineSegment;
for(int n=0; n<poly.Points.Count; n++) for (int n = 0; n < poly.Points.Count; n++)
{ {
var closure_n = n; var closure_n = n;
list.Add(new PathPoint(poly.Points[closure_n], s, figure, (p) => poly.Points[closure_n] = p) { PolyLineIndex = closure_n }); list.Add(new PathPoint(poly.Points[closure_n], s, figure, (p) => poly.Points[closure_n] = p) { PolyLineIndex = closure_n });
} }
} }
else if (s is BezierSegment) { else if (s is BezierSegment)
{
var pathp = new PathPoint(((BezierSegment)s).Point3, s, figure, (p) => ((BezierSegment)s).Point3 = p); var pathp = new PathPoint(((BezierSegment)s).Point3, s, figure, (p) => ((BezierSegment)s).Point3 = p);
list.Add(new PathPoint(((BezierSegment)s).Point1, s, figure, (p) => ((BezierSegment)s).Point1 = p) { TargetPathPoint = pathp}); var previous = list.Last();
list.Add(new PathPoint(((BezierSegment)s).Point1, s, figure, (p) => ((BezierSegment)s).Point1 = p) { TargetPathPoint = previous });
list.Add(new PathPoint(((BezierSegment)s).Point2, s, figure, (p) => ((BezierSegment)s).Point2 = p) { TargetPathPoint = pathp }); list.Add(new PathPoint(((BezierSegment)s).Point2, s, figure, (p) => ((BezierSegment)s).Point2 = p) { TargetPathPoint = pathp });
list.Add(pathp); list.Add(pathp);
} }
else if (s is QuadraticBezierSegment) { else if (s is QuadraticBezierSegment)
{
var pathp = new PathPoint(((QuadraticBezierSegment)s).Point2, s, figure, (p) => ((QuadraticBezierSegment)s).Point2 = p); var pathp = new PathPoint(((QuadraticBezierSegment)s).Point2, s, figure, (p) => ((QuadraticBezierSegment)s).Point2 = p);
list.Add(new PathPoint(((QuadraticBezierSegment)s).Point1, s, figure, (p) => ((QuadraticBezierSegment)s).Point1 = p) { TargetPathPoint = pathp }); list.Add(new PathPoint(((QuadraticBezierSegment)s).Point1, s, figure, (p) => ((QuadraticBezierSegment)s).Point1 = p) { TargetPathPoint = pathp });
list.Add(pathp); list.Add(pathp);
} }
else if (s is ArcSegment) else if (s is ArcSegment)
list.Add(new PathPoint(((ArcSegment)s).Point, s, figure, (p) => ((ArcSegment)s).Point = p)); {
var arc = ((ArcSegment)s);
var pathp = new PathPoint(arc.Point, s, figure, (p) => arc.Point = p);
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))) { TargetPathPoint = pathp });
list.Add(pathp);
}
} }
} }
} }
@ -529,7 +534,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
} }
} }
List<PathPoint> MovePoints(List<PathPoint> pc, double displacementX, double displacementY, double theta, int? snapangle) List<PathPoint> MovePoints(List<PathPoint> pc, double displacementX, double displacementY)
{ {
//iterate all selected points //iterate all selected points
foreach (int i in _selectedThumbs.Keys) foreach (int i in _selectedThumbs.Keys)
@ -540,25 +545,6 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
double x = _selectedThumbs[i].X + displacementX; double x = _selectedThumbs[i].X + displacementX;
double y = _selectedThumbs[i].Y + displacementY; double y = _selectedThumbs[i].Y + displacementY;
//if snap is applied
if (snapangle != null)
{
if (_selectedThumbs.Count > 0)
{
//horizontal snap
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].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].Point.X : x - displacementX;
}
}
}
p.X = x; p.X = x;
p.Y = y; p.Y = y;
pc[i].Point = p; pc[i].Point = p;
@ -570,7 +556,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
public bool InvokeDefaultAction public bool InvokeDefaultAction
{ {
get { return _selectedThumbs.Count == 0 || _selectedThumbs.Count == GetPoints().Count - 1; } get { return _selectedThumbs.Count == 0 || _selectedThumbs.Count == pathPoints.Count - 1; }
} }
int _movingDistance; int _movingDistance;
@ -590,7 +576,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
var dx2 = (e.Key == Key.Right) ? Keyboard.IsKeyDown(Key.LeftShift) ? _movingDistance + 10 : _movingDistance + 1 : 0; var dx2 = (e.Key == Key.Right) ? Keyboard.IsKeyDown(Key.LeftShift) ? _movingDistance + 10 : _movingDistance + 1 : 0;
var dy2 = (e.Key == Key.Down) ? Keyboard.IsKeyDown(Key.LeftShift) ? _movingDistance + 10 : _movingDistance + 1 : 0; var dy2 = (e.Key == Key.Down) ? Keyboard.IsKeyDown(Key.LeftShift) ? _movingDistance + 10 : _movingDistance + 1 : 0;
ChangeOperation(MovePoints(GetPoints(), dx1 + dx2, dy1 + dy2, 0, null)); ChangeOperation(MovePoints(pathPoints, dx1 + dx2, dy1 + dy2));
_movingDistance = (dx1 + dx2 + dy1 + dy2); _movingDistance = (dx1 + dx2 + dy1 + dy2);
} }

12
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs

@ -23,6 +23,7 @@ using System.Diagnostics;
using System.Windows; using System.Windows;
using ICSharpCode.WpfDesign.Extensions; using ICSharpCode.WpfDesign.Extensions;
using System.Linq;
namespace ICSharpCode.WpfDesign namespace ICSharpCode.WpfDesign
{ {
@ -196,6 +197,17 @@ namespace ICSharpCode.WpfDesign
}); });
} }
} }
public void ReapplyAllExtensions()
{
var manager = this.Services.GetService<Extensions.ExtensionManager>();
foreach (var e in this._extensions.ToList()) {
ApplyUnapplyExtensionServer(manager, false, e.Server);
ApplyUnapplyExtensionServer(manager, true, e.Server);
}
}
#endregion #endregion
#region Manage behavior #region Manage behavior

14
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementType.cs

@ -25,6 +25,12 @@ namespace ICSharpCode.WpfDesign
/// </summary> /// </summary>
public sealed class PlacementType public sealed class PlacementType
{ {
/// <summary>
/// Placement is done by Moving a inner Point (for Example on Path, Line, ...)
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly PlacementType MovePoint = Register("MovePoint");
/// <summary> /// <summary>
/// Placement is done by resizing an element in a drag'n'drop operation. /// Placement is done by resizing an element in a drag'n'drop operation.
/// </summary> /// </summary>
@ -51,10 +57,10 @@ namespace ICSharpCode.WpfDesign
public static readonly PlacementType Delete = Register("Delete"); public static readonly PlacementType Delete = Register("Delete");
/// <summary> /// <summary>
/// Inserting from Cliboard /// Inserting from Cliboard
/// </summary> /// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly PlacementType PasteItem = Register("PasteItem"); public static readonly PlacementType PasteItem = Register("PasteItem");
readonly string name; readonly string name;

Loading…
Cancel
Save