Browse Source

Support for drawing a Polyline

pull/637/head
jkuehner 11 years ago
parent
commit
47d7ba0834
  1. 8
      samples/XamlDesigner/XamlDesigner.sln
  2. 12
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasDrawLineBehavior.cs
  3. 148
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasDrawPolyLineBehavior.cs
  4. 4
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/CreateComponentTool.cs
  5. 71
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/MouseGestureBase.cs
  6. 1
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj
  7. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DrawItemExtension.cs
  8. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj

8
samples/XamlDesigner/XamlDesigner.sln

@ -1,7 +1,9 @@ @@ -1,7 +1,9 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 5.0
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
# SharpDevelop 5.1
VisualStudioVersion = 12.0.20827.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamlDesigner", "XamlDesigner.csproj", "{27DA2B5C-2AAA-4478-AB00-3E184273C241}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign", "..\..\src\AddIns\DisplayBindings\WpfDesign\WpfDesign\Project\WpfDesign.csproj", "{66A378A1-E9F4-4AD5-8946-D0EC06C2902F}"

12
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasDrawLineBehavior.cs

@ -29,7 +29,7 @@ using ICSharpCode.WpfDesign.Designer.Services; @@ -29,7 +29,7 @@ using ICSharpCode.WpfDesign.Designer.Services;
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
[ExtensionFor(typeof(Canvas))]
public class CanvasDrawLineBehavior : BehaviorExtension, IDrawItemBehavior
public class CanvasDrawLineBehavior : BehaviorExtension, IDrawItemExtension
{
private ChangeGroup changeGroup;
@ -42,14 +42,6 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -42,14 +42,6 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
return item;
}
protected override void OnInitialized()
{
base.OnInitialized();
if (ExtendedItem.ContentProperty == null || Metadata.IsPlacementDisabled(ExtendedItem.ComponentType))
return;
ExtendedItem.AddBehavior(typeof(IDrawItemBehavior), this);
}
#region IDrawItemBehavior implementation
public bool CanItemBeDrawn(Type createItemType)
@ -82,7 +74,6 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -82,7 +74,6 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
}
#endregion
}
sealed class DrawLineMouseGesture : ClickOrDragMouseGesture
{
@ -129,3 +120,4 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -129,3 +120,4 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
}
}
}

148
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasDrawPolyLineBehavior.cs

@ -0,0 +1,148 @@ @@ -0,0 +1,148 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using ICSharpCode.WpfDesign.Extensions;
using ICSharpCode.WpfDesign.Designer.Services;
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
[ExtensionFor(typeof(Canvas))]
public class CanvasDrawPolyLineBehavior : BehaviorExtension, IDrawItemExtension
{
private ChangeGroup changeGroup;
DesignItem CreateItem(DesignContext context, Type componentType)
{
object newInstance = context.Services.ExtensionManager.CreateInstanceWithCustomInstanceFactory(componentType, null);
DesignItem item = context.Services.Component.RegisterComponentForDesigner(newInstance);
changeGroup = item.OpenGroup("Draw Polyline");
context.Services.ExtensionManager.ApplyDefaultInitializers(item);
return item;
}
#region IDrawItemBehavior implementation
public bool CanItemBeDrawn(Type createItemType)
{
return createItemType == typeof(Polyline);
}
public void StartDrawItem(DesignItem clickedOn, Type createItemType, IDesignPanel panel, System.Windows.Input.MouseEventArgs e)
{
var createdItem = CreateItem(panel.Context, createItemType);
var startPoint = e.GetPosition(clickedOn.View);
var operation = PlacementOperation.TryStartInsertNewComponents(clickedOn,
new DesignItem[] { createdItem },
new Rect[] { new Rect(startPoint.X, startPoint.Y, double.NaN, double.NaN) },
PlacementType.AddItem);
if (operation != null) {
createdItem.Services.Selection.SetSelectedComponents(new DesignItem[] { createdItem });
operation.Commit();
}
createdItem.Properties[Shape.StrokeProperty].SetValue(Colors.Black);
createdItem.Properties[Shape.StrokeThicknessProperty].SetValue(2d);
createdItem.Properties[Shape.StretchProperty].SetValue(Stretch.None);
createdItem.Properties[Polyline.PointsProperty].CollectionElements.Add(createdItem.Services.Component.RegisterComponentForDesigner(new Point(0,0)));
new DrawPolylineMouseGesture(createdItem, clickedOn.View, changeGroup).Start(panel, (MouseButtonEventArgs) e);
}
#endregion
sealed class DrawPolylineMouseGesture : ClickOrDragMouseGesture
{
private ChangeGroup changeGroup;
private DesignItem newLine;
private Point startPoint;
public DrawPolylineMouseGesture(DesignItem newLine, IInputElement relativeTo, ChangeGroup changeGroup)
{
this.newLine = newLine;
this.positionRelativeTo = relativeTo;
this.changeGroup = changeGroup;
startPoint = Mouse.GetPosition(null);
}
protected override void OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
base.OnPreviewMouseLeftButtonDown(sender, e);
}
protected override void OnMouseMove(object sender, MouseEventArgs e)
{
var delta = e.GetPosition(null) - startPoint;
var point = new Point(delta.X, delta.Y);
if (((Polyline)newLine.View).Points.Count <= 1)
newLine.Properties[Polyline.PointsProperty].CollectionElements.Add(newLine.Services.Component.RegisterComponentForDesigner(point));
newLine.Properties[Polyline.PointsProperty].CollectionElements.RemoveAt(((Polyline)newLine.View).Points.Count - 1);
newLine.Properties[Polyline.PointsProperty].CollectionElements.Add(newLine.Services.Component.RegisterComponentForDesigner(point));
}
protected override void OnMouseUp(object sender, MouseButtonEventArgs e)
{
var delta = e.GetPosition(null) - startPoint;
var point = new Point(delta.X, delta.Y);
newLine.Properties[Polyline.PointsProperty].CollectionElements.Add(newLine.Services.Component.RegisterComponentForDesigner(point));
}
protected override void OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
base.OnMouseDoubleClick(sender, e);
newLine.Properties[Polyline.PointsProperty].CollectionElements.RemoveAt(((Polyline)newLine.View).Points.Count - 1);
if (changeGroup != null)
{
changeGroup.Commit();
changeGroup = null;
}
Stop();
}
protected override void OnStopped()
{
if (changeGroup != null)
{
changeGroup.Abort();
changeGroup = null;
}
if (services.Tool.CurrentTool is CreateComponentTool)
{
services.Tool.CurrentTool = services.Tool.PointerTool;
}
base.OnStopped();
}
}
}
}

4
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/CreateComponentTool.cs

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Linq;
using System.Windows;
using System;
using System.Diagnostics;
@ -202,7 +203,8 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -202,7 +203,8 @@ namespace ICSharpCode.WpfDesign.Designer.Services
IDesignPanel designPanel = (IDesignPanel)sender;
DesignPanelHitTestResult result = designPanel.HitTest(e.GetPosition(designPanel), false, true, HitTestType.Default);
if (result.ModelHit != null) {
var drawItembehavior = result.ModelHit.GetBehavior<IDrawItemBehavior>();
var darwItemBehaviors = result.ModelHit.Extensions.OfType<IDrawItemExtension>();
var drawItembehavior = darwItemBehaviors.FirstOrDefault(x => x.CanItemBeDrawn(componentType));
if (drawItembehavior != null && drawItembehavior.CanItemBeDrawn(componentType)) {
drawItembehavior.StartDrawItem(result.ModelHit, componentType, designPanel, e);
}

71
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/MouseGestureBase.cs

@ -18,6 +18,8 @@ @@ -18,6 +18,8 @@
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace ICSharpCode.WpfDesign.Designer.Services
@ -71,6 +73,10 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -71,6 +73,10 @@ namespace ICSharpCode.WpfDesign.Designer.Services
designPanel.MouseMove += OnMouseMove;
designPanel.MouseUp += OnMouseUp;
designPanel.KeyDown += OnKeyDown;
designPanel.PreviewMouseLeftButtonDown += OnPreviewMouseLeftButtonDown;
designPanel.PreviewMouseLeftButtonUp += OnPreviewMouseLeftButtonUp;
designPanel.PreviewMouseRightButtonDown += OnPreviewMouseRightButtonDown;
designPanel.PreviewMouseRightButtonUp += OnPreviewMouseRightButtonUp;
}
void UnRegisterEvents()
@ -80,6 +86,10 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -80,6 +86,10 @@ namespace ICSharpCode.WpfDesign.Designer.Services
designPanel.MouseMove -= OnMouseMove;
designPanel.MouseUp -= OnMouseUp;
designPanel.KeyDown -= OnKeyDown;
designPanel.PreviewMouseLeftButtonDown -= OnPreviewMouseLeftButtonDown;
designPanel.PreviewMouseLeftButtonUp -= OnPreviewMouseLeftButtonUp;
designPanel.PreviewMouseRightButtonDown -= OnPreviewMouseRightButtonDown;
designPanel.PreviewMouseRightButtonUp -= OnPreviewMouseRightButtonUp;
}
void OnKeyDown(object sender, KeyEventArgs e)
@ -95,10 +105,27 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -95,10 +105,27 @@ namespace ICSharpCode.WpfDesign.Designer.Services
Stop();
}
protected virtual void OnMouseDown(object sender, MouseButtonEventArgs e)
protected virtual void OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (MouseButtonHelper.IsDoubleClick(sender, e))
OnMouseDoubleClick(sender, e);
}
protected virtual void OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{ }
protected virtual void OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{ }
protected virtual void OnPreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
{ }
protected virtual void OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
{ }
protected virtual void OnMouseDown(object sender, MouseButtonEventArgs e)
{ }
protected virtual void OnMouseMove(object sender, MouseEventArgs e)
{
}
@ -119,5 +146,47 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -119,5 +146,47 @@ namespace ICSharpCode.WpfDesign.Designer.Services
protected virtual void OnStarted(MouseButtonEventArgs e) {}
protected virtual void OnStopped() {}
static class MouseButtonHelper
{
private const long k_DoubleClickSpeed = 500;
private const double k_MaxMoveDistance = 10;
private static long _LastClickTicks = 0;
private static Point _LastPosition;
private static WeakReference _LastSender;
internal static bool IsDoubleClick(object sender, MouseButtonEventArgs e)
{
Point position = e.GetPosition(null);
long clickTicks = DateTime.Now.Ticks;
long elapsedTicks = clickTicks - _LastClickTicks;
long elapsedTime = elapsedTicks / TimeSpan.TicksPerMillisecond;
bool quickClick = (elapsedTime <= k_DoubleClickSpeed);
bool senderMatch = (_LastSender != null && sender.Equals(_LastSender.Target));
if (senderMatch && quickClick && Distance(position, _LastPosition) <= k_MaxMoveDistance)
{
// Double click!
_LastClickTicks = 0;
_LastSender = null;
return true;
}
// Not a double click
_LastClickTicks = clickTicks;
_LastPosition = position;
if (!quickClick)
_LastSender = new WeakReference(sender);
return false;
}
private static double Distance(Point pointA, Point pointB)
{
double x = pointA.X - pointB.X;
double y = pointA.Y - pointB.Y;
return Math.Sqrt(x * x + y * y);
}
}
}
}

1
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj

@ -87,6 +87,7 @@ @@ -87,6 +87,7 @@
<Compile Include="Controls\RenderTransformOriginThumb.cs" />
<Compile Include="Extensions\BorderForImageControl.cs" />
<Compile Include="Extensions\CanvasDrawLineBehavior.cs" />
<Compile Include="Extensions\CanvasDrawPolyLineBehavior.cs" />
<Compile Include="Extensions\DefaultCommandsContextMenu.xaml.cs">
<DependentUpon>DefaultCommandsContextMenu.xaml</DependentUpon>
<SubType>Code</SubType>

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DrawItemBehavior.cs → src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DrawItemExtension.cs

@ -27,7 +27,7 @@ namespace ICSharpCode.WpfDesign @@ -27,7 +27,7 @@ namespace ICSharpCode.WpfDesign
/// Behavior interface implemented by container elements to support resizing
/// drawing new Elements
/// </summary>
public interface IDrawItemBehavior
public interface IDrawItemExtension
{
bool CanItemBeDrawn(Type createItemType);
void StartDrawItem(DesignItem clickedOn, Type createItemType, IDesignPanel panel, MouseEventArgs e);

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj

@ -73,7 +73,7 @@ @@ -73,7 +73,7 @@
<Compile Include="Adorners\AdornerProvider.cs" />
<Compile Include="Adorners\AdornerProviderClasses.cs" />
<Compile Include="Adorners\RelativePlacement.cs" />
<Compile Include="DrawItemBehavior.cs" />
<Compile Include="DrawItemExtension.cs" />
<Compile Include="DummyValueInsteadOfNullTypeDescriptionProvider.cs" />
<Compile Include="ExtensionMethods.cs" />
<Compile Include="Extensions\ExtensionAttribute.cs" />

Loading…
Cancel
Save