Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions UI/Controls/Ink/DrawingAttributes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Windows.Media;

namespace InkkSlinger.UI.Controls.Ink
{
public class DrawingAttributes
{
public Color Color { get; set; } = Colors.Black;
public double Width { get; set; } = 2.0;
public double Height { get; set; } = 2.0;
}
}
74 changes: 74 additions & 0 deletions UI/Controls/Ink/InkCanvas.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace InkkSlinger.UI.Controls.Ink
{
public class InkCanvas : FrameworkElement
{
public static readonly DependencyProperty StrokesProperty =
DependencyProperty.Register(nameof(Strokes), typeof(StrokeCollection), typeof(InkCanvas),
new FrameworkPropertyMetadata(new StrokeCollection(), FrameworkPropertyMetadataOptions.AffectsRender));

public static readonly DependencyProperty DefaultDrawingAttributesProperty =
DependencyProperty.Register(nameof(DefaultDrawingAttributes), typeof(DrawingAttributes), typeof(InkCanvas),
new FrameworkPropertyMetadata(new DrawingAttributes(), FrameworkPropertyMetadataOptions.AffectsRender));

public StrokeCollection Strokes
{
get => (StrokeCollection)GetValue(StrokesProperty);
set => SetValue(StrokesProperty, value);
}

public DrawingAttributes DefaultDrawingAttributes
{
get => (DrawingAttributes)GetValue(DefaultDrawingAttributesProperty);
set => SetValue(DefaultDrawingAttributesProperty, value);
}

private StylusPointCollection _currentPoints;
private bool _isDrawing;

protected override void OnRender(DrawingContext dc)
{
base.OnRender(dc);
foreach (var stroke in Strokes)
{
var geo = stroke.GetGeometry();
if (geo != Geometry.Empty)
dc.DrawGeometry(null, new Pen(new SolidColorBrush(stroke.DrawingAttributes.Color), stroke.DrawingAttributes.Width), geo);
}
}

protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
_isDrawing = true;
var p = e.GetPosition(this);
_currentPoints = new StylusPointCollection { new StylusPoint(p.X, p.Y) };
CaptureMouse();
}

protected override void OnMouseMove(MouseEventArgs e)
{
if (!_isDrawing) return;
var p = e.GetPosition(this);
_currentPoints.Add(new StylusPoint(p.X, p.Y));
InvalidateVisual();
}

protected override void OnMouseUp(MouseButtonEventArgs e)
{
if (!_isDrawing) return;
var p = e.GetPosition(this);
_currentPoints.Add(new StylusPoint(p.X, p.Y));
Strokes.Add(new Stroke(_currentPoints, DefaultDrawingAttributes));
_isDrawing = false;
ReleaseMouseCapture();
InvalidateVisual();
}
}
}
30 changes: 30 additions & 0 deletions UI/Controls/Ink/InkPresenter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Windows;
using System.Windows.Media;

namespace InkkSlinger.UI.Controls.Ink
{
public class InkPresenter : FrameworkElement
{
public static readonly DependencyProperty StrokesProperty =
DependencyProperty.Register(nameof(Strokes), typeof(StrokeCollection), typeof(InkPresenter),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));

public StrokeCollection Strokes
{
get => (StrokeCollection)GetValue(StrokesProperty);
set => SetValue(StrokesProperty, value);
}

protected override void OnRender(DrawingContext dc)
{
base.OnRender(dc);
if (Strokes == null) return;
foreach (var stroke in Strokes)
{
var geo = stroke.GetGeometry();
if (geo != Geometry.Empty)
dc.DrawGeometry(null, new Pen(new SolidColorBrush(stroke.DrawingAttributes.Color), stroke.DrawingAttributes.Width), geo);
}
}
}
}
26 changes: 26 additions & 0 deletions UI/Controls/Ink/Stroke.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Windows;
using System.Windows.Media;

namespace InkkSlinger.UI.Controls.Ink
{
public class Stroke
{
public StylusPointCollection StylusPoints { get; }
public DrawingAttributes DrawingAttributes { get; set; }

public Stroke(StylusPointCollection stylusPoints, DrawingAttributes drawingAttributes)
{
StylusPoints = stylusPoints;
DrawingAttributes = drawingAttributes;
}

public Geometry GetGeometry()
{
if (StylusPoints.Count < 2) return Geometry.Empty;
var fig = new PathFigure { StartPoint = new Point(StylusPoints[0].X, StylusPoints[0].Y) };
for (int i = 1; i < StylusPoints.Count; i++)
fig.Segments.Add(new LineSegment(new Point(StylusPoints[i].X, StylusPoints[i].Y), true));
return new PathGeometry { Figures = { fig } };
}
}
}
6 changes: 6 additions & 0 deletions UI/Controls/Ink/StrokeCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using System.Collections.ObjectModel;

namespace InkkSlinger.UI.Controls.Ink
{
public class StrokeCollection : ObservableCollection<Stroke> { }
}
16 changes: 16 additions & 0 deletions UI/Controls/Ink/StylusPoint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace InkkSlinger.UI.Controls.Ink
{
public struct StylusPoint
{
public double X { get; }
public double Y { get; }
public float PressureFactor { get; }

public StylusPoint(double x, double y, float pressureFactor = 0.5f)
{
X = x;
Y = y;
PressureFactor = pressureFactor;
}
}
}
6 changes: 6 additions & 0 deletions UI/Controls/Ink/StylusPointCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using System.Collections.Generic;

namespace InkkSlinger.UI.Controls.Ink
{
public class StylusPointCollection : List<StylusPoint> { }
}