Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2221 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
18 changed files with 650 additions and 27 deletions
@ -0,0 +1,22 @@ |
|||||||
|
// <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; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign.Designer |
||||||
|
{ |
||||||
|
static class Linq |
||||||
|
{ |
||||||
|
public static T[] ToArray<T>(ICollection<T> collection) |
||||||
|
{ |
||||||
|
T[] arr = new T[collection.Count]; |
||||||
|
collection.CopyTo(arr, 0); |
||||||
|
return arr; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,91 @@ |
|||||||
|
// <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 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<SiteEventArgs> ComponentRegistered; |
||||||
|
public event EventHandler<SiteEventArgs> ComponentUnregistered; |
||||||
|
|
||||||
|
Dictionary<object, XamlDesignSite> _sites = new Dictionary<object, XamlDesignSite>(); |
||||||
|
|
||||||
|
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(); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// currently for use by UnregisterAllComponents only because it doesn't update the XAML
|
||||||
|
/// </summary>
|
||||||
|
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)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// registers components from an existing XAML tree
|
||||||
|
/// </summary>
|
||||||
|
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; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// unregisters all components
|
||||||
|
/// </summary>
|
||||||
|
internal void UnregisterAllComponents() |
||||||
|
{ |
||||||
|
Array.ForEach(Linq.ToArray(_sites.Values), UnregisterComponentFromDesigner); |
||||||
|
_sites.Clear(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,136 @@ |
|||||||
|
// <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.Input; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign.Designer.Services |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// See <see cref="IToolService"/> for description.
|
||||||
|
/// </summary>
|
||||||
|
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(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,124 @@ |
|||||||
|
// <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.Input; |
||||||
|
using System.Windows; |
||||||
|
|
||||||
|
namespace ICSharpCode.WpfDesign |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Describes the layer of input handling.
|
||||||
|
/// When multiple actions are possible, that with the highest layer will be used.
|
||||||
|
/// </summary>
|
||||||
|
public enum InputHandlingLayer |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// No layer specified. This layer is lower than all other layers.
|
||||||
|
/// </summary>
|
||||||
|
None, |
||||||
|
/// <summary>
|
||||||
|
/// Layer used for passing the input to the component.
|
||||||
|
/// Normally never receives actions because there is always a <see cref="Tool"/>.
|
||||||
|
/// </summary>
|
||||||
|
Component, |
||||||
|
/// <summary>
|
||||||
|
/// Layer used for tools.
|
||||||
|
/// </summary>
|
||||||
|
Tool, |
||||||
|
/// <summary>
|
||||||
|
/// Layer used for certain components that should get input, for example scroll thumbs
|
||||||
|
/// in user-defined ScrollViewers and the headers inside a TabControl.
|
||||||
|
/// </summary>
|
||||||
|
ComponentHigh, |
||||||
|
/// <summary>
|
||||||
|
/// This layer is higher than all other layers.
|
||||||
|
/// </summary>
|
||||||
|
Highest |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Describes a tool that can handle input on the design surface.
|
||||||
|
/// Modelled after the description on http://urbanpotato.net/Default.aspx/document/2300
|
||||||
|
/// </summary>
|
||||||
|
public interface ITool |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Gets the input handling layer of the tool.
|
||||||
|
/// </summary>
|
||||||
|
InputHandlingLayer InputLayer { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the cursor used by the tool.
|
||||||
|
/// </summary>
|
||||||
|
Cursor Cursor { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Notifies the tool of the MouseDown event.
|
||||||
|
/// </summary>
|
||||||
|
void OnMouseDown(IDesignPanel designPanel, MouseButtonEventArgs e); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Service that manages tool selection.
|
||||||
|
/// </summary>
|
||||||
|
public interface IToolService |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Gets the 'pointer' tool.
|
||||||
|
/// The pointer tool is the default tool for selecting and moving elements.
|
||||||
|
/// </summary>
|
||||||
|
ITool PointerTool { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets/Sets the currently selected tool.
|
||||||
|
/// </summary>
|
||||||
|
ITool CurrentTool { get; set; } |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for the design panel. The design panel is the UIElement containing the
|
||||||
|
/// designed elements and is responsible for handling mouse and keyboard events.
|
||||||
|
/// </summary>
|
||||||
|
public interface IDesignPanel : IInputElement |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Gets the service provider used by the DesignPanel.
|
||||||
|
/// </summary>
|
||||||
|
DefaultServiceProvider Services { get; } |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts an input action. This prevents components and tools from getting input events,
|
||||||
|
/// leaving input handling to event handlers attached to the design panel.
|
||||||
|
/// </summary>
|
||||||
|
void StartInputAction(); |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops an input action. This reenables input handling of
|
||||||
|
/// </summary>
|
||||||
|
void StopInputAction(); |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the designed element for the specified original source.
|
||||||
|
/// </summary>
|
||||||
|
DesignSite FindDesignedElementForOriginalSource(object originalSource); |
||||||
|
|
||||||
|
|
||||||
|
// The following members were missing in <see cref="IInputElement"/>, but of course
|
||||||
|
// are supported on the DesignPanel:
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a mouse button is pressed.
|
||||||
|
/// </summary>
|
||||||
|
event MouseButtonEventHandler MouseDown; |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a mouse button is released.
|
||||||
|
/// </summary>
|
||||||
|
event MouseButtonEventHandler MouseUp; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue