Browse Source

Support drawing new "Line" Objects on a Canvas

pull/637/head
jkuehner 11 years ago
parent
commit
990298c457
  1. 10
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/BasicMetadata.cs
  2. 55
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasDrawLineBehavior.cs
  3. 27
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/LineHandlerExtension.cs
  4. 154
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PointTrackerPlacementSupport.cs
  5. 10
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/CreateComponentTool.cs
  6. 14
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs
  7. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DrawItemBehavior.cs
  8. 32
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Metadata.cs
  9. 3
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs

10
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/BasicMetadata.cs

@ -285,6 +285,16 @@ namespace ICSharpCode.WpfDesign.Designer @@ -285,6 +285,16 @@ namespace ICSharpCode.WpfDesign.Designer
Metadata.AddDefaultSize(typeof(Label), new Size(130, 120));
Metadata.AddDefaultSize(typeof(Expander), new Size(130, 120));
Metadata.AddDefaultPropertyValue(typeof(Line), Line.X1Property, 0.0);
Metadata.AddDefaultPropertyValue(typeof(Line), Line.Y1Property, 0.0);
Metadata.AddDefaultPropertyValue(typeof(Line), Line.X2Property, 20.0);
Metadata.AddDefaultPropertyValue(typeof(Line), Line.Y2Property, 20.0);
Metadata.AddDefaultPropertyValue(typeof(Line), Line.StrokeProperty, Colors.Black);
Metadata.AddDefaultPropertyValue(typeof(Line), Line.StrokeThicknessProperty, 2d);
Metadata.AddDefaultPropertyValue(typeof(Line), Line.StretchProperty, Stretch.None);
}
}
}

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

@ -21,6 +21,7 @@ using System.Linq; @@ -21,6 +21,7 @@ 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;
@ -30,6 +31,17 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -30,6 +31,17 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
[ExtensionFor(typeof(Canvas))]
public class CanvasDrawLineBehavior : BehaviorExtension, IDrawItemBehavior
{
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 Line");
context.Services.ExtensionManager.ApplyDefaultInitializers(item);
return item;
}
protected override void OnInitialized()
{
base.OnInitialized();
@ -44,26 +56,29 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -44,26 +56,29 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
{
return createItemType == typeof(Line);
}
public void StartDrawItem(DesignItem clickedOn, DesignItem createdItem, ChangeGroup changeGroup, IDesignPanel panel, System.Windows.Input.MouseEventArgs e)
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, 1, 1) },
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();
}
//changeGroup.Commit();
createdItem.Properties[Shape.StrokeProperty].SetValue(Colors.Black);
createdItem.Properties[Shape.StrokeThicknessProperty].SetValue(2d);
createdItem.Properties[Shape.StretchProperty].SetValue(Stretch.None);
var lineHandler = createdItem.Extensions.OfType<LineHandlerExtension>().First();
lineHandler.DragListener.ExternalStart();
new DrawLineMouseGesture(lineHandler, clickedOn.View).Start(panel, (MouseButtonEventArgs) e);
new DrawLineMouseGesture(lineHandler, clickedOn.View, changeGroup).Start(panel, (MouseButtonEventArgs) e);
}
#endregion
@ -71,12 +86,14 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -71,12 +86,14 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
sealed class DrawLineMouseGesture : ClickOrDragMouseGesture
{
LineHandlerExtension l;
public DrawLineMouseGesture(LineHandlerExtension l, IInputElement relativeTo)
private LineHandlerExtension l;
private ChangeGroup changeGroup;
public DrawLineMouseGesture(LineHandlerExtension l, IInputElement relativeTo, ChangeGroup changeGroup)
{
this.l = l;
this.positionRelativeTo = relativeTo;
this.changeGroup = changeGroup;
}
protected override void OnMouseMove(object sender, MouseEventArgs e)
@ -88,21 +105,21 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -88,21 +105,21 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
protected override void OnMouseUp(object sender, MouseButtonEventArgs e)
{
l.DragListener.ExternalStop();
if (changeGroup != null)
{
changeGroup.Commit();
changeGroup = null;
}
base.OnMouseUp(sender, e);
}
protected override void OnStopped()
{
//if (operation != null)
//{
// operation.Abort();
// operation = null;
//}
//if (changeGroup != null)
//{
// changeGroup.Abort();
// changeGroup = null;
//}
if (changeGroup != null)
{
changeGroup.Abort();
changeGroup = null;
}
if (services.Tool.CurrentTool is CreateComponentTool)
{
services.Tool.CurrentTool = services.Tool.PointerTool;

27
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/LineHandlerExtension.cs

@ -18,19 +18,12 @@ @@ -18,19 +18,12 @@
using System;
using ICSharpCode.WpfDesign.Extensions;
using ICSharpCode.WpfDesign;
using ICSharpCode.WpfDesign.Adorners;
using ICSharpCode.WpfDesign.Designer;
using ICSharpCode.WpfDesign.Designer.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows;
using System.Windows.Controls;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.WpfDesign.Designer.UIExtensions;
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
@ -219,29 +212,17 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -219,29 +212,17 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
protected override void OnInitialized()
{
base.OnInitialized();
if (ExtendedItem.Properties.GetProperty(Line.StrokeProperty).ValueOnInstance == null)
{
ExtendedItem.Properties[Shape.StrokeProperty].SetValue(Colors.Black);
ExtendedItem.Properties[Shape.StrokeThicknessProperty].SetValue(2d);
ExtendedItem.Properties[Shape.StretchProperty].SetValue(Stretch.None);
ExtendedItem.Properties.GetProperty(Line.X1Property).SetValue(0);
ExtendedItem.Properties.GetProperty(Line.Y1Property).SetValue(0);
ExtendedItem.Properties.GetProperty(Line.X2Property).SetValue(20);
ExtendedItem.Properties.GetProperty(Line.Y2Property).SetValue(20);
(ExtendedItem.View as Line).BringIntoView();
}
resizeThumbs = new ResizeThumb[]
{
CreateThumb(PlacementAlignment.TopLeft, Cursors.SizeNWSE),
CreateThumb(PlacementAlignment.BottomRight, Cursors.SizeNWSE)
CreateThumb(PlacementAlignment.TopLeft, Cursors.Cross),
CreateThumb(PlacementAlignment.BottomRight, Cursors.Cross)
};
extendedItemArray[0] = this.ExtendedItem;
Invalidate();
//ResetWidthHeightProperties();
this.ExtendedItem.PropertyChanged += OnPropertyChanged;
this.Services.Selection.PrimarySelectionChanged += OnPrimarySelectionChanged;
resizeBehavior = PlacementOperation.GetPlacementBehavior(extendedItemArray);

154
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PointTrackerPlacementSupport.cs

@ -1,11 +1,21 @@ @@ -1,11 +1,21 @@
/*
* Created by SharpDevelop.
* User: trubra
* Date: 2014-12-22
* Time: 11:05
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
// 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.Windows;
using System.Windows.Shapes;
@ -15,79 +25,79 @@ using ICSharpCode.WpfDesign.Adorners; @@ -15,79 +25,79 @@ using ICSharpCode.WpfDesign.Adorners;
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
public class PointTrackerPlacementSupport : AdornerPlacement
{
private Shape shape;
private PlacementAlignment alignment;
{
private Shape shape;
private PlacementAlignment alignment;
public int Index
{
get; set;
}
public PointTrackerPlacementSupport(Shape s, PlacementAlignment align, int index)
{
shape = s;
alignment = align;
Index = index;
}
public int Index
{
get; set;
}
public PointTrackerPlacementSupport(Shape s, PlacementAlignment align, int index)
{
shape = s;
alignment = align;
Index = index;
}
public PointTrackerPlacementSupport(Shape s, PlacementAlignment align)
{
shape = s;
alignment = align;
Index = -1;
}
public PointTrackerPlacementSupport(Shape s, PlacementAlignment align)
{
shape = s;
alignment = align;
Index = -1;
}
/// <summary>
/// Arranges the adorner element on the specified adorner panel.
/// </summary>
public override void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize)
{
Point p = new Point(0, 0);
double thumbsize = 7;
double distance = thumbsize / 2;
if (shape as Line != null)
{
Line s = shape as Line;
double x, y;
//will give you the angle of the line if more than 180 degrees it becomes negative from
Double theta = (180 / Math.PI) * Math.Atan2(s.Y2 - s.Y1, s.X2 - s.X1);
/// <summary>
/// Arranges the adorner element on the specified adorner panel.
/// </summary>
public override void Arrange(AdornerPanel panel, UIElement adorner, Size adornedElementSize)
{
Point p = new Point(0, 0);
double thumbsize = 7;
double distance = 0;// thumbsize / 2;
if (shape as Line != null)
{
Line s = shape as Line;
double x, y;
//will give you the angle of the line if more than 180 degrees it becomes negative from
Double theta = (180 / Math.PI) * Math.Atan2(s.Y2 - s.Y1, s.X2 - s.X1);
//this will give you the x offset from the line x point in parts of half the size of the thumb
double dx = Math.Cos(theta * (Math.PI / 180)) * distance;
//this will give you the x offset from the line x point in parts of half the size of the thumb
double dx = Math.Cos(theta * (Math.PI / 180)) * distance;
//this will give you the y offset from the line y point in parts of half the size of the thumb
double dy = Math.Sin(theta * (Math.PI / 180)) * distance;
if (alignment == PlacementAlignment.BottomRight)
{
//x offset is linear
x = s.X2 - Math.Abs(theta) / (180 / thumbsize) + dx;
//y offset is angular
y = s.Y2 - ((.5 - Math.Sin(theta * (Math.PI / 180)) * .5) * thumbsize) + dy;
}
else
{
x = s.X1 - ((180 - Math.Abs(theta)) / (180 / thumbsize)) - dx;
y = s.Y1 - ((.5 - Math.Sin(theta * (Math.PI / 180) + Math.PI) * .5) * thumbsize) - dy;
}
p = new Point(x, y);
//this will give you the y offset from the line y point in parts of half the size of the thumb
double dy = Math.Sin(theta * (Math.PI / 180)) * distance;
if (alignment == PlacementAlignment.BottomRight)
{
//x offset is linear
x = s.X2 - Math.Abs(theta) / (180 / thumbsize) + dx;
//y offset is angular
y = s.Y2 - ((.5 - Math.Sin(theta * (Math.PI / 180)) * .5) * thumbsize) + dy;
}
else
{
x = s.X1 - ((180 - Math.Abs(theta)) / (180 / thumbsize)) - dx;
y = s.Y1 - ((.5 - Math.Sin(theta * (Math.PI / 180) + Math.PI) * .5) * thumbsize) - dy;
}
p = new Point(x, y);
}
Polygon pg = shape as Polygon;
Polyline pl = shape as Polyline;
if (pg != null || pl != null)
{
if (Index > 0)
{
p = pl != null ? pl.Points[Index] : pg.Points[Index];
}
Polygon pg = shape as Polygon;
Polyline pl = shape as Polyline;
if (pg != null || pl != null)
{
if (Index > 0)
{
p = pl != null ? pl.Points[Index] : pg.Points[Index];
}
}
adorner.Arrange(new Rect(p, new Size(thumbsize, thumbsize)));
}
}
}
adorner.Arrange(new Rect(p, new Size(thumbsize, thumbsize)));
}
}
}
}

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

@ -155,6 +155,7 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -155,6 +155,7 @@ namespace ICSharpCode.WpfDesign.Designer.Services
object newInstance = context.Services.ExtensionManager.CreateInstanceWithCustomInstanceFactory(componentType, null);
DesignItem item = context.Services.Component.RegisterComponentForDesigner(newInstance);
changeGroup = item.OpenGroup("Drop Control");
context.Services.Component.SetDefaultPropertyValues(item);
context.Services.ExtensionManager.ApplyDefaultInitializers(item);
return item;
}
@ -163,7 +164,7 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -163,7 +164,7 @@ namespace ICSharpCode.WpfDesign.Designer.Services
{
CreateComponentTool cct = new CreateComponentTool(createdItem);
return AddItemWithCustomSize(container, cct.CreateItem(container.Context), position, size);
}
}
public static bool AddItemWithDefaultSize(DesignItem container, Type createdItem, Size size)
{
@ -203,16 +204,13 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -203,16 +204,13 @@ namespace ICSharpCode.WpfDesign.Designer.Services
if (result.ModelHit != null) {
var drawItembehavior = result.ModelHit.GetBehavior<IDrawItemBehavior>();
if (drawItembehavior != null && drawItembehavior.CanItemBeDrawn(componentType)) {
var createdItem = CreateItem(designPanel.Context);
drawItembehavior.StartDrawItem(result.ModelHit, createdItem, changeGroup, designPanel, e);
// IDrawItemBehavior now is responsible for the changeGroup created by CreateItem()
changeGroup = null;
drawItembehavior.StartDrawItem(result.ModelHit, componentType, designPanel, e);
}
else {
var placementBehavior = result.ModelHit.GetBehavior<IPlacementBehavior>();
if (placementBehavior != null) {
var createdItem = CreateItem(designPanel.Context);
new CreateComponentMouseGesture(result.ModelHit, createdItem, changeGroup).Start(designPanel, e);
// CreateComponentMouseGesture now is responsible for the changeGroup created by CreateItem()
changeGroup = null;

14
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs

@ -29,7 +29,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -29,7 +29,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
sealed class XamlComponentService : IComponentService
{
public event EventHandler<DesignItemPropertyChangedEventArgs> PropertyChanged;
#region IdentityEqualityComparer
sealed class IdentityEqualityComparer : IEqualityComparer<object>
{
@ -69,7 +69,17 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -69,7 +69,17 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
_sites.TryGetValue(component, out site);
return site;
}
public void SetDefaultPropertyValues(DesignItem designItem)
{
var values = Metadata.GetDefaultPropertyValues(designItem.ComponentType);
if (values != null) {
foreach (var value in values) {
designItem.Properties[value.Key].SetValue(value.Value);
}
}
}
public DesignItem RegisterComponentForDesigner(object component)
{
if (component == null) {

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

@ -30,6 +30,6 @@ namespace ICSharpCode.WpfDesign @@ -30,6 +30,6 @@ namespace ICSharpCode.WpfDesign
public interface IDrawItemBehavior
{
bool CanItemBeDrawn(Type createItemType);
void StartDrawItem(DesignItem clickedOn, DesignItem createdItem, ChangeGroup changeGroup, IDesignPanel panel, MouseEventArgs e);
void StartDrawItem(DesignItem clickedOn, Type createItemType, IDesignPanel panel, MouseEventArgs e);
}
}

32
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Metadata.cs

@ -45,6 +45,8 @@ namespace ICSharpCode.WpfDesign @@ -45,6 +45,8 @@ namespace ICSharpCode.WpfDesign
// Why not per-design context (as a service?)
static Dictionary<Type, List<object>> standardValues = new Dictionary<Type, List<object>>();
static Dictionary<Type, Dictionary<DependencyProperty, object>> standardPropertyValues = new Dictionary<Type, Dictionary<DependencyProperty, object>>();
/// <summary>
/// Registers a set of standard values for a <paramref name="type"/> by using the
/// public static properties of the type <paramref name="valuesContainer"/>.
@ -321,11 +323,39 @@ namespace ICSharpCode.WpfDesign @@ -321,11 +323,39 @@ namespace ICSharpCode.WpfDesign
if (defaultSizes.TryGetValue(t, out s)) {
return s;
}
t = checkBasetype ? t.BaseType : null;
t = checkBasetype ? t.BaseType : null;
}
}
return null;
}
/// <summary>
/// Registers a default Property Value wich should be used
/// </summary>
public static void AddDefaultPropertyValue(Type t, DependencyProperty p, object value)
{
lock (standardPropertyValues)
{
if (!standardPropertyValues.ContainsKey(t))
standardPropertyValues.Add(t, new Dictionary<DependencyProperty, object>());
standardPropertyValues[t][p] = value;
}
}
/// <summary>
/// Gets Default Propertie Values for a type
/// </summary>
public static Dictionary<DependencyProperty, object> GetDefaultPropertyValues(Type t)
{
lock (standardPropertyValues)
{
if (standardPropertyValues.ContainsKey(t))
return standardPropertyValues[t];
return null;
}
}
}
/// <summary>

3
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs

@ -129,6 +129,9 @@ namespace ICSharpCode.WpfDesign @@ -129,6 +129,9 @@ namespace ICSharpCode.WpfDesign
/// <summary>Property Changed</summary>
event EventHandler<DesignItemPropertyChangedEventArgs> PropertyChanged;
/// <summary> Set's default Property Values as defined in Metadata </summary>
void SetDefaultPropertyValues(DesignItem designItem);
}
#endregion

Loading…
Cancel
Save