From 5c2dacc0299f40b951d9961731bb1109d5f94e5f Mon Sep 17 00:00:00 2001 From: jkuehner Date: Sun, 27 Apr 2014 12:09:38 +0200 Subject: [PATCH 01/16] Rotate Thumb -> Update Adorner on Rotation --- .../Project/Extensions/RotateThumbExtension.cs | 5 +++++ 1 file changed, 5 insertions(+) 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..eaff7256b7 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs @@ -41,6 +41,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions readonly DesignItem[] extendedItemArray = new DesignItem[1]; IPlacementBehavior resizeBehavior; PlacementOperation operation; + private AdornerLayer _adornerLayer; public RotateThumbExtension() { @@ -79,6 +80,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions 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( @@ -136,6 +139,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } rtTransform.Properties["Angle"].SetValue(destAngle); this.angle = destAngle * Math.PI / 180.0; + + _adornerLayer.UpdateAdornersForElement(this.ExtendedItem.View, true); } } From b5629032e457046aa50eb4acb76a3e04cd5e8f7a Mon Sep 17 00:00:00 2001 From: jkuehner Date: Sun, 27 Apr 2014 12:11:11 +0200 Subject: [PATCH 02/16] Extension Server for Only one Selected Item --- .../Extensions/SelectionExtensionServer.cs | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs index 9fd90eeefb..783bbb90a4 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs @@ -102,6 +102,51 @@ namespace ICSharpCode.WpfDesign.Extensions } } + /// + /// Applies an extension to the primary selection if Only One Item is Selected. + /// + public class OnlyOneItemSelectedExtensionServer : DefaultExtensionServer + { + DesignItem oldPrimarySelection; + bool oldCntBelowTwo = false; + + /// + /// Is called after the extension server is initialized and the Context property has been set. + /// + protected override void OnInitialized() + { + base.OnInitialized(); + this.Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged; + this.Services.Selection.SelectionChanged += OnPrimarySelectionChanged; + } + + void OnPrimarySelectionChanged(object sender, EventArgs e) + { + DesignItem newPrimarySelection = this.Services.Selection.PrimarySelection; + + if (oldPrimarySelection != newPrimarySelection || oldCntBelowTwo != (this.Services.Selection.SelectedItems.Count < 2)) + { + if (oldPrimarySelection == null) { + ReapplyExtensions(new DesignItem[] { newPrimarySelection }); + } else if (newPrimarySelection == null) { + ReapplyExtensions(new DesignItem[] { oldPrimarySelection }); + } else { + ReapplyExtensions(new DesignItem[] { oldPrimarySelection, newPrimarySelection }); + } + oldPrimarySelection = newPrimarySelection; + oldCntBelowTwo = this.Services.Selection.SelectedItems.Count < 2; + } + } + + /// + /// Gets if the item is the primary selection. + /// + public override bool ShouldApplyExtensions(DesignItem extendedItem) + { + return (this.Services.Selection.SelectedItems.Count < 2 && this.Services.Selection.PrimarySelection == extendedItem); + } + } + /// /// Applies an extension to the parent of the primary selection. /// From 501623b3eb2df45d949ea0bc6ed8ea1c67f004c2 Mon Sep 17 00:00:00 2001 From: jkuehner Date: Sun, 27 Apr 2014 12:12:05 +0200 Subject: [PATCH 03/16] TopLeftContainerDragHandle for all Framework Elements --- .../Project/Extensions/TopLeftContainerDragHandle.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) 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..6c111f3453 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TopLeftContainerDragHandle.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TopLeftContainerDragHandle.cs @@ -35,13 +35,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions /// The drag handle displayed for panels. /// [ExtensionServer(typeof(PrimarySelectionExtensionServer))] - [ExtensionFor(typeof(Panel))] - [ExtensionFor(typeof(Image))] - [ExtensionFor(typeof(MediaElement))] - [ExtensionFor(typeof(ItemsControl))] - [ExtensionFor(typeof(Border))] - [ExtensionFor(typeof(Viewbox))] - [ExtensionFor(typeof(ContentControl))] + [ExtensionFor(typeof(FrameworkElement))] public class TopLeftContainerDragHandle : AdornerProvider { /// From ca626f919d19d7a027bd56ce069ecdafdd3ee1f6 Mon Sep 17 00:00:00 2001 From: jkuehner Date: Sun, 27 Apr 2014 12:14:39 +0200 Subject: [PATCH 04/16] In WPF Designer A few extensions should only be used when only One Item is Selected, because they only work with one Item (ResizeThumb, RotateThumb, RenderTransform, QuickOperationMenu) --- .../Project/Extensions/QuickOperationMenuExtension.cs | 1 + .../Project/Extensions/RenderTransformOriginExtension.cs | 1 + .../Project/Extensions/ResizeThumbExtension.cs | 1 + .../Project/Extensions/RightClickContextMenuExtension.cs | 1 + 4 files changed, 4 insertions(+) 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 { From 9bb17efaf9f3c4c71addf378198972c3b0d229da Mon Sep 17 00:00:00 2001 From: jkuehner Date: Sun, 27 Apr 2014 12:16:35 +0200 Subject: [PATCH 05/16] Adorner Display fix (fixes #435) --- .../WpfDesign.Designer/Project/Controls/AdornerLayer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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; } From 3dd49163c978af283f5c5a9bd603d1da3a0625aa Mon Sep 17 00:00:00 2001 From: jkuehner Date: Sun, 27 Apr 2014 12:17:59 +0200 Subject: [PATCH 06/16] Snapline for middle of Object (like in VisualStudio) --- .../Extensions/SnaplinePlacementBehavior.cs | 88 ++++++++++--------- 1 file changed, 47 insertions(+), 41 deletions(-) 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..c71f44ab0f 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,52 @@ 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); } } } - + 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))) + .Except(operation.PlacedItems.Select(f => f.Item))) { 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 +217,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 +233,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 +244,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions verticalMap = null; } } - + void DrawLine(double x1, double y1, double x2, double y2) { var line1 = new Line() { @@ -250,7 +256,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions Stroke = Brushes.White }; surface.Children.Add(line1); - + var line2 = new Line() { X1 = x1, Y1 = y1, @@ -263,7 +269,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 +280,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 +302,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 +324,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } } } - + drawLines = offsetDict.Values.ToList(); return true; } - + [DebuggerDisplay("Snapline: {Offset}")] class Snapline { From 3e187df808d5c3445b32b157613331d12dc28702 Mon Sep 17 00:00:00 2001 From: jkuehner Date: Sun, 27 Apr 2014 12:19:43 +0200 Subject: [PATCH 07/16] Make Snapplines also work for Items in other Containers --- .../Extensions/SnaplinePlacementBehavior.cs | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) 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 c71f44ab0f..81cc6f585b 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs @@ -178,6 +178,29 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } } + private IEnumerable AllDesignItems(DesignItem designItem = null) + { + if (designItem == null) + { + designItem = this.ExtendedItem.Services.DesignPanel.Context.RootItem; + yield return designItem; + yield return designItem.ContentProperty.Value; + designItem = designItem.ContentProperty.Value; + } + //yield return designItem.ContentProperty.Value; + + if (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(); @@ -188,7 +211,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions AddLines(containerRect, 0, false); - foreach (var item in ExtendedItem.ContentProperty.CollectionElements + foreach (var item in AllDesignItems() /* ExtendedItem.ContentProperty.CollectionElements */ .Except(operation.PlacedItems.Select(f => f.Item))) { var bounds = GetPosition(operation, item); From 8c15e941d8fd369f966f1a33e75004478684c895 Mon Sep 17 00:00:00 2001 From: jkuehner Date: Sun, 27 Apr 2014 12:21:18 +0200 Subject: [PATCH 08/16] RotateThumb -> Only when Only one Item is selected --- .../Project/Extensions/RotateThumbExtension.cs | 1 + 1 file changed, 1 insertion(+) 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 eaff7256b7..4f7e09f3fe 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 { From ed0a56671b1a3a928a39140a7157156b6c59071b Mon Sep 17 00:00:00 2001 From: jkuehner Date: Sun, 27 Apr 2014 18:40:04 +0200 Subject: [PATCH 09/16] Skew Thumb Extension --- .../Project/Extensions/SkewThumbExtension.cs | 231 ++++++++++++++++++ .../Project/WpfDesign.Designer.csproj | 1 + .../Project/Adorners/AdornerPanel.cs | 5 + 3 files changed, 237 insertions(+) create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs 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..e941ab6649 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs @@ -0,0 +1,231 @@ +// 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; + + 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; + } + + 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); + } + + 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; + } + + 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); + } + + #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; + DragListener drag2 = new DragListener(thumb2); + drag2.Started += dragY_Started; + drag2.Changed += dragY_Changed; + } + + 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/WpfDesign.Designer.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj index a335f5f1f6..a34a76e1b1 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,7 @@ + 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) From 35c2af4055289b31ccf85f4176aacb6f26116745 Mon Sep 17 00:00:00 2001 From: jkuehner Date: Sun, 27 Apr 2014 18:40:25 +0200 Subject: [PATCH 10/16] Remove unused Code from Rote Thumb --- .../Project/Extensions/RotateThumbExtension.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) 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 4f7e09f3fe..616a1807a7 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs @@ -77,8 +77,7 @@ 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(); @@ -139,7 +138,6 @@ 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); } @@ -160,9 +158,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) From 19e600c7fb2342f5648ed4d64e29c7d8d87b4d42 Mon Sep 17 00:00:00 2001 From: jkuehner Date: Sun, 27 Apr 2014 23:14:26 +0200 Subject: [PATCH 11/16] Fix UNDO on Resize and Skew Extension --- .../Extensions/RotateThumbExtension.cs | 6 ++++++ .../Project/Extensions/SkewThumbExtension.cs | 19 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) 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 616a1807a7..63e7e70d68 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs @@ -66,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; } @@ -143,6 +144,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } } + void drag_Rotate_Completed(ICSharpCode.WpfDesign.Designer.Controls.DragListener drag) + { + operation.Commit(); + } + #endregion protected override void OnInitialized() diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs index e941ab6649..ad6839044e 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SkewThumbExtension.cs @@ -56,6 +56,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions private DesignItem rtTransform; private Thumb thumb1; private Thumb thumb2; + PlacementOperation operation; private void dragX_Started(DragListener drag) { @@ -78,6 +79,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } rtTransform = this.ExtendedItem.Properties[FrameworkElement.RenderTransformProperty].Value; + + operation = PlacementOperation.Start(extendedItemArray, PlacementType.Resize); } private void dragX_Changed(DragListener drag) @@ -112,6 +115,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions _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(); @@ -133,6 +141,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions } rtTransform = this.ExtendedItem.Properties[FrameworkElement.RenderTransformProperty].Value; + + operation = PlacementOperation.Start(extendedItemArray, PlacementType.Resize); } private void dragY_Changed(DragListener drag) @@ -168,6 +178,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions _adornerLayer.UpdateAdornersForElement(this.ExtendedItem.View, true); } + void dragY_Completed(ICSharpCode.WpfDesign.Designer.Controls.DragListener drag) + { + operation.Commit(); + } + #endregion protected override void OnInitialized() @@ -200,9 +215,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions 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.Changed += dragY_Changed; + drag2.Completed += dragY_Completed; } void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) From 46f44c9361e781720ad3a058e4e211fd7218ef57 Mon Sep 17 00:00:00 2001 From: jkuehner Date: Mon, 28 Apr 2014 08:50:44 +0200 Subject: [PATCH 12/16] New Selection Extensions Server (PrimarySelectionButOnlyWhenMultipleSelectedExtensionServer) & fix OnlyOneItemSelectedExtensionServer --- .../Extensions/SelectionExtensionServer.cs | 56 +++++++++++-------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs index 783bbb90a4..75db9cd2c4 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/SelectionExtensionServer.cs @@ -103,39 +103,51 @@ namespace ICSharpCode.WpfDesign.Extensions } /// - /// Applies an extension to the primary selection if Only One Item is Selected. + /// Applies an extension to the primary selection, but only when multiple Items are selected! /// - public class OnlyOneItemSelectedExtensionServer : DefaultExtensionServer + public class PrimarySelectionButOnlyWhenMultipleSelectedExtensionServer : PrimarySelectionExtensionServer { - DesignItem oldPrimarySelection; - bool oldCntBelowTwo = false; + /// + /// 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.PrimarySelectionChanged += OnPrimarySelectionChanged; - this.Services.Selection.SelectionChanged += OnPrimarySelectionChanged; + this.Services.Selection.SelectionChanged += OnSelectionChanged; } - void OnPrimarySelectionChanged(object sender, EventArgs e) + void OnSelectionChanged(object sender, EventArgs e) { - DesignItem newPrimarySelection = this.Services.Selection.PrimarySelection; - - if (oldPrimarySelection != newPrimarySelection || oldCntBelowTwo != (this.Services.Selection.SelectedItems.Count < 2)) - { - if (oldPrimarySelection == null) { - ReapplyExtensions(new DesignItem[] { newPrimarySelection }); - } else if (newPrimarySelection == null) { - ReapplyExtensions(new DesignItem[] { oldPrimarySelection }); - } else { - ReapplyExtensions(new DesignItem[] { oldPrimarySelection, newPrimarySelection }); - } - oldPrimarySelection = newPrimarySelection; - oldCntBelowTwo = this.Services.Selection.SelectedItems.Count < 2; - } + if (this.Services.Selection.SelectedItems.Count > 1) + ReapplyExtensions(this.Services.Selection.SelectedItems); } /// @@ -143,7 +155,7 @@ namespace ICSharpCode.WpfDesign.Extensions /// public override bool ShouldApplyExtensions(DesignItem extendedItem) { - return (this.Services.Selection.SelectedItems.Count < 2 && this.Services.Selection.PrimarySelection == extendedItem); + return Services.Selection.PrimarySelection == extendedItem && Services.Selection.SelectionCount < 2; } } From 9cdcb17cd454fe3c04c761e65a6a877c596ade27 Mon Sep 17 00:00:00 2001 From: jkuehner Date: Mon, 28 Apr 2014 08:51:31 +0200 Subject: [PATCH 13/16] Canvas extension -> Only when One item is selected --- .../Project/Extensions/CanvasPositionExtension.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From 78fe8ec6984e2fb8d06e60853a8ff4e50bace2e1 Mon Sep 17 00:00:00 2001 From: jkuehner Date: Mon, 28 Apr 2014 08:52:27 +0200 Subject: [PATCH 14/16] Show a Border around multiple Selected Items and a TopLeftContainerDragHandle (multipleItems) --- .../Project/Controls/PanelMoveAdorner.cs | 2 +- .../Extensions/TopLeftContainerDragHandle.cs | 8 +- ...TopLeftContainerDragHandleMultipleItems.cs | 93 +++++++++++++++++++ .../Project/WpfDesign.Designer.csproj | 1 + 4 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TopLeftContainerDragHandleMultipleItems.cs 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/TopLeftContainerDragHandle.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TopLeftContainerDragHandle.cs index 6c111f3453..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,9 +32,9 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions { /// - /// The drag handle displayed for panels. + /// The drag handle displayed for Framework Elements /// - [ExtensionServer(typeof(PrimarySelectionExtensionServer))] + [ExtensionServer(typeof(OnlyOneItemSelectedExtensionServer))] [ExtensionFor(typeof(FrameworkElement))] public class TopLeftContainerDragHandle : AdornerProvider { @@ -44,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/WpfDesign.Designer.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj index a34a76e1b1..09acd365fa 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj @@ -88,6 +88,7 @@ + FlatCollectionEditor.xaml Code From 2f78283d2d844250a70abd2ca804919b3b1cfbf3 Mon Sep 17 00:00:00 2001 From: jkuehner Date: Mon, 28 Apr 2014 10:40:28 +0200 Subject: [PATCH 15/16] Snapline -> Null Ref fix --- .../Extensions/SnaplinePlacementBehavior.cs | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) 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 81cc6f585b..9a30964556 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SnaplinePlacementBehavior.cs @@ -184,12 +184,13 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions { designItem = this.ExtendedItem.Services.DesignPanel.Context.RootItem; yield return designItem; - yield return designItem.ContentProperty.Value; - designItem = designItem.ContentProperty.Value; + if (designItem.ContentProperty.Value != null) { + yield return designItem.ContentProperty.Value; + designItem = designItem.ContentProperty.Value; + } } - //yield return designItem.ContentProperty.Value; - if (designItem.ContentProperty.IsCollection) + if (designItem.ContentProperty != null && designItem.ContentProperty.IsCollection) foreach (var collectionElement in designItem.ContentProperty.CollectionElements) { yield return collectionElement; @@ -212,13 +213,14 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions AddLines(containerRect, 0, false); foreach (var item in AllDesignItems() /* ExtendedItem.ContentProperty.CollectionElements */ - .Except(operation.PlacedItems.Select(f => f.Item))) - { - var bounds = GetPosition(operation, item); + .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); + AddLines(bounds, 0, false); + AddLines(bounds, Margin, true); + AddBaseline(item, bounds, horizontalMap); + } } } From 1220ef63acc55ccafa1f738d96cf990cb1766190 Mon Sep 17 00:00:00 2001 From: jkuehner Date: Mon, 28 Apr 2014 19:26:10 +0200 Subject: [PATCH 16/16] OutlineView -> Fix jump to selected Item --- .../Project/OutlineView/DragTreeViewItem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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(); }