Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2405 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
9 changed files with 435 additions and 106 deletions
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.ComponentModel; |
||||
using System.Diagnostics; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Input; |
||||
using System.Windows.Media; |
||||
|
||||
using ICSharpCode.WpfDesign.Extensions; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
||||
{ |
||||
/// <summary>
|
||||
/// The rectangle shown during a drag'n'drop operation.
|
||||
/// </summary>
|
||||
public class DragFrame : Control |
||||
{ |
||||
static DragFrame() |
||||
{ |
||||
//This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
|
||||
//This style is defined in themes\generic.xaml
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(DragFrame), new FrameworkPropertyMetadata(typeof(DragFrame))); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,169 @@
@@ -0,0 +1,169 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using ICSharpCode.WpfDesign.Extensions; |
||||
using ICSharpCode.WpfDesign.Adorners; |
||||
using System.Windows; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
||||
{ |
||||
/// <summary>
|
||||
/// Implements IChildResizeSupport supporting size changes using the
|
||||
/// Width, Height, Margin properties.
|
||||
/// </summary>
|
||||
//[ExtensionFor(typeof(FrameworkElement))]
|
||||
sealed class DefaultChildResizeSupport : IChildResizeSupport |
||||
{ |
||||
// the default behavior is not an extension because it does not depend
|
||||
// on a parent container instance
|
||||
public static readonly DefaultChildResizeSupport Instance = new DefaultChildResizeSupport(); |
||||
|
||||
/* |
||||
/// <inherits/>
|
||||
protected override void OnInitialized() |
||||
{ |
||||
base.OnInitialized(); |
||||
this.ExtendedItem.AddBehavior(typeof(IChildResizeSupport), this); |
||||
} |
||||
*/ |
||||
|
||||
/// <inherits/>
|
||||
public bool CanResizeChild(DesignItem childItem) |
||||
{ |
||||
FrameworkElement child = (FrameworkElement)childItem.Component; |
||||
return !double.IsNaN(child.Width) |
||||
|| !double.IsNaN(child.Height) |
||||
|| childItem.Properties[FrameworkElement.MarginProperty].IsSet; |
||||
} |
||||
|
||||
/// <inherits/>
|
||||
public Placement GetPlacement(DesignItem childItem, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical) |
||||
{ |
||||
FrameworkElement child = (FrameworkElement)childItem.Component; |
||||
if (childItem.Properties[FrameworkElement.MarginProperty].IsSet == false) { |
||||
if (child.HorizontalAlignment == HorizontalAlignment.Left) |
||||
horizontal = HorizontalAlignment.Right; |
||||
else if (child.HorizontalAlignment == HorizontalAlignment.Right) |
||||
horizontal = HorizontalAlignment.Left; |
||||
else |
||||
horizontal = HorizontalAlignment.Center; |
||||
if (child.VerticalAlignment == VerticalAlignment.Top) |
||||
horizontal = HorizontalAlignment.Right; |
||||
else if (child.VerticalAlignment == VerticalAlignment.Bottom) |
||||
vertical = VerticalAlignment.Bottom; |
||||
else |
||||
vertical = VerticalAlignment.Center; |
||||
} |
||||
return RootElementResizeSupport.Instance.GetPlacement(childItem, horizontalChange, verticalChange, horizontal, vertical); |
||||
} |
||||
|
||||
/// <inherits/>
|
||||
public void Resize(DesignItem childItem, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical) |
||||
{ |
||||
RelativePlacement p = (RelativePlacement)GetPlacement(childItem, horizontalChange, verticalChange, horizontal, vertical); |
||||
Resize(childItem, p, horizontalChange, verticalChange, horizontal, vertical); |
||||
} |
||||
|
||||
static void Resize(DesignItem childItem, RelativePlacement p, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical) |
||||
{ |
||||
DesignItemProperty margin = childItem.Properties[FrameworkElement.MarginProperty]; |
||||
if (margin.IsSet) { |
||||
Thickness t = (Thickness)margin.ValueOnInstance; |
||||
t.Left += p.XOffset; |
||||
t.Top += p.YOffset; |
||||
t.Right -= p.XOffset + p.WidthOffset; |
||||
t.Bottom -= p.YOffset + p.HeightOffset; |
||||
margin.SetValue(t); |
||||
} |
||||
|
||||
FrameworkElement child = (FrameworkElement)childItem.Component; |
||||
double width = child.Width; |
||||
double height = child.Height; |
||||
if (margin.IsSet) { |
||||
// when margin is used, only set width/height if it is not Auto
|
||||
if (!double.IsNaN(width)) { |
||||
childItem.Properties[FrameworkElement.WidthProperty].SetValue( Math.Max(0, horizontalChange + width) ); |
||||
} |
||||
if (!double.IsNaN(height)) { |
||||
childItem.Properties[FrameworkElement.HeightProperty].SetValue( Math.Max(0, verticalChange + height) ); |
||||
} |
||||
} else { |
||||
// when margin is not used, we'll have to set width+height
|
||||
// but don't create width if we don't have any horizontal change
|
||||
if (double.IsNaN(width) && horizontalChange != 0) { |
||||
width = child.ActualWidth; |
||||
} |
||||
if (double.IsNaN(height) && verticalChange != 0) { |
||||
height = child.ActualHeight; |
||||
} |
||||
if (!double.IsNaN(width)) { |
||||
childItem.Properties[FrameworkElement.WidthProperty].SetValue( Math.Max(0, horizontalChange + width) ); |
||||
} |
||||
if (!double.IsNaN(height)) { |
||||
childItem.Properties[FrameworkElement.HeightProperty].SetValue( Math.Max(0, verticalChange + height) ); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
sealed class RootElementResizeSupport : IChildResizeSupport |
||||
{ |
||||
public static readonly RootElementResizeSupport Instance = new RootElementResizeSupport(); |
||||
|
||||
public bool CanResizeChild(DesignItem child) |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
public Placement GetPlacement(DesignItem child, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical) |
||||
{ |
||||
RelativePlacement rp = new RelativePlacement(HorizontalAlignment.Stretch, VerticalAlignment.Stretch); |
||||
|
||||
if (horizontal == HorizontalAlignment.Right) { |
||||
rp.WidthOffset += horizontalChange; |
||||
} else if (horizontal == HorizontalAlignment.Left) { |
||||
rp.XOffset -= horizontalChange; |
||||
rp.WidthOffset += horizontalChange; |
||||
} else { |
||||
rp.XOffset -= horizontalChange / 2; |
||||
rp.WidthOffset += horizontalChange; |
||||
} |
||||
|
||||
if (vertical == VerticalAlignment.Bottom) { |
||||
rp.HeightOffset += verticalChange; |
||||
} else if (vertical == VerticalAlignment.Top) { |
||||
rp.YOffset -= verticalChange; |
||||
rp.HeightOffset += verticalChange; |
||||
} else { |
||||
rp.YOffset -= verticalChange / 2; |
||||
rp.HeightOffset += verticalChange; |
||||
} |
||||
|
||||
return rp; |
||||
} |
||||
|
||||
public void Resize(DesignItem childItem, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical) |
||||
{ |
||||
FrameworkElement child = (FrameworkElement)childItem.Component; |
||||
double width = child.Width; |
||||
double height = child.Height; |
||||
if (double.IsNaN(width) && horizontalChange != 0) { |
||||
width = child.ActualWidth; |
||||
} |
||||
if (double.IsNaN(height) && verticalChange != 0) { |
||||
height = child.ActualHeight; |
||||
} |
||||
if (!double.IsNaN(width)) { |
||||
childItem.Properties[FrameworkElement.WidthProperty].SetValue( Math.Max(0, horizontalChange + width) ); |
||||
} |
||||
if (!double.IsNaN(height)) { |
||||
childItem.Properties[FrameworkElement.HeightProperty].SetValue( Math.Max(0, verticalChange + height) ); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,167 @@
@@ -0,0 +1,167 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Windows; |
||||
using System.Windows.Input; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Controls.Primitives; |
||||
using ICSharpCode.WpfDesign.Adorners; |
||||
using ICSharpCode.WpfDesign.Extensions; |
||||
using ICSharpCode.WpfDesign.Designer.Controls; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
||||
{ |
||||
/// <summary>
|
||||
/// The resize thumb at the top left edge of a component.
|
||||
/// </summary>
|
||||
[ExtensionFor(typeof(FrameworkElement))] |
||||
public sealed class ResizeThumbExtension : PrimarySelectionAdornerProvider |
||||
{ |
||||
AdornerPanel adornerPanel; |
||||
DragFrame dragFrame; |
||||
|
||||
/// <summary></summary>
|
||||
public ResizeThumbExtension() |
||||
{ |
||||
adornerPanel = new AdornerPanel(); |
||||
adornerPanel.Order = AdornerOrder.Foreground; |
||||
|
||||
CreateThumb(HorizontalAlignment.Left, VerticalAlignment.Top); |
||||
CreateThumb(HorizontalAlignment.Right, VerticalAlignment.Top); |
||||
CreateThumb(HorizontalAlignment.Left, VerticalAlignment.Bottom); |
||||
CreateThumb(HorizontalAlignment.Right, VerticalAlignment.Bottom); |
||||
} |
||||
|
||||
void CreateThumb(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) |
||||
{ |
||||
ResizeThumb resizeThumb = new ResizeThumb(); |
||||
AdornerPanel.SetPlacement(resizeThumb, new RelativePlacement(horizontalAlignment, verticalAlignment)); |
||||
adornerPanel.Children.Add(resizeThumb); |
||||
|
||||
resizeThumb.DragStarted += OnDragStarted; |
||||
resizeThumb.DragDelta += OnDragDelta(horizontalAlignment, verticalAlignment); |
||||
resizeThumb.DragCompleted += OnDragCompleted(horizontalAlignment, verticalAlignment); |
||||
} |
||||
|
||||
IChildResizeSupport resizeBehavior; |
||||
|
||||
void OnDragStarted(object sender, DragStartedEventArgs e) |
||||
{ |
||||
if (dragFrame == null) |
||||
dragFrame = new DragFrame(); |
||||
|
||||
AdornerPanel.SetPlacement(dragFrame, Placement.FillContent); |
||||
adornerPanel.Children.Add(dragFrame); |
||||
adornerPanel.Cursor = Cursors.SizeNWSE; |
||||
// newSize.Width = double.IsNaN(component.Width) ? component.ActualWidth : component.Width;
|
||||
// newSize.Height = double.IsNaN(component.Height) ? component.ActualHeight : component.Height;
|
||||
} |
||||
|
||||
DragDeltaEventHandler OnDragDelta(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) |
||||
{ |
||||
return delegate(object sender, DragDeltaEventArgs e) { |
||||
if (resizeBehavior != null) { |
||||
Placement p = resizeBehavior.GetPlacement(this.ExtendedItem, |
||||
FixChange(e.HorizontalChange, horizontalAlignment), |
||||
FixChange(e.VerticalChange, verticalAlignment), |
||||
horizontalAlignment, verticalAlignment); |
||||
if (p != null) { |
||||
AdornerPanel.SetPlacement(dragFrame, p); |
||||
} |
||||
} |
||||
}; |
||||
} |
||||
|
||||
DragCompletedEventHandler OnDragCompleted(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) |
||||
{ |
||||
return delegate (object sender, DragCompletedEventArgs e) { |
||||
adornerPanel.Children.Remove(dragFrame); |
||||
adornerPanel.ClearValue(AdornerPanel.CursorProperty); |
||||
|
||||
if (resizeBehavior != null) { |
||||
resizeBehavior.Resize(this.ExtendedItem, |
||||
FixChange(e.HorizontalChange, horizontalAlignment), |
||||
FixChange(e.VerticalChange, verticalAlignment), |
||||
horizontalAlignment, verticalAlignment); |
||||
} |
||||
}; |
||||
} |
||||
|
||||
double FixChange(double val, VerticalAlignment va) |
||||
{ |
||||
if (va == VerticalAlignment.Bottom) |
||||
return val; |
||||
else if (va == VerticalAlignment.Top) |
||||
return -val; |
||||
else |
||||
return 0; |
||||
} |
||||
|
||||
double FixChange(double val, HorizontalAlignment ha) |
||||
{ |
||||
if (ha == HorizontalAlignment.Right) |
||||
return val; |
||||
else if (ha == HorizontalAlignment.Left) |
||||
return -val; |
||||
else |
||||
return 0; |
||||
} |
||||
|
||||
/// <summary/>
|
||||
protected override void OnInitialized() |
||||
{ |
||||
base.OnInitialized(); |
||||
this.ExtendedItem.PropertyChanged += OnPropertyChanged; |
||||
this.Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged; |
||||
|
||||
DesignItem parentItem = this.ExtendedItem.Parent; |
||||
if (parentItem == null) // resizing the root element
|
||||
resizeBehavior = RootElementResizeSupport.Instance; |
||||
else |
||||
resizeBehavior = parentItem.GetBehavior<IChildResizeSupport>() ?? DefaultChildResizeSupport.Instance; |
||||
|
||||
UpdateAdornerVisibility(); |
||||
OnPrimarySelectionChanged(null, null); |
||||
} |
||||
|
||||
void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) |
||||
{ |
||||
UpdateAdornerVisibility(); |
||||
} |
||||
|
||||
/// <summary/>
|
||||
protected override void OnRemove() |
||||
{ |
||||
this.ExtendedItem.PropertyChanged -= OnPropertyChanged; |
||||
this.Services.Selection.PrimarySelectionChanged -= OnPrimarySelectionChanged; |
||||
base.OnRemove(); |
||||
} |
||||
|
||||
void OnPrimarySelectionChanged(object sender, EventArgs e) |
||||
{ |
||||
bool isPrimarySelection = this.Services.Selection.PrimarySelection == this.ExtendedItem; |
||||
foreach (ResizeThumb g in adornerPanel.Children) { |
||||
g.IsPrimarySelection = isPrimarySelection; |
||||
} |
||||
} |
||||
|
||||
void UpdateAdornerVisibility() |
||||
{ |
||||
if (resizeBehavior == null || !resizeBehavior.CanResizeChild(this.ExtendedItem)) { |
||||
if (this.Adorners.Count == 1) { |
||||
this.Adorners.Clear(); |
||||
} |
||||
} else { |
||||
if (this.Adorners.Count == 0) { |
||||
this.Adorners.Add(adornerPanel); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,99 +0,0 @@
@@ -1,99 +0,0 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Controls.Primitives; |
||||
using ICSharpCode.WpfDesign.Adorners; |
||||
using ICSharpCode.WpfDesign.Extensions; |
||||
using ICSharpCode.WpfDesign.Designer.Controls; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
||||
{ |
||||
/// <summary>
|
||||
/// The resize thumb at the top left edge of a component.
|
||||
/// </summary>
|
||||
[ExtensionFor(typeof(FrameworkElement))] |
||||
public sealed class TopLeftResizeThumb : PrimarySelectionAdornerProvider |
||||
{ |
||||
AdornerPanel adornerPanel; |
||||
|
||||
/// <summary></summary>
|
||||
public TopLeftResizeThumb() |
||||
{ |
||||
adornerPanel = new AdornerPanel(); |
||||
adornerPanel.Order = AdornerOrder.Foreground; |
||||
|
||||
ResizeThumb resizeThumb; |
||||
|
||||
resizeThumb = new ResizeThumb(); |
||||
AdornerPanel.SetPlacement(resizeThumb, new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Top)); |
||||
adornerPanel.Children.Add(resizeThumb); |
||||
|
||||
resizeThumb = new ResizeThumb(); |
||||
AdornerPanel.SetPlacement(resizeThumb, new RelativePlacement(HorizontalAlignment.Right, VerticalAlignment.Top)); |
||||
adornerPanel.Children.Add(resizeThumb); |
||||
|
||||
resizeThumb = new ResizeThumb(); |
||||
AdornerPanel.SetPlacement(resizeThumb, new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Bottom)); |
||||
adornerPanel.Children.Add(resizeThumb); |
||||
|
||||
resizeThumb = new ResizeThumb(); |
||||
AdornerPanel.SetPlacement(resizeThumb, new RelativePlacement(HorizontalAlignment.Right, VerticalAlignment.Bottom)); |
||||
adornerPanel.Children.Add(resizeThumb); |
||||
} |
||||
|
||||
/// <summary/>
|
||||
protected override void OnInitialized() |
||||
{ |
||||
base.OnInitialized(); |
||||
this.ExtendedItem.PropertyChanged += OnPropertyChanged; |
||||
this.Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged; |
||||
UpdateAdornerVisibility(); |
||||
OnPrimarySelectionChanged(null, null); |
||||
} |
||||
|
||||
/// <summary/>
|
||||
protected override void OnRemove() |
||||
{ |
||||
this.ExtendedItem.PropertyChanged -= OnPropertyChanged; |
||||
this.Services.Selection.PrimarySelectionChanged -= OnPrimarySelectionChanged; |
||||
base.OnRemove(); |
||||
} |
||||
|
||||
void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) |
||||
{ |
||||
if (e.PropertyName == "Width" || e.PropertyName == "Height") { |
||||
UpdateAdornerVisibility(); |
||||
} |
||||
} |
||||
|
||||
void OnPrimarySelectionChanged(object sender, EventArgs e) |
||||
{ |
||||
bool isPrimarySelection = this.Services.Selection.PrimarySelection == this.ExtendedItem; |
||||
foreach (ResizeThumb g in adornerPanel.Children) { |
||||
g.IsPrimarySelection = isPrimarySelection; |
||||
} |
||||
} |
||||
|
||||
void UpdateAdornerVisibility() |
||||
{ |
||||
FrameworkElement element = (FrameworkElement)this.ExtendedItem.Component; |
||||
if (double.IsNaN(element.Width) && double.IsNaN(element.Height)) { |
||||
if (this.Adorners.Count == 1) { |
||||
this.Adorners.Clear(); |
||||
} |
||||
} else { |
||||
if (this.Adorners.Count == 0) { |
||||
this.Adorners.Add(adornerPanel); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using ICSharpCode.WpfDesign.Adorners; |
||||
using System.Windows; |
||||
|
||||
namespace ICSharpCode.WpfDesign |
||||
{ |
||||
/// <summary>
|
||||
/// Behavior interface implemented by container elements to support resizing
|
||||
/// child elements.
|
||||
/// </summary>
|
||||
public interface IChildResizeSupport |
||||
{ |
||||
/// <summary>
|
||||
/// Gets if the child element can be resized.
|
||||
/// </summary>
|
||||
bool CanResizeChild(DesignItem child); |
||||
|
||||
/// <summary>
|
||||
/// Gets the placement for the drag frame adorner.
|
||||
/// </summary>
|
||||
/// <param name="child">The child being dragged</param>
|
||||
/// <param name="horizontalChange">The horizontal change - positive=make larger, negative=make smaller</param>
|
||||
/// <param name="verticalChange">The vertical change - positive=make larger, negative=make smaller</param>
|
||||
/// <param name="horizontal">The orientation of the resize thumb used. This parameter may be used to determine on which side of the element the element grows/shrinks.</param>
|
||||
/// <param name="vertical">The orientation of the resize thumb used. This parameter may be used to determine on which side of the element the element grows/shrinks.</param>
|
||||
/// <returns>A placement describing the new location of the child being resized.</returns>
|
||||
Placement GetPlacement(DesignItem child, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical); |
||||
|
||||
/// <summary>
|
||||
/// Resizes the child.
|
||||
/// </summary>
|
||||
/// <param name="child">The child being dragged</param>
|
||||
/// <param name="horizontalChange">The horizontal change - positive=make larger, negative=make smaller</param>
|
||||
/// <param name="verticalChange">The vertical change - positive=make larger, negative=make smaller</param>
|
||||
/// <param name="horizontal">The orientation of the resize thumb used. This parameter may be used to determine on which side of the element the element grows/shrinks.</param>
|
||||
/// <param name="vertical">The orientation of the resize thumb used. This parameter may be used to determine on which side of the element the element grows/shrinks.</param>
|
||||
/// <returns>A placement describing the new location of the child being resized.</returns>
|
||||
void Resize(DesignItem child, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical); |
||||
} |
||||
} |
Loading…
Reference in new issue