Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/wpfdesigner@6317 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61pull/1/head
3 changed files with 189 additions and 1 deletions
@ -0,0 +1,176 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt"/>
|
||||||
|
// <license see="prj:///doc/license.txt"/>
|
||||||
|
// <author name="Kumar Devvrat"/>
|
||||||
|
// <version>$Revision: $</version>
|
||||||
|
// </file>
|
||||||
|
using System; |
||||||
|
using System.Linq; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Media; |
||||||
|
using System.Windows.Shapes; |
||||||
|
|
||||||
|
using ICSharpCode.WpfDesign.Adorners; |
||||||
|
using ICSharpCode.WpfDesign.Extensions; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign.Designer.Extensions |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Provides <see cref="IPlacementBehavior"/> for <see cref="StackPanel"/>.
|
||||||
|
/// </summary>
|
||||||
|
[ExtensionFor(typeof (StackPanel), OverrideExtension = typeof (DefaultPlacementBehavior))] |
||||||
|
public class StackPanelPlacementSupport : DefaultPlacementBehavior |
||||||
|
{ |
||||||
|
private StackPanel _stackPanel; |
||||||
|
private AdornerPanel _adornerPanel; |
||||||
|
private Rectangle _rectangle = new Rectangle(); // Draws a rectangle to indicate the position of insertion.
|
||||||
|
private readonly List<Rect> _rects = new List<Rect>(); // Contains the Rect of all the children of StackPanel.
|
||||||
|
|
||||||
|
|
||||||
|
private bool _isItemGettingResized; // Indicates whether any children is getting resized.
|
||||||
|
private int _indexToInsert; // Postion where to insert the element.
|
||||||
|
|
||||||
|
|
||||||
|
protected override void OnInitialized() |
||||||
|
{ |
||||||
|
base.OnInitialized(); |
||||||
|
_stackPanel = this.ExtendedItem.View as StackPanel; |
||||||
|
var children = this.ExtendedItem.ContentProperty.CollectionElements; |
||||||
|
foreach (var child in children) { |
||||||
|
Point p = child.View.TranslatePoint(new Point(0, 0), this.ExtendedItem.View); |
||||||
|
_rects.Add(new Rect(p, child.View.RenderSize)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void BeginPlacement(PlacementOperation operation) |
||||||
|
{ |
||||||
|
base.BeginPlacement(operation); |
||||||
|
if (_rects.Count > 0) |
||||||
|
_rects.Clear(); |
||||||
|
|
||||||
|
/* Add Rect of all children to _rects */ |
||||||
|
var children = this.ExtendedItem.ContentProperty.CollectionElements; |
||||||
|
foreach (var child in children) { |
||||||
|
Point p = child.View.TranslatePoint(new Point(0, 0), this.ExtendedItem.View); |
||||||
|
_rects.Add(new Rect(p, child.View.RenderSize)); |
||||||
|
} |
||||||
|
if (_adornerPanel != null && this.ExtendedItem.Services.DesignPanel.Adorners.Contains(_adornerPanel)) |
||||||
|
this.ExtendedItem.Services.DesignPanel.Adorners.Remove(_adornerPanel); |
||||||
|
|
||||||
|
/* Place the Rectangle */ |
||||||
|
_adornerPanel = new AdornerPanel(); |
||||||
|
_rectangle = new Rectangle(); |
||||||
|
_adornerPanel.SetAdornedElement(this.ExtendedItem.View, this.ExtendedItem); |
||||||
|
_adornerPanel.Children.Add(_rectangle); |
||||||
|
this.ExtendedItem.Services.DesignPanel.Adorners.Add(_adornerPanel); |
||||||
|
} |
||||||
|
|
||||||
|
public override void EndPlacement(PlacementOperation operation) |
||||||
|
{ |
||||||
|
base.EndPlacement(operation); |
||||||
|
if (_adornerPanel != null && this.ExtendedItem.Services.DesignPanel.Adorners.Contains(_adornerPanel)) |
||||||
|
this.ExtendedItem.Services.DesignPanel.Adorners.Remove(_adornerPanel); |
||||||
|
} |
||||||
|
|
||||||
|
public override void EnterContainer(PlacementOperation operation) |
||||||
|
{ |
||||||
|
base.EnterContainer(operation); |
||||||
|
foreach (var info in operation.PlacedItems) { |
||||||
|
info.Item.Properties[FrameworkElement.MarginProperty].Reset(); |
||||||
|
info.Item.Properties[FrameworkElement.HorizontalAlignmentProperty].Reset(); |
||||||
|
info.Item.Properties[FrameworkElement.VerticalAlignmentProperty].Reset(); |
||||||
|
} |
||||||
|
_rectangle.Visibility = Visibility.Visible; |
||||||
|
} |
||||||
|
|
||||||
|
public override void LeaveContainer(PlacementOperation operation) |
||||||
|
{ |
||||||
|
base.LeaveContainer(operation); |
||||||
|
/* Hide the rectangle in case switching to the other container |
||||||
|
* otherwise it will show up intersecting with the container */ |
||||||
|
_rectangle.Visibility = Visibility.Hidden; |
||||||
|
} |
||||||
|
|
||||||
|
public override void SetPosition(PlacementInformation info) |
||||||
|
{ |
||||||
|
base.SetPosition(info); |
||||||
|
|
||||||
|
var resizeExtensions = info.Item.Extensions.OfType<ResizeThumbExtension>(); |
||||||
|
if (resizeExtensions != null && resizeExtensions.Count() != 0) { |
||||||
|
var resizeExtension = resizeExtensions.First(); |
||||||
|
_isItemGettingResized = resizeExtension.IsResizing; |
||||||
|
} |
||||||
|
|
||||||
|
if (_stackPanel != null && !_isItemGettingResized) { |
||||||
|
if (_stackPanel.Orientation == Orientation.Vertical) { |
||||||
|
var offset = FindHorizontalRectanglePlacementOffset(info.Bounds); |
||||||
|
DrawHorizontalRectangle(offset); |
||||||
|
} else { |
||||||
|
var offset = FindVerticalRectanglePlacementOffset(info.Bounds); |
||||||
|
DrawVerticalRectangle(offset); |
||||||
|
} |
||||||
|
|
||||||
|
ChangePostionTo(info.Item.View, _indexToInsert); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void ChangePostionTo(UIElement element, int index) |
||||||
|
{ |
||||||
|
int elementIndex = 0; |
||||||
|
if (_stackPanel.Children.Contains(element)) |
||||||
|
elementIndex = _stackPanel.Children.IndexOf(element); |
||||||
|
if (index > elementIndex) |
||||||
|
index--; |
||||||
|
_stackPanel.Children.Remove(element); |
||||||
|
_stackPanel.Children.Insert(index, element); |
||||||
|
} |
||||||
|
|
||||||
|
private double FindHorizontalRectanglePlacementOffset(Rect rect) |
||||||
|
{ |
||||||
|
_rects.Sort((r1, r2) => r1.Top.CompareTo(r2.Top)); |
||||||
|
var itemCenter = (rect.Top + rect.Bottom)/2; |
||||||
|
for (int i = 0; i < _rects.Count; i++) { |
||||||
|
var rectCenter = (_rects[i].Top + _rects[i].Bottom)/2; |
||||||
|
if (rectCenter >= itemCenter) { |
||||||
|
_indexToInsert = i; |
||||||
|
return _rects[i].Top; |
||||||
|
} |
||||||
|
} |
||||||
|
_indexToInsert = _rects.Count; |
||||||
|
return _rects.Count > 0 ? _rects.Last().Bottom : 0; |
||||||
|
} |
||||||
|
|
||||||
|
private double FindVerticalRectanglePlacementOffset(Rect rect) |
||||||
|
{ |
||||||
|
_rects.Sort((r1, r2) => r1.Left.CompareTo(r2.Left)); |
||||||
|
var itemCenter = (rect.Left + rect.Right)/2; |
||||||
|
for (int i = 0; i < _rects.Count; i++) { |
||||||
|
var rectCenter = (_rects[i].Left + _rects[i].Top)/2; |
||||||
|
if (rectCenter >= itemCenter) { |
||||||
|
_indexToInsert = i; |
||||||
|
return _rects[i].Left; |
||||||
|
} |
||||||
|
} |
||||||
|
_indexToInsert = _rects.Count; |
||||||
|
return _rects.Count > 0 ? _rects.Last().Right : 0; |
||||||
|
} |
||||||
|
|
||||||
|
private void DrawHorizontalRectangle(double offset) |
||||||
|
{ |
||||||
|
_rectangle.Height = 2; |
||||||
|
_rectangle.Fill = Brushes.Black; |
||||||
|
var placement = new RelativePlacement(HorizontalAlignment.Stretch, VerticalAlignment.Top) {YOffset = offset}; |
||||||
|
AdornerPanel.SetPlacement(_rectangle, placement); |
||||||
|
} |
||||||
|
|
||||||
|
private void DrawVerticalRectangle(double offset) |
||||||
|
{ |
||||||
|
_rectangle.Width = 2; |
||||||
|
_rectangle.Fill = Brushes.Black; |
||||||
|
var placement = new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Stretch) {XOffset = offset}; |
||||||
|
AdornerPanel.SetPlacement(_rectangle, placement); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue