This commit is contained in:
Vitaliy
2017-01-09 13:25:52 +03:00
parent a9f4f0f297
commit 6ead62af6e
98 changed files with 12058 additions and 72 deletions

View File

@@ -0,0 +1,47 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
namespace Diagrams
{
public class ResizeRotateAdorner : Adorner
{
private VisualCollection visuals;
private ResizeRotateChrome chrome;
protected override int VisualChildrenCount
{
get
{
return this.visuals.Count;
}
}
public ResizeRotateAdorner(ContentControl designerItem)
: base(designerItem)
{
SnapsToDevicePixels = true;
this.chrome = new ResizeRotateChrome();
this.chrome.DataContext = designerItem;
this.visuals = new VisualCollection(this);
this.visuals.Add(this.chrome);
this.Focusable = true;
}
protected override Size ArrangeOverride(Size arrangeBounds)
{
this.chrome.Arrange(new Rect(arrangeBounds));
return arrangeBounds;
}
protected override Visual GetVisualChild(int index)
{
return this.visuals[index];
}
}
}

View File

@@ -0,0 +1,13 @@
using System.Windows;
using System.Windows.Controls;
namespace Diagrams
{
public class ResizeRotateChrome : Control
{
static ResizeRotateChrome()
{
FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(ResizeRotateChrome), new FrameworkPropertyMetadata(typeof(ResizeRotateChrome)));
}
}
}

View File

@@ -0,0 +1,44 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
namespace Diagrams
{
public class SizeAdorner : Adorner
{
private SizeChrome chrome;
private VisualCollection visuals;
private ContentControl designerItem;
protected override int VisualChildrenCount
{
get
{
return this.visuals.Count;
}
}
public SizeAdorner(ContentControl designerItem)
: base(designerItem)
{
this.SnapsToDevicePixels = true;
this.designerItem = designerItem;
this.chrome = new SizeChrome();
this.chrome.DataContext = designerItem;
this.visuals = new VisualCollection(this);
this.visuals.Add(this.chrome);
}
protected override Visual GetVisualChild(int index)
{
return this.visuals[index];
}
protected override Size ArrangeOverride(Size arrangeBounds)
{
this.chrome.Arrange(new Rect(new Point(0.0, 0.0), arrangeBounds));
return arrangeBounds;
}
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace Diagrams
{
public class SizeChrome : Control
{
static SizeChrome()
{
FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(SizeChrome), new FrameworkPropertyMetadata(typeof(SizeChrome)));
}
}
public class DoubleFormatConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double d = (double)value;
if (double.IsNaN(d)) return "(Auto)";
return Math.Round(d);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
}

View File

@@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows;
using System.Windows.Media;
using System.Windows.Input;
using System.Windows.Media.Animation;
namespace Diagrams
{
public class DesignerItemDecorator : Control
{
private Adorner adorner;
public bool ShowDecorator
{
get { return (bool)GetValue(ShowDecoratorProperty); }
set { SetValue(ShowDecoratorProperty, value); }
}
public static readonly DependencyProperty ShowDecoratorProperty =
DependencyProperty.Register("ShowDecorator", typeof(bool), typeof(DesignerItemDecorator),
new FrameworkPropertyMetadata(false, new PropertyChangedCallback(ShowDecoratorProperty_Changed)));
public DesignerItemDecorator()
{
Unloaded += new RoutedEventHandler(this.DesignerItemDecorator_Unloaded);
}
private void HideAdorner()
{
if (this.adorner != null)
{
this.adorner.Visibility = Visibility.Hidden;
}
}
private void ShowAdorner()
{
if (this.adorner == null)
{
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
if (adornerLayer != null)
{
ContentControl designerItem = this.DataContext as ContentControl;
Canvas canvas = VisualTreeHelper.GetParent(designerItem) as Canvas;
this.adorner = new ResizeRotateAdorner(designerItem);
adornerLayer.Add(this.adorner);
if (this.ShowDecorator)
{
this.adorner.Visibility = Visibility.Visible;
var anim = new DoubleAnimation(0, 1, TimeSpan.FromSeconds(.2));
this.adorner.BeginAnimation(OpacityProperty, anim);
}
else
{
this.adorner.Visibility = Visibility.Hidden;
}
}
}
else
{
this.adorner.Visibility = Visibility.Visible;
var anim = new DoubleAnimation(0, 1, TimeSpan.FromSeconds(.2));
this.adorner.BeginAnimation(OpacityProperty, anim);
}
}
private void DesignerItemDecorator_Unloaded(object sender, RoutedEventArgs e)
{
if (this.adorner != null)
{
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
if (adornerLayer != null)
{
adornerLayer.Remove(this.adorner);
}
this.adorner = null;
}
}
private static void ShowDecoratorProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DesignerItemDecorator decorator = (DesignerItemDecorator)d;
bool showDecorator = (bool)e.NewValue;
if (showDecorator)
{
decorator.ShowAdorner();
}
else
{
decorator.HideAdorner();
}
}
}
}

View File

@@ -0,0 +1,43 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:Diagrams">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="SizeChrome.xaml"/>
<ResourceDictionary Source="ResizeRotateChrome.xaml"/>
</ResourceDictionary.MergedDictionaries>
<ControlTemplate x:Key="MoveThumbTemplate" TargetType="{x:Type s:MoveThumb}">
<Rectangle Fill="Transparent"/>
</ControlTemplate>
<Style x:Key="DesignerItemStyle" TargetType="ContentControl">
<Setter Property="MinHeight" Value="26"/>
<Setter Property="MinWidth" Value="30"/>
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Focusable" Value="False" />
<Setter Property="MaxHeight" Value="900" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
<s:MoveThumb Focusable="False" Cursor="SizeAll" Template="{StaticResource MoveThumbTemplate}" />
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"
Margin="{TemplateBinding Padding}"/>
<s:DesignerItemDecorator x:Name="ItemDecorator" Focusable="False"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Selector.IsSelected" Value="True">
<Setter TargetName="ItemDecorator" Property="ShowDecorator" Value="True" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,112 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:Diagrams">
<Style TargetType="{x:Type Shape}" x:Key="ThumbCorner">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Stroke" Value="#FF0166AC" />
<Setter Property="StrokeThickness" Value="1" />
<Setter Property="Width" Value="7" />
<Setter Property="Height" Value="7" />
<Setter Property="Margin" Value="-2" />
<Setter Property="Fill">
<Setter.Value>
<RadialGradientBrush Center="0.2, 0.2" GradientOrigin="0.2, 0.2" RadiusX="0.8" RadiusY="0.8">
<GradientStop Color="White" Offset="0.0" />
<GradientStop Color="#FF9AFF9F" Offset="0.8" />
</RadialGradientBrush>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type s:ResizeRotateChrome}">
<Setter Property="Focusable" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type s:ResizeRotateChrome}">
<Grid>
<Grid Opacity="0" Margin="-3">
<s:MoveThumb Margin="0,-20,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Height="16"
Width="16"
Cursor="SizeAll"
Template="{DynamicResource MoveThumbTemplate}" />
<s:RotateThumb Width="20"
Height="20"
Margin="0,-20,0,0"
Cursor="Hand"
VerticalAlignment="Top"
HorizontalAlignment="Center"/>
<s:ResizeThumb Height="3"
Cursor="SizeNS"
VerticalAlignment="Top"
HorizontalAlignment="Stretch"/>
<s:ResizeThumb Width="3"
Cursor="SizeWE"
VerticalAlignment="Stretch"
HorizontalAlignment="Left"/>
<s:ResizeThumb Width="3"
Cursor="SizeWE"
VerticalAlignment="Stretch"
HorizontalAlignment="Right"/>
<s:ResizeThumb Height="3"
Cursor="SizeNS"
VerticalAlignment="Bottom"
HorizontalAlignment="Stretch"/>
<s:ResizeThumb Width="7"
Height="7"
Margin="-2"
Cursor="SizeNWSE"
VerticalAlignment="Top"
HorizontalAlignment="Left"/>
<s:ResizeThumb Width="7"
Height="7"
Margin="-2"
Cursor="SizeNESW"
VerticalAlignment="Top"
HorizontalAlignment="Right"/>
<s:ResizeThumb Width="7"
Height="7"
Margin="-2"
Cursor="SizeNESW"
VerticalAlignment="Bottom"
HorizontalAlignment="Left"/>
<s:ResizeThumb Width="7"
Height="7"
Margin="-2"
Cursor="SizeNWSE"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"/>
</Grid>
<Canvas HorizontalAlignment="Right" VerticalAlignment="Top">
<ContentControl Canvas.Left="10" Content="{Binding Tag}" />
</Canvas>
<Grid IsHitTestVisible="False" Opacity="1" Margin="-3">
<Rectangle SnapsToDevicePixels="True"
StrokeThickness="1"
Margin="1"
Stroke="{DynamicResource DisabledBorderBrush}" StrokeDashArray="1 0 1"/>
<Line StrokeThickness="1" X1="0" Y1="0" X2="0" Y2="20"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Margin="0,-19,0,0"
Stroke="White" StrokeDashArray="1 2"/>
<Path Style="{StaticResource ThumbCorner}" Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,-20,0,0" Width="20" Height="20" Data="M 11.7927,9.92031C 12.5184,8.74318 12.6759,7.05297 12.1717,5.75967C 11.5909,4.44354 10.2501,3.37314 8.87896,3.04485C 7.39649,2.74559 5.63977,3.1934 4.48733,4.196C 3.50995,5.1756 2.91946,6.75691 3.08599,8.14841L 0.0842173,8.57665C 0.0347556,8.20576 0.00766225,7.8312 -1.64198e-005,7.45693C 0.038148,6.21681 0.383575,4.9557 0.968669,3.8699C 1.5589,2.89611 2.36362,2.03356 3.28126,1.37902C 5.28605,0.0810452 8.05891,-0.284222 10.3301,0.412526C 12.1794,1.09169 13.9099,2.53647 14.8289,4.31779C 15.3434,5.43808 15.5957,6.72245 15.5449,7.95982C 15.4307,9.19718 15.0066,10.4344 14.358,11.484L 16.0043,12.4819L 11.226,13.5191L 10.1463,8.92239L 11.7927,9.92031 Z M -1.64198e-005,-1.90735e-006 Z M 15.564,14.9728 Z "
Fill="YellowGreen" Stroke="{DynamicResource PressedBorderBrush}" />
<Rectangle Style="{StaticResource ThumbCorner}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Rectangle Style="{StaticResource ThumbCorner}" HorizontalAlignment="Right" VerticalAlignment="Top"/>
<Rectangle Style="{StaticResource ThumbCorner}" HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
<Rectangle Style="{StaticResource ThumbCorner}" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
<Viewbox Width="16" Height="16" HorizontalAlignment="Right" VerticalAlignment="Top" IsHitTestVisible="False" Margin="0,-20,0,0">
<Path Width="16" Height="16" Stretch="Fill" Fill="{DynamicResource NormalBrush}" StrokeThickness=".5" Stroke="{DynamicResource GlyphBrush}" Data="M 0,8.L 3.18485,4.81417L 3.18485,6.37077L 6.37181,6.37077L 6.37181,3.18408L 4.81418,3.18408L 8.00114,0L 11.1881,3.18408L 9.63047,3.18408L 9.63047,6.37077L 12.8174,6.37077L 12.8174,4.81417L 16.0044,8.L 12.8174,11.1876L 12.8174,9.63096L 9.63047,9.63096L 9.63047,12.8177L 11.1881,12.8177L 8.00114,16.0044L 4.81418,12.8177L 6.37181,12.8177L 6.37181,9.63096L 3.18485,9.63096L 3.18485,11.1876L 0,8. Z M 0,0 Z M 16.0044,16.0044 Z"/>
</Viewbox>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,49 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:Diagrams">
<s:DoubleFormatConverter x:Key="doubleFormatConverter"/>
<Style TargetType="{x:Type s:SizeChrome}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type s:SizeChrome}">
<Grid SnapsToDevicePixels="True">
<Path Stroke="Red"
StrokeThickness="1"
Height="10"
VerticalAlignment="Bottom"
Margin="-2,0,-2,-15"
Stretch="Fill"
Data="M0,0 0,10 M 0,5 100,5 M 100,0 100,10" StrokeDashArray="1 2"/>
<TextBlock Text="{Binding Path=Width, Converter={StaticResource doubleFormatConverter}}"
Background="White"
Padding="3,0,3,0"
Foreground="#FF9C3535"
Margin="0,0,0,-18"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"/>
<Path Stroke="#FF9C3535"
StrokeThickness="1"
Width="10"
HorizontalAlignment="Right"
Margin="0,-2,-15,-2"
Stretch="Fill"
Data="M5,0 5,100 M 0,0 10,0 M 0,100 10,100" StrokeDashArray="1 2"/>
<TextBlock Text="{Binding Path=Height, Converter={StaticResource doubleFormatConverter}}"
Background="White"
Foreground="#FF9C3535"
Padding="3,0,3,0"
Margin="0,0,-18,0"
HorizontalAlignment="Right"
VerticalAlignment="Center">
<TextBlock.LayoutTransform>
<RotateTransform Angle="90" CenterX="1" CenterY="0.5"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,91 @@
using BrightSharp.Extensions;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System;
namespace BrightSharp.Diagrams
{
public static class SelectionBehavior
{
public static void Attach(FrameworkElement fe)
{
ContentControl selectedControl = null;
Style designerStyle = (Style)Application.Current.FindResource("DesignerItemStyle");
if (fe is Panel)
{
var fePanel = (Panel)fe;
fe.PreviewMouseLeftButtonDown += (s, e) =>
{
if (e.Source is DependencyObject)
{
var clickedElement = ((DependencyObject)e.OriginalSource).Ancestors<ContentControl>().FirstOrDefault(el => el.Style == designerStyle && WpfExtensions.GetItemsPanel(el.GetParent(true)) == fe);
if (clickedElement == null)
{
foreach (DependencyObject item in fePanel.Children)
{
Selector.SetIsSelected(item, false);
}
selectedControl = null;
return;
}
foreach (var control in fePanel.Children.OfType<ContentControl>())
{
if (ProcessControl(control, clickedElement, ref selectedControl))
{
e.Handled = selectedControl.Content is ButtonBase;
return;
}
}
}
};
}
else if (fe is ItemsControl)
{
var feItemsControl = (ItemsControl)fe;
fe.PreviewMouseLeftButtonDown += (s, e) =>
{
if (e.Source is DependencyObject)
{
var clickedElement = ((DependencyObject)e.Source).Ancestors<ContentControl>().FirstOrDefault(el => el.Style == designerStyle && el.Parent == fe);
if (clickedElement == null)
{
foreach (DependencyObject item in feItemsControl.Items)
{
Selector.SetIsSelected(item, false);
}
selectedControl = null;
return;
}
foreach (var control in feItemsControl.Items.OfType<ContentControl>())
{
if (ProcessControl(control, clickedElement, ref selectedControl))
{
e.Handled = selectedControl.Content is ButtonBase;
return;
}
}
}
};
}
}
private static bool ProcessControl(ContentControl control, ContentControl clickedElement, ref ContentControl selectedControl)
{
if (control == clickedElement && control != selectedControl)
{
if (selectedControl != null)
{
Selector.SetIsSelected(selectedControl, false);
}
Selector.SetIsSelected(control, true);
selectedControl = control;
return true;
}
return false;
}
}
}

