Browse Source

Worked on Move/Resize in the WPF Designer.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2415 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
c2435dcefc
  1. 2
      src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml
  2. 2
      src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml.cs
  3. 7
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ControlStyles.xaml
  4. 55
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GrayOutDesignerExceptActiveArea.cs
  5. 46
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ResizeThumb.cs
  6. 8
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SelectionFrame.cs
  7. 96
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasChildResizeSupport.cs
  8. 168
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DefaultChildResizeSupport.cs
  9. 29
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelSelectionHandler.cs
  10. 151
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/ResizeThumbExtension.cs
  11. 51
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ClickOrDragMouseGesture.cs
  12. 80
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/DragMoveMouseGesture.cs
  13. 19
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ToolService.cs
  14. 5
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj
  15. 16
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPanel.cs
  16. 39
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPlacement.cs
  17. 33
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPlacementSpace.cs
  18. 4
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerProvider.cs
  19. 46
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/RelativePlacement.cs
  20. 34
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/MouseInteraction.cs
  21. 110
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementAlignment.cs
  22. 51
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementBehavior.cs
  23. 179
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementOperation.cs
  24. 50
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementType.cs
  25. 7
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Tools.cs
  26. 8
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj

2
src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml

@ -26,7 +26,7 @@
BorderThickness="10" Width="400" Height="300"> BorderThickness="10" Width="400" Height="300">
<StackPanel> <StackPanel>
<Canvas Height="50"> <Canvas Height="50">
<Button Width="60" Height="25.96">CB</Button> <Button>CB</Button>
</Canvas> </Canvas>
<Button>Button 1</Button> <Button>Button 1</Button>
<Button>Button 2</Button> <Button>Button 2</Button>

2
src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml.cs

@ -65,7 +65,7 @@ namespace StandaloneDesigner
void OnSelectionChanged(object sender, DesignItemCollectionEventArgs e) void OnSelectionChanged(object sender, DesignItemCollectionEventArgs e)
{ {
propertyEditor.EditedObject = DesignItemDataSource.GetDataSourceForDesignItems(designSurface.DesignContext.Services.Selection.SelectedItems); //propertyEditor.EditedObject = DesignItemDataSource.GetDataSourceForDesignItems(designSurface.DesignContext.Services.Selection.SelectedItems);
} }
} }
} }

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

@ -21,16 +21,19 @@
<Trigger Property="IsEnabled" Value="False"> <Trigger Property="IsEnabled" Value="False">
<Setter TargetName="thumbRectangle" Property="Fill" Value="Gray"/> <Setter TargetName="thumbRectangle" Property="Fill" Value="Gray"/>
</Trigger> </Trigger>
<Trigger Property="ResizeThumbVisible" Value="False">
<Setter TargetName="thumbRectangle" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers> </ControlTemplate.Triggers>
</ControlTemplate> </ControlTemplate>
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Style> </Style>
<Style TargetType="{x:Type src:DragFrame}"> <Style TargetType="{x:Type src:SelectionFrame}">
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="{x:Type src:DragFrame}"> <ControlTemplate TargetType="{x:Type src:SelectionFrame}">
<Rectangle Fill="#519ABFE5" Stroke="#FF7A8787" StrokeThickness="1"/> <Rectangle Fill="#519ABFE5" Stroke="#FF7A8787" StrokeThickness="1"/>
</ControlTemplate> </ControlTemplate>
</Setter.Value> </Setter.Value>

55
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GrayOutDesignerExceptActiveArea.cs

@ -6,8 +6,12 @@
// </file> // </file>
using System; using System;
using System.Diagnostics;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading;
using System.Windows.Media.Animation;
using ICSharpCode.WpfDesign.Adorners;
namespace ICSharpCode.WpfDesign.Designer.Controls namespace ICSharpCode.WpfDesign.Designer.Controls
{ {
@ -17,19 +21,18 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
sealed class GrayOutDesignerExceptActiveArea : FrameworkElement sealed class GrayOutDesignerExceptActiveArea : FrameworkElement
{ {
//Geometry infiniteRectangle = new RectangleGeometry(new Rect(0, 0, double.PositiveInfinity, double.PositiveInfinity)); //Geometry infiniteRectangle = new RectangleGeometry(new Rect(0, 0, double.PositiveInfinity, double.PositiveInfinity));
Geometry infiniteRectangle = new RectangleGeometry(new Rect(0, 0, 10000, 10000)); Geometry infiniteRectangle = new RectangleGeometry(new Rect(-100, -100, 10000, 10000));
Geometry activeAreaGeometry; Geometry activeAreaGeometry;
Geometry combinedGeometry; Geometry combinedGeometry;
Brush grayOutBrush; Brush grayOutBrush;
AdornerPanel adornerPanel;
IDesignPanel designPanel;
const double MaxOpacity = 0.3;
public GrayOutDesignerExceptActiveArea() public GrayOutDesignerExceptActiveArea()
{ {
Color c = SystemColors.GrayTextColor; this.GrayOutBrush = new SolidColorBrush(SystemColors.GrayTextColor);
c.R = (byte)Math.Max(0, c.R - 20); this.GrayOutBrush.Opacity = MaxOpacity;
c.G = (byte)Math.Max(0, c.G - 20);
c.B = (byte)Math.Max(0, c.B - 20);
c.A = 30;
this.GrayOutBrush = new SolidColorBrush(c);
} }
public Brush GrayOutBrush { public Brush GrayOutBrush {
@ -45,11 +48,6 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
} }
} }
public void SetActiveArea(UIElement activeContainer)
{
this.ActiveAreaGeometry = new RectangleGeometry(new Rect(activeContainer.RenderSize), 0, 0, (Transform)activeContainer.TransformToVisual(this));
}
protected override void OnRender(DrawingContext drawingContext) protected override void OnRender(DrawingContext drawingContext)
{ {
drawingContext.DrawGeometry(grayOutBrush, null, combinedGeometry); drawingContext.DrawGeometry(grayOutBrush, null, combinedGeometry);
@ -57,17 +55,40 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
internal static void Start(ref GrayOutDesignerExceptActiveArea grayOut, IDesignPanel designPanel, UIElement activeContainer) internal static void Start(ref GrayOutDesignerExceptActiveArea grayOut, IDesignPanel designPanel, UIElement activeContainer)
{ {
if (designPanel != null) { Debug.Assert(activeContainer != null);
if (designPanel != null && grayOut == null) {
grayOut = new GrayOutDesignerExceptActiveArea(); grayOut = new GrayOutDesignerExceptActiveArea();
designPanel.MarkerCanvas.Children.Add(grayOut); grayOut.designPanel = designPanel;
grayOut.SetActiveArea(activeContainer); grayOut.adornerPanel = new AdornerPanel();
grayOut.adornerPanel.Order = AdornerOrder.BehindForeground;
grayOut.adornerPanel.SetAdornedElement(designPanel.Context.RootItem.View, null);
grayOut.adornerPanel.Children.Add(grayOut);
grayOut.ActiveAreaGeometry = new RectangleGeometry(new Rect(activeContainer.RenderSize), 0, 0, (Transform)activeContainer.TransformToVisual(grayOut.adornerPanel.AdornedElement));
Animate(grayOut.GrayOutBrush, Brush.OpacityProperty, 0, MaxOpacity);
designPanel.Adorners.Add(grayOut.adornerPanel);
}
} }
static readonly TimeSpan animationTime = new TimeSpan(2000000);
static void Animate(Animatable element, DependencyProperty property, double from, double to)
{
element.BeginAnimation(property, new DoubleAnimation(from, to, new Duration(animationTime), FillBehavior.Stop));
} }
internal static void Stop(ref GrayOutDesignerExceptActiveArea grayOut, IDesignPanel designPanel) internal static void Stop(ref GrayOutDesignerExceptActiveArea grayOut)
{ {
if (grayOut != null) { if (grayOut != null) {
designPanel.MarkerCanvas.Children.Remove(grayOut); Animate(grayOut.GrayOutBrush, Brush.OpacityProperty, MaxOpacity, 0);
IDesignPanel designPanel = grayOut.designPanel;
AdornerPanel adornerPanelToRemove = grayOut.adornerPanel;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = animationTime;
timer.Tick += delegate {
timer.Stop();
designPanel.Adorners.Remove(adornerPanelToRemove);
};
timer.Start();
grayOut = null; grayOut = null;
} }
} }

46
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ResizeThumb.cs

@ -7,7 +7,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Windows; using System.Windows;
using System.Windows.Input;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Controls.Primitives; using System.Windows.Controls.Primitives;
using ICSharpCode.WpfDesign.Adorners; using ICSharpCode.WpfDesign.Adorners;
@ -17,7 +19,6 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
{ {
/// <summary> /// <summary>
/// A thumb where the look can depend on the IsPrimarySelection property. /// A thumb where the look can depend on the IsPrimarySelection property.
/// Used by UIElementSelectionRectangle.
/// </summary> /// </summary>
public class ResizeThumb : Thumb public class ResizeThumb : Thumb
{ {
@ -27,6 +28,14 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
public static readonly DependencyProperty IsPrimarySelectionProperty public static readonly DependencyProperty IsPrimarySelectionProperty
= DependencyProperty.Register("IsPrimarySelection", typeof(bool), typeof(ResizeThumb)); = DependencyProperty.Register("IsPrimarySelection", typeof(bool), typeof(ResizeThumb));
/// <summary>
/// Dependency property for <see cref="IsPrimarySelection"/>.
/// </summary>
public static readonly DependencyProperty ResizeThumbVisibleProperty
= DependencyProperty.Register("ResizeThumbVisible", typeof(bool), typeof(ResizeThumb), new FrameworkPropertyMetadata(true));
internal PlacementAlignment Alignment;
static ResizeThumb() static ResizeThumb()
{ {
//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.
@ -41,5 +50,40 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
get { return (bool)GetValue(IsPrimarySelectionProperty); } get { return (bool)GetValue(IsPrimarySelectionProperty); }
set { SetValue(IsPrimarySelectionProperty, value); } set { SetValue(IsPrimarySelectionProperty, value); }
} }
/// <summary>
/// Gets/Sets if the resize thumb is visible.
/// </summary>
public bool ResizeThumbVisible {
get { return (bool)GetValue(ResizeThumbVisibleProperty); }
set { SetValue(ResizeThumbVisibleProperty, value); }
}
}
/// <summary>
/// Resize thumb that automatically disappears if the adornered element is too small.
/// </summary>
sealed class ResizeThumbImpl : ResizeThumb
{
bool checkWidth, checkHeight;
internal ResizeThumbImpl(bool checkWidth, bool checkHeight)
{
Debug.Assert((checkWidth && checkHeight) == false);
this.checkWidth = checkWidth;
this.checkHeight = checkHeight;
}
protected override Size ArrangeOverride(Size arrangeBounds)
{
AdornerPanel parent = this.Parent as AdornerPanel;
if (parent != null && parent.AdornedElement != null) {
if (checkWidth)
this.ResizeThumbVisible = parent.AdornedElement.RenderSize.Width > 14;
else if (checkHeight)
this.ResizeThumbVisible = parent.AdornedElement.RenderSize.Height > 14;
}
return base.ArrangeOverride(arrangeBounds);
}
} }
} }

8
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/DragFrame.cs → src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SelectionFrame.cs

@ -18,15 +18,15 @@ using ICSharpCode.WpfDesign.Extensions;
namespace ICSharpCode.WpfDesign.Designer.Controls namespace ICSharpCode.WpfDesign.Designer.Controls
{ {
/// <summary> /// <summary>
/// The rectangle shown during a drag'n'drop operation. /// The rectangle shown during a rubber-band selecting operation.
/// </summary> /// </summary>
public class DragFrame : Control public class SelectionFrame : Control
{ {
static DragFrame() static SelectionFrame()
{ {
//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.
//This style is defined in themes\generic.xaml //This style is defined in themes\generic.xaml
DefaultStyleKeyProperty.OverrideMetadata(typeof(DragFrame), new FrameworkPropertyMetadata(typeof(DragFrame))); DefaultStyleKeyProperty.OverrideMetadata(typeof(SelectionFrame), new FrameworkPropertyMetadata(typeof(SelectionFrame)));
} }
} }
} }

96
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasChildResizeSupport.cs

@ -11,55 +11,105 @@ using System.Windows.Controls;
using ICSharpCode.WpfDesign.Adorners; using ICSharpCode.WpfDesign.Adorners;
using ICSharpCode.WpfDesign.Extensions; using ICSharpCode.WpfDesign.Extensions;
using ICSharpCode.WpfDesign.Designer.Controls;
namespace ICSharpCode.WpfDesign.Designer.Extensions namespace ICSharpCode.WpfDesign.Designer.Extensions
{ {
/// <summary> /// <summary>
/// Provides <see cref="IChildResizeSupport"/> behavior for <see cref="Canvas"/>. /// Provides <see cref="IPlacementBehavior"/> behavior for <see cref="Canvas"/>.
/// </summary> /// </summary>
[ExtensionFor(typeof(Canvas), OverrideExtension = typeof(DefaultChildResizeSupport))] [ExtensionFor(typeof(Canvas))]
public sealed class CanvasChildResizeSupport : BehaviorExtension, IChildResizeSupport public sealed class CanvasPlacementSupport : BehaviorExtension, IPlacementBehavior
{ {
/// <inherits/> /// <inherits/>
protected override void OnInitialized() protected override void OnInitialized()
{ {
base.OnInitialized(); base.OnInitialized();
this.ExtendedItem.AddBehavior(typeof(IChildResizeSupport), this); this.ExtendedItem.AddBehavior(typeof(IPlacementBehavior), this);
} }
GrayOutDesignerExceptActiveArea grayOut;
/// <inherits/> /// <inherits/>
public bool CanResizeChild(DesignItem child) public bool CanPlace(DesignItem child, PlacementType type, PlacementAlignment position)
{ {
return DefaultChildResizeSupport.Instance.CanResizeChild(child); return type == PlacementType.Resize || type == PlacementType.Move;
} }
/// <inherits/> /// <inherits/>
public Placement GetPlacement(DesignItem child, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical) public void StartPlacement(PlacementOperation operation, out bool supportsRemoveFromContainer)
{ {
return RootElementResizeSupport.Instance.GetPlacement(child, horizontalChange, verticalChange, horizontal, vertical); supportsRemoveFromContainer = false;
//DesignItemProperty margin = operation.PlacedItem.Properties[FrameworkElement.MarginProperty];
UIElement child = (UIElement)operation.PlacedItem.Component;
operation.Left = GetLeft(child);
operation.Top = GetTop(child);
operation.Right = operation.Left + GetWidth(child);
operation.Bottom = operation.Top + GetHeight(child);
GrayOutDesignerExceptActiveArea.Start(ref grayOut, this.Services.GetService<IDesignPanel>(), this.ExtendedItem.View);
} }
/// <inherits/> static double GetLeft(UIElement element)
public void Resize(DesignItem childItem, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical) {
double v = (double)element.GetValue(Canvas.LeftProperty);
if (double.IsNaN(v))
return 0;
else
return v;
}
static double GetTop(UIElement element)
{ {
RelativePlacement p = (RelativePlacement)GetPlacement(childItem, horizontalChange, verticalChange, horizontal, vertical); double v = (double)element.GetValue(Canvas.TopProperty);
DefaultChildResizeSupport.Resize(childItem, p); if (double.IsNaN(v))
return 0;
else
return v;
}
bool marginIsSet = childItem.Properties[FrameworkElement.MarginProperty].IsSet; static double GetWidth(UIElement element)
{
double v = (double)element.GetValue(FrameworkElement.WidthProperty);
if (double.IsNaN(v))
return element.RenderSize.Width;
else
return v;
}
DesignItemProperty left = childItem.Properties.GetAttachedProperty(Canvas.LeftProperty); static double GetHeight(UIElement element)
DesignItemProperty top = childItem.Properties.GetAttachedProperty(Canvas.TopProperty); {
double v = (double)element.GetValue(FrameworkElement.HeightProperty);
if (double.IsNaN(v))
return element.RenderSize.Height;
else
return v;
}
if (left.IsSet) { /// <inherits/>
left.SetValue( p.XOffset + (double)left.ValueOnInstance); public void UpdatePlacement(PlacementOperation operation)
} else if (p.XOffset != 0 && !marginIsSet) { {
left.SetValue( p.XOffset ); DesignItem item = operation.PlacedItem;
UIElement child = (UIElement)item.Component;
if (operation.Left != GetLeft(child)) {
item.Properties.GetAttachedProperty(Canvas.LeftProperty).SetValue(operation.Left);
}
if (operation.Top != GetTop(child)) {
item.Properties.GetAttachedProperty(Canvas.TopProperty).SetValue(operation.Top);
} }
if (top.IsSet) { if (operation.Right - operation.Left != GetWidth(child)) {
top.SetValue( p.YOffset + (double)top.ValueOnInstance); item.Properties.GetProperty(FrameworkElement.WidthProperty).SetValue(operation.Right - operation.Left);
} else if (p.YOffset != 0 && !marginIsSet) {
top.SetValue( p.YOffset );
} }
if (operation.Bottom - operation.Top != GetHeight(child)) {
item.Properties.GetProperty(FrameworkElement.HeightProperty).SetValue(operation.Bottom - operation.Top);
}
}
/// <inherits/>
public void FinishPlacement(PlacementOperation operation)
{
GrayOutDesignerExceptActiveArea.Stop(ref grayOut);
} }
} }
} }

168
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DefaultChildResizeSupport.cs

@ -1,168 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Windows;
using ICSharpCode.WpfDesign.Adorners;
using ICSharpCode.WpfDesign.Extensions;
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
/// <summary>
/// Implements IChildResizeSupport supporting size changes using the
/// Width, Height, Margin properties.
/// </summary>
[ExtensionFor(typeof(FrameworkElement))]
public sealed class DefaultChildResizeSupport : BehaviorExtension, IChildResizeSupport
{
internal static readonly DefaultChildResizeSupport Instance = new DefaultChildResizeSupport();
/// <inherits/>
protected override void OnInitialized()
{
base.OnInitialized();
this.ExtendedItem.AddBehavior(typeof(IChildResizeSupport), this);
}
/// <inherits/>
public bool CanResizeChild(DesignItem childItem)
{
FrameworkElement child = (FrameworkElement)childItem.Component;
return !double.IsNaN(child.Width)
|| !double.IsNaN(child.Height)
|| childItem.Properties[FrameworkElement.MarginProperty].IsSet;
}
/// <inherits/>
public Placement GetPlacement(DesignItem childItem, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical)
{
FrameworkElement child = (FrameworkElement)childItem.Component;
if (childItem.Properties[FrameworkElement.MarginProperty].IsSet == false) {
if (child.HorizontalAlignment == HorizontalAlignment.Left)
horizontal = HorizontalAlignment.Right;
else if (child.HorizontalAlignment == HorizontalAlignment.Right)
horizontal = HorizontalAlignment.Left;
else
horizontal = HorizontalAlignment.Center;
if (child.VerticalAlignment == VerticalAlignment.Top)
horizontal = HorizontalAlignment.Right;
else if (child.VerticalAlignment == VerticalAlignment.Bottom)
vertical = VerticalAlignment.Bottom;
else
vertical = VerticalAlignment.Center;
}
return RootElementResizeSupport.Instance.GetPlacement(childItem, horizontalChange, verticalChange, horizontal, vertical);
}
/// <inherits/>
public void Resize(DesignItem childItem, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical)
{
RelativePlacement p = (RelativePlacement)GetPlacement(childItem, horizontalChange, verticalChange, horizontal, vertical);
Resize(childItem, p);
}
internal static void Resize(DesignItem childItem, RelativePlacement p)
{
DesignItemProperty margin = childItem.Properties[FrameworkElement.MarginProperty];
if (margin.IsSet) {
Thickness t = (Thickness)margin.ValueOnInstance;
t.Left += p.XOffset;
t.Top += p.YOffset;
t.Right -= p.XOffset + p.WidthOffset;
t.Bottom -= p.YOffset + p.HeightOffset;
margin.SetValue(t);
}
double horizontalChange = p.WidthOffset;
double verticalChange = p.HeightOffset;
FrameworkElement child = (FrameworkElement)childItem.Component;
double width = child.Width;
double height = child.Height;
if (margin.IsSet) {
// when margin is used, only set width/height if it is not Auto
if (!double.IsNaN(width)) {
childItem.Properties[FrameworkElement.WidthProperty].SetValue( Math.Max(0, horizontalChange + width) );
}
if (!double.IsNaN(height)) {
childItem.Properties[FrameworkElement.HeightProperty].SetValue( Math.Max(0, verticalChange + height) );
}
} else {
// when margin is not used, we'll have to set width+height
// but don't create width if we don't have any horizontal change
if (double.IsNaN(width) && horizontalChange != 0) {
width = child.ActualWidth;
}
if (double.IsNaN(height) && verticalChange != 0) {
height = child.ActualHeight;
}
if (!double.IsNaN(width)) {
childItem.Properties[FrameworkElement.WidthProperty].SetValue( Math.Max(0, horizontalChange + width) );
}
if (!double.IsNaN(height)) {
childItem.Properties[FrameworkElement.HeightProperty].SetValue( Math.Max(0, verticalChange + height) );
}
}
}
}
sealed class RootElementResizeSupport : IChildResizeSupport
{
public static readonly RootElementResizeSupport Instance = new RootElementResizeSupport();
public bool CanResizeChild(DesignItem child)
{
return true;
}
public Placement GetPlacement(DesignItem child, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical)
{
RelativePlacement rp = new RelativePlacement(HorizontalAlignment.Stretch, VerticalAlignment.Stretch);
if (horizontal == HorizontalAlignment.Right) {
rp.WidthOffset += horizontalChange;
} else if (horizontal == HorizontalAlignment.Left) {
rp.XOffset -= horizontalChange;
rp.WidthOffset += horizontalChange;
} else {
rp.XOffset -= horizontalChange;
rp.WidthOffset += horizontalChange * 2;
}
if (vertical == VerticalAlignment.Bottom) {
rp.HeightOffset += verticalChange;
} else if (vertical == VerticalAlignment.Top) {
rp.YOffset -= verticalChange;
rp.HeightOffset += verticalChange;
} else {
rp.YOffset -= verticalChange;
rp.HeightOffset += verticalChange * 2;
}
return rp;
}
public void Resize(DesignItem childItem, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical)
{
FrameworkElement child = (FrameworkElement)childItem.Component;
double width = child.Width;
double height = child.Height;
if (double.IsNaN(width) && horizontalChange != 0) {
width = child.ActualWidth;
}
if (double.IsNaN(height) && verticalChange != 0) {
height = child.ActualHeight;
}
if (!double.IsNaN(width)) {
childItem.Properties[FrameworkElement.WidthProperty].SetValue( Math.Max(0, horizontalChange + width) );
}
if (!double.IsNaN(height)) {
childItem.Properties[FrameworkElement.HeightProperty].SetValue( Math.Max(0, verticalChange + height) );
}
}
}
}

29
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelSelectionHandler.cs

@ -7,6 +7,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
@ -39,28 +40,26 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
} }
} }
sealed class RangeSelectionGesture : MouseGestureBase sealed class RangeSelectionGesture : ClickOrDragMouseGesture
{ {
DesignItem container; DesignItem container;
AdornerPanel adornerPanel; AdornerPanel adornerPanel;
DragFrame selectionFrame; SelectionFrame selectionFrame;
Point startPoint;
GrayOutDesignerExceptActiveArea grayOut; GrayOutDesignerExceptActiveArea grayOut;
public RangeSelectionGesture(DesignItem container) public RangeSelectionGesture(DesignItem container)
{ {
this.container = container; this.container = container;
this.positionRelativeTo = container.View;
} }
protected override void OnStarted(MouseButtonEventArgs e) protected override void OnDragStarted()
{ {
startPoint = e.GetPosition(container.View);
adornerPanel = new AdornerPanel(); adornerPanel = new AdornerPanel();
adornerPanel.SetAdornedElement(container.View, container); adornerPanel.SetAdornedElement(container.View, container);
selectionFrame = new DragFrame(); selectionFrame = new SelectionFrame();
SetPlacement(e.GetPosition(container.View));
adornerPanel.Children.Add(selectionFrame); adornerPanel.Children.Add(selectionFrame);
designPanel.Adorners.Add(adornerPanel); designPanel.Adorners.Add(adornerPanel);
@ -70,12 +69,18 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
protected override void OnMouseMove(object sender, MouseEventArgs e) protected override void OnMouseMove(object sender, MouseEventArgs e)
{ {
SetPlacement(e.GetPosition(container.View)); base.OnMouseMove(sender, e);
if (hasDragStarted) {
SetPlacement(e.GetPosition(positionRelativeTo));
}
} }
protected override void OnMouseUp(object sender, MouseButtonEventArgs e) protected override void OnMouseUp(object sender, MouseButtonEventArgs e)
{ {
Point endPoint = e.GetPosition(container.View); if (hasDragStarted == false) {
services.Selection.SetSelectedComponents(new DesignItem [] { container }, SelectionTypes.Auto);
} else {
Point endPoint = e.GetPosition(positionRelativeTo);
Rect frameRect = new Rect( Rect frameRect = new Rect(
Math.Min(startPoint.X, endPoint.X), Math.Min(startPoint.X, endPoint.X),
Math.Min(startPoint.Y, endPoint.Y), Math.Min(startPoint.Y, endPoint.Y),
@ -88,6 +93,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
items.Add(container); items.Add(container);
} }
services.Selection.SetSelectedComponents(items, SelectionTypes.Auto); services.Selection.SetSelectedComponents(items, SelectionTypes.Auto);
}
Stop(); Stop();
} }
@ -155,8 +161,9 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
designPanel.Adorners.Remove(adornerPanel); designPanel.Adorners.Remove(adornerPanel);
adornerPanel = null; adornerPanel = null;
} }
GrayOutDesignerExceptActiveArea.Stop(ref grayOut, designPanel); GrayOutDesignerExceptActiveArea.Stop(ref grayOut);
selectionFrame = null; selectionFrame = null;
base.OnStopped();
} }
} }
} }

151
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/ResizeThumbExtension.cs

@ -6,6 +6,7 @@
// </file> // </file>
using System; using System;
using System.Diagnostics;
using System.Windows; using System.Windows;
using System.Windows.Controls.Primitives; using System.Windows.Controls.Primitives;
using System.Windows.Input; using System.Windows.Input;
@ -17,107 +18,105 @@ using ICSharpCode.WpfDesign.Extensions;
namespace ICSharpCode.WpfDesign.Designer.Extensions namespace ICSharpCode.WpfDesign.Designer.Extensions
{ {
/// <summary> /// <summary>
/// The resize thumb at the top left edge of a component. /// The resize thumb around a component.
/// </summary> /// </summary>
[ExtensionFor(typeof(FrameworkElement))] [ExtensionFor(typeof(FrameworkElement))]
public sealed class ResizeThumbExtension : PrimarySelectionAdornerProvider public sealed class ResizeThumbExtension : PrimarySelectionAdornerProvider
{ {
AdornerPanel adornerPanel; readonly AdornerPanel adornerPanel;
DragFrame dragFrame; readonly ResizeThumb[] resizeThumbs;
IChildResizeSupport resizeBehavior; IPlacementBehavior resizeBehavior;
GrayOutDesignerExceptActiveArea grayOut; PlacementOperation operation;
ResizeThumb activeResizeThumb;
/// <summary></summary> /// <summary></summary>
public ResizeThumbExtension() public ResizeThumbExtension()
{ {
adornerPanel = new AdornerPanel(); adornerPanel = new AdornerPanel();
adornerPanel.Order = AdornerOrder.Foreground; adornerPanel.Order = AdornerOrder.Foreground;
this.Adorners.Add(adornerPanel);
CreateThumb(HorizontalAlignment.Left, VerticalAlignment.Top); resizeThumbs = new ResizeThumb[] {
CreateThumb(HorizontalAlignment.Right, VerticalAlignment.Top); CreateThumb(PlacementAlignments.TopLeft, Cursors.SizeNWSE),
CreateThumb(HorizontalAlignment.Left, VerticalAlignment.Bottom); CreateThumb(PlacementAlignments.Top, Cursors.SizeNS),
CreateThumb(HorizontalAlignment.Right, VerticalAlignment.Bottom); CreateThumb(PlacementAlignments.TopRight, Cursors.SizeNESW),
CreateThumb(PlacementAlignments.Left, Cursors.SizeWE),
CreateThumb(PlacementAlignments.Right, Cursors.SizeWE),
CreateThumb(PlacementAlignments.BottomLeft, Cursors.SizeNESW),
CreateThumb(PlacementAlignments.Bottom, Cursors.SizeNS),
CreateThumb(PlacementAlignments.BottomRight, Cursors.SizeNWSE)
};
} }
void CreateThumb(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) ResizeThumb CreateThumb(PlacementAlignment alignment, Cursor cursor)
{ {
ResizeThumb resizeThumb = new ResizeThumb(); ResizeThumb resizeThumb = new ResizeThumbImpl( cursor == Cursors.SizeNS, cursor == Cursors.SizeWE );
AdornerPanel.SetPlacement(resizeThumb, new RelativePlacement(horizontalAlignment, verticalAlignment)); resizeThumb.Cursor = cursor;
resizeThumb.Alignment = alignment;
AdornerPanel.SetPlacement(resizeThumb, new RelativePlacement(alignment.Horizontal, alignment.Vertical));
adornerPanel.Children.Add(resizeThumb); adornerPanel.Children.Add(resizeThumb);
resizeThumb.DragStarted += OnDragStarted; resizeThumb.DragStarted += OnDragStarted;
resizeThumb.DragDelta += OnDragDelta(horizontalAlignment, verticalAlignment); resizeThumb.DragDelta += OnDragDelta(alignment);
resizeThumb.DragCompleted += OnDragCompleted(horizontalAlignment, verticalAlignment); resizeThumb.DragCompleted += OnDragCompleted;
return resizeThumb;
} }
void OnDragStarted(object sender, DragStartedEventArgs e) void OnDragStarted(object sender, DragStartedEventArgs e)
{ {
if (dragFrame == null) activeResizeThumb = (ResizeThumb)sender;
dragFrame = new DragFrame(); operation = PlacementOperation.Start(this.ExtendedItem, PlacementType.Resize);
this.ExtendedItem.Services.GetService<IDesignPanel>().KeyDown += OnDesignPanelKeyDown;
if (this.ExtendedItem.Parent != null) {
GrayOutDesignerExceptActiveArea.Start(ref grayOut, this.Services.GetService<IDesignPanel>(), this.ExtendedItem.Parent.View);
}
AdornerPanel.SetPlacement(dragFrame, Placement.FillContent);
adornerPanel.Children.Add(dragFrame);
adornerPanel.Cursor = Cursors.SizeNWSE;
// newSize.Width = double.IsNaN(component.Width) ? component.ActualWidth : component.Width;
// newSize.Height = double.IsNaN(component.Height) ? component.ActualHeight : component.Height;
} }
DragDeltaEventHandler OnDragDelta(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) DragDeltaEventHandler OnDragDelta(PlacementAlignment alignment)
{ {
return delegate(object sender, DragDeltaEventArgs e) { return delegate(object sender, DragDeltaEventArgs e) {
if (resizeBehavior != null) { switch (alignment.Horizontal) {
Placement p = resizeBehavior.GetPlacement(this.ExtendedItem, case HorizontalAlignment.Left:
FixChange(e.HorizontalChange, horizontalAlignment), operation.Left += e.HorizontalChange;
FixChange(e.VerticalChange, verticalAlignment), if (operation.Left > operation.Right)
horizontalAlignment, verticalAlignment); operation.Left = operation.Right;
if (p != null) { break;
AdornerPanel.SetPlacement(dragFrame, p); case HorizontalAlignment.Right:
} operation.Right += e.HorizontalChange;
} if (operation.Right < operation.Left)
operation.Right = operation.Left;
break;
}
switch (alignment.Vertical) {
case VerticalAlignment.Top:
operation.Top += e.VerticalChange;
if (operation.Top > operation.Bottom)
operation.Top = operation.Bottom;
break;
case VerticalAlignment.Bottom:
operation.Bottom += e.VerticalChange;
if (operation.Bottom < operation.Top)
operation.Bottom = operation.Top;
break;
}
operation.UpdatePlacement();
}; };
} }
DragCompletedEventHandler OnDragCompleted(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) void OnDragCompleted(object sender, DragCompletedEventArgs e)
{ {
return delegate (object sender, DragCompletedEventArgs e) { if (operation != null) {
adornerPanel.Children.Remove(dragFrame); this.ExtendedItem.Services.GetService<IDesignPanel>().KeyDown -= OnDesignPanelKeyDown;
adornerPanel.ClearValue(AdornerPanel.CursorProperty); if (e.Canceled)
GrayOutDesignerExceptActiveArea.Stop(ref grayOut, this.Services.GetService<IDesignPanel>()); operation.Abort();
else
if (e.Canceled == false && resizeBehavior != null) { operation.Commit();
using (ChangeGroup group = this.ExtendedItem.OpenGroup("Resize")) { operation = null;
resizeBehavior.Resize(this.ExtendedItem,
FixChange(e.HorizontalChange, horizontalAlignment),
FixChange(e.VerticalChange, verticalAlignment),
horizontalAlignment, verticalAlignment);
group.Commit();
} }
} }
};
}
double FixChange(double val, VerticalAlignment va) void OnDesignPanelKeyDown(object sender, KeyEventArgs e)
{ {
if (va == VerticalAlignment.Bottom) if (e.Key == Key.Escape) {
return val; activeResizeThumb.CancelDrag();
else if (va == VerticalAlignment.Top)
return -val;
else
return 0;
} }
double FixChange(double val, HorizontalAlignment ha)
{
if (ha == HorizontalAlignment.Right)
return val;
else if (ha == HorizontalAlignment.Left)
return -val;
else
return 0;
} }
/// <summary/> /// <summary/>
@ -127,11 +126,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
this.ExtendedItem.PropertyChanged += OnPropertyChanged; this.ExtendedItem.PropertyChanged += OnPropertyChanged;
this.Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged; this.Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged;
DesignItem parentItem = this.ExtendedItem.Parent; resizeBehavior = PlacementOperation.GetPlacementBehavior(this.ExtendedItem);
if (parentItem == null) // resizing the root element
resizeBehavior = RootElementResizeSupport.Instance;
else
resizeBehavior = parentItem.GetBehavior<IChildResizeSupport>();
UpdateAdornerVisibility(); UpdateAdornerVisibility();
OnPrimarySelectionChanged(null, null); OnPrimarySelectionChanged(null, null);
@ -160,14 +155,10 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
void UpdateAdornerVisibility() void UpdateAdornerVisibility()
{ {
if (resizeBehavior == null || !resizeBehavior.CanResizeChild(this.ExtendedItem)) { FrameworkElement fe = this.ExtendedItem.View as FrameworkElement;
if (this.Adorners.Count == 1) { foreach (ResizeThumb r in resizeThumbs) {
this.Adorners.Clear(); bool isVisible = resizeBehavior != null && resizeBehavior.CanPlace(this.ExtendedItem, PlacementType.Resize, r.Alignment);
} r.Visibility = isVisible ? Visibility.Visible : Visibility.Hidden;
} else {
if (this.Adorners.Count == 0) {
this.Adorners.Add(adornerPanel);
}
} }
} }
} }

51
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ClickOrDragMouseGesture.cs

@ -0,0 +1,51 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;
namespace ICSharpCode.WpfDesign.Designer.Services
{
/// <summary>
/// Base class for mouse gestures that should start dragging only after a minimum drag distance.
/// </summary>
abstract class ClickOrDragMouseGesture : MouseGestureBase
{
protected Point startPoint;
protected bool hasDragStarted;
protected IInputElement positionRelativeTo;
const double MinimumDragDistance = 3;
protected sealed override void OnStarted(MouseButtonEventArgs e)
{
Debug.Assert(positionRelativeTo != null);
hasDragStarted = false;
startPoint = e.GetPosition(positionRelativeTo);
}
protected override void OnMouseMove(object sender, MouseEventArgs e)
{
if (!hasDragStarted) {
Vector v = e.GetPosition(positionRelativeTo) - startPoint;
if (v.LengthSquared >= MinimumDragDistance * MinimumDragDistance) {
hasDragStarted = true;
OnDragStarted();
}
}
}
protected override void OnStopped()
{
hasDragStarted = false;
}
protected virtual void OnDragStarted() {}
}
}

80
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/DragMoveMouseGesture.cs

@ -0,0 +1,80 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;
namespace ICSharpCode.WpfDesign.Designer.Services
{
/// <summary>
/// Mouse gesture for moving elements inside a container or between containers.
/// Belongs to the PointerTool.
/// </summary>
sealed class DragMoveMouseGesture : ClickOrDragMouseGesture
{
DesignItem clickedOn;
PlacementOperation operation;
internal DragMoveMouseGesture(DesignItem clickedOn)
{
Debug.Assert(clickedOn != null);
this.clickedOn = clickedOn;
if (clickedOn.Parent != null)
this.positionRelativeTo = clickedOn.Parent.View;
else
this.positionRelativeTo = clickedOn.View;
}
double startLeft, startRight, startTop, startBottom;
protected override void OnDragStarted()
{
IPlacementBehavior b = PlacementOperation.GetPlacementBehavior(clickedOn);
if (b != null && b.CanPlace(clickedOn, PlacementType.Move, PlacementAlignments.TopLeft)) {
operation = PlacementOperation.Start(clickedOn, PlacementType.Move);
startLeft = operation.Left;
startRight = operation.Right;
startTop = operation.Top;
startBottom = operation.Bottom;
}
}
protected override void OnMouseMove(object sender, MouseEventArgs e)
{
base.OnMouseMove(sender, e); // call OnDragStarted if min. drag distace is reached
if (operation != null) {
Vector v = e.GetPosition(positionRelativeTo) - startPoint;
operation.Left = startLeft + v.X;
operation.Right = startRight + v.X;
operation.Top = startTop + v.Y;
operation.Bottom = startBottom + v.Y;
operation.UpdatePlacement();
}
}
protected override void OnMouseUp(object sender, MouseButtonEventArgs e)
{
if (operation != null) {
operation.Commit();
operation = null;
}
Stop();
}
protected override void OnStopped()
{
if (operation != null) {
operation.Abort();
operation = null;
}
}
}
}

19
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ToolService.cs

@ -71,7 +71,11 @@ namespace ICSharpCode.WpfDesign.Designer.Services
if (b != null) { if (b != null) {
b.HandleSelectionMouseDown(designPanel, e, result); b.HandleSelectionMouseDown(designPanel, e, result);
} else { } else {
designPanel.Context.Services.Selection.SetSelectedComponents(new DesignItem[] { result.ModelHit }, SelectionTypes.Auto); ISelectionService selectionService = designPanel.Context.Services.Selection;
selectionService.SetSelectedComponents(new DesignItem[] { result.ModelHit }, SelectionTypes.Auto);
if (selectionService.IsComponentSelected(result.ModelHit)) {
new DragMoveMouseGesture(result.ModelHit).Start(designPanel, e);
}
} }
} }
} }
@ -97,6 +101,7 @@ namespace ICSharpCode.WpfDesign.Designer.Services
protected IDesignPanel designPanel; protected IDesignPanel designPanel;
protected ServiceContainer services; protected ServiceContainer services;
protected bool canAbortWithEscape = true;
bool isStarted; bool isStarted;
public void Start(IDesignPanel designPanel, MouseButtonEventArgs e) public void Start(IDesignPanel designPanel, MouseButtonEventArgs e)
@ -126,6 +131,7 @@ namespace ICSharpCode.WpfDesign.Designer.Services
designPanel.MouseDown += OnMouseDown; designPanel.MouseDown += OnMouseDown;
designPanel.MouseMove += OnMouseMove; designPanel.MouseMove += OnMouseMove;
designPanel.MouseUp += OnMouseUp; designPanel.MouseUp += OnMouseUp;
designPanel.KeyDown += OnKeyDown;
} }
void UnRegisterEvents() void UnRegisterEvents()
@ -134,9 +140,18 @@ namespace ICSharpCode.WpfDesign.Designer.Services
designPanel.MouseDown -= OnMouseDown; designPanel.MouseDown -= OnMouseDown;
designPanel.MouseMove -= OnMouseMove; designPanel.MouseMove -= OnMouseMove;
designPanel.MouseUp -= OnMouseUp; designPanel.MouseUp -= OnMouseUp;
designPanel.KeyDown -= OnKeyDown;
}
void OnKeyDown(object sender, KeyEventArgs e)
{
if (canAbortWithEscape && e.Key == Key.Escape) {
e.Handled = true;
Stop();
}
} }
protected virtual void OnLostMouseCapture(object sender, MouseEventArgs e) void OnLostMouseCapture(object sender, MouseEventArgs e)
{ {
Stop(); Stop();
} }

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

