Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2237 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
31 changed files with 1204 additions and 78 deletions
@ -0,0 +1,33 @@ |
|||||||
|
// <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.Controls; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Media; |
||||||
|
using System.Windows.Shapes; |
||||||
|
using System.Windows.Controls.Primitives; |
||||||
|
using ICSharpCode.WpfDesign.Adorners; |
||||||
|
using ICSharpCode.WpfDesign.Extensions; |
||||||
|
using ICSharpCode.WpfDesign.Designer.Controls; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign.Designer.Controls |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// A thumb where the look can depend on the IsPrimarySelection property.
|
||||||
|
/// Used by UIElementSelectionRectangle.
|
||||||
|
/// </summary>
|
||||||
|
public class ContainerDragHandle : Control |
||||||
|
{ |
||||||
|
static ContainerDragHandle() |
||||||
|
{ |
||||||
|
//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(ContainerDragHandle), new FrameworkPropertyMetadata(typeof(ContainerDragHandle))); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
// <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; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign.Designer.Controls |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// A thumb where the look can depend on the IsPrimarySelection property.
|
||||||
|
/// Used by UIElementSelectionRectangle.
|
||||||
|
/// </summary>
|
||||||
|
public class ResizeThumb : Thumb |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Dependency property for <see cref="IsPrimarySelection"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty IsPrimarySelectionProperty |
||||||
|
= DependencyProperty.Register("IsPrimarySelection", typeof(bool), typeof(ResizeThumb)); |
||||||
|
|
||||||
|
static ResizeThumb() |
||||||
|
{ |
||||||
|
//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(ResizeThumb), new FrameworkPropertyMetadata(typeof(ResizeThumb))); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets/Sets if the resize thumb is attached to the primary selection.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsPrimarySelection { |
||||||
|
get { return (bool)GetValue(IsPrimarySelectionProperty); } |
||||||
|
set { SetValue(IsPrimarySelectionProperty, value); } |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
// <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.Controls; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Media; |
||||||
|
using System.Windows.Shapes; |
||||||
|
using ICSharpCode.WpfDesign.Adorners; |
||||||
|
using ICSharpCode.WpfDesign.Extensions; |
||||||
|
using ICSharpCode.WpfDesign.Designer.Controls; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign.Designer.Extensions |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// The drag handle displayed for panels.
|
||||||
|
/// </summary>
|
||||||
|
[ExtensionServer(typeof(PrimarySelectionExtensionServer))] |
||||||
|
[ExtensionFor(typeof(Panel), OverrideExtension = typeof(TopLeftResizeThumb))] |
||||||
|
public class TopLeftContainerDragHandle : AdornerProvider |
||||||
|
{ |
||||||
|
/// <summary/>
|
||||||
|
public TopLeftContainerDragHandle() |
||||||
|
{ |
||||||
|
ContainerDragHandle rect = new ContainerDragHandle(); |
||||||
|
|
||||||
|
rect.PreviewMouseDown += delegate { |
||||||
|
Services.Selection.SetSelectedComponents(new DesignItem[] { this.ExtendedItem }, SelectionTypes.Auto); |
||||||
|
}; |
||||||
|
|
||||||
|
RelativePlacement p = new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Top); |
||||||
|
p.XOffset = -1; |
||||||
|
p.YOffset = -1; |
||||||
|
|
||||||
|
AddAdorner(p, AdornerOrder.Background, rect); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
// <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 class TopLeftResizeThumb : PrimarySelectionAdornerProvider |
||||||
|
{ |
||||||
|
/// <summary></summary>
|
||||||
|
public TopLeftResizeThumb() |
||||||
|
{ |
||||||
|
ResizeThumb resizeThumb = new ResizeThumb(); |
||||||
|
|
||||||
|
RelativePlacement p = new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Top); |
||||||
|
AddAdorner(p, AdornerOrder.Foreground, resizeThumb); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,247 @@ |
|||||||
|
// <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.Diagnostics; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign.Designer.Services |
||||||
|
{ |
||||||
|
#region ITransactionItem
|
||||||
|
interface ITransactionItem |
||||||
|
{ |
||||||
|
void Do(); |
||||||
|
void Undo(); |
||||||
|
|
||||||
|
string Title { get; set; } |
||||||
|
} |
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region UndoTransaction
|
||||||
|
/// <summary>
|
||||||
|
/// Supports ChangeGroup transactions and undo behavior.
|
||||||
|
/// </summary>
|
||||||
|
sealed class UndoTransaction : ChangeGroup, ITransactionItem |
||||||
|
{ |
||||||
|
public enum TransactionState |
||||||
|
{ |
||||||
|
Open, |
||||||
|
Completed, |
||||||
|
Undone, |
||||||
|
Failed |
||||||
|
} |
||||||
|
|
||||||
|
TransactionState _state; |
||||||
|
|
||||||
|
public TransactionState State |
||||||
|
{ |
||||||
|
get { return _state; } |
||||||
|
} |
||||||
|
|
||||||
|
List<ITransactionItem> items = new List<ITransactionItem>(); |
||||||
|
|
||||||
|
public void Execute(ITransactionItem item) |
||||||
|
{ |
||||||
|
AssertState(TransactionState.Open); |
||||||
|
item.Do(); |
||||||
|
items.Add(item); |
||||||
|
} |
||||||
|
|
||||||
|
private void AssertState(TransactionState expectedState) |
||||||
|
{ |
||||||
|
if (_state != expectedState) |
||||||
|
throw new InvalidOperationException("Expected state " + expectedState + ", but state is " + _state); |
||||||
|
} |
||||||
|
|
||||||
|
public event EventHandler Committed; |
||||||
|
public event EventHandler RolledBack; |
||||||
|
|
||||||
|
public override void Commit() |
||||||
|
{ |
||||||
|
AssertState(TransactionState.Open); |
||||||
|
_state = TransactionState.Completed; |
||||||
|
if (Committed != null) |
||||||
|
Committed(this, EventArgs.Empty); |
||||||
|
} |
||||||
|
|
||||||
|
public override void Abort() |
||||||
|
{ |
||||||
|
AssertState(TransactionState.Open); |
||||||
|
_state = TransactionState.Failed; |
||||||
|
InternalRollback(); |
||||||
|
if (RolledBack != null) |
||||||
|
RolledBack(this, EventArgs.Empty); |
||||||
|
} |
||||||
|
|
||||||
|
public void Undo() |
||||||
|
{ |
||||||
|
AssertState(TransactionState.Completed); |
||||||
|
_state = TransactionState.Undone; |
||||||
|
InternalRollback(); |
||||||
|
} |
||||||
|
|
||||||
|
void InternalRollback() |
||||||
|
{ |
||||||
|
try { |
||||||
|
for (int i = items.Count - 1; i >= 0; i--) { |
||||||
|
items[i].Undo(); |
||||||
|
} |
||||||
|
} catch { |
||||||
|
_state = TransactionState.Failed; |
||||||
|
throw; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void Redo() |
||||||
|
{ |
||||||
|
AssertState(TransactionState.Undone); |
||||||
|
try { |
||||||
|
for (int i = 0; i < items.Count; i--) { |
||||||
|
items[i].Do(); |
||||||
|
} |
||||||
|
} catch { |
||||||
|
_state = TransactionState.Failed; |
||||||
|
try { |
||||||
|
InternalRollback(); |
||||||
|
} catch (Exception ex) { |
||||||
|
Debug.WriteLine("Exception rolling back after Redo error:\n" + ex.ToString()); |
||||||
|
} |
||||||
|
throw; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void ITransactionItem.Do() |
||||||
|
{ |
||||||
|
if (_state != TransactionState.Completed) { |
||||||
|
Redo(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected override void Disposed() |
||||||
|
{ |
||||||
|
if (_state == TransactionState.Open) { |
||||||
|
try { |
||||||
|
Abort(); |
||||||
|
} catch (Exception ex) { |
||||||
|
Debug.WriteLine("Exception rolling back after failure:\n" + ex.ToString()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region UndoService
|
||||||
|
/// <summary>
|
||||||
|
/// Service supporting Undo/Redo actions on the design surface.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class UndoService |
||||||
|
{ |
||||||
|
Stack<UndoTransaction> _transactionStack = new Stack<UndoTransaction>(); |
||||||
|
Stack<ITransactionItem> _undoStack = new Stack<ITransactionItem>(); |
||||||
|
Stack<ITransactionItem> _redoStack = new Stack<ITransactionItem>(); |
||||||
|
|
||||||
|
UndoTransaction CurrentTransaction { |
||||||
|
get { |
||||||
|
if (_transactionStack.Count == 0) |
||||||
|
return null; |
||||||
|
else |
||||||
|
return _transactionStack.Peek(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal UndoTransaction StartTransaction() |
||||||
|
{ |
||||||
|
UndoTransaction t = new UndoTransaction(); |
||||||
|
t.Committed += TransactionFinished; |
||||||
|
t.RolledBack += TransactionFinished; |
||||||
|
t.Committed += delegate(object sender, EventArgs e) { |
||||||
|
Execute((UndoTransaction)sender); |
||||||
|
}; |
||||||
|
return t; |
||||||
|
} |
||||||
|
|
||||||
|
void TransactionFinished(object sender, EventArgs e) |
||||||
|
{ |
||||||
|
if (sender != _transactionStack.Pop()) { |
||||||
|
throw new Exception("Invalid transaction finish, nested transactions must finish first"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal void Execute(ITransactionItem item) |
||||||
|
{ |
||||||
|
if (_transactionStack.Count == 0) { |
||||||
|
item.Do(); |
||||||
|
_undoStack.Push(item); |
||||||
|
_redoStack.Clear(); |
||||||
|
} else { |
||||||
|
_transactionStack.Peek().Execute(item); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets if undo actions are available.
|
||||||
|
/// </summary>
|
||||||
|
public bool CanUndo { |
||||||
|
get { return _undoStack.Count > 0; } |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Undoes the last action.
|
||||||
|
/// </summary>
|
||||||
|
public void Undo() |
||||||
|
{ |
||||||
|
if (!CanUndo) |
||||||
|
throw new InvalidOperationException("Cannot Undo: undo stack is empty"); |
||||||
|
if (_transactionStack.Count != 0) |
||||||
|
throw new InvalidOperationException("Cannot Undo while transaction is running"); |
||||||
|
ITransactionItem item = _undoStack.Pop(); |
||||||
|
try { |
||||||
|
item.Undo(); |
||||||
|
_redoStack.Push(item); |
||||||
|
} catch { |
||||||
|
// state might be invalid now, clear stacks to prevent getting more inconsistencies
|
||||||
|
Clear(); |
||||||
|
throw; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets if there are redo actions available.
|
||||||
|
/// </summary>
|
||||||
|
public bool CanRedo { get { return _redoStack.Count > 0; } } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Redoes a previously undone action.
|
||||||
|
/// </summary>
|
||||||
|
public void Redo() |
||||||
|
{ |
||||||
|
if (!CanRedo) |
||||||
|
throw new InvalidOperationException("Cannot Redo: redo stack is empty"); |
||||||
|
if (_transactionStack.Count != 0) |
||||||
|
throw new InvalidOperationException("Cannot Redo while transaction is running"); |
||||||
|
ITransactionItem item = _redoStack.Pop(); |
||||||
|
try { |
||||||
|
item.Do(); |
||||||
|
_undoStack.Push(item); |
||||||
|
} catch { |
||||||
|
// state might be invalid now, clear stacks to prevent getting more inconsistencies
|
||||||
|
Clear(); |
||||||
|
throw; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears saved actions (both undo and redo stack).
|
||||||
|
/// </summary>
|
||||||
|
public void Clear() |
||||||
|
{ |
||||||
|
_undoStack.Clear(); |
||||||
|
_redoStack.Clear(); |
||||||
|
} |
||||||
|
} |
||||||
|
#endregion
|
||||||
|
} |
@ -0,0 +1,85 @@ |
|||||||
|
// <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.XamlDom; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign.Designer.Xaml |
||||||
|
{ |
||||||
|
sealed class XamlModelProperty : DesignItemProperty |
||||||
|
{ |
||||||
|
readonly XamlDesignItem _designItem; |
||||||
|
readonly XamlProperty _property; |
||||||
|
|
||||||
|
public XamlModelProperty(XamlDesignItem designItem, XamlProperty property) |
||||||
|
{ |
||||||
|
this._designItem = designItem; |
||||||
|
this._property = property; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool IsCollection { |
||||||
|
get { |
||||||
|
return _property.IsCollection; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override System.Collections.Generic.IList<DesignItem> CollectionElements { |
||||||
|
get { |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override DesignItem Value { |
||||||
|
get { |
||||||
|
if (IsCollection) |
||||||
|
throw new DesignerException("Cannot access Value for collection properties."); |
||||||
|
|
||||||
|
XamlComponentService componentService = _designItem.ComponentService; |
||||||
|
object valueOnInstance = this.ValueOnInstance; |
||||||
|
DesignItem designItem = componentService.GetDesignItem(valueOnInstance); |
||||||
|
if (designItem != null) |
||||||
|
return designItem; |
||||||
|
|
||||||
|
return componentService.RegisterComponentForDesigner(valueOnInstance); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override object ValueOnInstance { |
||||||
|
get { |
||||||
|
return _property.ValueOnInstance; |
||||||
|
} |
||||||
|
set { |
||||||
|
_property.ValueOnInstance = value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override bool IsSet { |
||||||
|
get { |
||||||
|
return _property.IsSet; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void SetValue(object value) |
||||||
|
{ |
||||||
|
XamlComponentService componentService = _designItem.ComponentService; |
||||||
|
|
||||||
|
DesignItem designItem = componentService.GetDesignItem(value); |
||||||
|
if (designItem != null) { |
||||||
|
if (designItem.Parent != null) |
||||||
|
throw new DesignerException("Cannot set value to design item that already has a parent"); |
||||||
|
} else { |
||||||
|
designItem = componentService.RegisterComponentForDesigner(value); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public override void Reset() |
||||||
|
{ |
||||||
|
_property.Reset(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
// <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; |
||||||
|
using ICSharpCode.WpfDesign.XamlDom; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign.Designer.Xaml |
||||||
|
{ |
||||||
|
sealed class XamlModelPropertyCollection : DesignItemPropertyCollection |
||||||
|
{ |
||||||
|
XamlDesignItem _item; |
||||||
|
|
||||||
|
public XamlModelPropertyCollection(XamlDesignItem item) |
||||||
|
{ |
||||||
|
this._item = item; |
||||||
|
} |
||||||
|
|
||||||
|
public override DesignItemProperty this[DependencyProperty dependencyProperty] { |
||||||
|
get { |
||||||
|
//return new XamlModelProperty(_item, dependencyProperty);
|
||||||
|
return this[dependencyProperty.Name]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override DesignItemProperty this[string name] { |
||||||
|
get { |
||||||
|
return new XamlModelProperty(_item, _item.XamlObject.FindOrCreateProperty(name)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override System.Collections.Generic.IEnumerator<DesignItemProperty> GetEnumerator() |
||||||
|
{ |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||||
|
xmlns:src="clr-namespace:ICSharpCode.WpfDesign.Designer" |
||||||
|
> |
||||||
|
|
||||||
|
<Style TargetType="{x:Type src:Controls.ResizeThumb}"> |
||||||
|
<Setter Property="Template"> |
||||||
|
<Setter.Value> |
||||||
|
<ControlTemplate TargetType="{x:Type src:Controls.ResizeThumb}"> |
||||||
|
<Rectangle Name="thumbRectangle" |
||||||
|
Width="7" Height="7" SnapsToDevicePixels="True" |
||||||
|
Stroke="Black" Fill="White" RadiusX="1.4142" RadiusY="1.4142"/> |
||||||
|
<ControlTemplate.Triggers> |
||||||
|
<Trigger Property="IsPrimarySelection" Value="False"> |
||||||
|
<Setter TargetName="thumbRectangle" Property="Stroke" Value="White"/> |
||||||
|
<Setter TargetName="thumbRectangle" Property="Fill" Value="Black"/> |
||||||
|
</Trigger> |
||||||
|
<Trigger Property="IsEnabled" Value="False"> |
||||||
|
<Setter TargetName="thumbRectangle" Property="Fill" Value="Gray"/> |
||||||
|
</Trigger> |
||||||
|
</ControlTemplate.Triggers> |
||||||
|
</ControlTemplate> |
||||||
|
</Setter.Value> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
|
||||||
|
<Style TargetType="{x:Type src:Controls.ContainerDragHandle}"> |
||||||
|
<Setter Property="Template"> |
||||||
|
<Setter.Value> |
||||||
|
<ControlTemplate TargetType="{x:Type src:Controls.ContainerDragHandle}"> |
||||||
|
<Canvas Height="13" Width="13" Name="Canvas" Background="#00FFFFFF" SnapsToDevicePixels="True"> |
||||||
|
<Rectangle Height="13" Width="13" RadiusX="2" RadiusY="2" |
||||||
|
Fill="#669ABFE5" Name="BorderRectangle" Stroke="#FF9ABFE5" StrokeThickness="1" /> |
||||||
|
<Path Fill="#FF748EAA" Canvas.Left="1" Canvas.Top="1"> |
||||||
|
<Path.Data> |
||||||
|
<GeometryGroup> |
||||||
|
<PathGeometry Figures="M5.5,0L3,3L8,3 M11,5.5L8,3L8,8 M5.5,11L3,8L8,8 M0,5.5L3,3L3,8" /> |
||||||
|
<RectangleGeometry Rect="3,5,5,1" /> |
||||||
|
<RectangleGeometry Rect="5,3,1,5" /> |
||||||
|
<RectangleGeometry Rect="5,5,1,1" /> |
||||||
|
</GeometryGroup> |
||||||
|
</Path.Data> |
||||||
|
</Path> |
||||||
|
</Canvas> |
||||||
|
</ControlTemplate> |
||||||
|
</Setter.Value> |
||||||
|
</Setter> |
||||||
|
</Style> |
||||||
|
</ResourceDictionary> |
@ -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; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Base class for change groups.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class ChangeGroup : IDisposable |
||||||
|
{ |
||||||
|
string title; |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets/Sets the title of the change group.
|
||||||
|
/// </summary>
|
||||||
|
public string Title { |
||||||
|
get { return title; } |
||||||
|
set { title = value; } |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Commits the change group.
|
||||||
|
/// </summary>
|
||||||
|
public abstract void Commit(); |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Aborts the change group.
|
||||||
|
/// </summary>
|
||||||
|
public abstract void Abort(); |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is called when the change group is disposed. Should Abort the change group if it is not already committed.
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void Disposed(); |
||||||
|
|
||||||
|
void IDisposable.Dispose() |
||||||
|
{ |
||||||
|
Disposed(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
// <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.Collections.Generic; |
||||||
|
using System.Windows; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Represents a property of a DesignItem.
|
||||||
|
/// All changes done via the DesignItemProperty class are represented in the underlying model (e.g. XAML).
|
||||||
|
/// This also ensures that
|
||||||
|
/// Changes directly done to control instances might not be reflected in the model.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class DesignItemProperty |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Gets if the property represents a collection.
|
||||||
|
/// </summary>
|
||||||
|
public abstract bool IsCollection { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the elements represented by the collection.
|
||||||
|
/// </summary>
|
||||||
|
public abstract IList<DesignItem> CollectionElements { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the value of the property. This property returns null if the value is not set.
|
||||||
|
/// </summary>
|
||||||
|
public abstract DesignItem Value { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets/Sets the value of the property on the designed instance.
|
||||||
|
/// If the property is not set, this returns the default value.
|
||||||
|
/// The setter does NOT update the underlying model, use SetValue() instead!
|
||||||
|
/// </summary>
|
||||||
|
public abstract object ValueOnInstance { get; set; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the value of the property.
|
||||||
|
/// </summary>
|
||||||
|
public abstract void SetValue(object value); |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets if the property is set on the design item.
|
||||||
|
/// </summary>
|
||||||
|
public abstract bool IsSet { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resets the property value to the default, possibly removing it from the list of properties.
|
||||||
|
/// </summary>
|
||||||
|
public abstract void Reset(); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a collection of design item properties.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class DesignItemPropertyCollection : IEnumerable<DesignItemProperty> |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Gets the design item property representing the specified dependency property.
|
||||||
|
/// </summary>
|
||||||
|
public abstract DesignItemProperty this[DependencyProperty dependencyProperty] { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the property with the specified name.
|
||||||
|
/// </summary>
|
||||||
|
public abstract DesignItemProperty this[string name] { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an enumerator to enumerate the properties that have a non-default value.
|
||||||
|
/// </summary>
|
||||||
|
public abstract IEnumerator<DesignItemProperty> GetEnumerator(); |
||||||
|
|
||||||
|
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() |
||||||
|
{ |
||||||
|
return this.GetEnumerator(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,75 @@ |
|||||||
|
// <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>
|
||||||
|
/// Combines two extension servers using a logical OR.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class LogicalOrExtensionServer<A, B> : DefaultExtensionServer |
||||||
|
where A : ExtensionServer |
||||||
|
where B : ExtensionServer |
||||||
|
{ |
||||||
|
ExtensionServer _a; |
||||||
|
ExtensionServer _b; |
||||||
|
|
||||||
|
/// <summary/>
|
||||||
|
protected override void OnInitialized() |
||||||
|
{ |
||||||
|
base.OnInitialized(); |
||||||
|
_a = Context.Services.ExtensionManager.GetExtensionServer(new ExtensionServerAttribute(typeof(A))); |
||||||
|
_b = Context.Services.ExtensionManager.GetExtensionServer(new ExtensionServerAttribute(typeof(B))); |
||||||
|
_a.ShouldApplyExtensionsInvalidated += OnShouldApplyExtensionsInvalidated; |
||||||
|
_b.ShouldApplyExtensionsInvalidated += OnShouldApplyExtensionsInvalidated; |
||||||
|
} |
||||||
|
|
||||||
|
void OnShouldApplyExtensionsInvalidated(object sender, DesignItemCollectionEventArgs e) |
||||||
|
{ |
||||||
|
ReapplyExtensions(e.Items); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary/>
|
||||||
|
public override bool ShouldApplyExtensions(DesignItem extendedItem) |
||||||
|
{ |
||||||
|
return _a.ShouldApplyExtensions(extendedItem) || _b.ShouldApplyExtensions(extendedItem); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Combines two extension servers using a logical AND.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class LogicalAndExtensionServer<A, B> : DefaultExtensionServer |
||||||
|
where A : ExtensionServer |
||||||
|
where B : ExtensionServer |
||||||
|
{ |
||||||
|
ExtensionServer _a; |
||||||
|
ExtensionServer _b; |
||||||
|
|
||||||
|
/// <summary/>
|
||||||
|
protected override void OnInitialized() |
||||||
|
{ |
||||||
|
base.OnInitialized(); |
||||||
|
_a = Context.Services.ExtensionManager.GetExtensionServer(new ExtensionServerAttribute(typeof(A))); |
||||||
|
_b = Context.Services.ExtensionManager.GetExtensionServer(new ExtensionServerAttribute(typeof(B))); |
||||||
|
_a.ShouldApplyExtensionsInvalidated += OnShouldApplyExtensionsInvalidated; |
||||||
|
_b.ShouldApplyExtensionsInvalidated += OnShouldApplyExtensionsInvalidated; |
||||||
|
} |
||||||
|
|
||||||
|
void OnShouldApplyExtensionsInvalidated(object sender, DesignItemCollectionEventArgs e) |
||||||
|
{ |
||||||
|
ReapplyExtensions(e.Items); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary/>
|
||||||
|
public override bool ShouldApplyExtensions(DesignItem extendedItem) |
||||||
|
{ |
||||||
|
return _a.ShouldApplyExtensions(extendedItem) && _b.ShouldApplyExtensions(extendedItem); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue