diff --git a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml index 87cb007a0c..1fe110c423 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml +++ b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml @@ -13,7 +13,10 @@ - + + + + ]]> diff --git a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml.cs b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml.cs index 4e7cdf13ea..1b459fcc81 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.IO; using System.Windows; using System.Windows.Controls; @@ -20,6 +21,7 @@ namespace StandaloneDesigner void tabControlSelectionChanged(object sender, RoutedEventArgs e) { + if (e.Source != tabControl) return; if (tabControl.SelectedItem == designTab) { designSurface.LoadDesigner(new XmlTextReader(new StringReader(CodeTextBox.Text))); } else { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs index cfec97905f..78ffc31030 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs @@ -6,31 +6,130 @@ // using System; +using System.Diagnostics; using System.Windows; +using System.Windows.Input; using System.Windows.Controls; using System.Windows.Media; +using System.Windows.Threading; using ICSharpCode.WpfDesign.Designer.Controls; namespace ICSharpCode.WpfDesign.Designer { - sealed class DesignPanel : SingleVisualChildElement + sealed class DesignPanel : SingleVisualChildElement, IDesignPanel { + sealed class InnerDesignPanel : SingleVisualChildElement + { + internal void SetElement(UIElement element) + { + this.VisualChild = element; + } + } + + DefaultServiceProvider _services; + InnerDesignPanel _innerDesignPanel; UIElement _designedElement; + public DesignPanel(DefaultServiceProvider services) + { + this._services = services; + + this.Focusable = true; + + _innerDesignPanel = new InnerDesignPanel(); + this.VisualChild = _innerDesignPanel; + } + public UIElement DesignedElement { get { return _designedElement; } set { _designedElement = value; - this.VisualChild = value; + _innerDesignPanel.SetElement(value); } } protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) { - - return base.HitTestCore(hitTestParameters); + return new PointHitTestResult(this, hitTestParameters.HitPoint); + } + + protected override GeometryHitTestResult HitTestCore(GeometryHitTestParameters hitTestParameters) + { + return new GeometryHitTestResult(this, IntersectionDetail.NotCalculated); + } + + protected override void OnPreviewMouseDown(MouseButtonEventArgs e) + { + base.OnPreviewMouseDown(e); + if (!_isInInputAction) { + Debug.WriteLine("DesignPanel.PreviewMouseDown Source=" + e.Source.GetType().Name + " OriginalSource=" + e.OriginalSource.GetType().Name); + DesignSite site = FindDesignedElementForOriginalSource(e.OriginalSource); + if (site != null) { + Debug.WriteLine(" Found designed element: " + site.Component.GetType().Name); + } + _services.Tool.CurrentTool.OnMouseDown(this, e); + } + } + + public DesignSite FindDesignedElementForOriginalSource(object originalSource) + { + if (originalSource == null) + return null; + DesignSite site = _services.Component.GetSite(originalSource); + if (site != null) + return site; + if (originalSource == _innerDesignPanel) + return null; + DependencyObject dObj = originalSource as DependencyObject; + if (dObj == null) + return null; + return FindDesignedElementForOriginalSource(VisualTreeHelper.GetParent(dObj)); + } + + /// + /// prevent designed controls from getting the keyboard focus + /// + protected override void OnPreviewGotKeyboardFocus(KeyboardFocusChangedEventArgs e) + { + if (e.NewFocus != this) { + if (e.NewFocus is TabItem) { + Dispatcher.BeginInvoke(DispatcherPriority.Normal, + new Action(delegate { Focus(); })); + } else { + e.Handled = true; + Focus(); + } + } + } + + #region IDesignPanel implementation + public UIElement DesignPanelUI { + get { return this; } + } + + public DefaultServiceProvider Services { + get { return _services; } + } + #endregion + + bool _isInInputAction; + + void IDesignPanel.StartInputAction() + { + if (_isInInputAction) throw new InvalidOperationException(); + _isInInputAction = true; + _innerDesignPanel.IsHitTestVisible = false; + } + + void IDesignPanel.StopInputAction() + { + if (!_isInInputAction) throw new InvalidOperationException(); + _isInInputAction = false; + _innerDesignPanel.IsHitTestVisible = true; } } + + internal delegate void Action(); } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs index e1b6fe5398..64b895bb1d 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs @@ -22,7 +22,8 @@ namespace ICSharpCode.WpfDesign.Designer /// public sealed class DesignSurface : SingleVisualChildElement { - readonly DefaultServiceProvider _defaultServiceProvider; + readonly DefaultServiceProvider _services; + readonly DefaultComponentService _componentService; readonly ScrollViewer _scrollViewer; readonly DesignPanel _designPanel; @@ -32,13 +33,16 @@ namespace ICSharpCode.WpfDesign.Designer public DesignSurface() { DesignServiceContainer serviceContainer = new DesignServiceContainer(); + _services = new DefaultServiceProvider(serviceContainer); + serviceContainer.AddService(typeof(IVisualDesignService), new DefaultVisualDesignService()); serviceContainer.AddService(typeof(ISelectionService), new DefaultSelectionService()); - - _defaultServiceProvider = new DefaultServiceProvider(serviceContainer); + serviceContainer.AddService(typeof(IToolService), new DefaultToolService()); + _componentService = new DefaultComponentService(this); + serviceContainer.AddService(typeof(IComponentService), _componentService); _scrollViewer = new ScrollViewer(); - _designPanel = new DesignPanel(); + _designPanel = new DesignPanel(_services); _scrollViewer.Content = _designPanel; this.VisualChild = _scrollViewer; } @@ -46,8 +50,8 @@ namespace ICSharpCode.WpfDesign.Designer /// /// Gets the service provider. /// - public DefaultServiceProvider DefaultServiceProvider { - get { return _defaultServiceProvider; } + public DefaultServiceProvider Services { + get { return _services; } } /// @@ -68,9 +72,20 @@ namespace ICSharpCode.WpfDesign.Designer InitializeDesigner(XamlParser.Parse(xamlReader)); } + /// + /// Saves the designer content into the specified XmlWriter. + /// + public void SaveDesigner(XmlWriter writer) + { + _currentDocument.Save(writer); + } + + XamlDocument _currentDocument; + void InitializeDesigner(XamlDocument document) { - DesignSite rootSite = new XamlDesignSite(document.RootElement, this); + _currentDocument = document; + DesignSite rootSite = _componentService.RegisterXamlComponentRecursive(document.RootElement); _designPanel.DesignedElement = DefaultVisualDesignService.CreateUIElementFor(rootSite); } @@ -79,10 +94,11 @@ namespace ICSharpCode.WpfDesign.Designer /// public void UnloadDesigner() { + _currentDocument = null; UIElement designedElement = this.DesignedElement; if (designedElement != null) { + _componentService.UnregisterAllComponents(); _designPanel.DesignedElement = null; - } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Linq.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Linq.cs new file mode 100644 index 0000000000..defcfbe596 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Linq.cs @@ -0,0 +1,22 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; + +namespace ICSharpCode.WpfDesign.Designer +{ + static class Linq + { + public static T[] ToArray(ICollection collection) + { + T[] arr = new T[collection.Count]; + collection.CopyTo(arr, 0); + return arr; + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ComponentService.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ComponentService.cs new file mode 100644 index 0000000000..ca4eab3450 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ComponentService.cs @@ -0,0 +1,91 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using ICSharpCode.WpfDesign.XamlDom; + +namespace ICSharpCode.WpfDesign.Designer.Services +{ + sealed class DefaultComponentService : IComponentService + { + readonly DesignSurface _surface; + + public DefaultComponentService(DesignSurface surface) + { + this._surface = surface; + } + + public event EventHandler ComponentRegistered; + public event EventHandler ComponentUnregistered; + + Dictionary _sites = new Dictionary(); + + public DesignSite GetSite(object component) + { + if (component == null) + throw new ArgumentNullException("component"); + XamlDesignSite site; + _sites.TryGetValue(component, out site); + return site; + } + + public DesignSite RegisterComponentForDesigner(object component) + { + if (component == null) + throw new ArgumentNullException("component"); + throw new NotImplementedException(); + } + + /// + /// currently for use by UnregisterAllComponents only because it doesn't update the XAML + /// + void UnregisterComponentFromDesigner(DesignSite site) + { + if (site == null) + throw new ArgumentNullException("site"); + + if (!_sites.Remove(site.Component)) + throw new ArgumentException("The site was not registered here!"); + + if (ComponentUnregistered != null) { + ComponentUnregistered(this, new SiteEventArgs(site)); + } + } + + /// + /// registers components from an existing XAML tree + /// + internal XamlDesignSite RegisterXamlComponentRecursive(XamlObject obj) + { + if (obj == null) return null; + + foreach (XamlProperty prop in obj.Properties) { + RegisterXamlComponentRecursive(prop.PropertyValue as XamlObject); + foreach (XamlPropertyValue val in prop.CollectionElements) { + RegisterXamlComponentRecursive(val as XamlObject); + } + } + + XamlDesignSite site = new XamlDesignSite(obj, _surface); + _sites.Add(site.Component, site); + if (ComponentRegistered != null) { + ComponentRegistered(this, new SiteEventArgs(site)); + } + return site; + } + + /// + /// unregisters all components + /// + internal void UnregisterAllComponents() + { + Array.ForEach(Linq.ToArray(_sites.Values), UnregisterComponentFromDesigner); + _sites.Clear(); + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ToolService.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ToolService.cs new file mode 100644 index 0000000000..49bc669d7b --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ToolService.cs @@ -0,0 +1,136 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Windows.Input; + +namespace ICSharpCode.WpfDesign.Designer.Services +{ + /// + /// See for description. + /// + sealed class DefaultToolService : IToolService + { + PointerTool _pointerTool; + ITool _currentTool; + + public DefaultToolService() + { + _currentTool = _pointerTool = new PointerTool(); + } + + public ITool PointerTool { + get { return _pointerTool; } + } + + public ITool CurrentTool { + get { return _currentTool; } + set { + if (value == null) + throw new ArgumentNullException("value"); + _currentTool = value; + } + } + } + + sealed class PointerTool : ITool + { + public InputHandlingLayer InputLayer { + get { return InputHandlingLayer.Tool; } + } + + public Cursor Cursor { + get { return Cursors.Arrow; } + } + + public void OnMouseDown(IDesignPanel designPanel, MouseButtonEventArgs e) + { + e.Handled = true; + new SelectionTask().Start(designPanel, e); + } + } + + abstract class TaskBase + { + protected IDesignPanel designPanel; + bool isStarted; + + public void Start(IDesignPanel designPanel, MouseButtonEventArgs e) + { + this.designPanel = designPanel; + isStarted = true; + designPanel.StartInputAction(); + RegisterEvents(); + if (designPanel.CaptureMouse()) { + OnStarted(e); + } else { + Stop(); + } + } + + void RegisterEvents() + { + designPanel.LostMouseCapture += OnLostMouseCapture; + designPanel.MouseDown += OnMouseDown; + designPanel.MouseMove += OnMouseMove; + designPanel.MouseUp += OnMouseUp; + } + + void UnRegisterEvents() + { + designPanel.LostMouseCapture -= OnLostMouseCapture; + designPanel.MouseDown -= OnMouseDown; + designPanel.MouseMove -= OnMouseMove; + designPanel.MouseUp -= OnMouseUp; + } + + protected virtual void OnLostMouseCapture(object sender, MouseEventArgs e) + { + Stop(); + } + + protected virtual void OnMouseDown(object sender, MouseButtonEventArgs e) + { + } + + protected virtual void OnMouseMove(object sender, MouseEventArgs e) + { + } + + protected virtual void OnMouseUp(object sender, MouseButtonEventArgs e) + { + Stop(); + } + + protected void Stop() + { + if (!isStarted) return; + isStarted = false; + designPanel.ReleaseMouseCapture(); + UnRegisterEvents(); + designPanel.StopInputAction(); + OnStopped(); + } + + protected virtual void OnStarted(MouseButtonEventArgs e) {} + protected virtual void OnStopped() {} + } + + sealed class SelectionTask : TaskBase + { + protected override void OnStarted(MouseButtonEventArgs e) + { + base.OnStarted(e); + } + + protected override void OnStopped() + { + //designPanel.cur + base.OnStopped(); + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj index 51a7577a77..869d2d892c 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj @@ -59,8 +59,11 @@ + + + diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/XamlDesignSite.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/XamlDesignSite.cs index b8f3b7e302..2dd7080a8f 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/XamlDesignSite.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/XamlDesignSite.cs @@ -6,6 +6,7 @@ // using System; +using System.Windows; using ICSharpCode.WpfDesign.XamlDom; namespace ICSharpCode.WpfDesign.Designer @@ -27,9 +28,15 @@ namespace ICSharpCode.WpfDesign.Designer } } + public override UIElement View { + get { + return null; + } + } + public override object GetService(Type serviceType) { - return designSurface.DefaultServiceProvider.GetService(serviceType); + return designSurface.Services.GetService(serviceType); } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs index 85c3a3d3e9..ba0116f782 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs @@ -124,8 +124,11 @@ namespace ICSharpCode.WpfDesign.XamlDom XamlPropertyInfo defaultProperty = GetDefaultProperty(elementType); XamlPropertyValue setDefaultValueTo = null; object defaultPropertyValue = null; + XamlProperty defaultCollectionProperty = null; + if (defaultProperty != null && defaultProperty.IsCollection && !element.IsEmpty) { defaultPropertyValue = defaultProperty.GetValue(instance); + obj.AddProperty(defaultCollectionProperty = new XamlProperty(obj, defaultProperty, null)); } foreach (XmlNode childNode in element.ChildNodes) { @@ -145,6 +148,7 @@ namespace ICSharpCode.WpfDesign.XamlDom if (childValue != null) { if (defaultProperty != null && defaultProperty.IsCollection) { defaultProperty.AddValue(defaultPropertyValue, childValue); + defaultCollectionProperty.AddCollectionElement(childValue); } else { if (setDefaultValueTo != null) throw new XamlLoadException("default property may have only one value assigned"); @@ -164,6 +168,7 @@ namespace ICSharpCode.WpfDesign.XamlDom throw new XamlLoadException("This element does not have a default value, cannot assign to it"); } defaultProperty.SetValue(instance, setDefaultValueTo.GetValueFor(defaultProperty)); + obj.AddProperty(new XamlProperty(obj, defaultProperty, setDefaultValueTo)); } if (iSupportInitializeInstance != null) { @@ -216,7 +221,7 @@ namespace ICSharpCode.WpfDesign.XamlDom MethodInfo getMethod = elementType.GetMethod("Get" + propertyName, BindingFlags.Public | BindingFlags.Static); MethodInfo setMethod = elementType.GetMethod("Set" + propertyName, BindingFlags.Public | BindingFlags.Static); if (getMethod != null && setMethod != null) { - return new XamlAttachedPropertyInfo(getMethod, setMethod); + return new XamlAttachedPropertyInfo(getMethod, setMethod, propertyName); } return null; } @@ -283,12 +288,14 @@ namespace ICSharpCode.WpfDesign.XamlDom bool valueWasSet = false; object collectionInstance = null; + XamlProperty collectionProperty = null; if (propertyInfo.IsCollection) { if (defaultProperty.FullyQualifiedName == propertyInfo.FullyQualifiedName) { collectionInstance = defaultPropertyValue; } else { collectionInstance = propertyInfo.GetValue(obj.Instance); } + obj.AddProperty(collectionProperty = new XamlProperty(obj, propertyInfo, null)); } XmlSpace oldXmlSpace = currentXmlSpace; @@ -301,6 +308,7 @@ namespace ICSharpCode.WpfDesign.XamlDom if (childValue != null) { if (propertyInfo.IsCollection) { propertyInfo.AddValue(collectionInstance, childValue); + collectionProperty.AddCollectionElement(childValue); } else { if (valueWasSet) throw new XamlLoadException("non-collection property may have only one child element"); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs index 01502f3975..127fd0f395 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs @@ -6,6 +6,7 @@ // using System; +using System.Collections.Generic; using System.ComponentModel; using System.Text; using System.Xml; @@ -20,6 +21,7 @@ namespace ICSharpCode.WpfDesign.XamlDom XamlObject parentObject; XamlPropertyInfo propertyInfo; XamlPropertyValue propertyValue; + List collectionElements = new List(); internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo, XamlPropertyValue propertyValue) { @@ -35,6 +37,36 @@ namespace ICSharpCode.WpfDesign.XamlDom get { return parentObject; } } + /// + /// Gets the property name. + /// + public string PropertyName { + get { return propertyInfo.Name; } + } + + /// + /// Gets the value of the property. Can be null if the property is a collection property. + /// + public XamlPropertyValue PropertyValue { + get { return propertyValue; } + } + + /// + /// Gets the collection elements of the property. Is empty if the property is not a collection. + /// + public IList CollectionElements { + get { return collectionElements.AsReadOnly(); } + } + + /// + /// used internally by the XamlParser. + /// Add a collection element that already is part of the XML DOM. + /// + internal void AddCollectionElement(XamlPropertyValue val) + { + collectionElements.Add(val); + } + /*public bool IsAttributeSyntax { get { return attribute != null; @@ -60,6 +92,9 @@ namespace ICSharpCode.WpfDesign.XamlDom /// public abstract class XamlPropertyValue { + /// + /// used internally by the XamlParser. + /// internal abstract object GetValueFor(XamlPropertyInfo targetProperty); } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs index 65ce1d3e65..15e921c927 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs @@ -23,7 +23,9 @@ namespace ICSharpCode.WpfDesign.XamlDom public abstract object GetValue(object instance); public abstract void SetValue(object instance, object value); public abstract TypeConverter TypeConverter { get; } + public abstract string Name { get; } public abstract string FullyQualifiedName { get; } + public abstract bool IsAttached { get; } public abstract bool IsCollection { get; } internal abstract void AddValue(object collectionInstance, XamlPropertyValue newElement); } @@ -32,11 +34,13 @@ namespace ICSharpCode.WpfDesign.XamlDom { MethodInfo _getMethod; MethodInfo _setMethod; + string _name; - public XamlAttachedPropertyInfo(MethodInfo getMethod, MethodInfo setMethod) + public XamlAttachedPropertyInfo(MethodInfo getMethod, MethodInfo setMethod, string name) { this._getMethod = getMethod; this._setMethod = setMethod; + this._name = name; } public override TypeConverter TypeConverter { @@ -47,14 +51,20 @@ namespace ICSharpCode.WpfDesign.XamlDom public override string FullyQualifiedName { get { - return _getMethod.DeclaringType.FullName + "." + _getMethod.Name; + return _getMethod.DeclaringType.FullName + "." + _name; } } + public override string Name { + get { return _name; } + } + + public override bool IsAttached { + get { return true; } + } + public override bool IsCollection { - get { - return false; - } + get { return false; } } public override object GetValue(object instance) @@ -107,6 +117,14 @@ namespace ICSharpCode.WpfDesign.XamlDom } } + public override string Name { + get { return _propertyDescriptor.Name; } + } + + public override bool IsAttached { + get { return false; } + } + public override bool IsCollection { get { return CollectionSupport.IsCollectionType(_propertyDescriptor.PropertyType); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DefaultServiceProvider.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DefaultServiceProvider.cs index 8839c09776..4038087b7b 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DefaultServiceProvider.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DefaultServiceProvider.cs @@ -81,5 +81,25 @@ namespace ICSharpCode.WpfDesign return GetServiceChecked(); } } + + /// + /// Gets the . + /// This service is guaranteed to always exist -> this property will never return null. + /// + public IToolService Tool { + get { + return GetServiceChecked(); + } + } + + /// + /// Gets the . + /// This service is guaranteed to always exist -> this property will never return null. + /// + public IComponentService Component { + get { + return GetServiceChecked(); + } + } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignSite.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignSite.cs index eb66f8a2a0..27d763e3d2 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignSite.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignSite.cs @@ -7,12 +7,18 @@ using System; using System.Collections.Generic; +using System.Windows; namespace ICSharpCode.WpfDesign { /// /// The DesignSite connects a component with the service system and the designers. /// + /// + /// About the Cider extension system: + /// http://blogs.msdn.com/jnak/archive/2006/04/24/580393.aspx + /// http://blogs.msdn.com/jnak/archive/2006/08/04/687166.aspx + /// public abstract class DesignSite : IServiceProvider { /// @@ -20,6 +26,11 @@ namespace ICSharpCode.WpfDesign /// public abstract object Component { get; } + /// + /// Gets the view used for the component. + /// + public abstract UIElement View { get; } + DefaultServiceProvider _defaultServiceProvider; /// diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ComponentEventArgs.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/EventArgs.cs similarity index 84% rename from src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ComponentEventArgs.cs rename to src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/EventArgs.cs index ec488dace7..13036b3ef1 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ComponentEventArgs.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/EventArgs.cs @@ -13,23 +13,23 @@ namespace ICSharpCode.WpfDesign /// /// Event arguments specifying a component as parameter. /// - public class ComponentEventArgs : EventArgs + public class SiteEventArgs : EventArgs { - readonly object _component; + readonly DesignSite _site; /// /// Creates a new ComponentEventArgs instance. /// - public ComponentEventArgs(object component) + public SiteEventArgs(DesignSite site) { - _component = component; + _site = site; } /// /// The component affected by the event. /// - public object Component { - get { return _component; } + public DesignSite Site { + get { return _site; } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs index 5d09bf4bd5..3b91c30eab 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs @@ -123,6 +123,8 @@ namespace ICSharpCode.WpfDesign /// /// Gets the collection of selected components. + /// This is a copy of the actual selected components collection, the returned copy + /// of the collection will not reflect future changes to the selection. /// ICollection SelectedComponents { get; } @@ -145,4 +147,29 @@ namespace ICSharpCode.WpfDesign int SelectionCount { get; } } #endregion + + #region IComponentService + /// Supports adding and removing components + public interface IComponentService + { + /// + /// Gets the site of an existing, registered component. + /// + /// + /// The site of the component, or null if the component is not registered. + /// + DesignSite GetSite(object component); + + /// Registers a component for usage in the designer. + DesignSite RegisterComponentForDesigner(object component); + + // /// Unregisters a component from usage in the designer. + // void UnregisterComponentFromDesigner(DesignSite site); + + /// Event raised whenever a component is registered + event EventHandler ComponentRegistered; + /// Event raised whenever a component is unregistered + event EventHandler ComponentUnregistered; + } + #endregion } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Tools.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Tools.cs new file mode 100644 index 0000000000..65e14bb8cb --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Tools.cs @@ -0,0 +1,124 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Windows.Input; +using System.Windows; + +namespace ICSharpCode.WpfDesign +{ + /// + /// Describes the layer of input handling. + /// When multiple actions are possible, that with the highest layer will be used. + /// + public enum InputHandlingLayer + { + /// + /// No layer specified. This layer is lower than all other layers. + /// + None, + /// + /// Layer used for passing the input to the component. + /// Normally never receives actions because there is always a . + /// + Component, + /// + /// Layer used for tools. + /// + Tool, + /// + /// Layer used for certain components that should get input, for example scroll thumbs + /// in user-defined ScrollViewers and the headers inside a TabControl. + /// + ComponentHigh, + /// + /// This layer is higher than all other layers. + /// + Highest + } + + /// + /// Describes a tool that can handle input on the design surface. + /// Modelled after the description on http://urbanpotato.net/Default.aspx/document/2300 + /// + public interface ITool + { + /// + /// Gets the input handling layer of the tool. + /// + InputHandlingLayer InputLayer { get; } + + /// + /// Gets the cursor used by the tool. + /// + Cursor Cursor { get; } + + /// + /// Notifies the tool of the MouseDown event. + /// + void OnMouseDown(IDesignPanel designPanel, MouseButtonEventArgs e); + } + + /// + /// Service that manages tool selection. + /// + public interface IToolService + { + /// + /// Gets the 'pointer' tool. + /// The pointer tool is the default tool for selecting and moving elements. + /// + ITool PointerTool { get; } + + /// + /// Gets/Sets the currently selected tool. + /// + ITool CurrentTool { get; set; } + } + + /// + /// Interface for the design panel. The design panel is the UIElement containing the + /// designed elements and is responsible for handling mouse and keyboard events. + /// + public interface IDesignPanel : IInputElement + { + /// + /// Gets the service provider used by the DesignPanel. + /// + DefaultServiceProvider Services { get; } + + /// + /// Starts an input action. This prevents components and tools from getting input events, + /// leaving input handling to event handlers attached to the design panel. + /// + void StartInputAction(); + + /// + /// Stops an input action. This reenables input handling of + /// + void StopInputAction(); + + /// + /// Finds the designed element for the specified original source. + /// + DesignSite FindDesignedElementForOriginalSource(object originalSource); + + + // The following members were missing in , but of course + // are supported on the DesignPanel: + + /// + /// Occurs when a mouse button is pressed. + /// + event MouseButtonEventHandler MouseDown; + + /// + /// Occurs when a mouse button is released. + /// + event MouseButtonEventHandler MouseUp; + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj index 9d360615b4..b2ba4f406e 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj @@ -55,12 +55,13 @@ Configuration\GlobalAssemblyInfo.cs - + +