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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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