View File

@@ -0,0 +1,49 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
namespace Diagrams
{
public class MoveThumb : Thumb
{
private RotateTransform rotateTransform;
private ContentControl designerItem;
public MoveThumb()
{
DragStarted += new DragStartedEventHandler(this.MoveThumb_DragStarted);
DragDelta += new DragDeltaEventHandler(this.MoveThumb_DragDelta);
}
private void MoveThumb_DragStarted(object sender, DragStartedEventArgs e)
{
this.designerItem = DataContext as ContentControl;
if (this.designerItem != null)
{
this.rotateTransform = this.designerItem.RenderTransform as RotateTransform;
}
}
private void MoveThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
if (this.designerItem != null)
{
Point dragDelta = new Point(e.HorizontalChange, e.VerticalChange);
if (this.rotateTransform != null)
{
dragDelta = this.rotateTransform.Transform(dragDelta);
}
if (double.IsNaN(Canvas.GetLeft(this.designerItem))) Canvas.SetLeft(this.designerItem, 0);
if (double.IsNaN(Canvas.GetTop(this.designerItem))) Canvas.SetTop(this.designerItem, 0);
Canvas.SetLeft(this.designerItem, Canvas.GetLeft(this.designerItem) + dragDelta.X);
Canvas.SetTop(this.designerItem, Canvas.GetTop(this.designerItem) + dragDelta.Y);
}
}
}
}

View File

@@ -0,0 +1,139 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Media;
using System.Collections.Generic;
using System.Windows.Input;
namespace Diagrams
{
public class ResizeThumb : Thumb
{
private RotateTransform rotateTransform;
private double angle;
private Adorner adorner;
private Point transformOrigin;
private ContentControl designerItem;
private Canvas canvas;
public ResizeThumb()
{
DragStarted += new DragStartedEventHandler(this.ResizeThumb_DragStarted);
DragDelta += new DragDeltaEventHandler(this.ResizeThumb_DragDelta);
DragCompleted += new DragCompletedEventHandler(this.ResizeThumb_DragCompleted);
MouseRightButtonDown += new MouseButtonEventHandler(this.ResizeThumb_MouseRightButtonDown);
}
private void ResizeThumb_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
this.designerItem = this.designerItem ?? this.DataContext as ContentControl;
if (VerticalAlignment == VerticalAlignment.Top || VerticalAlignment == VerticalAlignment.Bottom)
{
this.designerItem.Height = double.NaN;
}
if (HorizontalAlignment == HorizontalAlignment.Left || HorizontalAlignment == HorizontalAlignment.Right)
{
this.designerItem.Width = double.NaN;
}
}
private void ResizeThumb_DragStarted(object sender, DragStartedEventArgs e)
{
this.designerItem = this.DataContext as ContentControl;
if (this.designerItem != null)
{
this.canvas = VisualTreeHelper.GetParent(this.designerItem) as Canvas;
if (this.canvas != null)
{
this.transformOrigin = this.designerItem.RenderTransformOrigin;
this.rotateTransform = this.designerItem.RenderTransform as RotateTransform;
if (this.rotateTransform != null)
{
this.angle = this.rotateTransform.Angle * Math.PI / 180.0;
}
else
{
this.angle = 0.0d;
}
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.canvas);
if (adornerLayer != null)
{
this.adorner = new SizeAdorner(this.designerItem);
adornerLayer.Add(this.adorner);
}
}
}
}
private void ResizeThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
if (this.designerItem != null)
{
double deltaVertical, deltaHorizontal;
if (double.IsNaN(Canvas.GetTop(this.designerItem))) Canvas.SetTop(this.designerItem, 0);
if (double.IsNaN(Canvas.GetLeft(this.designerItem))) Canvas.SetLeft(this.designerItem, 0);
if ((VerticalAlignment == VerticalAlignment.Top || VerticalAlignment == VerticalAlignment.Bottom) && double.IsNaN(this.designerItem.Height)) this.designerItem.Height = this.designerItem.ActualHeight;
if ((HorizontalAlignment == HorizontalAlignment.Left || HorizontalAlignment == HorizontalAlignment.Right) && double.IsNaN(this.designerItem.Width)) this.designerItem.Width = this.designerItem.ActualWidth;
switch (VerticalAlignment)
{
case System.Windows.VerticalAlignment.Bottom:
deltaVertical = Math.Min(-e.VerticalChange, this.designerItem.ActualHeight - this.designerItem.MinHeight);
Canvas.SetTop(this.designerItem, Canvas.GetTop(this.designerItem) + (this.transformOrigin.Y * deltaVertical * (1 - Math.Cos(-this.angle))));
Canvas.SetLeft(this.designerItem, Canvas.GetLeft(this.designerItem) - deltaVertical * this.transformOrigin.Y * Math.Sin(-this.angle));
this.designerItem.Height -= deltaVertical;
break;
case System.Windows.VerticalAlignment.Top:
deltaVertical = Math.Min(e.VerticalChange, this.designerItem.ActualHeight - this.designerItem.MinHeight);
Canvas.SetTop(this.designerItem, Canvas.GetTop(this.designerItem) + deltaVertical * Math.Cos(-this.angle) + (this.transformOrigin.Y * deltaVertical * (1 - Math.Cos(-this.angle))));
Canvas.SetLeft(this.designerItem, Canvas.GetLeft(this.designerItem) + deltaVertical * Math.Sin(-this.angle) - (this.transformOrigin.Y * deltaVertical * Math.Sin(-this.angle)));
this.designerItem.Height -= deltaVertical;
break;
default:
break;
}
switch (HorizontalAlignment)
{
case System.Windows.HorizontalAlignment.Left:
deltaHorizontal = Math.Min(e.HorizontalChange, this.designerItem.ActualWidth - this.designerItem.MinWidth);
Canvas.SetTop(this.designerItem, Canvas.GetTop(this.designerItem) + deltaHorizontal * Math.Sin(this.angle) - this.transformOrigin.X * deltaHorizontal * Math.Sin(this.angle));
Canvas.SetLeft(this.designerItem, Canvas.GetLeft(this.designerItem) + deltaHorizontal * Math.Cos(this.angle) + (this.transformOrigin.X * deltaHorizontal * (1 - Math.Cos(this.angle))));
this.designerItem.Width -= deltaHorizontal;
break;
case System.Windows.HorizontalAlignment.Right:
deltaHorizontal = Math.Min(-e.HorizontalChange, this.designerItem.ActualWidth - this.designerItem.MinWidth);
Canvas.SetTop(this.designerItem, Canvas.GetTop(this.designerItem) - this.transformOrigin.X * deltaHorizontal * Math.Sin(this.angle));
Canvas.SetLeft(this.designerItem, Canvas.GetLeft(this.designerItem) + (deltaHorizontal * this.transformOrigin.X * (1 - Math.Cos(this.angle))));
this.designerItem.Width -= deltaHorizontal;
break;
default:
break;
}
}
e.Handled = true;
}
private void ResizeThumb_DragCompleted(object sender, DragCompletedEventArgs e)
{
if (this.adorner != null)
{
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.canvas);
if (adornerLayer != null)
{
adornerLayer.Remove(this.adorner);
}
this.adorner = null;
}
}
}
}

View File

@@ -0,0 +1,86 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
namespace Diagrams
{
public class RotateThumb : Thumb
{
private double initialAngle;
private RotateTransform rotateTransform;
private Vector startVector;
private Point centerPoint;
private ContentControl designerItem;
private Canvas canvas;
public RotateThumb()
{
DragDelta += new DragDeltaEventHandler(this.RotateThumb_DragDelta);
DragStarted += new DragStartedEventHandler(this.RotateThumb_DragStarted);
MouseRightButtonDown += RotateThumb_MouseLeftButtonDown;
}
private void RotateThumb_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.RightButton == MouseButtonState.Pressed)
{
this.rotateTransform = this.designerItem.RenderTransform as RotateTransform;
if (this.rotateTransform != null)
{
this.rotateTransform.Angle = 0;
this.designerItem.InvalidateMeasure();
}
}
}
private void RotateThumb_DragStarted(object sender, DragStartedEventArgs e)
{
this.designerItem = DataContext as ContentControl;
if (this.designerItem != null)
{
this.canvas = VisualTreeHelper.GetParent(this.designerItem) as Canvas;
if (this.canvas != null)
{
this.centerPoint = this.designerItem.TranslatePoint(
new Point(this.designerItem.ActualWidth * this.designerItem.RenderTransformOrigin.X,
this.designerItem.ActualHeight * this.designerItem.RenderTransformOrigin.Y),
this.canvas);
Point startPoint = Mouse.GetPosition(this.canvas);
this.startVector = Point.Subtract(startPoint, this.centerPoint);
this.rotateTransform = this.designerItem.RenderTransform as RotateTransform;
if (this.rotateTransform == null)
{
this.designerItem.RenderTransform = new RotateTransform(0);
this.initialAngle = 0;
}
else
{
this.initialAngle = this.rotateTransform.Angle;
}
}
}
}
private void RotateThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
if (this.designerItem != null && this.canvas != null)
{
Point currentPoint = Mouse.GetPosition(this.canvas);
Vector deltaVector = Point.Subtract(currentPoint, this.centerPoint);
double angle = Vector.AngleBetween(this.startVector, deltaVector);
RotateTransform rotateTransform = this.designerItem.RenderTransform as RotateTransform;
rotateTransform.Angle = this.initialAngle + Math.Round(angle, 0);
this.designerItem.InvalidateMeasure();
}
}
}
}