diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs
index f3ad95c10b..caef54e20c 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs
@@ -221,11 +221,11 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
protected override Size ArrangeOverride(Size finalSize)
{
- foreach (AdornerPanel adorner in this.Children) {
- adorner.Arrange(new Rect(new Point(0, 0), adorner.DesiredSize));
+ foreach (AdornerPanel adorner in this.Children) {
if (adorner.AdornedElement.IsDescendantOf(_designPanel)) {
adorner.RenderTransform = (Transform)adorner.AdornedElement.TransformToAncestor(_designPanel);
}
+ adorner.Arrange(new Rect(new Point(0, 0), adorner.DesiredSize));
}
return finalSize;
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs
index 3869f3c036..3958c4e123 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs
@@ -54,7 +54,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
e.Handled = true;
- item.Services.Selection.SetSelectedComponents(new DesignItem [] { item }, SelectionTypes.Auto);
+ //item.Services.Selection.SetSelectedComponents(new DesignItem [] { item }, SelectionTypes.Auto);
new DragMoveMouseGesture(item, false).Start(item.Services.DesignPanel, e);
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasPositionExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasPositionExtension.cs
index b61374636b..2d919353a3 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasPositionExtension.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasPositionExtension.cs
@@ -28,7 +28,7 @@ using ICSharpCode.WpfDesign.Extensions;
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
[ExtensionFor(typeof(FrameworkElement))]
- [ExtensionServer(typeof(PrimarySelectionExtensionServer))]
+ [ExtensionServer(typeof(OnlyOneItemSelectedExtensionServer))]
public class CanvasPositionExtension : AdornerProvider
{
private MarginHandle[] _handles;
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/QuickOperationMenuExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/QuickOperationMenuExtension.cs
index 574112516b..2ca8308f66 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/QuickOperationMenuExtension.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/QuickOperationMenuExtension.cs
@@ -31,6 +31,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
///
/// Extends the Quick operation menu for the designer.
///
+ [ExtensionServer(typeof(OnlyOneItemSelectedExtensionServer))]
[ExtensionFor(typeof (FrameworkElement))]
class QuickOperationMenuExtension : PrimarySelectionAdornerProvider
{
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RenderTransformOriginExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RenderTransformOriginExtension.cs
index 53ba6a4c56..86f105f55d 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RenderTransformOriginExtension.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RenderTransformOriginExtension.cs
@@ -32,6 +32,7 @@ using System.Windows.Media;
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
+ [ExtensionServer(typeof(OnlyOneItemSelectedExtensionServer))]
[ExtensionFor(typeof(FrameworkElement))]
public class RenderTransformOriginExtension : SelectionAdornerProvider
{
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/ResizeThumbExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/ResizeThumbExtension.cs
index c068428963..c25bad2de3 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/ResizeThumbExtension.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/ResizeThumbExtension.cs
@@ -32,6 +32,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
///
/// The resize thumb around a component.
///
+ [ExtensionServer(typeof(OnlyOneItemSelectedExtensionServer))]
[ExtensionFor(typeof(FrameworkElement))]
public sealed class ResizeThumbExtension : SelectionAdornerProvider
{
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RightClickContextMenuExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RightClickContextMenuExtension.cs
index 2de65cf3aa..20dd2adacd 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RightClickContextMenuExtension.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RightClickContextMenuExtension.cs
@@ -30,6 +30,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
///
///
///
+ [ExtensionServer(typeof(OnlyOneItemSelectedExtensionServer))]
[ExtensionFor(typeof(UIElement))]
public sealed class RightClickContextMenuExtension : PrimarySelectionAdornerProvider
{
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs
index 9b3d297dd0..63e7e70d68 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs
@@ -32,6 +32,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
///
/// The resize thumb around a component.
///
+ [ExtensionServer(typeof(OnlyOneItemSelectedExtensionServer))]
[ExtensionFor(typeof(FrameworkElement))]
public sealed class RotateThumbExtension : SelectionAdornerProvider
{
@@ -41,6 +42,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
readonly DesignItem[] extendedItemArray = new DesignItem[1];
IPlacementBehavior resizeBehavior;
PlacementOperation operation;
+ private AdornerLayer _adornerLayer;
public RotateThumbExtension()
{
@@ -64,6 +66,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
DragListener drag = new DragListener(rotateThumb);
drag.Started += drag_Rotate_Started;
drag.Changed += drag_Rotate_Changed;
+ drag.Completed += drag_Rotate_Completed;
return rotateThumb;
}
@@ -75,10 +78,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
private RotateTransform rotateTransform;
private double initialAngle;
private DesignItem rtTransform;
- private double angle;
-
+
private void drag_Rotate_Started(DragListener drag)
{
+ _adornerLayer = this.adornerPanel.TryFindParent();
+
var designerItem = this.ExtendedItem.Component as FrameworkElement;
this.parent = VisualTreeHelper.GetParent(designerItem) as UIElement;
this.centerPoint = designerItem.TranslatePoint(
@@ -135,10 +139,16 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
rtTransform = this.ExtendedItem.Properties[FrameworkElement.RenderTransformProperty].Value;
}
rtTransform.Properties["Angle"].SetValue(destAngle);
- this.angle = destAngle * Math.PI / 180.0;
+
+ _adornerLayer.UpdateAdornersForElement(this.ExtendedItem.View, true);
}
}
+ void drag_Rotate_Completed(ICSharpCode.WpfDesign.Designer.Controls.DragListener drag)
+ {
+ operation.Commit();
+ }
+
#endregion
protected override void OnInitialized()
@@ -154,9 +164,6 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
var designerItem = this.ExtendedItem.Component as FrameworkElement;
this.rotateTransform = designerItem.RenderTransform as RotateTransform;
-
- if (rotateTransform != null)
- angle = rotateTransform.Angle;
}
void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs
new file mode 100644
index 0000000000..ad6839044e
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs
@@ -0,0 +1,248 @@
+// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Controls.Primitives;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Shapes;
+using ICSharpCode.WpfDesign.Adorners;
+using ICSharpCode.WpfDesign.Designer.Controls;
+using ICSharpCode.WpfDesign.Extensions;
+using System.Collections.Generic;
+
+namespace ICSharpCode.WpfDesign.Designer.Extensions
+{
+ [ExtensionServer(typeof(OnlyOneItemSelectedExtensionServer))]
+ [ExtensionFor(typeof(FrameworkElement))]
+ public sealed class SkewThumbExtension : SelectionAdornerProvider
+ {
+ readonly AdornerPanel adornerPanel;
+ readonly DesignItem[] extendedItemArray = new DesignItem[1];
+
+ private AdornerLayer _adornerLayer;
+
+ public SkewThumbExtension()
+ {
+ adornerPanel = new AdornerPanel();
+ adornerPanel.Order = AdornerOrder.BeforeForeground;
+ this.Adorners.Add(adornerPanel);
+ }
+
+ #region Skew
+
+ private Point startPoint;
+ private UIElement parent;
+ private SkewTransform skewTransform;
+ private double skewX;
+ private double skewY;
+ private DesignItem rtTransform;
+ private Thumb thumb1;
+ private Thumb thumb2;
+ PlacementOperation operation;
+
+ private void dragX_Started(DragListener drag)
+ {
+ _adornerLayer = this.adornerPanel.TryFindParent();
+
+ var designerItem = this.ExtendedItem.Component as FrameworkElement;
+ this.parent = VisualTreeHelper.GetParent(designerItem) as UIElement;
+
+ startPoint = Mouse.GetPosition(this.parent);
+
+ if (this.skewTransform == null)
+ {
+ this.skewX = 0;
+ this.skewY = 0;
+ }
+ else
+ {
+ this.skewX = this.skewTransform.AngleX;
+ this.skewY = this.skewTransform.AngleY;
+ }
+
+ rtTransform = this.ExtendedItem.Properties[FrameworkElement.RenderTransformProperty].Value;
+
+ operation = PlacementOperation.Start(extendedItemArray, PlacementType.Resize);
+ }
+
+ private void dragX_Changed(DragListener drag)
+ {
+ Point currentPoint = Mouse.GetPosition(this.parent);
+ Vector deltaVector = Point.Subtract(currentPoint, this.startPoint);
+
+ var destAngle = (-0.5*deltaVector.X) + skewX;
+
+ if (destAngle == 0 && skewY == 0)
+ {
+ this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).Reset();
+ rtTransform = null;
+ skewTransform = null;
+ }
+ else
+ {
+ if (rtTransform == null)
+ {
+ if (!this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformOriginProperty).IsSet) {
+ this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformOriginProperty).SetValue(new Point(0.5,0.5));
+ }
+
+ if (this.skewTransform == null)
+ this.skewTransform = new SkewTransform(0, 0);
+ this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).SetValue(skewTransform);
+ rtTransform = this.ExtendedItem.Properties[FrameworkElement.RenderTransformProperty].Value;
+ }
+ rtTransform.Properties["AngleX"].SetValue(destAngle);
+ }
+
+ _adornerLayer.UpdateAdornersForElement(this.ExtendedItem.View, true);
+ }
+
+ void dragX_Completed(ICSharpCode.WpfDesign.Designer.Controls.DragListener drag)
+ {
+ operation.Commit();
+ }
+
+ private void dragY_Started(DragListener drag)
+ {
+ _adornerLayer = this.adornerPanel.TryFindParent();
+
+ var designerItem = this.ExtendedItem.Component as FrameworkElement;
+ this.parent = VisualTreeHelper.GetParent(designerItem) as UIElement;
+
+ startPoint = Mouse.GetPosition(this.parent);
+
+ if (this.skewTransform == null)
+ {
+ this.skewX = 0;
+ this.skewY = 0;
+ }
+ else
+ {
+ this.skewX = this.skewTransform.AngleX;
+ this.skewY = this.skewTransform.AngleY;
+ }
+
+ rtTransform = this.ExtendedItem.Properties[FrameworkElement.RenderTransformProperty].Value;
+
+ operation = PlacementOperation.Start(extendedItemArray, PlacementType.Resize);
+ }
+
+ private void dragY_Changed(DragListener drag)
+ {
+ Point currentPoint = Mouse.GetPosition(this.parent);
+ Vector deltaVector = Point.Subtract(currentPoint, this.startPoint);
+
+ var destAngle = (-0.5*deltaVector.Y) + skewY;
+
+ if (destAngle == 0 && skewX == 0)
+ {
+ this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).Reset();
+ rtTransform = null;
+ skewTransform = null;
+ }
+ else
+ {
+ if (rtTransform == null)
+ {
+ if (!this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformOriginProperty).IsSet)
+ {
+ this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformOriginProperty).SetValue(new Point(0.5, 0.5));
+ }
+
+ if (this.skewTransform == null)
+ this.skewTransform = new SkewTransform(0, 0);
+ this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).SetValue(skewTransform);
+ rtTransform = this.ExtendedItem.Properties[FrameworkElement.RenderTransformProperty].Value;
+ }
+ rtTransform.Properties["AngleY"].SetValue(destAngle);
+ }
+
+ _adornerLayer.UpdateAdornersForElement(this.ExtendedItem.View, true);
+ }
+
+ void dragY_Completed(ICSharpCode.WpfDesign.Designer.Controls.DragListener drag)
+ {
+ operation.Commit();
+ }
+
+ #endregion
+
+ protected override void OnInitialized()
+ {
+
+ if (this.ExtendedItem.Component is WindowClone)
+ return;
+ base.OnInitialized();
+
+ extendedItemArray[0] = this.ExtendedItem;
+ this.ExtendedItem.PropertyChanged += OnPropertyChanged;
+
+ var designerItem = this.ExtendedItem.Component as FrameworkElement;
+ this.skewTransform = designerItem.RenderTransform as SkewTransform;
+
+ if (skewTransform != null)
+ {
+ skewX = skewTransform.AngleX;
+ skewY = skewTransform.AngleY;
+ }
+
+ thumb1 = new Thumb() { Cursor = Cursors.ScrollWE, Height = 14, Width = 4, Opacity = 1 };
+ thumb2 = new Thumb() { Cursor = Cursors.ScrollNS, Width = 14, Height = 4, Opacity = 1 };
+
+ OnPropertyChanged(null, null);
+
+ adornerPanel.Children.Add(thumb1);
+ adornerPanel.Children.Add(thumb2);
+
+ DragListener drag1 = new DragListener(thumb1);
+ drag1.Started += dragX_Started;
+ drag1.Changed += dragX_Changed;
+ drag1.Completed += dragX_Completed;
+ DragListener drag2 = new DragListener(thumb2);
+ drag2.Started += dragY_Started;
+ drag2.Changed += dragY_Changed;
+ drag2.Completed += dragY_Completed;
+ }
+
+ void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ {
+ if (sender == null || e.PropertyName == "Width" || e.PropertyName == "Height") {
+ AdornerPanel.SetPlacement(thumb1,
+ new RelativePlacement(HorizontalAlignment.Center, VerticalAlignment.Top) {
+ YOffset = 0,
+ XOffset = -1 * ((FrameworkElement)ExtendedItem.View).ActualWidth / 4
+ });
+
+ AdornerPanel.SetPlacement(thumb2,
+ new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Center) {
+ YOffset = -1 * ((FrameworkElement)ExtendedItem.View).ActualHeight / 4,
+ XOffset = 0
+ });
+ }
+ }
+
+ protected override void OnRemove()
+ {
+ this.ExtendedItem.PropertyChanged -= OnPropertyChanged;
+ base.OnRemove();
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs
index 80a3c0f2fe..9a30964556 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs
@@ -41,51 +41,51 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
List horizontalMap;
List verticalMap;
double? baseline;
-
+
public const double Accuracy = 5;
public const double Margin = 8;
-
+
public override void BeginPlacement(PlacementOperation operation)
{
base.BeginPlacement(operation);
CreateSurface(operation);
}
-
+
public override void EndPlacement(PlacementOperation operation)
{
base.EndPlacement(operation);
DeleteSurface();
}
-
+
public override void EnterContainer(PlacementOperation operation)
{
base.EnterContainer(operation);
CreateSurface(operation);
}
-
+
public override void LeaveContainer(PlacementOperation operation)
{
base.LeaveContainer(operation);
DeleteSurface();
}
-
+
public override void BeforeSetPosition(PlacementOperation operation)
{
base.BeforeSetPosition(operation);
if (surface == null) return;
-
+
DesignPanel designPanel = ExtendedItem.Services.DesignPanel as DesignPanel;
if (designPanel == null || !designPanel.UseSnaplinePlacement)
return;
surface.Children.Clear();
if (Keyboard.IsKeyDown(Key.LeftCtrl)) return;
-
+
Rect bounds = Rect.Empty;
foreach (var item in operation.PlacedItems) {
bounds.Union(item.Bounds);
}
-
+
var horizontalInput = new List();
var verticalInput = new List();
var info = operation.PlacedItems[0];
@@ -99,7 +99,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
horizontalInput.Add(new Snapline() { Group = 1, Offset = textOffset, Start = bounds.Left, End = bounds.Right });
}
}
-
+
// debug
//foreach (var t in horizontalMap.Concat(horizontalInput)) {
// surface.Children.Add(new Line() { X1 = t.Start, X2 = t.End, Y1 = t.Offset, Y2 = t.Offset, Stroke = Brushes.Black });
@@ -108,12 +108,12 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
// surface.Children.Add(new Line() { X1 = t.Offset, X2 = t.Offset, Y1 = t.Start , Y2 = t.End, Stroke = Brushes.Black });
//}
//return;
-
+
List drawLines;
double delta;
-
+
if (Snap(horizontalInput, horizontalMap, Accuracy, out drawLines, out delta)) {
-
+
if (operation.Type == PlacementType.Resize) {
if (info.ResizeThumbAlignment.Vertical == VerticalAlignment.Top) {
bounds.Y += delta;
@@ -129,14 +129,14 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
item.Bounds = r;
}
}
-
+
foreach (var d in drawLines) {
DrawLine(d.Start, d.Offset, d.End, d.Offset);
}
}
-
+
if (Snap(verticalInput, verticalMap, Accuracy, out drawLines, out delta)) {
-
+
if (operation.Type == PlacementType.Resize) {
if (info.ResizeThumbAlignment.Horizontal == HorizontalAlignment.Left) {
bounds.X += delta;
@@ -158,52 +158,77 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
}
}
}
-
+
void CreateSurface(PlacementOperation operation)
{
if (ExtendedItem.Services.GetService() != null) {
-
+
surface = new Canvas();
adornerPanel = new AdornerPanel();
adornerPanel.SetAdornedElement(ExtendedItem.View, ExtendedItem);
AdornerPanel.SetPlacement(surface, AdornerPlacement.FillContent);
adornerPanel.Children.Add(surface);
ExtendedItem.Services.DesignPanel.Adorners.Add(adornerPanel);
-
+
BuildMaps(operation);
-
+
if (operation.Type != PlacementType.Resize && operation.PlacedItems.Count == 1) {
baseline = GetBaseline(operation.PlacedItems[0].Item.View);
}
}
}
-
+
+ private IEnumerable AllDesignItems(DesignItem designItem = null)
+ {
+ if (designItem == null)
+ {
+ designItem = this.ExtendedItem.Services.DesignPanel.Context.RootItem;
+ yield return designItem;
+ if (designItem.ContentProperty.Value != null) {
+ yield return designItem.ContentProperty.Value;
+ designItem = designItem.ContentProperty.Value;
+ }
+ }
+
+ if (designItem.ContentProperty != null && designItem.ContentProperty.IsCollection)
+ foreach (var collectionElement in designItem.ContentProperty.CollectionElements)
+ {
+ yield return collectionElement;
+
+ foreach (var el in AllDesignItems(collectionElement))
+ {
+ yield return el;
+ }
+ }
+ }
+
void BuildMaps(PlacementOperation operation)
{
horizontalMap = new List();
verticalMap = new List();
-
+
var containerRect = new Rect(0, 0, ModelTools.GetWidth(ExtendedItem.View), ModelTools.GetHeight(ExtendedItem.View));
AddLines(containerRect, -Margin, false);
-
+
AddLines(containerRect, 0, false);
- foreach (var item in ExtendedItem.ContentProperty.CollectionElements
- .Except(operation.PlacedItems.Select(f => f.Item)))
- {
- var bounds = GetPosition(operation, item);
-
- AddLines(bounds, 0, false);
- AddLines(bounds, Margin, true);
- AddBaseline(item, bounds, horizontalMap);
+ foreach (var item in AllDesignItems() /* ExtendedItem.ContentProperty.CollectionElements */
+ .Except(operation.PlacedItems.Select(f => f.Item))) {
+ if (item != null) {
+ var bounds = GetPosition(operation, item);
+
+ AddLines(bounds, 0, false);
+ AddLines(bounds, Margin, true);
+ AddBaseline(item, bounds, horizontalMap);
+ }
}
}
-
+
void AddLines(Rect r, double inflate, bool requireOverlap)
{
AddLines(r, inflate, requireOverlap, horizontalMap, verticalMap, null);
}
-
+
void AddLines(Rect r, double inflate, bool requireOverlap, List h, List v, PlacementAlignment? filter)
{
Rect r2 = r;
@@ -217,8 +242,14 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
v.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Left - 1, Start = r.Top, End = r.Bottom });
if (filter == null || filter.Value.Horizontal == HorizontalAlignment.Right)
v.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Right - 1, Start = r.Top, End = r.Bottom });
+
+ if (filter == null)
+ {
+ h.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Top + Math.Abs((r2.Top - r2.Bottom) / 2), Start = r.Left, End = r.Right });
+ v.Add(new Snapline() { RequireOverlap = requireOverlap, Offset = r2.Left + Math.Abs((r2.Left - r2.Right) / 2), Start = r.Top, End = r.Bottom });
+ }
}
-
+
void AddBaseline(DesignItem item, Rect bounds, List list)
{
var baseline = GetBaseline(item.View);
@@ -227,7 +258,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
list.Add(new Snapline() { Group = 1, Offset = textOffset, Start = bounds.Left, End = bounds.Right });
}
}
-
+
void DeleteSurface()
{
if (surface != null) {
@@ -238,7 +269,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
verticalMap = null;
}
}
-
+
void DrawLine(double x1, double y1, double x2, double y2)
{
var line1 = new Line() {
@@ -250,7 +281,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
Stroke = Brushes.White
};
surface.Children.Add(line1);
-
+
var line2 = new Line() {
X1 = x1,
Y1 = y1,
@@ -263,7 +294,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
};
surface.Children.Add(line2);
}
-
+
//TODO: GlyphRun must be used
static double? GetBaseline(UIElement element) {
var textBox = element as TextBox;
@@ -274,21 +305,21 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
var textBlock = element as TextBlock;
if (textBlock != null)
return textBlock.TranslatePoint(new Point(0, textBlock.ActualHeight), element).Y;
-
+
return null;
}
-
+
static bool Snap(List input, List map, double accuracy,
- out List drawLines, out double delta)
+ out List drawLines, out double delta)
{
delta = double.MaxValue;
drawLines = null;
-
+
foreach (var inputLine in input) {
foreach (var mapLine in map) {
if (Math.Abs(mapLine.Offset - inputLine.Offset) <= accuracy) {
if (!inputLine.RequireOverlap && !mapLine.RequireOverlap ||
- Math.Max(inputLine.Start, mapLine.Start) < Math.Min(inputLine.End, mapLine.End))
+ Math.Max(inputLine.Start, mapLine.Start) < Math.Min(inputLine.End, mapLine.End))
{
if (mapLine.Group == inputLine.Group)
delta = mapLine.Offset - inputLine.Offset;
@@ -296,10 +327,10 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
}
}
}
-
+
if (delta == double.MaxValue) return false;
var offsetDict = new Dictionary();
-
+
foreach (var inputLine in input) {
inputLine.Offset += delta;
foreach (var mapLine in map) {
@@ -318,11 +349,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
}
}
}
-
+
drawLines = offsetDict.Values.ToList();
return true;
}
-
+
[DebuggerDisplay("Snapline: {Offset}")]
class Snapline
{
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TopLeftContainerDragHandle.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TopLeftContainerDragHandle.cs
index e19a19ac27..c8220c2e32 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TopLeftContainerDragHandle.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TopLeftContainerDragHandle.cs
@@ -32,16 +32,10 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
{
///
- /// The drag handle displayed for panels.
+ /// The drag handle displayed for Framework Elements
///
- [ExtensionServer(typeof(PrimarySelectionExtensionServer))]
- [ExtensionFor(typeof(Panel))]
- [ExtensionFor(typeof(Image))]
- [ExtensionFor(typeof(MediaElement))]
- [ExtensionFor(typeof(ItemsControl))]
- [ExtensionFor(typeof(Border))]
- [ExtensionFor(typeof(Viewbox))]
- [ExtensionFor(typeof(ContentControl))]
+ [ExtensionServer(typeof(OnlyOneItemSelectedExtensionServer))]
+ [ExtensionFor(typeof(FrameworkElement))]
public class TopLeftContainerDragHandle : AdornerProvider
{
///
@@ -50,9 +44,9 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
ContainerDragHandle rect = new ContainerDragHandle();
rect.PreviewMouseDown += delegate(object sender, MouseButtonEventArgs e) {
- Services.Selection.SetSelectedComponents(new DesignItem[] { this.ExtendedItem }, SelectionTypes.Auto);
+ //Services.Selection.SetSelectedComponents(new DesignItem[] { this.ExtendedItem }, SelectionTypes.Auto);
new DragMoveMouseGesture(this.ExtendedItem, false).Start(this.ExtendedItem.Services.DesignPanel,e);
- e.Handled=true;
+ e.Handled=true;
};
RelativePlacement p = new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Top);
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TopLeftContainerDragHandleMultipleItems.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TopLeftContainerDragHandleMultipleItems.cs
new file mode 100644
index 0000000000..12a2505b3d
--- /dev/null
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TopLeftContainerDragHandleMultipleItems.cs
@@ -0,0 +1,93 @@
+// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+using System;
+using System.Windows.Controls;
+using System.Windows;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Shapes;
+using ICSharpCode.WpfDesign.Adorners;
+using ICSharpCode.WpfDesign.Extensions;
+
+using ICSharpCode.WpfDesign.Designer.Services;
+using ICSharpCode.WpfDesign.Designer.Controls;
+
+namespace ICSharpCode.WpfDesign.Designer.Extensions
+{
+
+ ///
+ /// The drag handle displayed for Framework Elements
+ ///
+ [ExtensionServer(typeof(PrimarySelectionButOnlyWhenMultipleSelectedExtensionServer))]
+ [ExtensionFor(typeof(FrameworkElement))]
+ public class TopLeftContainerDragHandleMultipleItems : AdornerProvider
+ {
+ ///
+ public TopLeftContainerDragHandleMultipleItems()
+ { }
+
+ protected override void OnInitialized()
+ {
+ base.OnInitialized();
+
+ ContainerDragHandle rect = new ContainerDragHandle();
+
+ rect.PreviewMouseDown += delegate(object sender, MouseButtonEventArgs e) {
+ //Services.Selection.SetSelectedComponents(new DesignItem[] { this.ExtendedItem }, SelectionTypes.Auto);
+ new DragMoveMouseGesture(this.ExtendedItem, false).Start(this.ExtendedItem.Services.DesignPanel,e);
+ e.Handled=true;
+ };
+
+ var items = this.ExtendedItem.Services.Selection.SelectedItems;
+
+ double minX = 0;
+ double minY = 0;
+ double maxX = 0;
+ double maxY = 0;
+
+ foreach (DesignItem di in items) {
+ Point relativeLocation = di.View.TranslatePoint(new Point(0, 0), this.ExtendedItem.View);
+
+ minX = minX < relativeLocation.X ? minX : relativeLocation.X;
+ minY = minY < relativeLocation.Y ? minY : relativeLocation.Y;
+ maxX = maxX > relativeLocation.X + ((FrameworkElement)this.ExtendedItem.View).ActualWidth ? maxX : relativeLocation.X + ((FrameworkElement)this.ExtendedItem.View).ActualWidth;
+ maxY = maxY > relativeLocation.Y + ((FrameworkElement)this.ExtendedItem.View).ActualHeight ? maxY : relativeLocation.Y + ((FrameworkElement)this.ExtendedItem.View).ActualHeight;
+ }
+
+ Rectangle rect2 = new Rectangle() {
+ Width = (maxX - minX) + 4,
+ Height = (maxY - minY) + 4,
+ Stroke = Brushes.Black,
+ StrokeThickness = 2,
+ StrokeDashArray = new DoubleCollection(){ 2, 2 },
+ };
+
+ RelativePlacement p = new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Top);
+ p.XOffset = minX - 3;
+ p.YOffset = minY - 3;
+
+ RelativePlacement p2 = new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Top);
+ p2.XOffset = (minX + rect2.Width) - 2;
+ p2.YOffset = (minY + rect2.Height) - 2;
+
+ AddAdorner(p, AdornerOrder.Background, rect);
+ AddAdorner(p2, AdornerOrder.Background, rect2);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/OutlineView/DragTreeViewItem.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/OutlineView/DragTreeViewItem.cs
index c5bd677aa0..e4ec1d0ce5 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/OutlineView/DragTreeViewItem.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/OutlineView/DragTreeViewItem.cs
@@ -94,8 +94,8 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
public static void OnIsSelectedChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
{
- var el = s as FrameworkElement;
- if (el != null)
+ var el = s as DragTreeViewItem;
+ if (el != null && el.IsSelected)
el.BringIntoView();
}
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj
index a335f5f1f6..09acd365fa 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj
@@ -87,6 +87,8 @@
+
+
FlatCollectionEditor.xaml
Code
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPanel.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPanel.cs
index 6670b2bb65..f9bd39d38d 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPanel.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Adorners/AdornerPanel.cs
@@ -179,6 +179,11 @@ namespace ICSharpCode.WpfDesign.Adorners
///
public static readonly AdornerOrder Foreground = new AdornerOrder(300);
+ ///
+ /// The adorner is in the before foreground layer.
+ ///
+ public static readonly AdornerOrder BeforeForeground = new AdornerOrder(400);
+
int i;
internal AdornerOrder(int i)
diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs
index 9fd90eeefb..75db9cd2c4 100644
--- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs
+++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs
@@ -102,6 +102,63 @@ namespace ICSharpCode.WpfDesign.Extensions
}
}
+ ///
+ /// Applies an extension to the primary selection, but only when multiple Items are selected!
+ ///
+ public class PrimarySelectionButOnlyWhenMultipleSelectedExtensionServer : PrimarySelectionExtensionServer
+ {
+ ///
+ /// Is called after the extension server is initialized and the Context property has been set.
+ ///
+ protected override void OnInitialized()
+ {
+ base.OnInitialized();
+ this.Services.Selection.SelectionChanged += OnSelectionChanged;
+ }
+
+ void OnSelectionChanged(object sender, EventArgs e)
+ {
+ ReapplyExtensions(this.Services.Selection.SelectedItems);
+ }
+
+ ///
+ /// Gets if the item is in the secondary selection.
+ ///
+ public override bool ShouldApplyExtensions(DesignItem extendedItem)
+ {
+ return Services.Selection.PrimarySelection == extendedItem && Services.Selection.SelectionCount > 1;
+ }
+ }
+
+ ///
+ /// Applies an extension to the primary selection if Only One Item is Selected.
+ ///
+ public class OnlyOneItemSelectedExtensionServer : PrimarySelectionExtensionServer
+ {
+ ///
+ /// Is called after the extension server is initialized and the Context property has been set.
+ ///
+ protected override void OnInitialized()
+ {
+ base.OnInitialized();
+ this.Services.Selection.SelectionChanged += OnSelectionChanged;
+ }
+
+ void OnSelectionChanged(object sender, EventArgs e)
+ {
+ if (this.Services.Selection.SelectedItems.Count > 1)
+ ReapplyExtensions(this.Services.Selection.SelectedItems);
+ }
+
+ ///
+ /// Gets if the item is the primary selection.
+ ///
+ public override bool ShouldApplyExtensions(DesignItem extendedItem)
+ {
+ return Services.Selection.PrimarySelection == extendedItem && Services.Selection.SelectionCount < 2;
+ }
+ }
+
///
/// Applies an extension to the parent of the primary selection.
///