@ -58,7 +58,7 @@
<Compile Include="Configuration\AssemblyInfo.cs" /> <Compile Include="Configuration\AssemblyInfo.cs" />
<Compile Include="Controls\AdornerLayer.cs" /> <Compile Include="Controls\AdornerLayer.cs" />
<Compile Include="Controls\ContainerDragHandle.cs" /> <Compile Include="Controls\ContainerDragHandle.cs" />
<Compile Include="Controls\DragFrame.cs" /> <Compile Include="Controls\SelectionFrame.cs" />
<Compile Include="Controls\ErrorBalloon.cs" /> <Compile Include="Controls\ErrorBalloon.cs" />
<Compile Include="Controls\GrayOutDesignerExceptActiveArea.cs" /> <Compile Include="Controls\GrayOutDesignerExceptActiveArea.cs" />
<Compile Include="Controls\PropertyEditor\DependencyPropertyDotButton.cs" /> <Compile Include="Controls\PropertyEditor\DependencyPropertyDotButton.cs" />
@ -72,7 +72,6 @@
<Compile Include="Controls\WindowClone.cs" /> <Compile Include="Controls\WindowClone.cs" />
<Compile Include="DesignPanel.cs" /> <Compile Include="DesignPanel.cs" />
<Compile Include="Extensions\CanvasChildResizeSupport.cs" /> <Compile Include="Extensions\CanvasChildResizeSupport.cs" />
<Compile Include="Extensions\DefaultChildResizeSupport.cs" />
<Compile Include="Extensions\PanelInstanceFactory.cs" /> <Compile Include="Extensions\PanelInstanceFactory.cs" />
<Compile Include="Extensions\PanelSelectionHandler.cs" /> <Compile Include="Extensions\PanelSelectionHandler.cs" />
<Compile Include="Extensions\SelectedElementRectangleExtension.cs" /> <Compile Include="Extensions\SelectedElementRectangleExtension.cs" />
@ -81,6 +80,8 @@
<Compile Include="Extensions\ResizeThumbExtension.cs" /> <Compile Include="Extensions\ResizeThumbExtension.cs" />
<Compile Include="Func.cs" /> <Compile Include="Func.cs" />
<Compile Include="ServiceRequiredException.cs" /> <Compile Include="ServiceRequiredException.cs" />
<Compile Include="Services\ClickOrDragMouseGesture.cs" />
<Compile Include="Services\DragMoveMouseGesture.cs" />
<Compile Include="Services\ErrorService.cs" /> <Compile Include="Services\ErrorService.cs" />
<Compile Include="Services\SelectionService.cs" /> <Compile Include="Services\SelectionService.cs" />
<Compile Include="Services\ToolService.cs" /> <Compile Include="Services\ToolService.cs" />

16
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPanel.cs

@ -23,26 +23,26 @@ namespace ICSharpCode.WpfDesign.Adorners
/// The dependency property used to store the placement of adorner visuals. /// The dependency property used to store the placement of adorner visuals.
/// </summary> /// </summary>
public static readonly DependencyProperty PlacementProperty = DependencyProperty.RegisterAttached( public static readonly DependencyProperty PlacementProperty = DependencyProperty.RegisterAttached(
"Placement", typeof(Placement), typeof(AdornerPanel), "Placement", typeof(AdornerPlacement), typeof(AdornerPanel),
new FrameworkPropertyMetadata(Placement.FillContent, FrameworkPropertyMetadataOptions.AffectsParentMeasure) new FrameworkPropertyMetadata(AdornerPlacement.FillContent, FrameworkPropertyMetadataOptions.AffectsParentMeasure)
); );
/// <summary> /// <summary>
/// Gets the placement of the specified adorner. /// Gets the placement of the specified adorner.
/// </summary> /// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
public static Placement GetPlacement(UIElement adorner) public static AdornerPlacement GetPlacement(UIElement adorner)
{ {
if (adorner == null) if (adorner == null)
throw new ArgumentNullException("adorner"); throw new ArgumentNullException("adorner");
return (Placement)adorner.GetValue(PlacementProperty); return (AdornerPlacement)adorner.GetValue(PlacementProperty);
} }
/// <summary> /// <summary>
/// Sets the placement of the specified adorner. /// Sets the placement of the specified adorner.
/// </summary> /// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
public static void SetPlacement(UIElement adorner, Placement placement) public static void SetPlacement(UIElement adorner, AdornerPlacement placement)
{ {
if (adorner == null) if (adorner == null)
throw new ArgumentNullException("adorner"); throw new ArgumentNullException("adorner");
@ -152,6 +152,12 @@ namespace ICSharpCode.WpfDesign.Adorners
/// </summary> /// </summary>
public static readonly AdornerOrder Content = new AdornerOrder(200); public static readonly AdornerOrder Content = new AdornerOrder(200);
/// <summary>
/// The adorner is in the layer behind the foreground but above the content. This layer
/// is used for the gray-out effect.
/// </summary>
public static readonly AdornerOrder BehindForeground = new AdornerOrder(280);
/// <summary> /// <summary>
/// The adorner is in the foreground layer. /// The adorner is in the foreground layer.
/// </summary> /// </summary>

39
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPlacement.cs

@ -0,0 +1,39 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Media;
namespace ICSharpCode.WpfDesign.Adorners
{
/// <summary>
/// Defines how a design-time adorner is placed.
/// </summary>
public abstract class AdornerPlacement
{
/// <summary>
/// A placement instance that places the adorner above the content, using the same bounds as the content.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly AdornerPlacement FillContent = new FillContentPlacement();
/// <summary>
/// Arranges the adorner element on the specified adorner panel.
/// </summary>
public abstract void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize);
sealed class FillContentPlacement : AdornerPlacement
{
public override void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize)
{
adorner.Arrange(new Rect(adornedElementSize));
}
}
}
}

33
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPlacementSpace.cs

@ -0,0 +1,33 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Media;
namespace ICSharpCode.WpfDesign.Adorners
{
/// <summary>
/// Describes the space in which an adorner is placed.
/// </summary>
public enum AdornerPlacementSpace
{
/// <summary>
/// The adorner is affected by the render transform of the adorned element.
/// </summary>
Render,
/// <summary>
/// The adorner is affected by the layout transform of the adorned element.
/// </summary>
Layout,
/// <summary>
/// The adorner is not affected by transforms of designed controls.
/// </summary>
Designer
}
}

4
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerProvider.cs

@ -124,7 +124,7 @@ namespace ICSharpCode.WpfDesign.Adorners
/// <summary> /// <summary>
/// Adds an UIElement as adorner with the specified placement. /// Adds an UIElement as adorner with the specified placement.
/// </summary> /// </summary>
protected void AddAdorner(Placement placement, AdornerOrder order, UIElement adorner) protected void AddAdorner(AdornerPlacement placement, AdornerOrder order, UIElement adorner)
{ {
AdornerPanel p = new AdornerPanel(); AdornerPanel p = new AdornerPanel();
p.Order = order; p.Order = order;
@ -136,7 +136,7 @@ namespace ICSharpCode.WpfDesign.Adorners
/// <summary> /// <summary>
/// Adds several UIElements as adorners with the specified placement. /// Adds several UIElements as adorners with the specified placement.
/// </summary> /// </summary>
protected void AddAdorners(Placement placement, params UIElement[] adorners) protected void AddAdorners(AdornerPlacement placement, params UIElement[] adorners)
{ {
AdornerPanel p = new AdornerPanel(); AdornerPanel p = new AdornerPanel();
foreach (UIElement adorner in adorners) { foreach (UIElement adorner in adorners) {

46
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/Placement.cs → src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/RelativePlacement.cs

@ -15,35 +15,10 @@ namespace ICSharpCode.WpfDesign.Adorners
// We have to support the different coordinate spaces as explained in // We have to support the different coordinate spaces as explained in
// http://myfun.spaces.live.com/blog/cns!AC1291870308F748!242.entry // http://myfun.spaces.live.com/blog/cns!AC1291870308F748!242.entry
/// <summary>
/// Defines how a design-time adorner is placed.
/// </summary>
public abstract class Placement
{
/// <summary>
/// A placement instance that places the adorner above the content, using the same bounds as the content.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly Placement FillContent = new FillContentPlacement();
/// <summary>
/// Arranges the adorner element on the specified adorner panel.
/// </summary>
public abstract void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize);
sealed class FillContentPlacement : Placement
{
public override void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize)
{
adorner.Arrange(new Rect(adornedElementSize));
}
}
}
/// <summary> /// <summary>
/// Placement class providing properties for different kinds of relative placements. /// Placement class providing properties for different kinds of relative placements.
/// </summary> /// </summary>
public sealed class RelativePlacement : Placement public sealed class RelativePlacement : AdornerPlacement
{ {
/// <summary> /// <summary>
/// Creates a new RelativePlacement instance. The default instance is a adorner with zero size, you /// Creates a new RelativePlacement instance. The default instance is a adorner with zero size, you
@ -233,23 +208,4 @@ namespace ICSharpCode.WpfDesign.Adorners
adorner.Arrange(new Rect(CalculatePosition(adornedElementSize, adornerSize), adornerSize)); adorner.Arrange(new Rect(CalculatePosition(adornedElementSize, adornerSize), adornerSize));
} }
} }
/// <summary>
/// Describes the space in which an adorner is placed.
/// </summary>
public enum PlacementSpace
{
/// <summary>
/// The adorner is affected by the render transform of the adorned element.
/// </summary>
Render,
/// <summary>
/// The adorner is affected by the layout transform of the adorned element.
/// </summary>
Layout,
/// <summary>
/// The adorner is not affected by transforms of designed controls.
/// </summary>
Designer
}
} }

34
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/MouseInteraction.cs

@ -26,38 +26,4 @@ namespace ICSharpCode.WpfDesign
/// </summary> /// </summary>
void HandleSelectionMouseDown(IDesignPanel designPanel, MouseButtonEventArgs e, DesignPanelHitTestResult result); void HandleSelectionMouseDown(IDesignPanel designPanel, MouseButtonEventArgs e, DesignPanelHitTestResult result);
} }
/// <summary>
/// Behavior interface implemented by container elements to support resizing
/// child elements.
/// </summary>
public interface IChildResizeSupport
{
/// <summary>
/// Gets if the child element can be resized.
/// </summary>
bool CanResizeChild(DesignItem child);
/// <summary>
/// Gets the placement for the drag frame adorner.
/// </summary>
/// <param name="child">The child being dragged</param>
/// <param name="horizontalChange">The horizontal change - positive=make larger, negative=make smaller</param>
/// <param name="verticalChange">The vertical change - positive=make larger, negative=make smaller</param>
/// <param name="horizontal">The orientation of the resize thumb used. This parameter may be used to determine on which side of the element the element grows/shrinks.</param>
/// <param name="vertical">The orientation of the resize thumb used. This parameter may be used to determine on which side of the element the element grows/shrinks.</param>
/// <returns>A placement describing the new location of the child being resized.</returns>
Placement GetPlacement(DesignItem child, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical);
/// <summary>
/// Resizes the child.
/// </summary>
/// <param name="child">The child being dragged</param>
/// <param name="horizontalChange">The horizontal change - positive=make larger, negative=make smaller</param>
/// <param name="verticalChange">The vertical change - positive=make larger, negative=make smaller</param>
/// <param name="horizontal">The orientation of the resize thumb used. This parameter may be used to determine on which side of the element the element grows/shrinks.</param>
/// <param name="vertical">The orientation of the resize thumb used. This parameter may be used to determine on which side of the element the element grows/shrinks.</param>
/// <returns>A placement describing the new location of the child being resized.</returns>
void Resize(DesignItem child, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical);
}
} }

110
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementAlignment.cs

@ -0,0 +1,110 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Windows;
namespace ICSharpCode.WpfDesign
{
/// <summary>
/// A combination of HorizontalAlignment/VerticalAlignment.
/// </summary>
public struct PlacementAlignment : IEquatable<PlacementAlignment>
{
readonly HorizontalAlignment horizontal;
readonly VerticalAlignment vertical;
/// <summary>
/// Gets the horizontal component.
/// </summary>
public HorizontalAlignment Horizontal {
get { return horizontal; }
}
/// <summary>
/// Gets the vertical component.
/// </summary>
public VerticalAlignment Vertical {
get { return vertical; }
}
/// <summary>
/// Creates a new instance of the PlacementAlignment structure.
/// </summary>
public PlacementAlignment(HorizontalAlignment horizontal, VerticalAlignment vertical)
{
if (horizontal == HorizontalAlignment.Stretch)
throw new ArgumentException("Strech is not a valid value", "horizontal");
if (vertical == VerticalAlignment.Stretch)
throw new ArgumentException("Strech is not a valid value", "vertical");
this.horizontal = horizontal;
this.vertical = vertical;
}
#region Equals and GetHashCode implementation
/// <summary>Compares this to <paramref name="other"/>.</summary>
public override bool Equals(object obj)
{
if (obj is PlacementAlignment)
return Equals((PlacementAlignment)obj); // use Equals method below
else
return false;
}
/// <summary>Compares this to <paramref name="other"/>.</summary>
public bool Equals(PlacementAlignment other)
{
return this.horizontal == other.horizontal && this.vertical == other.vertical;
}
/// <inherit/>
public override int GetHashCode()
{
unchecked {
return horizontal.GetHashCode() * 27 + vertical.GetHashCode();
}
}
/// <summary>Compares <paramref name="lhs"/> to <paramref name="rhs"/>.</summary>
public static bool operator ==(PlacementAlignment lhs, PlacementAlignment rhs)
{
return lhs.Equals(rhs);
}
/// <summary>Compares <paramref name="lhs"/> to <paramref name="rhs"/>.</summary>
public static bool operator !=(PlacementAlignment lhs, PlacementAlignment rhs)
{
return !(lhs.Equals(rhs));
}
#endregion
}
/// <summary>
/// Contains known PlacementAlignment values like an enumeration.
/// </summary>
public static class PlacementAlignments
{
/// <summary>Top left</summary>
public static readonly PlacementAlignment TopLeft = new PlacementAlignment(HorizontalAlignment.Left, VerticalAlignment.Top);
/// <summary>Top center</summary>
public static readonly PlacementAlignment Top = new PlacementAlignment(HorizontalAlignment.Center, VerticalAlignment.Top);
/// <summary>Top right</summary>
public static readonly PlacementAlignment TopRight = new PlacementAlignment(HorizontalAlignment.Right, VerticalAlignment.Top);
/// <summary>Center left</summary>
public static readonly PlacementAlignment Left = new PlacementAlignment(HorizontalAlignment.Left, VerticalAlignment.Center);
/// <summary>Center center</summary>
public static readonly PlacementAlignment Center = new PlacementAlignment(HorizontalAlignment.Center, VerticalAlignment.Center);
/// <summary>Center right</summary>
public static readonly PlacementAlignment Right = new PlacementAlignment(HorizontalAlignment.Right, VerticalAlignment.Center);
/// <summary>Bottom left</summary>
public static readonly PlacementAlignment BottomLeft = new PlacementAlignment(HorizontalAlignment.Left, VerticalAlignment.Bottom);
/// <summary>Bottom center</summary>
public static readonly PlacementAlignment Bottom = new PlacementAlignment(HorizontalAlignment.Center, VerticalAlignment.Bottom);
/// <summary>Bottom right</summary>
public static readonly PlacementAlignment BottomRight = new PlacementAlignment(HorizontalAlignment.Right, VerticalAlignment.Bottom);
}
}

51
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementBehavior.cs

@ -0,0 +1,51 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Windows;
using System.Windows.Input;
using ICSharpCode.WpfDesign.Adorners;
namespace ICSharpCode.WpfDesign
{
/// <summary>
/// Behavior interface implemented by container elements to support resizing
/// child elements.
/// </summary>
public interface IPlacementBehavior
{
/// <summary>
/// Gets if the child element can be resized.
/// </summary>
bool CanPlace(DesignItem child, PlacementType type, PlacementAlignment position);
/// <summary>
/// Starts placement mode of the child element specified in the placement operation.
/// </summary>
void StartPlacement(PlacementOperation operation, out bool supportsRemoveFromContainer);
/// <summary>
/// Updates the placement of the element specified in the placement operation.
/// </summary>
void UpdatePlacement(PlacementOperation operation);
/// <summary>
/// Finishes placement of a child element. This method is called both for aborted
/// and committed placement operations.
/// </summary>
void FinishPlacement(PlacementOperation operation);
}
/// <summary>
/// Behavior interface for root elements (elements where item.Parent is null).
/// Is used instead of <see cref="IPlacementBehavior"/> to support resizing the root element.
/// </summary>
public interface IRootPlacementBehavior : IPlacementBehavior
{
}
}

179
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementOperation.cs

