Browse Source

Allow placing elements in a Grid.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2443 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
fc0ca926c5
  1. 21
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GrayOutDesignerExceptActiveArea.cs
  2. 4
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GridAdorner.cs
  3. 3
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasPlacementSupport.cs
  4. 237
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/GridPlacementSupport.cs
  5. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementType.cs

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

@ -55,7 +55,26 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
drawingContext.DrawGeometry(grayOutBrush, null, combinedGeometry); drawingContext.DrawGeometry(grayOutBrush, null, combinedGeometry);
} }
Rect currentAnimateActiveAreaRectToTarget;
internal void AnimateActiveAreaRectTo(Rect newRect)
{
if (newRect.Equals(currentAnimateActiveAreaRectToTarget))
return;
activeAreaGeometry.BeginAnimation(
RectangleGeometry.RectProperty,
new RectAnimation(newRect, new Duration(new TimeSpan(0,0,0,0,100))),
HandoffBehavior.SnapshotAndReplace);
currentAnimateActiveAreaRectToTarget = newRect;
}
internal static void Start(ref GrayOutDesignerExceptActiveArea grayOut, ServiceContainer services, UIElement activeContainer) internal static void Start(ref GrayOutDesignerExceptActiveArea grayOut, ServiceContainer services, UIElement activeContainer)
{
Debug.Assert(activeContainer != null);
Start(ref grayOut, services, activeContainer, new Rect(activeContainer.RenderSize));
}
internal static void Start(ref GrayOutDesignerExceptActiveArea grayOut, ServiceContainer services, UIElement activeContainer, Rect activeRectInActiveContainer)
{ {
Debug.Assert(services != null); Debug.Assert(services != null);
Debug.Assert(activeContainer != null); Debug.Assert(activeContainer != null);
@ -68,7 +87,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
grayOut.adornerPanel.Order = AdornerOrder.BehindForeground; grayOut.adornerPanel.Order = AdornerOrder.BehindForeground;
grayOut.adornerPanel.SetAdornedElement(designPanel.Context.RootItem.View, null); grayOut.adornerPanel.SetAdornedElement(designPanel.Context.RootItem.View, null);
grayOut.adornerPanel.Children.Add(grayOut); grayOut.adornerPanel.Children.Add(grayOut);
grayOut.ActiveAreaGeometry = new RectangleGeometry(new Rect(activeContainer.RenderSize), 0, 0, (Transform)activeContainer.TransformToVisual(grayOut.adornerPanel.AdornedElement)); grayOut.ActiveAreaGeometry = new RectangleGeometry(activeRectInActiveContainer, 0, 0, (Transform)activeContainer.TransformToVisual(grayOut.adornerPanel.AdornedElement));
Animate(grayOut.GrayOutBrush, Brush.OpacityProperty, 0, MaxOpacity); Animate(grayOut.GrayOutBrush, Brush.OpacityProperty, 0, MaxOpacity);
designPanel.Adorners.Add(grayOut.adornerPanel); designPanel.Adorners.Add(grayOut.adornerPanel);
} }

4
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GridAdorner.cs

@ -244,12 +244,12 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
if (original1.IsStar && originalPixelSize1 > 0) if (original1.IsStar && originalPixelSize1 > 0)
new1 = new GridLength(original1.Value * (originalPixelSize1 + delta) / originalPixelSize1, GridUnitType.Star); new1 = new GridLength(original1.Value * (originalPixelSize1 + delta) / originalPixelSize1, GridUnitType.Star);
else else
new1 = new GridLength(original1.Value + delta); new1 = new GridLength(originalPixelSize1 + delta);
GridLength new2; GridLength new2;
if (original2.IsStar && originalPixelSize2 > 0) if (original2.IsStar && originalPixelSize2 > 0)
new2 = new GridLength(original2.Value * (originalPixelSize2 - delta) / originalPixelSize2, GridUnitType.Star); new2 = new GridLength(original2.Value * (originalPixelSize2 - delta) / originalPixelSize2, GridUnitType.Star);
else else
new2 = new GridLength(original2.Value - delta); new2 = new GridLength(originalPixelSize2 - delta);
firstRow.Properties[RowColumnSizeProperty].SetValue(new1); firstRow.Properties[RowColumnSizeProperty].SetValue(new1);
secondRow.Properties[RowColumnSizeProperty].SetValue(new2); secondRow.Properties[RowColumnSizeProperty].SetValue(new2);
((UIElement)VisualTreeHelper.GetParent(this)).InvalidateArrange(); ((UIElement)VisualTreeHelper.GetParent(this)).InvalidateArrange();

3
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasPlacementSupport.cs

@ -115,6 +115,9 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
foreach (PlacementInformation info in operation.PlacedItems) { foreach (PlacementInformation info in operation.PlacedItems) {
this.ExtendedItem.Properties["Children"].CollectionElements.Add(info.Item); this.ExtendedItem.Properties["Children"].CollectionElements.Add(info.Item);
SetPosition(info); SetPosition(info);
info.Item.Properties[FrameworkElement.HorizontalAlignmentProperty].Reset();
info.Item.Properties[FrameworkElement.VerticalAlignmentProperty].Reset();
info.Item.Properties[FrameworkElement.MarginProperty].Reset();
} }
BeginPlacement(operation); BeginPlacement(operation);
} }

237
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/GridPlacementSupport.cs

@ -8,7 +8,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows; using System.Windows;
using System.Diagnostics;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media;
using ICSharpCode.WpfDesign.Adorners; using ICSharpCode.WpfDesign.Adorners;
using ICSharpCode.WpfDesign.Extensions; using ICSharpCode.WpfDesign.Extensions;
@ -22,33 +24,247 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
[ExtensionFor(typeof(Grid))] [ExtensionFor(typeof(Grid))]
public sealed class GridPlacementSupport : BehaviorExtension, IPlacementBehavior public sealed class GridPlacementSupport : BehaviorExtension, IPlacementBehavior
{ {
Grid grid;
protected override void OnInitialized() protected override void OnInitialized()
{ {
base.OnInitialized(); base.OnInitialized();
grid = (Grid)this.ExtendedItem.Component;
this.ExtendedItem.AddBehavior(typeof(IPlacementBehavior), this); this.ExtendedItem.AddBehavior(typeof(IPlacementBehavior), this);
} }
public bool CanPlace(ICollection<DesignItem> childItems, PlacementType type, PlacementAlignment position) public bool CanPlace(ICollection<DesignItem> childItems, PlacementType type, PlacementAlignment position)
{ {
return type == PlacementType.Delete; return type == PlacementType.Resize || type == PlacementType.Move
|| type == PlacementType.Delete
|| type == PlacementType.AddItem;
} }
GrayOutDesignerExceptActiveArea grayOut;
public void BeginPlacement(PlacementOperation operation) public void BeginPlacement(PlacementOperation operation)
{ {
} }
public void EndPlacement(PlacementOperation operation) public void EndPlacement(PlacementOperation operation)
{ {
GrayOutDesignerExceptActiveArea.Stop(ref grayOut);
} }
public Rect GetPosition(PlacementOperation operation, DesignItem child) public Rect GetPosition(PlacementOperation operation, DesignItem child)
{ {
return new Rect(); FrameworkElement obj = child.Component as FrameworkElement;
if (obj == null) return new Rect();
Thickness margin = obj.Margin;
double left, width, right;
switch (obj.HorizontalAlignment) {
case HorizontalAlignment.Stretch:
left = GetColumnOffset(Grid.GetColumn(obj)) + margin.Left;
right = GetColumnOffset(Grid.GetColumn(obj) + Grid.GetColumnSpan(obj)) - margin.Right;
width = right - left;
break;
case HorizontalAlignment.Left:
left = GetColumnOffset(Grid.GetColumn(obj)) + margin.Left;
width = ModelTools.GetWidth(obj);
right = left + width;
break;
case HorizontalAlignment.Right:
right = GetColumnOffset(Grid.GetColumn(obj) + Grid.GetColumnSpan(obj)) - margin.Right;
width = ModelTools.GetWidth(obj);
left = right - width;
break;
case HorizontalAlignment.Center:
throw new NotImplementedException();
default:
throw new NotSupportedException();
}
double top, height, bottom;
switch (obj.VerticalAlignment) {
case VerticalAlignment.Stretch:
top = GetRowOffset(Grid.GetRow(obj)) + margin.Top;
bottom = GetRowOffset(Grid.GetRow(obj) + Grid.GetRowSpan(obj)) - margin.Bottom;
height = bottom - top;
break;
case VerticalAlignment.Top:
top = GetRowOffset(Grid.GetRow(obj)) + margin.Top;
height = ModelTools.GetHeight(obj);
bottom = top + height;
break;
case VerticalAlignment.Bottom:
bottom = GetRowOffset(Grid.GetRow(obj) + Grid.GetRowSpan(obj)) - margin.Bottom;
height = ModelTools.GetHeight(obj);
top = bottom - height;
break;
case VerticalAlignment.Center:
throw new NotImplementedException();
default:
throw new NotSupportedException();
}
return new Rect(left, top, width, height);
}
double GetColumnOffset(int index)
{
if (index < grid.ColumnDefinitions.Count)
return grid.ColumnDefinitions[index].Offset;
else
return grid.ActualWidth;
}
double GetRowOffset(int index)
{
if (index < grid.RowDefinitions.Count)
return grid.RowDefinitions[index].Offset;
else
return grid.ActualHeight;
}
const double epsilon = 0.00000001;
int GetColumnIndex(double x)
{
if (grid.ColumnDefinitions.Count == 0)
return 0;
for (int i = 1; i < grid.ColumnDefinitions.Count; i++) {
if (x < grid.ColumnDefinitions[i].Offset - epsilon)
return i - 1;
}
return grid.ColumnDefinitions.Count - 1;
}
int GetRowIndex(double y)
{
if (grid.RowDefinitions.Count == 0)
return 0;
for (int i = 1; i < grid.RowDefinitions.Count; i++) {
if (y < grid.RowDefinitions[i].Offset - epsilon)
return i - 1;
}
return grid.RowDefinitions.Count - 1;
}
int GetEndColumnIndex(double x)
{
if (grid.ColumnDefinitions.Count == 0)
return 0;
for (int i = 1; i < grid.ColumnDefinitions.Count; i++) {
if (x <= grid.ColumnDefinitions[i].Offset + epsilon)
return i - 1;
}
return grid.ColumnDefinitions.Count - 1;
}
int GetEndRowIndex(double y)
{
if (grid.RowDefinitions.Count == 0)
return 0;
for (int i = 1; i < grid.RowDefinitions.Count; i++) {
if (y <= grid.RowDefinitions[i].Offset + epsilon)
return i - 1;
}
return grid.RowDefinitions.Count - 1;
}
static void SetColumn(DesignItem item, int column, int columnSpan)
{
Debug.Assert(item != null && column >= 0 && columnSpan > 0);
item.Properties.GetAttachedProperty(Grid.ColumnProperty).SetValue(column);
if (columnSpan == 1) {
item.Properties.GetAttachedProperty(Grid.ColumnSpanProperty).Reset();
} else {
item.Properties.GetAttachedProperty(Grid.ColumnSpanProperty).SetValue(columnSpan);
}
}
static void SetRow(DesignItem item, int row, int rowSpan)
{
Debug.Assert(item != null && row >= 0 && rowSpan > 0);
item.Properties.GetAttachedProperty(Grid.RowProperty).SetValue(row);
if (rowSpan == 1) {
item.Properties.GetAttachedProperty(Grid.RowSpanProperty).Reset();
} else {
item.Properties.GetAttachedProperty(Grid.RowSpanProperty).SetValue(rowSpan);
}
}
static HorizontalAlignment SuggestHorizontalAlignment(Rect itemBounds, Rect availableSpaceRect)
{
if (itemBounds.Right < (availableSpaceRect.Left + availableSpaceRect.Right) / 2) {
return HorizontalAlignment.Left;
} else if (itemBounds.Left > (availableSpaceRect.Left + availableSpaceRect.Right) / 2) {
return HorizontalAlignment.Right;
} else {
return HorizontalAlignment.Stretch;
}
}
static VerticalAlignment SuggestVerticalAlignment(Rect itemBounds, Rect availableSpaceRect)
{
if (itemBounds.Bottom < (availableSpaceRect.Top + availableSpaceRect.Bottom) / 2) {
return VerticalAlignment.Top;
} else if (itemBounds.Top > (availableSpaceRect.Top + availableSpaceRect.Bottom) / 2) {
return VerticalAlignment.Bottom;
} else {
return VerticalAlignment.Stretch;
}
} }
public void SetPosition(PlacementInformation info) public void SetPosition(PlacementInformation info)
{ {
throw new NotImplementedException(); if (info.Operation.Type == PlacementType.AddItem) {
SetColumn(info.Item, GetColumnIndex(info.Bounds.Left), 1);
SetRow(info.Item, GetRowIndex(info.Bounds.Top), 1);
} else {
int leftColumnIndex = GetColumnIndex(info.Bounds.Left);
int rightColumnIndex = GetEndColumnIndex(info.Bounds.Right);
if (rightColumnIndex < leftColumnIndex) rightColumnIndex = leftColumnIndex;
SetColumn(info.Item, leftColumnIndex, rightColumnIndex - leftColumnIndex + 1);
int topRowIndex = GetRowIndex(info.Bounds.Top);
int bottomRowIndex = GetEndRowIndex(info.Bounds.Bottom);
if (bottomRowIndex < topRowIndex) bottomRowIndex = topRowIndex;
SetRow(info.Item, topRowIndex, bottomRowIndex - topRowIndex + 1);
Rect availableSpaceRect = new Rect(
new Point(GetColumnOffset(leftColumnIndex), GetRowOffset(topRowIndex)),
new Point(GetColumnOffset(rightColumnIndex + 1), GetRowOffset(bottomRowIndex + 1))
);
if (grayOut != null) {
grayOut.AnimateActiveAreaRectTo(availableSpaceRect);
} else {
GrayOutDesignerExceptActiveArea.Start(ref grayOut, this.Services, this.ExtendedItem.View, availableSpaceRect);
}
HorizontalAlignment ha = (HorizontalAlignment)info.Item.Properties[FrameworkElement.HorizontalAlignmentProperty].ValueOnInstance;
VerticalAlignment va = (VerticalAlignment)info.Item.Properties[FrameworkElement.VerticalAlignmentProperty].ValueOnInstance;
ha = SuggestHorizontalAlignment(info.Bounds, availableSpaceRect);
va = SuggestVerticalAlignment(info.Bounds, availableSpaceRect);
info.Item.Properties[FrameworkElement.HorizontalAlignmentProperty].SetValue(ha);
info.Item.Properties[FrameworkElement.VerticalAlignmentProperty].SetValue(va);
Thickness margin = new Thickness(0, 0, 0, 0);
if (ha == HorizontalAlignment.Left || ha == HorizontalAlignment.Stretch)
margin.Left = info.Bounds.Left - GetColumnOffset(leftColumnIndex);
if (va == VerticalAlignment.Top || va == VerticalAlignment.Stretch)
margin.Top = info.Bounds.Top - GetRowOffset(topRowIndex);
if (ha == HorizontalAlignment.Right || ha == HorizontalAlignment.Stretch)
margin.Right = GetColumnOffset(rightColumnIndex + 1) - info.Bounds.Right;
if (va == VerticalAlignment.Bottom || va == VerticalAlignment.Stretch)
margin.Bottom = GetRowOffset(bottomRowIndex + 1) - info.Bounds.Bottom;
info.Item.Properties[FrameworkElement.MarginProperty].SetValue(margin);
if (ha == HorizontalAlignment.Stretch)
info.Item.Properties[FrameworkElement.WidthProperty].Reset();
else
info.Item.Properties[FrameworkElement.WidthProperty].SetValue(info.Bounds.Width);
if (va == VerticalAlignment.Stretch)
info.Item.Properties[FrameworkElement.HeightProperty].Reset();
else
info.Item.Properties[FrameworkElement.HeightProperty].SetValue(info.Bounds.Height);
}
} }
public bool CanLeaveContainer(PlacementOperation operation) public bool CanLeaveContainer(PlacementOperation operation)
@ -58,6 +274,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
public void LeaveContainer(PlacementOperation operation) public void LeaveContainer(PlacementOperation operation)
{ {
EndPlacement(operation);
foreach (PlacementInformation info in operation.PlacedItems) { foreach (PlacementInformation info in operation.PlacedItems) {
if (info.Item.ComponentType == typeof(ColumnDefinition)) { if (info.Item.ComponentType == typeof(ColumnDefinition)) {
// TODO: combine the width of the deleted column with the previous column // TODO: combine the width of the deleted column with the previous column
@ -65,19 +282,27 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
} else if (info.Item.ComponentType == typeof(RowDefinition)) { } else if (info.Item.ComponentType == typeof(RowDefinition)) {
this.ExtendedItem.Properties["RowDefinitions"].CollectionElements.Remove(info.Item); this.ExtendedItem.Properties["RowDefinitions"].CollectionElements.Remove(info.Item);
} else { } else {
throw new NotImplementedException(); this.ExtendedItem.Properties["Children"].CollectionElements.Remove(info.Item);
info.Item.Properties.GetAttachedProperty(Grid.RowProperty).Reset();
info.Item.Properties.GetAttachedProperty(Grid.ColumnProperty).Reset();
info.Item.Properties.GetAttachedProperty(Grid.RowSpanProperty).Reset();
info.Item.Properties.GetAttachedProperty(Grid.ColumnSpanProperty).Reset();
} }
} }
} }
public bool CanEnterContainer(PlacementOperation operation) public bool CanEnterContainer(PlacementOperation operation)
{ {
return false; return true;
} }
public void EnterContainer(PlacementOperation operation) public void EnterContainer(PlacementOperation operation)
{ {
throw new NotImplementedException(); foreach (PlacementInformation info in operation.PlacedItems) {
this.ExtendedItem.Properties["Children"].CollectionElements.Add(info.Item);
SetPosition(info);
}
BeginPlacement(operation);
} }
} }
} }

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

@ -28,7 +28,7 @@ namespace ICSharpCode.WpfDesign
/// <summary> /// <summary>
/// Adding an element to a specified position in the container. /// Adding an element to a specified position in the container.
/// T /// AddItem is used when dragging a toolbox item to the design surface.
/// </summary> /// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
public static readonly PlacementType AddItem = Register("AddItem"); public static readonly PlacementType AddItem = Register("AddItem");

Loading…
Cancel
Save