Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2227 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
20 changed files with 1077 additions and 125 deletions
@ -0,0 +1,191 @@
@@ -0,0 +1,191 @@
|
||||
// <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.Diagnostics; |
||||
using System.Collections.Generic; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Media; |
||||
using ICSharpCode.WpfDesign.Adorners; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
||||
{ |
||||
/// <summary>
|
||||
/// A control that displays adorner panels.
|
||||
/// </summary>
|
||||
sealed class AdornerLayer : Panel |
||||
{ |
||||
#region AdornerPanelCollection
|
||||
internal sealed class AdornerPanelCollection : ICollection<AdornerPanel> |
||||
{ |
||||
readonly AdornerLayer _layer; |
||||
|
||||
public AdornerPanelCollection(AdornerLayer layer) |
||||
{ |
||||
this._layer = layer; |
||||
} |
||||
|
||||
public int Count { |
||||
get { return _layer.Children.Count; } |
||||
} |
||||
|
||||
public bool IsReadOnly { |
||||
get { return false; } |
||||
} |
||||
|
||||
public void Add(AdornerPanel item) |
||||
{ |
||||
if (item == null) |
||||
throw new ArgumentNullException("item"); |
||||
|
||||
_layer.AddAdorner(item); |
||||
} |
||||
|
||||
public void Clear() |
||||
{ |
||||
_layer.ClearAdorners(); |
||||
} |
||||
|
||||
public bool Contains(AdornerPanel item) |
||||
{ |
||||
if (item == null) |
||||
throw new ArgumentNullException("item"); |
||||
|
||||
return VisualTreeHelper.GetParent(item) == _layer; |
||||
} |
||||
|
||||
public void CopyTo(AdornerPanel[] array, int arrayIndex) |
||||
{ |
||||
Linq.ToArray(this).CopyTo(array, arrayIndex); |
||||
} |
||||
|
||||
public bool Remove(AdornerPanel item) |
||||
{ |
||||
if (item == null) |
||||
throw new ArgumentNullException("item"); |
||||
|
||||
return _layer.RemoveAdorner(item); |
||||
} |
||||
|
||||
public IEnumerator<AdornerPanel> GetEnumerator() |
||||
{ |
||||
foreach (AdornerPanel panel in _layer.Children) { |
||||
yield return panel; |
||||
} |
||||
} |
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() |
||||
{ |
||||
return this.GetEnumerator(); |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
AdornerPanelCollection _adorners; |
||||
readonly UIElement _designPanel; |
||||
|
||||
internal AdornerLayer(UIElement designPanel) |
||||
{ |
||||
this._designPanel = designPanel; |
||||
|
||||
_adorners = new AdornerPanelCollection(this); |
||||
ClearAdorners(); |
||||
} |
||||
|
||||
internal AdornerPanelCollection Adorners { |
||||
get { |
||||
return _adorners; |
||||
} |
||||
} |
||||
|
||||
sealed class AdornerInfo |
||||
{ |
||||
internal readonly List<AdornerPanel> adorners = new List<AdornerPanel>(); |
||||
} |
||||
|
||||
// adorned element => AdornerInfo
|
||||
Dictionary<UIElement, AdornerInfo> _dict; |
||||
|
||||
void ClearAdorners() |
||||
{ |
||||
this.Children.Clear(); |
||||
_dict = new Dictionary<UIElement, AdornerInfo>(); |
||||
} |
||||
|
||||
AdornerInfo GetAdornerInfo(UIElement adornedElement) |
||||
{ |
||||
AdornerInfo info; |
||||
if (!_dict.TryGetValue(adornedElement, out info)) { |
||||
info = _dict[adornedElement] = new AdornerInfo(); |
||||
} |
||||
return info; |
||||
} |
||||
|
||||
AdornerInfo GetExistingAdornerInfo(UIElement adornedElement) |
||||
{ |
||||
AdornerInfo info; |
||||
_dict.TryGetValue(adornedElement, out info); |
||||
return info; |
||||
} |
||||
|
||||
void AddAdorner(AdornerPanel adornerPanel) |
||||
{ |
||||
if (adornerPanel.AdornedElement == null) |
||||
throw new DesignerException("adornerPanel.AdornedElement must be set"); |
||||
|
||||
GetAdornerInfo(adornerPanel.AdornedElement).adorners.Add(adornerPanel); |
||||
|
||||
UIElementCollection children = this.Children; |
||||
int i = 0; |
||||
for (i = 0; i < children.Count; i++) { |
||||
AdornerPanel p = (AdornerPanel)children[i]; |
||||
if (p.Order.CompareTo(adornerPanel.Order) > 0) { |
||||
break; |
||||
} |
||||
} |
||||
children.Insert(i, adornerPanel); |
||||
|
||||
this.InvalidateMeasure(); |
||||
} |
||||
|
||||
protected override Size MeasureOverride(Size availableSize) |
||||
{ |
||||
Size infiniteSize = new Size(double.PositiveInfinity, double.PositiveInfinity); |
||||
foreach (AdornerPanel adorner in this.Children) { |
||||
adorner.Measure(infiniteSize); |
||||
} |
||||
return new Size(0, 0); |
||||
} |
||||
|
||||
protected override Size ArrangeOverride(Size finalSize) |
||||
{ |
||||
foreach (AdornerPanel adorner in this.Children) { |
||||
adorner.Arrange(new Rect(new Point(0, 0), adorner.DesiredSize)); |
||||
adorner.RenderTransform = (Transform)adorner.AdornedElement.TransformToAncestor(_designPanel); |
||||
} |
||||
return finalSize; |
||||
} |
||||
|
||||
bool RemoveAdorner(AdornerPanel adornerPanel) |
||||
{ |
||||
if (adornerPanel.AdornedElement == null) |
||||
return false; |
||||
|
||||
AdornerInfo info = GetExistingAdornerInfo(adornerPanel.AdornedElement); |
||||
if (info == null) |
||||
return false; |
||||
|
||||
if (info.adorners.Remove(adornerPanel)) { |
||||
this.Children.Remove(adornerPanel); |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,43 @@
@@ -0,0 +1,43 @@
|
||||
// <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.Windows.Media; |
||||
using System.Windows.Shapes; |
||||
using ICSharpCode.WpfDesign.Adorners; |
||||
using ICSharpCode.WpfDesign.Extensions; |
||||
using ICSharpCode.WpfDesign.Designer.Controls; |
||||
using System.Windows; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
||||
{ |
||||
/// <summary>
|
||||
/// Draws a dotted line around selected UIElements.
|
||||
/// </summary>
|
||||
[ExtensionFor(typeof(UIElement))] |
||||
public class SelectedElementRectangleExtension : SelectionAdornerProvider |
||||
{ |
||||
/// <summary>
|
||||
/// Creates a new SelectedElementRectangleExtension instance.
|
||||
/// </summary>
|
||||
public SelectedElementRectangleExtension() |
||||
{ |
||||
Rectangle r = new Rectangle(); |
||||
r.SnapsToDevicePixels = true; |
||||
r.Stroke = Brushes.Black; |
||||
r.StrokeDashCap = PenLineCap.Square; |
||||
r.StrokeDashArray = new DoubleCollection(new double[] { 0, 2 }); |
||||
r.IsHitTestVisible = false; |
||||
|
||||
Placement placement = new Placement(); |
||||
placement.WidthRelativeToContentWidth = 1; |
||||
placement.HeightRelativeToContentHeight = 1; |
||||
|
||||
this.AddAdorner(r, placement); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,117 @@
@@ -0,0 +1,117 @@
|
||||
// <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.Media; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Adorners |
||||
{ |
||||
/// <summary>
|
||||
/// Manages display of adorners on the design surface.
|
||||
/// </summary>
|
||||
public sealed class AdornerPanel : Panel |
||||
{ |
||||
#region Attached Property Placement
|
||||
/// <summary>
|
||||
/// The dependency property used to store the placement of adorner visuals.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty PlacementProperty = DependencyProperty.RegisterAttached( |
||||
"Placement", typeof(Placement), typeof(AdornerPanel), |
||||
new FrameworkPropertyMetadata(new Placement(), FrameworkPropertyMetadataOptions.AffectsParentMeasure) |
||||
); |
||||
|
||||
/// <summary>
|
||||
/// Gets the placement of the specified adorner visual.
|
||||
/// </summary>
|
||||
public static Placement GetPlacement(Visual visual) |
||||
{ |
||||
if (visual == null) |
||||
throw new ArgumentNullException("visual"); |
||||
return (Placement)visual.GetValue(PlacementProperty); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Sets the placement of the specified adorner visual.
|
||||
/// </summary>
|
||||
public static void SetPlacement(Visual visual, Placement placement) |
||||
{ |
||||
if (visual == null) |
||||
throw new ArgumentNullException("visual"); |
||||
if (placement == null) |
||||
throw new ArgumentNullException("placement"); |
||||
visual.SetValue(PlacementProperty, placement); |
||||
} |
||||
#endregion
|
||||
|
||||
UIElement _adornedElement; |
||||
AdornerOrder _Order = AdornerOrder.Content; |
||||
|
||||
public UIElement AdornedElement { |
||||
get { return _adornedElement; } |
||||
set { _adornedElement = value; } |
||||
} |
||||
|
||||
public AdornerOrder Order { |
||||
get { return _Order; } |
||||
set { _Order = value; } |
||||
} |
||||
|
||||
protected override Size MeasureOverride(Size availableSize) |
||||
{ |
||||
if (this.AdornedElement != null) { |
||||
foreach (DependencyObject v in this.VisualChildren) { |
||||
UIElement e = v as UIElement; |
||||
if (e != null) { |
||||
e.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); |
||||
} |
||||
} |
||||
return this.AdornedElement.RenderSize; |
||||
} else { |
||||
return base.MeasureOverride(availableSize); |
||||
} |
||||
} |
||||
|
||||
protected override Size ArrangeOverride(Size finalSize) |
||||
{ |
||||
foreach (UIElement element in base.InternalChildren) { |
||||
element.Arrange(new Rect(finalSize)); |
||||
} |
||||
return finalSize; |
||||
} |
||||
|
||||
private IEnumerable<DependencyObject> VisualChildren { |
||||
get { |
||||
int count = VisualTreeHelper.GetChildrenCount(this); |
||||
for (int i = 0; i < count; i++) { |
||||
yield return VisualTreeHelper.GetChild(this, i); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public struct AdornerOrder : IComparable<AdornerOrder> |
||||
{ |
||||
public static readonly AdornerOrder Background = new AdornerOrder(100); |
||||
public static readonly AdornerOrder Content = new AdornerOrder(200); |
||||
public static readonly AdornerOrder Foreground = new AdornerOrder(300); |
||||
|
||||
int i; |
||||
|
||||
public AdornerOrder(int i) |
||||
{ |
||||
this.i = i; |
||||
} |
||||
|
||||
public int CompareTo(AdornerOrder other) |
||||
{ |
||||
return i.CompareTo(other.i); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,145 @@
@@ -0,0 +1,145 @@
|
||||
// <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.ObjectModel; |
||||
using System.Windows; |
||||
using System.Windows.Media; |
||||
using ICSharpCode.WpfDesign.Extensions; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Adorners |
||||
{ |
||||
/// <summary>
|
||||
/// Base class for extensions that present adorners on the screen.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// About design-time adorners and their placement:
|
||||
/// read http://myfun.spaces.live.com/blog/cns!AC1291870308F748!240.entry
|
||||
/// and http://myfun.spaces.live.com/blog/cns!AC1291870308F748!242.entry
|
||||
/// </remarks>
|
||||
public abstract class AdornerProvider : DefaultExtension |
||||
{ |
||||
#region class AdornerCollection
|
||||
/// <summary>
|
||||
/// Describes a collection of adorner visuals.
|
||||
/// </summary>
|
||||
sealed class AdornerPanelCollection : Collection<AdornerPanel> |
||||
{ |
||||
readonly AdornerProvider _provider; |
||||
|
||||
internal AdornerPanelCollection(AdornerProvider provider) |
||||
{ |
||||
this._provider = provider; |
||||
} |
||||
|
||||
/// <summary/>
|
||||
protected override void InsertItem(int index, AdornerPanel item) |
||||
{ |
||||
base.InsertItem(index, item); |
||||
_provider.OnAdornerAdd(item); |
||||
} |
||||
|
||||
/// <summary/>
|
||||
protected override void RemoveItem(int index) |
||||
{ |
||||
_provider.OnAdornerRemove(base[index]); |
||||
base.RemoveItem(index); |
||||
} |
||||
|
||||
/// <summary/>
|
||||
protected override void SetItem(int index, AdornerPanel item) |
||||
{ |
||||
_provider.OnAdornerRemove(base[index]); |
||||
base.SetItem(index, item); |
||||
_provider.OnAdornerAdd(item); |
||||
} |
||||
|
||||
/// <summary/>
|
||||
protected override void ClearItems() |
||||
{ |
||||
foreach (AdornerPanel v in this) { |
||||
_provider.OnAdornerRemove(v); |
||||
} |
||||
base.ClearItems(); |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
AdornerPanelCollection _adorners; |
||||
bool isVisible; |
||||
|
||||
/// <summary>
|
||||
/// Creates a new AdornerProvider instance.
|
||||
/// </summary>
|
||||
public AdornerProvider() |
||||
{ |
||||
_adorners = new AdornerPanelCollection(this); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Is called after the ExtendedItem was set.
|
||||
/// This methods displays the registered adorners
|
||||
/// </summary>
|
||||
protected override void OnInitialized() |
||||
{ |
||||
base.OnInitialized(); |
||||
isVisible = true; |
||||
foreach (AdornerPanel v in _adorners) { |
||||
OnAdornerAdd(v); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Is called when the extension is removed.
|
||||
/// This method hides the registered adorners.
|
||||
/// </summary>
|
||||
protected override void OnRemove() |
||||
{ |
||||
base.OnRemove(); |
||||
foreach (AdornerPanel v in _adorners) { |
||||
OnAdornerRemove(v); |
||||
} |
||||
isVisible = false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the list of adorners displayed by this AdornerProvider.
|
||||
/// </summary>
|
||||
public Collection<AdornerPanel> Adorners { |
||||
get { return _adorners; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds an UIElement as adorner with the specified placement.
|
||||
/// </summary>
|
||||
protected void AddAdorner(UIElement adorner, Placement placement) |
||||
{ |
||||
AdornerPanel.SetPlacement(adorner, placement); |
||||
AdornerPanel p = new AdornerPanel(); |
||||
p.Children.Add(adorner); |
||||
this.Adorners.Add(p); |
||||
} |
||||
|
||||
internal void OnAdornerAdd(AdornerPanel item) |
||||
{ |
||||
if (!isVisible) return; |
||||
|
||||
item.AdornedElement = this.ExtendedItem.View; |
||||
|
||||
IDesignPanel avs = Services.GetService<IDesignPanel>(); |
||||
avs.Adorners.Add(item); |
||||
} |
||||
|
||||
internal void OnAdornerRemove(AdornerPanel item) |
||||
{ |
||||
if (!isVisible) return; |
||||
|
||||
IDesignPanel avs = Services.GetService<IDesignPanel>(); |
||||
avs.Adorners.Remove(item); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
// <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; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Adorners |
||||
{ |
||||
// Some classes that derive from AdornerProvider to specify a certain ExtensionServer.
|
||||
|
||||
/// <summary>
|
||||
/// An adorner extension that is attached permanently.
|
||||
/// </summary>
|
||||
[ExtensionServer(typeof(DefaultExtensionServer.Permanent))] |
||||
public abstract class PermanentAdornerProvider : AdornerProvider |
||||
{ |
||||
|
||||
} |
||||
|
||||
/// <summary>
|
||||
/// An adorner extension that is attached to selected components.
|
||||
/// </summary>
|
||||
[ExtensionServer(typeof(SelectionExtensionServer))] |
||||
public abstract class SelectionAdornerProvider : AdornerProvider |
||||
{ |
||||
|
||||
} |
||||
|
||||
/// <summary>
|
||||
/// An adorner extension that is attached to the primary selection.
|
||||
/// </summary>
|
||||
[ExtensionServer(typeof(PrimarySelectionExtensionServer))] |
||||
public abstract class PrimarySelectionAdornerProvider : AdornerProvider |
||||
{ |
||||
|
||||
} |
||||
|
||||
/// <summary>
|
||||
/// An adorner extension that is attached to the secondary selection.
|
||||
/// </summary>
|
||||
[ExtensionServer(typeof(SecondarySelectionExtensionServer))] |
||||
public abstract class SecondarySelectionAdornerProvider : AdornerProvider |
||||
{ |
||||
|
||||
} |
||||
} |
@ -0,0 +1,150 @@
@@ -0,0 +1,150 @@
|
||||
// <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.ObjectModel; |
||||
using System.Windows; |
||||
using System.Windows.Media; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Adorners |
||||
{ |
||||
// We have to support the different coordinate spaces as explained in
|
||||
// http://myfun.spaces.live.com/blog/cns!AC1291870308F748!242.entry
|
||||
|
||||
/// <summary>
|
||||
/// Defines how a design-time adorner is placed.
|
||||
/// </summary>
|
||||
public class Placement |
||||
{ |
||||
PlacementSpace space = PlacementSpace.Render; |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the space in which the adorner is placed.
|
||||
/// </summary>
|
||||
public PlacementSpace Space { |
||||
get { return space; } |
||||
set { space = value; } |
||||
} |
||||
|
||||
double widthRelativeToDesiredWidth, heightRelativeToDesiredHeight; |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the width of the adorner relative to the desired adorner width.
|
||||
/// </summary>
|
||||
public double WidthRelativeToDesiredWidth { |
||||
get { return widthRelativeToDesiredWidth; } |
||||
set { widthRelativeToDesiredWidth = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the height of the adorner relative to the desired adorner height.
|
||||
/// </summary>
|
||||
public double HeightRelativeToDesiredHeight { |
||||
get { return heightRelativeToDesiredHeight; } |
||||
set { heightRelativeToDesiredHeight = value; } |
||||
} |
||||
|
||||
double widthRelativeToContentWidth, heightRelativeToContentHeight; |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the width of the adorner relative to the width of the adorned item.
|
||||
/// </summary>
|
||||
public double WidthRelativeToContentWidth { |
||||
get { return widthRelativeToContentWidth; } |
||||
set { widthRelativeToContentWidth = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the height of the adorner relative to the height of the adorned item.
|
||||
/// </summary>
|
||||
public double HeightRelativeToContentHeight { |
||||
get { return heightRelativeToContentHeight; } |
||||
set { heightRelativeToContentHeight = value; } |
||||
} |
||||
|
||||
double widthOffset, heightOffset; |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets an offset that is added to the adorner width for the size calculation.
|
||||
/// </summary>
|
||||
public double WidthOffset { |
||||
get { return widthOffset; } |
||||
set { widthOffset = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets an offset that is added to the adorner height for the size calculation.
|
||||
/// </summary>
|
||||
public double HeightOffset { |
||||
get { return heightOffset; } |
||||
set { heightOffset = value; } |
||||
} |
||||
|
||||
Size CalculateSize(Visual adornerVisual, UIElement adornedElement) |
||||
{ |
||||
Size size = new Size(widthOffset, heightOffset); |
||||
if (widthRelativeToDesiredWidth != 0 || heightRelativeToDesiredHeight != 0) { |
||||
UIElement adornerElement = adornerVisual as UIElement; |
||||
if (adornerElement == null) { |
||||
throw new DesignerException("Cannot calculate the size relative to the adorner's desired size if the adorner is not an UIElement."); |
||||
} |
||||
size.Width += widthRelativeToDesiredWidth * adornerElement.DesiredSize.Width; |
||||
size.Height += heightRelativeToDesiredHeight * adornerElement.DesiredSize.Height; |
||||
} |
||||
size.Width += widthRelativeToContentWidth * adornedElement.RenderSize.Width; |
||||
size.Height += heightRelativeToContentHeight * adornedElement.RenderSize.Height; |
||||
return size; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Describes the space in which an adorner is placed.
|
||||
/// </summary>
|
||||
public enum PlacementSpace |
||||
{ |
||||
/// <summary>
|
||||
/// The adorner is affected by the render transform of the adorned element.
|
||||
/// </summary>
|
||||
Render, |
||||
/// <summary>
|
||||
/// The adorner is affected by the layout transform of the adorned element.
|
||||
/// </summary>
|
||||
Layout, |
||||
/// <summary>
|
||||
/// The adorner is not affected by transforms of designed controls.
|
||||
/// </summary>
|
||||
Designer |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// The possible layers where adorners can be placed.
|
||||
/// </summary>
|
||||
public enum AdornerZLayer |
||||
{ |
||||
/// <summary>
|
||||
/// This layer is below the other adorner layers.
|
||||
/// </summary>
|
||||
Low, |
||||
/// <summary>
|
||||
/// This layer is for normal background adorners.
|
||||
/// </summary>
|
||||
Normal, |
||||
/// <summary>
|
||||
/// This layer is for selection adorners
|
||||
/// </summary>
|
||||
Selection, |
||||
/// <summary>
|
||||
/// This layer is for primary selection adorners
|
||||
/// </summary>
|
||||
PrimarySelection, |
||||
/// <summary>
|
||||
/// This layer is above the other layers.
|
||||
/// It is used for temporary drawings, e.g. the selection frame while selecting multiple controls with the mouse.
|
||||
/// </summary>
|
||||
High |
||||
} |
||||
} |
@ -0,0 +1,114 @@
@@ -0,0 +1,114 @@
|
||||
// <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.Diagnostics; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Extensions |
||||
{ |
||||
/// <summary>
|
||||
/// Base class for extensions that have an parameter-less constructor and are initialized using the
|
||||
/// OnInitialize method.
|
||||
/// </summary>
|
||||
public class DefaultExtension : Extension |
||||
{ |
||||
DesignItem _extendedItem; |
||||
|
||||
/// <summary>
|
||||
/// Gets the item that is being extended by the BehaviorExtension.
|
||||
/// </summary>
|
||||
public DesignItem ExtendedItem { |
||||
get { |
||||
if (_extendedItem == null) |
||||
throw new InvalidOperationException("Cannot access BehaviorExtension.ExtendedItem: " + |
||||
"The property is not initialized yet. Please move initialization logic " + |
||||
"that depends on ExtendedItem into the OnInitialized method."); |
||||
return _extendedItem; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the design context of the extended item. "Context" is equivalent to "ExtendedItem.Context".
|
||||
/// </summary>
|
||||
public DesignContext Context { |
||||
get { |
||||
return this.ExtendedItem.Context; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the service container of the extended item. "Services" is equivalent to "ExtendedItem.Services".
|
||||
/// </summary>
|
||||
public ServiceContainer Services { |
||||
get { |
||||
return this.ExtendedItem.Services; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Is called after the ExtendedItem was set.
|
||||
/// Override this method to register your behavior with the item.
|
||||
/// </summary>
|
||||
protected virtual void OnInitialized() |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Is called when the extension is removed.
|
||||
/// </summary>
|
||||
protected virtual void OnRemove() |
||||
{ |
||||
} |
||||
|
||||
internal void CallOnRemove() { OnRemove(); } |
||||
|
||||
internal void InitializeDefaultExtension(DesignItem extendedItem) |
||||
{ |
||||
Debug.Assert(this._extendedItem == null); |
||||
Debug.Assert(extendedItem != null); |
||||
|
||||
this._extendedItem = extendedItem; |
||||
OnInitialized(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Base class for extension servers that create extensions that derive from <see cref="DefaultExtension"/>.
|
||||
/// </summary>
|
||||
public abstract class DefaultExtensionServer : ExtensionServer |
||||
{ |
||||
/// <summary>
|
||||
/// Creates an instance of the DefaultExtension and calls OnInitialize on it.
|
||||
/// </summary>
|
||||
public override Extension CreateExtension(Type extensionType, DesignItem extendedItem) |
||||
{ |
||||
DefaultExtension ext = (DefaultExtension)Activator.CreateInstance(extensionType); |
||||
ext.InitializeDefaultExtension(extendedItem); |
||||
return ext; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Calls OnRemove() on the DefaultExtension.
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")] |
||||
public override void RemoveExtension(Extension extension) |
||||
{ |
||||
Debug.Assert(extension != null); |
||||
Debug.Assert(extension is DefaultExtension); |
||||
|
||||
((DefaultExtension)extension).CallOnRemove(); |
||||
} |
||||
|
||||
internal sealed class Permanent : DefaultExtensionServer |
||||
{ |
||||
public override bool ShouldApplyExtensions(DesignItem extendedItem) |
||||
{ |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,93 @@
@@ -0,0 +1,93 @@
|
||||
// <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; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Extensions |
||||
{ |
||||
/// <summary>
|
||||
/// Applies an extension to the selected components.
|
||||
/// </summary>
|
||||
public class SelectionExtensionServer : DefaultExtensionServer |
||||
{ |
||||
/// <summary>
|
||||
/// Is called after the extension server is initialized and the Context property has been set.
|
||||
/// </summary>
|
||||
protected override void OnInitialized() |
||||
{ |
||||
base.OnInitialized(); |
||||
Services.Selection.SelectionChanged += OnSelectionChanged; |
||||
} |
||||
|
||||
void OnSelectionChanged(object sender, DesignItemCollectionEventArgs e) |
||||
{ |
||||
Services.ExtensionManager.ReapplyExtensions(e.Items, this); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if the item is selected.
|
||||
/// </summary>
|
||||
public override bool ShouldApplyExtensions(DesignItem extendedItem) |
||||
{ |
||||
return Services.Selection.IsComponentSelected(extendedItem); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Applies an extension to the selected components, but not to the primary selection.
|
||||
/// </summary>
|
||||
public class SecondarySelectionExtensionServer : SelectionExtensionServer |
||||
{ |
||||
/// <summary>
|
||||
/// Gets if the item is in the secondary selection.
|
||||
/// </summary>
|
||||
public override bool ShouldApplyExtensions(DesignItem extendedItem) |
||||
{ |
||||
return base.ShouldApplyExtensions(extendedItem) && Services.Selection.PrimarySelection != extendedItem; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Applies an extension to the primary selection.
|
||||
/// </summary>
|
||||
public class PrimarySelectionExtensionServer : DefaultExtensionServer |
||||
{ |
||||
DesignItem oldPrimarySelection; |
||||
|
||||
/// <summary>
|
||||
/// Is called after the extension server is initialized and the Context property has been set.
|
||||
/// </summary>
|
||||
protected override void OnInitialized() |
||||
{ |
||||
base.OnInitialized(); |
||||
this.Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged; |
||||
} |
||||
|
||||
void OnPrimarySelectionChanged(object sender, EventArgs e) |
||||
{ |
||||
DesignItem newPrimarySelection = this.Services.Selection.PrimarySelection; |
||||
if (oldPrimarySelection != newPrimarySelection) { |
||||
if (oldPrimarySelection == null) { |
||||
this.Services.ExtensionManager.ReapplyExtensions(new DesignItem[] { newPrimarySelection }, this); |
||||
} else if (newPrimarySelection == null) { |
||||
this.Services.ExtensionManager.ReapplyExtensions(new DesignItem[] { oldPrimarySelection }, this); |
||||
} else { |
||||
this.Services.ExtensionManager.ReapplyExtensions(new DesignItem[] { oldPrimarySelection, newPrimarySelection }, this); |
||||
} |
||||
oldPrimarySelection = newPrimarySelection; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if the item is the primary selection.
|
||||
/// </summary>
|
||||
public override bool ShouldApplyExtensions(DesignItem extendedItem) |
||||
{ |
||||
return Services.Selection.PrimarySelection == extendedItem; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue