Browse Source

Rotate Controls via a RotateThumb

pull/52/head
jkuehner 13 years ago
parent
commit
f2ea63706e
  1. 92
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ControlStyles.xaml
  2. 35
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/RotateThumb.cs
  3. 165
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs
  4. BIN
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Images/rotate.cur
  5. 7
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj

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

@ -44,6 +44,20 @@ @@ -44,6 +44,20 @@
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Controls:RotateThumb}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:RotateThumb}">
<Grid>
<Rectangle VerticalAlignment="Top" Width="2" Height="30" Fill="Black" Margin="0,0,0,0" />
<Ellipse VerticalAlignment="Top" StrokeThickness="1" Name="thumbRectangle" SnapsToDevicePixels="True" Stroke="Black"
Width="7" Height="7" Fill="Black">
</Ellipse>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Controls:SelectionFrame}">
<Setter Property="Template">
<Setter.Value>
@ -194,46 +208,44 @@ @@ -194,46 +208,44 @@
</Setter>
</Style>
<Style TargetType="{x:Type Controls:CanvasPositionHandle}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:MarginHandle}">
<Grid Height="10" Width="{Binding Path=HandleLength, Converter={x:Static ControlConvertors:HandleLengthWithOffset.Instance}, RelativeSource={RelativeSource Mode=TemplatedParent}}" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Path Name="startArrow" Fill="{StaticResource HandleBrush}" Stretch="Fill" Stroke="{TemplateBinding Panel.Background}" StrokeThickness="0.5" Margin="0,1,0,1" Data="M0,0 L0,1 1,0.5 z" Grid.Column="0" />
<!-- Wrap the handle-line and endArrow in this grid. It's visiblity is subjected to HandleLength -->
<Grid Height="10" Grid.Column="1" Name="lineArrow">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition MaxWidth="20" MinWidth="10" />
<ColumnDefinition Width="*" />
<!--<ColumnDefinition Width="8" />
<ColumnDefinition Width="1.5"/>-->
</Grid.ColumnDefinitions>
<Rectangle Fill="Transparent" Height="10" Grid.Column="0" Grid.ColumnSpan="4" />
<Path Name="line1" StrokeDashArray="2,2" Stretch="Fill" Stroke="{StaticResource HandleBrush}" StrokeThickness="1.5" Margin="0 0 0 0" Data="M0,-0.75 L1,-0.75" Grid.Column="0" />
<TextBlock Grid.Column="1" Text="{Binding Path=HandleLength, Mode=OneWay, Converter={x:Static Converters:FormatDoubleConverter.Instance }, RelativeSource={RelativeSource Mode=TemplatedParent}}" FontSize="9" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="1,1,1,1">
<TextBlock.LayoutTransform>
<RotateTransform Angle="{Binding Path=TextTransform, RelativeSource={RelativeSource Mode=TemplatedParent}}" CenterX="0.5" CenterY="0.5">
</RotateTransform>
</TextBlock.LayoutTransform>
</TextBlock>
<Path Name="line2" StrokeDashArray="2,2" Stretch="Fill" Stroke="{StaticResource HandleBrush}" StrokeThickness="1.5" Margin="0 0 0 0" Data="M0,-0.75 L1,-0.75" Grid.Column="2" />
<!--<Path Name="arrow2" Margin="0,1,0,1" Fill="{StaticResource HandleBrush}" Stretch="Fill" Stroke="{TemplateBinding Panel.Background}" StrokeThickness="0.5" Data="M0,0 L0,1 1,0.5 z" Grid.Column="3" />-->
<!--<Rectangle Width="1.5" Fill="{StaticResource HandleBrush}" Grid.Column="4"/>-->
</Grid>
<!-- Rotate the handle and angle of rotation being set by the Margin type. See enum HandleOrientation -->
<Grid.LayoutTransform>
<RotateTransform Angle="{Binding Path=Angle, RelativeSource={RelativeSource Mode=TemplatedParent}}">
</RotateTransform>
</Grid.LayoutTransform>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:MarginHandle}">
<Grid Height="10" Width="{Binding Path=HandleLength, Converter={x:Static ControlConvertors:HandleLengthWithOffset.Instance}, RelativeSource={RelativeSource Mode=TemplatedParent}}" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Path Name="startArrow" Fill="{StaticResource HandleBrush}" Stretch="Fill" Stroke="{TemplateBinding Panel.Background}" StrokeThickness="0.5" Margin="0,1,0,1" Data="M0,0 L0,1 1,0.5 z" Grid.Column="0" />
<!-- Wrap the handle-line and endArrow in this grid. It's visiblity is subjected to HandleLength -->
<Grid Height="10" Grid.Column="1" Name="lineArrow">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition MaxWidth="20" MinWidth="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle Fill="Transparent" Height="10" Grid.Column="0" Grid.ColumnSpan="4" />
<Path Name="line1" StrokeDashArray="2,2" Stretch="Fill" Stroke="{StaticResource HandleBrush}" StrokeThickness="1.5" Margin="0 0 0 0" Data="M0,-0.75 L1,-0.75" Grid.Column="0" />
<TextBlock Grid.Column="1" Text="{Binding Path=HandleLength, Mode=OneWay, Converter={x:Static Converters:FormatDoubleConverter.Instance }, RelativeSource={RelativeSource Mode=TemplatedParent}}" FontSize="9" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="1,1,1,1">
<TextBlock.LayoutTransform>
<RotateTransform Angle="{Binding Path=TextTransform, RelativeSource={RelativeSource Mode=TemplatedParent}}" CenterX="0.5" CenterY="0.5">
</RotateTransform>
</TextBlock.LayoutTransform>
</TextBlock>
<Path Name="line2" StrokeDashArray="2,2" Stretch="Fill" Stroke="{StaticResource HandleBrush}" StrokeThickness="1.5" Margin="0 0 0 0" Data="M0,-0.75 L1,-0.75" Grid.Column="2" />
<!--<Path Name="arrow2" Margin="0,1,0,1" Fill="{StaticResource HandleBrush}" Stretch="Fill" Stroke="{TemplateBinding Panel.Background}" StrokeThickness="0.5" Data="M0,0 L0,1 1,0.5 z" Grid.Column="3" />-->
<!--<Rectangle Width="1.5" Fill="{StaticResource HandleBrush}" Grid.Column="4"/>-->
</Grid>
<!-- Rotate the handle and angle of rotation being set by the Margin type. See enum HandleOrientation -->
<Grid.LayoutTransform>
<RotateTransform Angle="{Binding Path=Angle, RelativeSource={RelativeSource Mode=TemplatedParent}}">
</RotateTransform>
</Grid.LayoutTransform>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Controls:MarginHandle}">
<Setter Property="Template">
<Setter.Value>

35
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/RotateThumb.cs

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.WpfDesign.Adorners;
using ICSharpCode.WpfDesign.Designer.Extensions;
namespace ICSharpCode.WpfDesign.Designer.Controls
{
public class RotateThumb : ResizeThumb
{
private double initialAngle;
private RotateTransform rotateTransform;
private Vector startVector;
private Point centerPoint;
private Control designerItem;
private Panel canvas;
private AdornerPanel parent;
static RotateThumb()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(RotateThumb), new FrameworkPropertyMetadata(typeof(RotateThumb)));
}
public RotateThumb()
{
this.ResizeThumbVisible = true;
}
}
}

165
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs

@ -0,0 +1,165 @@ @@ -0,0 +1,165 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.WpfDesign.Adorners;
using ICSharpCode.WpfDesign.Designer.Controls;
using ICSharpCode.WpfDesign.Extensions;
using System.Collections.Generic;
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
/// <summary>
/// The resize thumb around a component.
/// </summary>
[ExtensionFor(typeof(FrameworkElement))]
public sealed class RotateThumbExtension : SelectionAdornerProvider
{
readonly AdornerPanel adornerPanel;
readonly Thumb thumb;
/// <summary>An array containing this.ExtendedItem as only element</summary>
readonly DesignItem[] extendedItemArray = new DesignItem[1];
IPlacementBehavior resizeBehavior;
PlacementOperation operation;
ChangeGroup changeGroup;
bool _isResizing;
/// <summary>
/// Gets whether this extension is resizing any element.
/// </summary>
public bool IsResizing{
get { return _isResizing; }
}
public RotateThumbExtension()
{
adornerPanel = new AdornerPanel();
adornerPanel.Order = AdornerOrder.Foreground;
this.Adorners.Add(adornerPanel);
thumb = CreateRotateThumb();
}
ResizeThumb CreateRotateThumb()
{
ResizeThumb rotateThumb = new RotateThumb();
rotateThumb.Cursor = Cursors.Hand;
rotateThumb.Cursor = ZoomControl.GetCursor("Images/rotate.cur");
rotateThumb.Alignment = PlacementAlignment.Top;
AdornerPanel.SetPlacement(rotateThumb,
new RelativePlacement(HorizontalAlignment.Center, VerticalAlignment.Top) { WidthRelativeToContentWidth = 1, HeightOffset = 0 });
adornerPanel.Children.Add(rotateThumb);
DragListener drag = new DragListener(rotateThumb);
drag.Started += drag_Rotate_Started;
drag.Changed += drag_Rotate_Changed;
return rotateThumb;
}
Size oldSize;
#region Rotate
private Point centerPoint;
private UIElement parent;
private Vector startVector;
private RotateTransform rotateTransform;
private double initialAngle;
private DesignItem rtTransform;
private double angle;
private void drag_Rotate_Started(DragListener drag)
{
var designerItem = this.ExtendedItem.Component as FrameworkElement;
this.parent = VisualTreeHelper.GetParent(designerItem) as UIElement;
this.centerPoint = designerItem.TranslatePoint(
new Point(designerItem.ActualWidth*designerItem.RenderTransformOrigin.X,
designerItem.ActualHeight*designerItem.RenderTransformOrigin.Y),
this.parent);
Point startPoint = Mouse.GetPosition(this.parent);
this.startVector = Point.Subtract(startPoint, this.centerPoint);
if (this.rotateTransform == null)
{
this.initialAngle = 0;
}
else
{
this.initialAngle = this.rotateTransform.Angle;
}
rtTransform = this.ExtendedItem.Properties[FrameworkElement.RenderTransformProperty].Value;
operation = PlacementOperation.Start(extendedItemArray, PlacementType.Resize);
}
private void drag_Rotate_Changed(DragListener drag)
{
Point currentPoint = Mouse.GetPosition(this.parent);
Vector deltaVector = Point.Subtract(currentPoint, this.centerPoint);
double angle = Vector.AngleBetween(this.startVector, deltaVector);
var destAngle = this.initialAngle + Math.Round(angle, 0);
if (!Keyboard.IsKeyDown(Key.LeftCtrl))
destAngle = ((int)destAngle / 15) * 15;
if (destAngle == 0)
{
this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).Reset();
rtTransform = null;
rotateTransform = null;
}
else
{
if (rtTransform == null)
{
if (this.rotateTransform == null)
this.rotateTransform = new RotateTransform(0);
this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).SetValue(rotateTransform);
rtTransform = this.ExtendedItem.Properties[FrameworkElement.RenderTransformProperty].Value;
}
rtTransform.Properties["Angle"].SetValue(destAngle);
this.angle = destAngle * Math.PI / 180.0;
}
}
#endregion
protected override void OnInitialized()
{
base.OnInitialized();
extendedItemArray[0] = this.ExtendedItem;
this.ExtendedItem.PropertyChanged += OnPropertyChanged;
this.Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged;
resizeBehavior = PlacementOperation.GetPlacementBehavior(extendedItemArray);
OnPrimarySelectionChanged(null, null);
}
void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{ }
protected override void OnRemove()
{
this.ExtendedItem.PropertyChanged -= OnPropertyChanged;
this.Services.Selection.PrimarySelectionChanged -= OnPrimarySelectionChanged;
base.OnRemove();
}
void OnPrimarySelectionChanged(object sender, EventArgs e)
{
bool isPrimarySelection = this.Services.Selection.PrimarySelection == this.ExtendedItem;
foreach (RotateThumb g in adornerPanel.Children) {
g.IsPrimarySelection = isPrimarySelection;
}
}
}
}

BIN
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Images/rotate.cur

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

7
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj

@ -99,6 +99,7 @@ @@ -99,6 +99,7 @@
<Compile Include="Controls\PageClone.cs" />
<Compile Include="Controls\PanelMoveAdorner.cs" />
<Compile Include="Controls\QuickOperationMenu.cs" />
<Compile Include="Controls\RotateThumb.cs" />
<Compile Include="Controls\SelectionFrame.cs" />
<Compile Include="Controls\ErrorBalloon.cs" />
<Compile Include="Controls\ResizeThumb.cs" />
@ -130,6 +131,7 @@ @@ -130,6 +131,7 @@
<Compile Include="Extensions\MarginHandleExtension.cs" />
<Compile Include="Extensions\QuickOperationMenuExtension.cs" />
<Compile Include="Extensions\RasterPlacementBehavior.cs" />
<Compile Include="Extensions\RotateThumbExtension.cs" />
<Compile Include="Extensions\SizeDisplayExtension.cs" />
<Compile Include="Extensions\SnaplinePlacementBehavior.cs">
<SubType>Code</SubType>
@ -336,4 +338,7 @@ @@ -336,4 +338,7 @@
<Resource Include="Images\Raster.png" />
<Resource Include="Images\Snapline.png" />
</ItemGroup>
</Project>
<ItemGroup>
<Resource Include="Images\rotate.cur" />
</ItemGroup>
</Project>

Loading…
Cancel
Save