@ -0,0 +1,179 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Windows;
using System.Windows.Input;
using ICSharpCode.WpfDesign.Adorners;
namespace ICSharpCode.WpfDesign
{
/// <summary>
/// Stores data about a placement operation.
/// </summary>
public sealed class PlacementOperation
{
readonly ChangeGroup changeGroup;
readonly DesignItem placedItem;
readonly PlacementType type;
readonly DesignItem oldContainer;
readonly IPlacementBehavior oldContainerBehavior;
DesignItem currentContainer;
IPlacementBehavior currentContainerBehavior;
bool supportsRemoveFromContainer;
bool isAborted, isCommitted;
//DesignItem newContainer;
#region Properties
/// <summary>
/// The item being placed.
/// </summary>
public DesignItem PlacedItem {
get { return placedItem; }
}
/// <summary>
/// The type of the placement being done.
/// </summary>
public PlacementType Type {
get { return type; }
}
/// <summary>
/// Gets if removing the placed item from the container is supported.
/// </summary>
public bool SupportsRemoveFromContainer {
get { return supportsRemoveFromContainer; }
}
/// <summary>
/// Gets if the placement operation was aborted.
/// </summary>
public bool IsAborted {
get { return isAborted; }
}
/// <summary>
/// Gets if the placement operation was committed.
/// </summary>
public bool IsCommitted {
get { return isCommitted; }
}
/// <summary>
/// The position of the left/right/top/bottom side in the coordinate system of the parent container.
/// These values must be set by IPlacementBehavior.StartPlacement and are updated by the drag operation.
/// </summary>
public double Left, Right, Top, Bottom;
#endregion
public void UpdatePlacement()
{
currentContainerBehavior.UpdatePlacement(this);
}
#region Start
/// <summary>
/// Starts a new placement operation that changes the placement of <paramref name="placedItem"/>.
/// </summary>
/// <param name="placedItem">The item to be placed.</param>
/// <param name="type">The type of the placement.</param>
/// <returns>A PlacementOperation object.</returns>
/// <remarks>
/// You MUST call either <see cref="Abort"/> or <see cref="Commit"/> on the returned PlacementOperation
/// once you are done with it, otherwise a ChangeGroup will be left open and Undo/Redo will fail to work!
/// </remarks>
public static PlacementOperation Start(DesignItem placedItem, PlacementType type)
{
if (placedItem == null)
throw new ArgumentNullException("placedItem");
if (type == null)
throw new ArgumentNullException("type");
PlacementOperation op = new PlacementOperation(placedItem, type);
try {
if (op.currentContainerBehavior == null)
throw new InvalidOperationException("Starting the operation is not supported");
op.Left = op.Top = op.Bottom = op.Right = double.NaN;
op.currentContainerBehavior.StartPlacement(op, out op.supportsRemoveFromContainer);
if (double.IsNaN(op.Left) || double.IsNaN(op.Top) || double.IsNaN(op.Bottom) || double.IsNaN(op.Right))
throw new InvalidOperationException("IPlacementBehavior.StartPlacement must set Left,Top,Right+Bottom to non-NAN values");
} catch {
op.changeGroup.Abort();
throw;
}
return op;
}
private PlacementOperation(DesignItem placedItem, PlacementType type)
{
this.placedItem = placedItem;
this.type = type;
this.oldContainer = placedItem.Parent;
this.oldContainerBehavior = GetPlacementBehavior(placedItem);
this.currentContainer = oldContainer;
this.currentContainerBehavior = oldContainerBehavior;
this.changeGroup = placedItem.OpenGroup(type.ToString());
}
/// <summary>
/// Gets the placement behavior associated with the specified item.
/// </summary>
public static IPlacementBehavior GetPlacementBehavior(DesignItem item)
{
if (item == null)
throw new ArgumentNullException("item");
if (item.Parent != null) {
return item.Parent.GetBehavior<IPlacementBehavior>();
} else {
return item.GetBehavior<IRootPlacementBehavior>();
}
}
#endregion
#region ChangeGroup handling
/// <summary>
/// Gets/Sets the description of the underlying change group.
/// </summary>
public string Description {
get { return changeGroup.Title; }
set { changeGroup.Title = value; }
}
/// <summary>
/// Aborts the operation.
/// This aborts the underlying change group, reverting all changes done while the operation was running.
/// </summary>
public void Abort()
{
if (!isAborted) {
if (isCommitted)
throw new InvalidOperationException("PlacementOperation is committed.");
isAborted = true;
currentContainerBehavior.FinishPlacement(this);
changeGroup.Abort();
}
}
/// <summary>
/// Commits the operation.
/// This commits the underlying change group.
/// </summary>
public void Commit()
{
if (isAborted || isCommitted)
throw new InvalidOperationException("PlacementOperation is already aborted/committed.");
isCommitted = true;
currentContainerBehavior.FinishPlacement(this);
changeGroup.Commit();
}
#endregion
}
}

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

@ -0,0 +1,50 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.WpfDesign
{
/// <summary>
/// Describes how a placement is done.
/// </summary>
public sealed class PlacementType
{
/// <summary>
/// Placement is done by resizing an element.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly PlacementType Resize = Register("Resize");
/// <summary>
/// Placement is done by moving an element.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly PlacementType Move = Register("Move");
readonly string name;
private PlacementType(string name)
{
this.name = name;
}
/// <summary>
/// Creates a new unique PlacementKind.
/// </summary>
public static PlacementType Register(string name)
{
return new PlacementType(name);
}
/// <inherit/>
public override string ToString()
{
return name;
}
}
}

7
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Tools.cs

@ -80,13 +80,6 @@ namespace ICSharpCode.WpfDesign
/// </summary> /// </summary>
ICollection<AdornerPanel> Adorners { get; } ICollection<AdornerPanel> Adorners { get; }
/// <summary>
/// A canvas that is on top of the design surface and all adorners.
/// Used for temporary drawings that are not attached to any element, e.g. graying out everything
/// except the target container in drag'n'drop operations.
/// </summary>
Canvas MarkerCanvas { get; }
/// <summary> /// <summary>
/// Performs a hit test on the design surface. /// Performs a hit test on the design surface.
/// </summary> /// </summary>

8
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj

@ -58,9 +58,12 @@
<Link>Configuration\GlobalAssemblyInfo.cs</Link> <Link>Configuration\GlobalAssemblyInfo.cs</Link>
</Compile> </Compile>
<Compile Include="Adorners\AdornerPanel.cs" /> <Compile Include="Adorners\AdornerPanel.cs" />
<Compile Include="Adorners\AdornerPlacement.cs" />
<Compile Include="Adorners\AdornerPlacementSpace.cs" />
<Compile Include="Adorners\AdornerProvider.cs" /> <Compile Include="Adorners\AdornerProvider.cs" />
<Compile Include="Adorners\AdornerProviderClasses.cs" /> <Compile Include="Adorners\AdornerProviderClasses.cs" />
<Compile Include="Adorners\Placement.cs" /> <Compile Include="Adorners\RelativePlacement.cs" />
<Compile Include="PlacementBehavior.cs" />
<Compile Include="MouseInteraction.cs" /> <Compile Include="MouseInteraction.cs" />
<Compile Include="ChangeGroup.cs" /> <Compile Include="ChangeGroup.cs" />
<Compile Include="DesignContext.cs" /> <Compile Include="DesignContext.cs" />
@ -82,6 +85,8 @@
<Compile Include="Extensions\SelectionExtensionServer.cs" /> <Compile Include="Extensions\SelectionExtensionServer.cs" />
<Compile Include="HashSet.cs" /> <Compile Include="HashSet.cs" />
<Compile Include="Func.cs" /> <Compile Include="Func.cs" />
<Compile Include="PlacementOperation.cs" />
<Compile Include="PlacementType.cs" />
<Compile Include="PropertyEditor\BooleanEditor.cs" /> <Compile Include="PropertyEditor\BooleanEditor.cs" />
<Compile Include="PropertyEditor\MultiSelectionDataProperty.cs" /> <Compile Include="PropertyEditor\MultiSelectionDataProperty.cs" />
<Compile Include="PropertyEditor\StandardValuesComboBoxEditor.cs" /> <Compile Include="PropertyEditor\StandardValuesComboBoxEditor.cs" />
@ -95,6 +100,7 @@
<Compile Include="PropertyEditor\PropertyEditorAttribute.cs" /> <Compile Include="PropertyEditor\PropertyEditorAttribute.cs" />
<Compile Include="PropertyEditor\PropertyEditorBindingHelper.cs" /> <Compile Include="PropertyEditor\PropertyEditorBindingHelper.cs" />
<Compile Include="PropertyEditor\TypeEditorAttribute.cs" /> <Compile Include="PropertyEditor\TypeEditorAttribute.cs" />
<Compile Include="PlacementAlignment.cs" />
<Compile Include="ServiceContainer.cs" /> <Compile Include="ServiceContainer.cs" />
<Compile Include="DesignItem.cs" /> <Compile Include="DesignItem.cs" />
<Compile Include="Services.cs" /> <Compile Include="Services.cs" />

Loading…
Cancel
Save