@ -1,11 +1,21 @@
/ *
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
* Created by SharpDevelop .
//
* User : trubra
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
* Date : 2 0 1 4 - 1 2 - 2 2
// software and associated documentation files (the "Software"), to deal in the Software
* Time : 1 0 : 3 4
// 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 change this template use Tools | Options | Coding | Edit Standard Headers .
// 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 ;
using ICSharpCode.WpfDesign.Extensions ;
using ICSharpCode.WpfDesign.Extensions ;
using ICSharpCode.WpfDesign ;
using ICSharpCode.WpfDesign ;
@ -21,430 +31,423 @@ using System;
using System.Collections.Generic ;
using System.Collections.Generic ;
using System.Diagnostics ;
using System.Diagnostics ;
using System.Linq ;
using System.Linq ;
using ICSharpCode.WpfDesign.Designer.UIExtensions ;
namespace ICSharpCode.WpfDesign.Designer.Extensions
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
{
/// <summary>
/// <summary>
/// Description of PolyLineHandlerExtension.
/// Description of PolyLineHandlerExtension.
/// </summary>
/// </summary>
[ExtensionFor(typeof(Polyline), OverrideExtensions = new Type[] { typeof ( ResizeThumbExtension ) , typeof ( SelectedElementRectangleExtension ) , typeof ( CanvasPositionExtension ) , typeof ( QuickOperationMenuExtension ) , typeof ( RotateThumbExtension ) , typeof ( RenderTransformOriginExtension ) , typeof ( InPlaceEditorExtension ) , typeof ( SizeDisplayExtension ) } ) ]
[ExtensionFor(typeof(Polyline), OverrideExtensions = new Type[] { typeof ( ResizeThumbExtension ) , typeof ( SelectedElementRectangleExtension ) , typeof ( CanvasPositionExtension ) , typeof ( QuickOperationMenuExtension ) , typeof ( RotateThumbExtension ) , typeof ( RenderTransformOriginExtension ) , typeof ( InPlaceEditorExtension ) , typeof ( SizeDisplayExtension ) , typeof ( SkewThumbExtension ) } ) ]
internal class PolyLineHandlerExtension : LineExtensionBase , IKeyDown , IKeyUp
internal class PolyLineHandlerExtension : LineExtensionBase , IKeyDown , IKeyUp
{
{
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 ;
#region thumb methods
#region thumb methods
protected ResizeThumb CreateThumb ( PlacementAlignment alignment , Cursor cursor , int index )
protected ResizeThumb CreateThumb ( PlacementAlignment alignment , Cursor cursor , int index )
{
{
ResizeThumb resizeThumb = new MultiPointResizeThumb { Index = index , Alignment = alignment , Cursor = cursor , IsPrimarySelection = true } ;
ResizeThumb resizeThumb = new MultiPointResizeThumb { Index = index , Alignment = alignment , Cursor = cursor , IsPrimarySelection = true } ;
AdornerPlacement ap = Place ( ref resizeThumb , alignment , index ) ;
AdornerPlacement ap = Place ( ref resizeThumb , alignment , index ) ;
( resizeThumb as MultiPointResizeThumb ) . AdornerPlacement = ap ;
( resizeThumb as MultiPointResizeThumb ) . AdornerPlacement = ap ;
AdornerPanel . SetPlacement ( resizeThumb , ap ) ;
AdornerPanel . SetPlacement ( resizeThumb , ap ) ;
adornerPanel . Children . Add ( resizeThumb ) ;
adornerPanel . Children . Add ( resizeThumb ) ;
DragListener drag = new DragListener ( resizeThumb ) ;
DragListener drag = new DragListener ( resizeThumb ) ;
WeakEventManager < ResizeThumb , MouseButtonEventArgs > . AddHandler ( resizeThumb , "PreviewMouseLeftButtonDown" , ResizeThumbOnMouseLeftButtonUp ) ;
WeakEventManager < ResizeThumb , MouseButtonEventArgs > . AddHandler ( resizeThumb , "PreviewMouseLeftButtonDown" , ResizeThumbOnMouseLeftButtonUp ) ;
drag . Started + = drag_Started ;
drag . Started + = drag_Started ;
drag . Changed + = drag_Changed ;
drag . Changed + = drag_Changed ;
drag . Completed + = drag_Completed ;
drag . Completed + = drag_Completed ;
return resizeThumb ;
return resizeThumb ;
}
}
private void ResetThumbs ( )
private void ResetThumbs ( )
{
{
foreach ( FrameworkElement rt in adornerPanel . Children )
foreach ( FrameworkElement rt in adornerPanel . Children )
{
{
if ( rt is ResizeThumb )
if ( rt is ResizeThumb )
( rt as ResizeThumb ) . IsPrimarySelection = true ;
( rt as ResizeThumb ) . IsPrimarySelection = true ;
}
}
_ selectedThumbs . Clear ( ) ;
_ selectedThumbs . Clear ( ) ;
}
}
private void SelectThumb ( MultiPointResizeThumb mprt )
private void SelectThumb ( MultiPointResizeThumb mprt )
{
{
PointCollection points = GetPointCollection ( ) ;
PointCollection points = GetPointCollection ( ) ;
Point p = points [ mprt . Index ] ;
Point p = points [ mprt . Index ] ;
_ 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 ;
}
}
#endregion
#endregion
#region eventhandlers
#region eventhandlers
private void ResizeThumbOnMouseLeftButtonUp ( object sender , MouseButtonEventArgs mouseButtonEventArgs )
private void ResizeThumbOnMouseLeftButtonUp ( object sender , MouseButtonEventArgs mouseButtonEventArgs )
{
{
//get current thumb
//get current thumb
MultiPointResizeThumb mprt = sender as MultiPointResizeThumb ;
MultiPointResizeThumb mprt = sender as MultiPointResizeThumb ;
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 ( ) ;
PointCollection points = GetPointCollection ( ) ;
PointCollection points = GetPointCollection ( ) ;
//iterate thumbs to lower index of remaining thumbs
//iterate thumbs to lower index of remaining thumbs
foreach ( MultiPointResizeThumb m in adornerPanel . Children )
foreach ( MultiPointResizeThumb m in adornerPanel . Children )
{
{
if ( m . Index > mprt . Index )
if ( m . Index > mprt . Index )
m . Index - - ;
m . Index - - ;
}
}
//remove point and thumb
//remove point and thumb
points . RemoveAt ( mprt . Index ) ;
points . RemoveAt ( mprt . Index ) ;
adornerPanel . Children . Remove ( mprt ) ;
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 ) &
! Keyboard . IsKeyDown ( Key . RightCtrl ) )
! Keyboard . IsKeyDown ( Key . RightCtrl ) )
{
{
ResetThumbs ( ) ;
ResetThumbs ( ) ;
}
}
//add selected thumb, if ctrl pressed this could be all points in poly
//add selected thumb, if ctrl pressed this could be all points in poly
if ( ! _ selectedThumbs . ContainsKey ( mprt . Index ) )
if ( ! _ selectedThumbs . ContainsKey ( mprt . Index ) )
SelectThumb ( mprt ) ;
SelectThumb ( mprt ) ;
_ isDragging = false ;
_ isDragging = false ;
}
}
}
}
}
}
// TODO : Remove all hide/show extensions from here.
// TODO : Remove all hide/show extensions from here.
protected void drag_Started ( DragListener drag )
protected void drag_Started ( DragListener drag )
{
{
//get current thumb
//get current thumb
MultiPointResizeThumb mprt = ( drag . Target as MultiPointResizeThumb ) ;
MultiPointResizeThumb mprt = ( drag . Target as MultiPointResizeThumb ) ;
if ( mprt ! = null )
if ( mprt ! = null )
{
{
SetOperation ( ) ;
SetOperation ( ) ;
}
}
}
}
void SetOperation ( )
void SetOperation ( )
{
{
var designPanel = ExtendedItem . Services . DesignPanel as DesignPanel ;
var designPanel = ExtendedItem . Services . DesignPanel as DesignPanel ;
if ( designPanel ! = null )
_ zoom = designPanel . TryFindParent < ZoomControl > ( ) ;
{
var p = VisualTreeHelper . GetParent ( designPanel ) ;
if ( resizeBehavior ! = null )
while ( p ! = null & & ! ( p is ZoomControl ) )
operation = PlacementOperation . Start ( extendedItemArray , PlacementType . Resize ) ;
{
else
p = VisualTreeHelper . GetParent ( p ) ;
{
}
changeGroup = ExtendedItem . Context . OpenGroup ( "Resize" , extendedItemArray ) ;
_ zoom = p as ZoomControl ;
}
}
_ isResizing = true ;
}
if ( resizeBehavior ! = null )
operation = PlacementOperation . Start ( extendedItemArray , PlacementType . Resize ) ;
void ChangeOperation ( PointCollection points )
else
{
{
//this is for SharpDevelop built in undo functionality
changeGroup = ExtendedItem . Context . OpenGroup ( "Resize" , extendedItemArray ) ;
if ( operation ! = null )
}
{
_ isResizing = true ;
var info = operation . PlacedItems [ 0 ] ;
}
var result = info . OriginalBounds ;
void ChangeOperation ( PointCollection points )
IEnumerable < double > xs = points . Select ( x = > x . X ) ;
{
IEnumerable < double > ys = points . Select ( y = > y . Y ) ;
//this is for SharpDevelop built in undo functionality
result . X = ( double ) ( info . Item . Properties . GetAttachedProperty ( Canvas . LeftProperty ) . ValueOnInstance ) ;
if ( operation ! = null )
result . Y = ( double ) ( info . Item . Properties . GetAttachedProperty ( Canvas . TopProperty ) . ValueOnInstance ) ;
{
result . Width = xs . Max ( ) - xs . Min ( ) ;
var info = operation . PlacedItems [ 0 ] ;
result . Height = ys . Max ( ) - ys . Min ( ) ;
var result = info . OriginalBounds ;
info . Bounds = result . Round ( ) ;
IEnumerable < double > xs = points . Select ( x = > x . X ) ;
operation . CurrentContainerBehavior . BeforeSetPosition ( operation ) ;
IEnumerable < double > ys = points . Select ( y = > y . Y ) ;
operation . CurrentContainerBehavior . SetPosition ( info ) ;
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 ( ) ;
ResetWidthHeightProperties ( ) ;
result . Height = ys . Max ( ) - ys . Min ( ) ;
}
info . Bounds = result . Round ( ) ;
operation . CurrentContainerBehavior . BeforeSetPosition ( operation ) ;
void CommitOperation ( )
operation . CurrentContainerBehavior . SetPosition ( info ) ;
{
}
if ( operation ! = null )
{
ResetWidthHeightProperties ( ) ;
PointCollection points ;
Polygon pg = ExtendedItem . View as Polygon ;
}
Polyline pl = ExtendedItem . View as Polyline ;
if ( pl = = null )
void CommitOperation ( )
{
{
points = pg . Points ;
if ( operation ! = null )
{
}
PointCollection points ;
else
Polygon pg = ExtendedItem . View as Polygon ;
{
Polyline pl = ExtendedItem . View as Polyline ;
points = pl . Points ;
if ( pl = = null )
}
{
points = pg . Points ;
foreach ( int i in _ selectedThumbs . Keys )
{
}
_ selectedThumbs [ i ] . X = points [ i ] . X ;
else
_ selectedThumbs [ i ] . Y = points [ i ] . Y ;
{
}
points = pl . Points ;
ExtendedItem . Properties . GetProperty ( pl ! = null ? Polyline . PointsProperty : Polygon . PointsProperty ) . SetValue ( points ) ;
}
ResetWidthHeightProperties ( ) ;
operation . Commit ( ) ;
foreach ( int i in _ selectedThumbs . Keys )
{
operation = null ;
_ selectedThumbs [ i ] . X = points [ i ] . X ;
}
_ selectedThumbs [ i ] . Y = points [ i ] . Y ;
else
}
{
ExtendedItem . Properties . GetProperty ( pl ! = null ? Polyline . PointsProperty : Polygon . PointsProperty ) . SetValue ( points ) ;
changeGroup . Commit ( ) ;
ResetWidthHeightProperties ( ) ;
changeGroup = null ;
operation . Commit ( ) ;
}
_ isResizing = false ;
operation = null ;
}
ResetWidthHeightProperties ( ) ;
else
Invalidate ( ) ;
{
}
changeGroup . Commit ( ) ;
changeGroup = null ;
protected void drag_Changed ( DragListener drag )
}
{
_ isResizing = false ;
PointCollection points = GetPointCollection ( ) ;
ResetWidthHeightProperties ( ) ;
MultiPointResizeThumb mprt = drag . Target as MultiPointResizeThumb ;
Invalidate ( ) ;
if ( mprt ! = null )
}
{
double dx = 0 ;
protected void drag_Changed ( DragListener drag )
double dy = 0 ;
{
//if has zoomed
PointCollection points = GetPointCollection ( ) ;
if ( _ zoom ! = null )
{
MultiPointResizeThumb mprt = drag . Target as MultiPointResizeThumb ;
dx = drag . Delta . X * ( 1 / _ zoom . CurrentZoom ) ;
if ( mprt ! = null )
dy = drag . Delta . Y * ( 1 / _ zoom . CurrentZoom ) ;
{
}
double dx = 0 ;
double dy = 0 ;
Double theta ;
//if has zoomed
//if one point selected snapping angle is calculated in relation to previous point
if ( _ zoom ! = null )
if ( _ selectedThumbs . Count = = 1 )
{
{
dx = drag . Delta . X * ( 1 / _ zoom . CurrentZoom ) ;
theta = ( 1 8 0 / Math . PI ) * Math . Atan2 ( _ selectedThumbs [ mprt . Index ] . Y + dy - points [ mprt . Index - 1 ] . Y , _ selectedThumbs [ mprt . Index ] . X + dx - points [ mprt . Index - 1 ] . X ) ;
dy = drag . Delta . Y * ( 1 / _ zoom . CurrentZoom ) ;
}
}
else //if multiple points snapping angle is calculated in relation to mouse dragging angle
{
Double theta ;
theta = ( 1 8 0 / Math . PI ) * Math . Atan2 ( dy , dx ) ;
//if one point selected snapping angle is calculated in relation to previous point
}
if ( _ selectedThumbs . Count = = 1 )
{
//snappingAngle is used for snapping function to horizontal or vertical plane in line drawing, and is activated by pressing ctrl or shift button
theta = ( 1 8 0 / Math . PI ) * Math . Atan2 ( _ selectedThumbs [ mprt . Index ] . Y + dy - points [ mprt . Index - 1 ] . Y , _ selectedThumbs [ mprt . Index ] . X + dx - points [ mprt . Index - 1 ] . X ) ;
int? snapAngle = null ;
}
else //if multiple points snapping angle is calculated in relation to mouse dragging angle
//shift+alt gives a new point
{
if ( ( Keyboard . IsKeyDown ( Key . LeftShift ) | | Keyboard . IsKeyDown ( Key . RightShift ) ) & & ( Keyboard . IsKeyDown ( Key . LeftAlt ) | | Keyboard . IsKeyDown ( Key . RightAlt ) ) )
theta = ( 1 8 0 / Math . PI ) * Math . Atan2 ( dy , dx ) ;
{
}
//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
//snappingAngle is used for snapping function to horizontal or vertical plane in line drawing, and is activated by pressing ctrl or shift button
//so it could be many thousands of times during a single dragging
int? snapAngle = null ;
if ( ! _ isDragging & & _ selectedThumbs . Count = = 1 & & ( Math . Abs ( dx ) > 0 | | Math . Abs ( dy ) > 0 ) )
{
//shift+alt gives a new point
if ( ( Keyboard . IsKeyDown ( Key . LeftShift ) | | Keyboard . IsKeyDown ( Key . RightShift ) ) & & ( Keyboard . IsKeyDown ( Key . LeftAlt ) | | Keyboard . IsKeyDown ( Key . RightAlt ) ) )
//duplicate point that is selected
{
Point p = points [ mprt . Index ] ;
//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
//insert duplicate
//so it could be many thousands of times during a single dragging
points . Insert ( mprt . Index , p ) ;
if ( ! _ isDragging & & _ selectedThumbs . Count = = 1 & & ( Math . Abs ( dx ) > 0 | | Math . Abs ( dy ) > 0 ) )
{
//create adorner marker
CreateThumb ( PlacementAlignment . BottomRight , Cursors . SizeNWSE , mprt . Index ) ;
//duplicate point that is selected
Point p = points [ mprt . Index ] ;
//set index of all points that had a higher index than selected to +1
foreach ( FrameworkElement rt in adornerPanel . Children )
//insert duplicate
{
points . Insert ( mprt . Index , p ) ;
if ( rt is MultiPointResizeThumb )
{
//create adorner marker
MultiPointResizeThumb t = rt as MultiPointResizeThumb ;
CreateThumb ( PlacementAlignment . BottomRight , Cursors . SizeNWSE , mprt . Index ) ;
if ( t . Index > mprt . Index )
t . 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 )
//set index of new point to old point index + 1
{
mprt . Index = mprt . Index + 1 ;
MultiPointResizeThumb t = rt as MultiPointResizeThumb ;
ResetThumbs ( ) ;
if ( t . Index > mprt . Index )
SelectThumb ( mprt ) ;
t . Index + + ;
}
}
}
snapAngle = 1 0 ;
}
//set index of new point to old point index + 1
mprt . Index = mprt . Index + 1 ;
//snapping occurs when mouse is within 10 degrees from horizontal or vertical plane if shift is pressed
ResetThumbs ( ) ;
else if ( Keyboard . IsKeyDown ( Key . LeftShift ) | | Keyboard . IsKeyDown ( Key . RightShift ) )
SelectThumb ( mprt ) ;
{
snapAngle = 1 0 ;
}
}
snapAngle = 1 0 ;
//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 ) )
{
//snapping occurs when mouse is within 10 degrees from horizontal or vertical plane if shift is pressed
snapAngle = 4 5 ;
else if ( Keyboard . IsKeyDown ( Key . LeftShift ) | | Keyboard . IsKeyDown ( Key . RightShift ) )
}
{
_ isDragging = true ;
snapAngle = 1 0 ;
points = MovePoints ( points , dx , dy , theta , snapAngle ) ;
}
//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 ) )
ChangeOperation ( points ) ;
{
( drag . Target as ResizeThumb ) . InvalidateArrange ( ) ;
snapAngle = 4 5 ;
}
_ isDragging = true ;
}
points = MovePoints ( points , dx , dy , theta , snapAngle ) ;
protected void drag_Completed ( DragListener drag )
}
{
ChangeOperation ( points ) ;
MultiPointResizeThumb mprt = drag . Target as MultiPointResizeThumb ;
( drag . Target as ResizeThumb ) . InvalidateArrange ( ) ;
if ( mprt ! = null )
{
if ( operation ! = null & & drag . IsCanceled )
}
{
operation . Abort ( ) ;
protected void drag_Completed ( DragListener drag )
}
{
else if ( drag . IsCanceled )
MultiPointResizeThumb mprt = drag . Target as MultiPointResizeThumb ;
{
if ( mprt ! = null )
changeGroup . Abort ( ) ;
{
}
if ( operation ! = null & & drag . IsCanceled )
CommitOperation ( ) ;
{
}
operation . Abort ( ) ;
}
}
else if ( drag . IsCanceled )
{
changeGroup . Abort ( ) ;
protected override void OnInitialized ( )
}
{
CommitOperation ( ) ;
base . OnInitialized ( ) ;
}
}
PointCollection points = GetPointCollection ( ) ;
if ( ExtendedItem . Properties [ Shape . StrokeProperty ] . ValueOnInstance = = null )
{
protected override void OnInitialized ( )
ExtendedItem . Properties [ Shape . StrokeProperty ] . SetValue ( Colors . Black ) ;
{
ExtendedItem . Properties [ Shape . StrokeThicknessProperty ] . SetValue ( 2d ) ;
base . OnInitialized ( ) ;
ExtendedItem . Properties [ Shape . StretchProperty ] . SetValue ( Stretch . None ) ;
points . AddRange ( new List < Point > { new Point ( 0 , 0 ) , new Point ( 2 0 , 2 0 ) } ) ;
PointCollection points = GetPointCollection ( ) ;
ExtendedItem . Properties . GetProperty ( ExtendedItem . View as Polyline ! = null ? Polyline . PointsProperty : Polygon . PointsProperty ) . SetValue ( points ) ;
}
if ( ExtendedItem . Properties [ Shape . StrokeProperty ] . ValueOnInstance = = null )
{
resizeThumbs = new List < ResizeThumb > ( ) ;
ExtendedItem . Properties [ Shape . StrokeProperty ] . SetValue ( Colors . Black ) ;
for ( int i = 1 ; i < points . Count ; i + + )
ExtendedItem . Properties [ Shape . StrokeThicknessProperty ] . SetValue ( 2d ) ;
{
ExtendedItem . Properties [ Shape . StretchProperty ] . SetValue ( Stretch . None ) ;
CreateThumb ( PlacementAlignment . BottomRight , Cursors . SizeNWSE , i ) ;
points . AddRange ( new List < Point > { new Point ( 0 , 0 ) , new Point ( 2 0 , 2 0 ) } ) ;
}
ExtendedItem . Properties . GetProperty ( ExtendedItem . View as Polyline ! = null ? Polyline . PointsProperty : Polygon . PointsProperty ) . SetValue ( points ) ;
}
Invalidate ( ) ;
resizeThumbs = new List < ResizeThumb > ( ) ;
ResetWidthHeightProperties ( ) ;
for ( int i = 1 ; i < points . Count ; i + + )
{
ResetThumbs ( ) ;
CreateThumb ( PlacementAlignment . BottomRight , Cursors . SizeNWSE , i ) ;
_ isDragging = false ;
}
extendedItemArray [ 0 ] = ExtendedItem ;
Invalidate ( ) ;
ExtendedItem . PropertyChanged + = OnPropertyChanged ;
Services . Selection . PrimarySelectionChanged + = OnPrimarySelectionChanged ;
ResetWidthHeightProperties ( ) ;
resizeBehavior = PlacementOperation . GetPlacementBehavior ( extendedItemArray ) ;
UpdateAdornerVisibility ( ) ;
ResetThumbs ( ) ;
OnPrimarySelectionChanged ( null , null ) ;
_ isDragging = false ;
}
extendedItemArray [ 0 ] = ExtendedItem ;
#endregion
ExtendedItem . PropertyChanged + = OnPropertyChanged ;
Services . Selection . PrimarySelectionChanged + = OnPrimarySelectionChanged ;
PointCollection GetPointCollection ( )
resizeBehavior = PlacementOperation . GetPlacementBehavior ( extendedItemArray ) ;
{
UpdateAdornerVisibility ( ) ;
Polygon pg = ExtendedItem . View as Polygon ;
OnPrimarySelectionChanged ( null , null ) ;
Polyline pl = ExtendedItem . View as Polyline ;
}
return pl = = null ? pg . Points : pl . Points ;
#endregion
}
PointCollection GetPointCollection ( )
PointCollection MovePoints ( PointCollection pc , double displacementX , double displacementY , double theta , int? snapangle )
{
{
Polygon pg = ExtendedItem . View as Polygon ;
//iterate all selected points
Polyline pl = ExtendedItem . View as Polyline ;
foreach ( int i in _ selectedThumbs . Keys )
{
return pl = = null ? pg . Points : pl . Points ;
Point p = pc [ i ] ;
}
//x and y is calculated from the currentl point
PointCollection MovePoints ( PointCollection pc , double displacementX , double displacementY , double theta , int? snapangle )
double x = _ selectedThumbs [ i ] . X + displacementX ;
{
double y = _ selectedThumbs [ i ] . Y + displacementY ;
//iterate all selected points
foreach ( int i in _ selectedThumbs . Keys )
//if snap is applied
{
if ( snapangle ! = null )
Point p = pc [ i ] ;
{
if ( _ selectedThumbs . Count > 0 )
//x and y is calculated from the currentl point
{
double x = _ selectedThumbs [ i ] . X + displacementX ;
//horizontal snap
double y = _ selectedThumbs [ i ] . Y + displacementY ;
if ( Math . Abs ( theta ) < snapangle | | 1 8 0 - Math . Abs ( theta ) < snapangle )
{
//if snap is applied
//if one point selected use point before as snap point, else snap to movement
if ( snapangle ! = null )
y = _ selectedThumbs . Count = = 1 ? pc [ i - 1 ] . Y : y - displacementY ;
{
}
if ( _ selectedThumbs . Count > 0 )
else if ( Math . Abs ( 9 0 - Math . Abs ( theta ) ) < snapangle ) //vertical snap
{
{
//horizontal snap
//if one point selected use point before as snap point, else snap to movement
if ( Math . Abs ( theta ) < snapangle | | 1 8 0 - Math . Abs ( theta ) < snapangle )
x = _ selectedThumbs . Count = = 1 ? pc [ i - 1 ] . X : x - displacementX ;
{
}
//if one point selected use point before as snap point, else snap to movement
}
y = _ selectedThumbs . Count = = 1 ? pc [ i - 1 ] . Y : y - displacementY ;
}
}
else if ( Math . Abs ( 9 0 - Math . Abs ( theta ) ) < snapangle ) //vertical snap
p . X = x ;
{
p . Y = y ;
//if one point selected use point before as snap point, else snap to movement
pc [ i ] = p ;
x = _ selectedThumbs . Count = = 1 ? pc [ i - 1 ] . X : x - displacementX ;
}
}
return pc ;
}
}
}
#region IKeyDown
p . X = x ;
p . Y = y ;
public bool InvokeDefaultAction
pc [ i ] = p ;
{
}
get { return _ selectedThumbs . Count = = 0 | | _ selectedThumbs . Count = = GetPointCollection ( ) . Count - 1 ; }
return pc ;
}
}
int _ movingDistance ;
#region IKeyDown
public void KeyDownAction ( object sender , KeyEventArgs e )
{
public bool InvokeDefaultAction
Debug . WriteLine ( "KeyDown" ) ;
{
if ( IsArrowKey ( e . Key ) )
get { return _ selectedThumbs . Count = = 0 | | _ selectedThumbs . Count = = GetPointCollection ( ) . Count - 1 ; }
if ( operation = = null )
}
{
SetOperation ( ) ;
int _ movingDistance ;
_ movingDistance = 0 ;
public void KeyDownAction ( object sender , KeyEventArgs e )
}
{
Debug . WriteLine ( "KeyDown" ) ;
if ( IsArrowKey ( e . Key ) )
var dx1 = ( e . Key = = Key . Left ) ? Keyboard . IsKeyDown ( Key . LeftShift ) ? _ movingDistance - 1 0 : _ movingDistance - 1 : 0 ;
if ( operation = = null )
var dy1 = ( e . Key = = Key . Up ) ? Keyboard . IsKeyDown ( Key . LeftShift ) ? _ movingDistance - 1 0 : _ movingDistance - 1 : 0 ;
{
var dx2 = ( e . Key = = Key . Right ) ? Keyboard . IsKeyDown ( Key . LeftShift ) ? _ movingDistance + 1 0 : _ movingDistance + 1 : 0 ;
SetOperation ( ) ;
var dy2 = ( e . Key = = Key . Down ) ? Keyboard . IsKeyDown ( Key . LeftShift ) ? _ movingDistance + 1 0 : _ movingDistance + 1 : 0 ;
_ movingDistance = 0 ;
}
ChangeOperation ( MovePoints ( GetPointCollection ( ) , dx1 + dx2 , dy1 + dy2 , 0 , null ) ) ;
_ movingDistance = ( dx1 + dx2 + dy1 + dy2 ) ;
}
var dx1 = ( e . Key = = Key . Left ) ? Keyboard . IsKeyDown ( Key . LeftShift ) ? _ movingDistance - 1 0 : _ movingDistance - 1 : 0 ;
var dy1 = ( e . Key = = Key . Up ) ? Keyboard . IsKeyDown ( Key . LeftShift ) ? _ movingDistance - 1 0 : _ movingDistance - 1 : 0 ;
public void KeyUpAction ( object sender , KeyEventArgs e )
var dx2 = ( e . Key = = Key . Right ) ? Keyboard . IsKeyDown ( Key . LeftShift ) ? _ movingDistance + 1 0 : _ movingDistance + 1 : 0 ;
{
var dy2 = ( e . Key = = Key . Down ) ? Keyboard . IsKeyDown ( Key . LeftShift ) ? _ movingDistance + 1 0 : _ movingDistance + 1 : 0 ;
Debug . WriteLine ( "Keyup" ) ;
if ( IsArrowKey ( e . Key ) )
ChangeOperation ( MovePoints ( GetPointCollection ( ) , dx1 + dx2 , dy1 + dy2 , 0 , null ) ) ;
CommitOperation ( ) ;
_ movingDistance = ( dx1 + dx2 + dy1 + dy2 ) ;
}
}
bool IsArrowKey ( Key key )
public void KeyUpAction ( object sender , KeyEventArgs e )
{
{
return ( key = = Key . Left | | key = = Key . Right | | key = = Key . Up | | key = = Key . Down ) ;
Debug . WriteLine ( "Keyup" ) ;
}
if ( IsArrowKey ( e . Key ) )
#endregion
CommitOperation ( ) ;
}
}
bool IsArrowKey ( Key key )
{
return ( key = = Key . Left | | key = = Key . Right | | key = = Key . Up | | key = = Key . Down ) ;
}
#endregion
}
}
}