From ba653e553df3cc0b78dcc34fe0789ae3c0b785c3 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Fri, 21 Apr 2017 18:24:59 +0200 Subject: [PATCH] Rewrote the Xamarin.Forms views: - SignaturePadCanvasView is now wrapped as this is chromeless - SignaturePadView is now a fully Xamarin.Forms view so that it can be better customized as there is access to the individual views --- ...gnaturePad.Forms.Platform.Shared.projitems | 2 +- ...derer.cs => SignaturePadCanvasRenderer.cs} | 140 ++--- .../SignaturePad.Forms.Shared.projitems | 1 + .../SignaturePadCanvasView.cs | 261 +++++++++ .../SignaturePadView.cs | 509 ++++++++++++------ .../SignaturePad.Forms.csproj | 2 +- .../SignaturePadCanvasRenderer.cs | 6 + .../SignaturePadRenderer.cs | 6 - 8 files changed, 672 insertions(+), 255 deletions(-) rename src/SignaturePad.Forms.Platform.Shared/{SignaturePadRenderer.cs => SignaturePadCanvasRenderer.cs} (53%) create mode 100644 src/SignaturePad.Forms.Shared/SignaturePadCanvasView.cs create mode 100644 src/SignaturePad.Forms/SignaturePadCanvasRenderer.cs delete mode 100644 src/SignaturePad.Forms/SignaturePadRenderer.cs diff --git a/src/SignaturePad.Forms.Platform.Shared/SignaturePad.Forms.Platform.Shared.projitems b/src/SignaturePad.Forms.Platform.Shared/SignaturePad.Forms.Platform.Shared.projitems index 8d79825..988a864 100644 --- a/src/SignaturePad.Forms.Platform.Shared/SignaturePad.Forms.Platform.Shared.projitems +++ b/src/SignaturePad.Forms.Platform.Shared/SignaturePad.Forms.Platform.Shared.projitems @@ -10,6 +10,6 @@ - + \ No newline at end of file diff --git a/src/SignaturePad.Forms.Platform.Shared/SignaturePadRenderer.cs b/src/SignaturePad.Forms.Platform.Shared/SignaturePadCanvasRenderer.cs similarity index 53% rename from src/SignaturePad.Forms.Platform.Shared/SignaturePadRenderer.cs rename to src/SignaturePad.Forms.Platform.Shared/SignaturePadCanvasRenderer.cs index 9345ba2..31c5914 100644 --- a/src/SignaturePad.Forms.Platform.Shared/SignaturePadRenderer.cs +++ b/src/SignaturePad.Forms.Platform.Shared/SignaturePadCanvasRenderer.cs @@ -1,47 +1,35 @@ +using System; using System.ComponentModel; -using System.IO; -using System.Threading.Tasks; using System.Linq; using Xamarin.Forms; using SignaturePad.Forms; using Color = Xamarin.Forms.Color; using Point = Xamarin.Forms.Point; #if WINDOWS_PHONE -using System.Windows.Media; -using System.Windows.Media.Imaging; using Xamarin.Forms.Platform.WinPhone; -using NativeSignaturePadView = Xamarin.Controls.SignaturePad; +using NativeSignaturePadCanvasView = Xamarin.Controls.SignaturePadCanvasView; using NativePoint = System.Windows.Point; #elif WINDOWS_UWP -using System.Runtime.InteropServices.WindowsRuntime; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Media.Imaging; using Xamarin.Forms.Platform.UWP; -using Microsoft.Graphics.Canvas; -using NativeSignaturePadView = Xamarin.Controls.SignaturePad; +using NativeSignaturePadCanvasView = Xamarin.Controls.SignaturePadCanvasView; using NativePoint = Windows.Foundation.Point; #elif __IOS__ -using UIKit; using Xamarin.Forms.Platform.iOS; -using NativeSignaturePadView = Xamarin.Controls.SignaturePadView; +using NativeSignaturePadCanvasView = Xamarin.Controls.SignaturePadCanvasView; using NativePoint = CoreGraphics.CGPoint; -using NativeColor = UIKit.UIColor; #elif __ANDROID__ -using Android.Graphics; -using Android.Widget; using Xamarin.Forms.Platform.Android; -using NativeSignaturePadView = Xamarin.Controls.SignaturePadView; +using NativeSignaturePadCanvasView = Xamarin.Controls.SignaturePadCanvasView; using NativePoint = System.Drawing.PointF; -using NativeColor = Android.Graphics.Color; #endif -[assembly: ExportRenderer (typeof (SignaturePadView), typeof (SignaturePadRenderer))] +[assembly: ExportRenderer (typeof (SignaturePadCanvasView), typeof (SignaturePadCanvasRenderer))] namespace SignaturePad.Forms { - public class SignaturePadRenderer : ViewRenderer + public class SignaturePadCanvasRenderer : ViewRenderer { - protected override void OnElementChanged (ElementChangedEventArgs e) + protected override void OnElementChanged (ElementChangedEventArgs e) { base.OnElementChanged (e); @@ -49,10 +37,13 @@ protected override void OnElementChanged (ElementChangedEventArgs s.Select (p => new Point (p.X, p.Y))); + } + } + + private void OnStrokesSpecified (object sender, SignaturePadCanvasView.StrokesEventArgs e) + { + var ctrl = Control; + if (ctrl != null) + { + ctrl.LoadStrokes (e.Strokes.Select (s => s.Select (p => new NativePoint ((float)p.X, (float)p.Y)).ToArray ()).ToArray ()); + } + } + + private void OnClearRequested (object sender, EventArgs e) { var ctrl = Control; if (ctrl != null) @@ -160,38 +178,6 @@ private void UpdateAll () return; } - if (Element.BackgroundColor != Color.Default) - { - Control.BackgroundColor = Element.BackgroundColor.ToNative (); - } - if (!string.IsNullOrEmpty (Element.CaptionText)) - { - Control.CaptionText = Element.CaptionText; - } - if (Element.CaptionTextColor != Color.Default) - { - Control.Caption.SetTextColor (Element.CaptionTextColor); - } - if (!string.IsNullOrEmpty (Element.ClearText)) - { - Control.ClearLabelText = Element.ClearText; - } - if (Element.ClearTextColor != Color.Default) - { - Control.ClearLabel.SetTextColor (Element.ClearTextColor); - } - if (!string.IsNullOrEmpty (Element.PromptText)) - { - Control.SignaturePromptText = Element.PromptText; - } - if (Element.PromptTextColor != Color.Default) - { - Control.SignaturePrompt.SetTextColor (Element.PromptTextColor); - } - if (Element.SignatureLineColor != Color.Default) - { - Control.SignatureLineColor = Element.SignatureLineColor.ToNative (); - } if (Element.StrokeColor != Color.Default) { Control.StrokeColor = Element.StrokeColor.ToNative (); @@ -212,43 +198,11 @@ private void Update (string property) return; } - if (property == SignaturePadView.BackgroundColorProperty.PropertyName) - { - Control.BackgroundColor = Element.BackgroundColor.ToNative (); - } - else if (property == SignaturePadView.CaptionTextProperty.PropertyName) - { - Control.CaptionText = Element.CaptionText; - } - else if (property == SignaturePadView.CaptionTextColorProperty.PropertyName) - { - Control.Caption.SetTextColor (Element.CaptionTextColor); - } - else if (property == SignaturePadView.ClearTextProperty.PropertyName) - { - Control.ClearLabelText = Element.ClearText; - } - else if (property == SignaturePadView.ClearTextColorProperty.PropertyName) - { - Control.ClearLabel.SetTextColor (Element.ClearTextColor); - } - else if (property == SignaturePadView.PromptTextProperty.PropertyName) - { - Control.SignaturePromptText = Element.PromptText; - } - else if (property == SignaturePadView.PromptTextColorProperty.PropertyName) - { - Control.SignaturePrompt.SetTextColor (Element.PromptTextColor); - } - else if (property == SignaturePadView.SignatureLineColorProperty.PropertyName) - { - Control.SignatureLineColor = Element.SignatureLineColor.ToNative (); - } - else if (property == SignaturePadView.StrokeColorProperty.PropertyName) + if (property == SignaturePadCanvasView.StrokeColorProperty.PropertyName) { Control.StrokeColor = Element.StrokeColor.ToNative (); } - else if (property == SignaturePadView.StrokeWidthProperty.PropertyName) + else if (property == SignaturePadCanvasView.StrokeWidthProperty.PropertyName) { Control.StrokeWidth = Element.StrokeWidth; } diff --git a/src/SignaturePad.Forms.Shared/SignaturePad.Forms.Shared.projitems b/src/SignaturePad.Forms.Shared/SignaturePad.Forms.Shared.projitems index dcc7f19..04c4436 100644 --- a/src/SignaturePad.Forms.Shared/SignaturePad.Forms.Shared.projitems +++ b/src/SignaturePad.Forms.Shared/SignaturePad.Forms.Shared.projitems @@ -12,5 +12,6 @@ + \ No newline at end of file diff --git a/src/SignaturePad.Forms.Shared/SignaturePadCanvasView.cs b/src/SignaturePad.Forms.Shared/SignaturePadCanvasView.cs new file mode 100644 index 0000000..0d07831 --- /dev/null +++ b/src/SignaturePad.Forms.Shared/SignaturePadCanvasView.cs @@ -0,0 +1,261 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using Xamarin.Forms; + +namespace SignaturePad.Forms +{ + [RenderWith (typeof (SignaturePadCanvasRenderer))] + public class SignaturePadCanvasView : View + { + public static readonly BindableProperty StrokeColorProperty = BindableProperty.Create ( + nameof (StrokeColor), + typeof (Color), + typeof (SignaturePadView), + Color.Default); + + public static readonly BindableProperty StrokeWidthProperty = BindableProperty.Create ( + nameof (StrokeWidth), + typeof (float), + typeof (SignaturePadView), + (float)0); + + public bool IsBlank + { + get { return RequestIsBlank (); } + } + + public float StrokeWidth + { + get { return (float)GetValue (StrokeWidthProperty); } + set { SetValue (StrokeWidthProperty, value); } + } + + public Color StrokeColor + { + get { return (Color)GetValue (StrokeColorProperty); } + set { SetValue (StrokeColorProperty, value); } + } + + public IEnumerable Points + { + get { return GetSignaturePoints (); } + set { SetSignaturePoints (value); } + } + + public IEnumerable> Strokes + { + get { return GetSignatureStrokes (); } + set { SetSignatureStrokes (value); } + } + + /// + /// Create an encoded image stream of the currently drawn signature. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, bool shouldCrop = true, bool keepAspectRatio = true) + { + return GetImageStreamAsync (format, new ImageConstructionSettings + { + ShouldCrop = shouldCrop, + DesiredSizeOrScale = new SizeOrScale (1f, SizeOrScaleType.Scale, keepAspectRatio) + }); + } + + /// + /// Create an encoded image stream of the currently drawn signature at the specified size. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, Size size, bool shouldCrop = true, bool keepAspectRatio = true) + { + return GetImageStreamAsync (format, new ImageConstructionSettings + { + ShouldCrop = shouldCrop, + DesiredSizeOrScale = new SizeOrScale (size, SizeOrScaleType.Size, keepAspectRatio) + }); + } + + /// + /// Create an encoded image stream of the currently drawn signature at the specified scale. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, float scale, bool shouldCrop = true, bool keepAspectRatio = true) + { + return GetImageStreamAsync (format, new ImageConstructionSettings + { + ShouldCrop = shouldCrop, + DesiredSizeOrScale = new SizeOrScale (scale, SizeOrScaleType.Scale, keepAspectRatio) + }); + } + + /// + /// Create an encoded image stream of the currently drawn signature with the specified stroke color. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, bool shouldCrop = true, bool keepAspectRatio = true) + { + return GetImageStreamAsync (format, new ImageConstructionSettings + { + ShouldCrop = shouldCrop, + DesiredSizeOrScale = new SizeOrScale (1f, SizeOrScaleType.Scale, keepAspectRatio), + StrokeColor = strokeColor + }); + } + + /// + /// Create an encoded image stream of the currently drawn signature at the specified size with the specified stroke color. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, Size size, bool shouldCrop = true, bool keepAspectRatio = true) + { + return GetImageStreamAsync (format, new ImageConstructionSettings + { + ShouldCrop = shouldCrop, + StrokeColor = strokeColor, + DesiredSizeOrScale = new SizeOrScale (size, SizeOrScaleType.Size, keepAspectRatio) + }); + } + + /// + /// Create an encoded image stream of the currently drawn signature at the specified scale with the specified stroke color. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, float scale, bool shouldCrop = true, bool keepAspectRatio = true) + { + return GetImageStreamAsync (format, new ImageConstructionSettings + { + ShouldCrop = shouldCrop, + StrokeColor = strokeColor, + DesiredSizeOrScale = new SizeOrScale (scale, SizeOrScaleType.Scale, keepAspectRatio) + }); + } + + /// + /// Create an encoded image stream of the currently drawn signature with the specified stroke and background colors. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, Color fillColor, bool shouldCrop = true, bool keepAspectRatio = true) + { + return GetImageStreamAsync (format, new ImageConstructionSettings + { + ShouldCrop = shouldCrop, + DesiredSizeOrScale = new SizeOrScale (1f, SizeOrScaleType.Scale, keepAspectRatio), + StrokeColor = strokeColor, + BackgroundColor = fillColor + }); + } + + /// + /// Create an encoded image stream of the currently drawn signature at the specified size with the specified stroke and background colors. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, Color fillColor, Size size, bool shouldCrop = true, bool keepAspectRatio = true) + { + return GetImageStreamAsync (format, new ImageConstructionSettings + { + ShouldCrop = shouldCrop, + StrokeColor = strokeColor, + BackgroundColor = fillColor, + DesiredSizeOrScale = new SizeOrScale (size, SizeOrScaleType.Size, keepAspectRatio) + }); + } + + /// + /// Create an encoded image stream of the currently drawn signature at the specified scale with the specified stroke and background colors. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, Color fillColor, float scale, bool shouldCrop = true, bool keepAspectRatio = true) + { + return GetImageStreamAsync (format, new ImageConstructionSettings + { + ShouldCrop = shouldCrop, + StrokeColor = strokeColor, + BackgroundColor = fillColor, + DesiredSizeOrScale = new SizeOrScale (scale, SizeOrScaleType.Scale, keepAspectRatio) + }); + } + + /// + /// Create an encoded image stream of the currently drawn signature using the specified settings. + /// + public Task GetImageStreamAsync (SignatureImageFormat imageFormat, ImageConstructionSettings settings) + { + var args = new ImageStreamRequestedEventArgs (imageFormat, settings); + ImageStreamRequested?.Invoke (this, args); + return args.ImageStreamTask; + } + + public void Clear () + { + ClearRequested?.Invoke (this, null); + } + + private IEnumerable GetSignaturePoints () + { + var args = new PointsEventArgs (); + PointsRequested?.Invoke (this, args); + return args.Points; + } + + private void SetSignaturePoints (IEnumerable points) + { + PointsSpecified?.Invoke (this, new PointsEventArgs { Points = points }); + } + + private IEnumerable> GetSignatureStrokes () + { + var args = new StrokesEventArgs (); + StrokesRequested?.Invoke (this, args); + return args.Strokes; + } + + private void SetSignatureStrokes (IEnumerable> strokes) + { + StrokesSpecified?.Invoke (this, new StrokesEventArgs { Strokes = strokes }); + } + + private bool RequestIsBlank () + { + var args = new IsBlankRequestedEventArgs (); + IsBlankRequested?.Invoke (this, args); + return args.IsBlank; + } + + internal void OnStrokeCompleted () + { + StrokeCompleted?.Invoke (this, EventArgs.Empty); + } + + public event EventHandler StrokeCompleted; + + internal event EventHandler ImageStreamRequested; + internal event EventHandler IsBlankRequested; + internal event EventHandler PointsRequested; + internal event EventHandler PointsSpecified; + internal event EventHandler StrokesRequested; + internal event EventHandler StrokesSpecified; + internal event EventHandler ClearRequested; + + internal class ImageStreamRequestedEventArgs : EventArgs + { + public ImageStreamRequestedEventArgs (SignatureImageFormat imageFormat, ImageConstructionSettings settings) + { + ImageFormat = imageFormat; + Settings = settings; + } + + public SignatureImageFormat ImageFormat { get; private set; } + + public ImageConstructionSettings Settings { get; private set; } + + public Task ImageStreamTask { get; set; } = Task.FromResult (null); + } + + internal class IsBlankRequestedEventArgs : EventArgs + { + public bool IsBlank { get; set; } = true; + } + + internal class PointsEventArgs : EventArgs + { + public IEnumerable Points { get; set; } = new Point[0]; + } + + internal class StrokesEventArgs : EventArgs + { + public IEnumerable> Strokes { get; set; } = new Point[0][]; + } + } +} diff --git a/src/SignaturePad.Forms.Shared/SignaturePadView.cs b/src/SignaturePad.Forms.Shared/SignaturePadView.cs index a7356dd..e2c9f90 100644 --- a/src/SignaturePad.Forms.Shared/SignaturePadView.cs +++ b/src/SignaturePad.Forms.Shared/SignaturePadView.cs @@ -1,269 +1,470 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Xamarin.Forms; namespace SignaturePad.Forms { - [RenderWith (typeof (SignaturePadRenderer))] - public class SignaturePadView : View + public class SignaturePadView : Grid { - public static readonly BindableProperty CaptionTextProperty = BindableProperty.Create (nameof (CaptionText), typeof (string), typeof (SignaturePadView), null); - public static readonly BindableProperty CaptionTextColorProperty = BindableProperty.Create (nameof (CaptionTextColor), typeof (Color), typeof (SignaturePadView), Color.Default); - public static readonly BindableProperty ClearTextProperty = BindableProperty.Create (nameof (ClearText), typeof (string), typeof (SignaturePadView), null); - public static readonly BindableProperty ClearTextColorProperty = BindableProperty.Create (nameof (ClearTextColor), typeof (Color), typeof (SignaturePadView), Color.Default); - public static readonly BindableProperty PromptTextProperty = BindableProperty.Create (nameof (PromptText), typeof (string), typeof (SignaturePadView), null); - public static readonly BindableProperty PromptTextColorProperty = BindableProperty.Create (nameof (PromptTextColor), typeof (Color), typeof (SignaturePadView), Color.Default); - public static readonly BindableProperty SignatureLineColorProperty = BindableProperty.Create (nameof (SignatureLineColor), typeof (Color), typeof (SignaturePadView), Color.Default); - public static readonly BindableProperty StrokeColorProperty = BindableProperty.Create (nameof (StrokeColor), typeof (Color), typeof (SignaturePadView), Color.Default); - public static readonly BindableProperty StrokeWidthProperty = BindableProperty.Create (nameof (StrokeWidth), typeof (float), typeof (SignaturePadView), (float)0); - - public bool IsBlank + public static readonly BindableProperty CaptionTextProperty = BindableProperty.Create ( + nameof (CaptionText), + typeof (string), + typeof (SignaturePadView), + (string)null, + propertyChanged: (bindable, oldValue, newValue) => ((SignaturePadView)bindable).CaptionLabel.Text = (string)newValue); + + public static readonly BindableProperty CaptionTextColorProperty = BindableProperty.Create ( + nameof (CaptionTextColor), + typeof (Color), + typeof (SignaturePadView), + Color.Default, + propertyChanged: (bindable, oldValue, newValue) => ((SignaturePadView)bindable).CaptionLabel.TextColor = (Color)newValue); + + public static readonly BindableProperty ClearTextProperty = BindableProperty.Create ( + nameof (ClearText), + typeof (string), + typeof (SignaturePadView), + (string)null, + propertyChanged: (bindable, oldValue, newValue) => ((SignaturePadView)bindable).ClearLabel.Text = (string)newValue); + + public static readonly BindableProperty ClearTextColorProperty = BindableProperty.Create ( + nameof (ClearTextColor), + typeof (Color), + typeof (SignaturePadView), + Color.Default, + propertyChanged: (bindable, oldValue, newValue) => ((SignaturePadView)bindable).ClearLabel.TextColor = (Color)newValue); + + public static readonly BindableProperty PromptTextProperty = BindableProperty.Create ( + nameof (PromptText), + typeof (string), + typeof (SignaturePadView), + (string)null, + propertyChanged: (bindable, oldValue, newValue) => ((SignaturePadView)bindable).SignaturePrompt.Text = (string)newValue); + + public static readonly BindableProperty PromptTextColorProperty = BindableProperty.Create ( + nameof (PromptTextColor), + typeof (Color), + typeof (SignaturePadView), + Color.Default, + propertyChanged: (bindable, oldValue, newValue) => ((SignaturePadView)bindable).SignaturePrompt.TextColor = (Color)newValue); + + public static readonly BindableProperty SignatureLineColorProperty = BindableProperty.Create ( + nameof (SignatureLineColor), + typeof (Color), + typeof (SignaturePadView), + Color.Default, + propertyChanged: (bindable, oldValue, newValue) => ((SignaturePadView)bindable).SignatureLine.Color = (Color)newValue); + + public static readonly BindableProperty StrokeColorProperty = BindableProperty.Create ( + nameof (StrokeColor), + typeof (Color), + typeof (SignaturePadView), + Color.Default, + propertyChanged: (bindable, oldValue, newValue) => ((SignaturePadView)bindable).SignaturePadCanvas.StrokeColor = (Color)newValue); + + public static readonly BindableProperty StrokeWidthProperty = BindableProperty.Create ( + nameof (StrokeWidth), + typeof (float), + typeof (SignaturePadView), + (float)0, + propertyChanged: (bindable, oldValue, newValue) => ((SignaturePadView)bindable).SignaturePadCanvas.StrokeWidth = (float)newValue); + + public static readonly BindableProperty BackgroundImageProperty = BindableProperty.Create ( + nameof (BackgroundImage), + typeof (ImageSource), + typeof (SignaturePadView), + (ImageSource)null, + propertyChanged: (bindable, oldValue, newValue) => ((SignaturePadView)bindable).BackgroundImageView.Source = (ImageSource)newValue); + + public static readonly BindableProperty BackgroundImageAspectProperty = BindableProperty.Create ( + nameof (BackgroundImageAspect), + typeof (Aspect), + typeof (SignaturePadView), + Aspect.AspectFit, + propertyChanged: (bindable, oldValue, newValue) => ((SignaturePadView)bindable).BackgroundImageView.Aspect = (Aspect)newValue); + + public static readonly BindableProperty BackgroundImageOpacityProperty = BindableProperty.Create ( + nameof (BackgroundImageOpacity), + typeof (double), + typeof (SignaturePadView), + (double)0, + propertyChanged: (bindable, oldValue, newValue) => ((SignaturePadView)bindable).BackgroundImageView.Opacity = (double)newValue); + + public SignaturePadView () { - get { return RequestIsBlank (); } + Initialize (); } - public string CaptionText + private void Initialize () { - get { return (string)GetValue (CaptionTextProperty); } - set { SetValue (CaptionTextProperty, value); } + const int ThinPad = 3; + const int ThickPad = 12; + const int LineHeight = 2; + + RowSpacing = 0; + ColumnSpacing = 0; + + RowDefinitions.Add (new RowDefinition { Height = new GridLength (1, GridUnitType.Star) }); + RowDefinitions.Add (new RowDefinition { Height = GridLength.Auto }); + + // add the background view + { + BackgroundImageView = new Image (); + BackgroundImageView.SetValue (Grid.HorizontalOptionsProperty, LayoutOptions.FillAndExpand); + BackgroundImageView.SetValue (Grid.VerticalOptionsProperty, LayoutOptions.FillAndExpand); + BackgroundImageView.SetValue (Grid.RowProperty, 0); + Children.Add (BackgroundImageView); + } + + // add the main signature view + { + SignaturePadCanvas = new SignaturePadCanvasView (); + SignaturePadCanvas.SetValue (Grid.HorizontalOptionsProperty, LayoutOptions.FillAndExpand); + SignaturePadCanvas.SetValue (Grid.VerticalOptionsProperty, LayoutOptions.FillAndExpand); + SignaturePadCanvas.SetValue (Grid.RowProperty, 0); + SignaturePadCanvas.SetValue (Grid.RowSpanProperty, 2); + SignaturePadCanvas.StrokeCompleted += (sender, e) => UpdateUi (); + Children.Add (SignaturePadCanvas); + } + + // add the caption + { + CaptionLabel = new Label + { + Text = "Sign here.", + FontSize = 11, + TextColor = Color.Gray, + HorizontalTextAlignment = TextAlignment.Center, + Margin = new Thickness (ThinPad) + }; + CaptionLabel.SetValue (Grid.HorizontalOptionsProperty, LayoutOptions.FillAndExpand); + CaptionLabel.SetValue (Grid.VerticalOptionsProperty, LayoutOptions.End); + CaptionLabel.SetValue (Grid.RowProperty, 1); + Children.Add (CaptionLabel); + } + + // add the signature line + { + SignatureLine = new BoxView + { + BackgroundColor = Color.Gray, + HeightRequest = LineHeight, + Margin = new Thickness (ThickPad, 0, ThickPad, 0) + }; + SignatureLine.SetValue (Grid.HorizontalOptionsProperty, LayoutOptions.FillAndExpand); + SignatureLine.SetValue (Grid.VerticalOptionsProperty, LayoutOptions.End); + Children.Add (SignatureLine); + } + + // add the prompt + { + SignaturePrompt = new Label + { + Text = "X", + FontSize = 20, + FontAttributes = FontAttributes.Bold, + Margin = new Thickness (ThickPad, 0, 0, ThinPad) + }; + SignaturePrompt.SetValue (Grid.HorizontalOptionsProperty, LayoutOptions.Start); + SignaturePrompt.SetValue (Grid.VerticalOptionsProperty, LayoutOptions.End); + Children.Add (SignaturePrompt); + } + + // add the clear label + { + ClearLabel = new Label + { + Text = "Clear", + FontSize = 11, + FontAttributes = FontAttributes.Bold, + IsVisible = false, + TextColor = Color.Gray, + Margin = new Thickness (0, ThickPad, ThickPad, 0) + }; + ClearLabel.SetValue (Grid.HorizontalOptionsProperty, LayoutOptions.End); + ClearLabel.SetValue (Grid.VerticalOptionsProperty, LayoutOptions.Start); + Children.Add (ClearLabel); + + // attach the "clear" command + ClearLabel.GestureRecognizers.Add (new TapGestureRecognizer { Command = new Command (() => Clear ()) }); + } + + // clear / initialize the view + Clear (); } - public Color CaptionTextColor + public IEnumerable> Strokes { - get { return (Color)GetValue (CaptionTextColorProperty); } - set { SetValue (CaptionTextColorProperty, value); } + get { return SignaturePadCanvas.Strokes; } + set + { + SignaturePadCanvas.Strokes = value; + UpdateUi (); + } } - public string ClearText + public IEnumerable Points { - get { return (string)GetValue (ClearTextProperty); } - set { SetValue (ClearTextProperty, value); } + get { return SignaturePadCanvas.Points; } + set + { + SignaturePadCanvas.Points = value; + UpdateUi (); + } } - public Color ClearTextColor + public bool IsBlank => SignaturePadCanvas.IsBlank; + + public SignaturePadCanvasView SignaturePadCanvas { get; private set; } + + public Color StrokeColor { - get { return (Color)GetValue (ClearTextColorProperty); } - set { SetValue (ClearTextColorProperty, value); } + get { return (Color)GetValue (StrokeColorProperty); } + set { SetValue (StrokeColorProperty, value); } } - public string PromptText + public float StrokeWidth { - get { return (string)GetValue (PromptTextProperty); } - set { SetValue (PromptTextProperty, value); } + get { return (float)GetValue (StrokeWidthProperty); } + set { SetValue (StrokeWidthProperty, value); } } - public Color PromptTextColor + /// + /// The prompt displayed at the beginning of the signature line. + /// + /// + /// Text value defaults to 'X'. + /// + /// The signature prompt. + public Label SignaturePrompt { get; private set; } + + /// + /// The caption displayed under the signature line. + /// + /// + /// Text value defaults to 'Sign here.' + /// + /// The caption. + public Label CaptionLabel { get; private set; } + + /// + /// The color of the caption text. + /// + /// The color of the caption text. + public Color CaptionTextColor { - get { return (Color)GetValue (PromptTextColorProperty); } - set { SetValue (PromptTextColorProperty, value); } + get { return (Color)GetValue (CaptionTextColorProperty); } + set { SetValue (CaptionTextColorProperty, value); } } + /// + /// The color of the signature line. + /// + /// The color of the signature line. public Color SignatureLineColor { get { return (Color)GetValue (SignatureLineColorProperty); } set { SetValue (SignatureLineColorProperty, value); } } - public float StrokeWidth + /// + /// An image view that may be used as a watermark or as a texture + /// for the signature pad. + /// + /// The background image view. + public Image BackgroundImageView { get; private set; } + + /// + /// An image view that may be used as a watermark or as a texture + /// for the signature pad. + /// + /// The background image. + public ImageSource BackgroundImage { - get { return (float)GetValue (StrokeWidthProperty); } - set { SetValue (StrokeWidthProperty, value); } + get { return (ImageSource)GetValue (BackgroundImageProperty); } + set { SetValue (BackgroundImageProperty, value); } } - public Color StrokeColor + /// + /// An image view that may be used as a watermark or as a texture + /// for the signature pad. + /// + /// The background image. + public Aspect BackgroundImageAspect { - get { return (Color)GetValue (StrokeColorProperty); } - set { SetValue (StrokeColorProperty, value); } + get { return (Aspect)GetValue (BackgroundImageAspectProperty); } + set { SetValue (BackgroundImageAspectProperty, value); } } - public IEnumerable Points + /// + /// The transparency of the watermark. + /// + /// The background image. + public double BackgroundImageOpacity { - get { return GetSignaturePoints (); } - set { SetSignaturePoints (value); } + get { return (double)GetValue (BackgroundImageOpacityProperty); } + set { SetValue (BackgroundImageOpacityProperty, value); } } /// - /// Create an encoded image stream of the currently drawn signature. + /// The text for the prompt displayed at the beginning of the signature line. /// - public Task GetImageStreamAsync (SignatureImageFormat format, bool shouldCrop = true, bool keepAspectRatio = true) + /// + /// Text value defaults to 'X'. + /// + /// The signature prompt. + public string PromptText { - return GetImageStreamAsync (format, new ImageConstructionSettings - { - ShouldCrop = shouldCrop, - DesiredSizeOrScale = new SizeOrScale (1f, SizeOrScaleType.Scale, keepAspectRatio) - }); + get { return (string)GetValue (PromptTextProperty); } + set { SetValue (PromptTextProperty, value); } } /// - /// Create an encoded image stream of the currently drawn signature at the specified size. + /// The color of the prompt text. /// - public Task GetImageStreamAsync (SignatureImageFormat format, Size size, bool shouldCrop = true, bool keepAspectRatio = true) + /// The color of the prompt text. + public Color PromptTextColor { - return GetImageStreamAsync (format, new ImageConstructionSettings - { - ShouldCrop = shouldCrop, - DesiredSizeOrScale = new SizeOrScale (size, SizeOrScaleType.Size, keepAspectRatio) - }); + get { return (Color)GetValue (PromptTextColorProperty); } + set { SetValue (PromptTextColorProperty, value); } } /// - /// Create an encoded image stream of the currently drawn signature at the specified scale. + /// The text for the caption displayed under the signature line. /// - public Task GetImageStreamAsync (SignatureImageFormat format, float scale, bool shouldCrop = true, bool keepAspectRatio = true) + /// + /// Text value defaults to 'Sign here.' + /// + /// The caption. + public string CaptionText { - return GetImageStreamAsync (format, new ImageConstructionSettings - { - ShouldCrop = shouldCrop, - DesiredSizeOrScale = new SizeOrScale (scale, SizeOrScaleType.Scale, keepAspectRatio) - }); + get { return (string)GetValue (CaptionTextProperty); } + set { SetValue (CaptionTextProperty, value); } } /// - /// Create an encoded image stream of the currently drawn signature with the specified stroke color. + /// Gets the text for the label that clears the pad when clicked. /// - public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, bool shouldCrop = true, bool keepAspectRatio = true) + /// The clear label. + public string ClearText { - return GetImageStreamAsync (format, new ImageConstructionSettings - { - ShouldCrop = shouldCrop, - DesiredSizeOrScale = new SizeOrScale (1f, SizeOrScaleType.Scale, keepAspectRatio), - StrokeColor = strokeColor - }); + get { return (string)GetValue (ClearTextProperty); } + set { SetValue (ClearTextProperty, value); } } /// - /// Create an encoded image stream of the currently drawn signature at the specified size with the specified stroke color. + /// The color of the clear text. /// - public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, Size size, bool shouldCrop = true, bool keepAspectRatio = true) + /// The color of the clear text. + public Color ClearTextColor { - return GetImageStreamAsync (format, new ImageConstructionSettings - { - ShouldCrop = shouldCrop, - StrokeColor = strokeColor, - DesiredSizeOrScale = new SizeOrScale (size, SizeOrScaleType.Size, keepAspectRatio) - }); + get { return (Color)GetValue (ClearTextColorProperty); } + set { SetValue (ClearTextColorProperty, value); } } /// - /// Create an encoded image stream of the currently drawn signature at the specified scale with the specified stroke color. + /// Gets the label that clears the pad when clicked. /// - public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, float scale, bool shouldCrop = true, bool keepAspectRatio = true) + /// The clear label. + public Label ClearLabel { get; private set; } + + /// + /// Gets the horizontal line that goes in the lower part of the pad. + /// + /// The signature line. + public BoxView SignatureLine { get; private set; } + + public void Clear () { - return GetImageStreamAsync (format, new ImageConstructionSettings - { - ShouldCrop = shouldCrop, - StrokeColor = strokeColor, - DesiredSizeOrScale = new SizeOrScale (scale, SizeOrScaleType.Scale, keepAspectRatio) - }); + SignaturePadCanvas.Clear (); + + UpdateUi (); } /// - /// Create an encoded image stream of the currently drawn signature with the specified stroke and background colors. + /// Create an encoded image of the currently drawn signature. /// - public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, Color fillColor, bool shouldCrop = true, bool keepAspectRatio = true) + public Task GetImageStreamAsync (SignatureImageFormat format, bool shouldCrop = true, bool keepAspectRatio = true) { - return GetImageStreamAsync (format, new ImageConstructionSettings - { - ShouldCrop = shouldCrop, - DesiredSizeOrScale = new SizeOrScale (1f, SizeOrScaleType.Scale, keepAspectRatio), - StrokeColor = strokeColor, - BackgroundColor = fillColor - }); + return SignaturePadCanvas.GetImageStreamAsync (format, shouldCrop, keepAspectRatio); } /// - /// Create an encoded image stream of the currently drawn signature at the specified size with the specified stroke and background colors. + /// Create an encoded image of the currently drawn signature at the specified size. /// - public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, Color fillColor, Size size, bool shouldCrop = true, bool keepAspectRatio = true) + public Task GetImageStreamAsync (SignatureImageFormat format, Size size, bool shouldCrop = true, bool keepAspectRatio = true) { - return GetImageStreamAsync (format, new ImageConstructionSettings - { - ShouldCrop = shouldCrop, - StrokeColor = strokeColor, - BackgroundColor = fillColor, - DesiredSizeOrScale = new SizeOrScale (size, SizeOrScaleType.Size, keepAspectRatio) - }); + return SignaturePadCanvas.GetImageStreamAsync (format, size, shouldCrop, keepAspectRatio); } /// - /// Create an encoded image stream of the currently drawn signature at the specified scale with the specified stroke and background colors. + /// Create an encoded image of the currently drawn signature at the specified scale. /// - public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, Color fillColor, float scale, bool shouldCrop = true, bool keepAspectRatio = true) + public Task GetImageStreamAsync (SignatureImageFormat format, float scale, bool shouldCrop = true, bool keepAspectRatio = true) { - return GetImageStreamAsync (format, new ImageConstructionSettings - { - ShouldCrop = shouldCrop, - StrokeColor = strokeColor, - BackgroundColor = fillColor, - DesiredSizeOrScale = new SizeOrScale (scale, SizeOrScaleType.Scale, keepAspectRatio) - }); + return SignaturePadCanvas.GetImageStreamAsync (format, scale, shouldCrop, keepAspectRatio); } /// - /// Create an encoded image stream of the currently drawn signature using the specified settings. + /// Create an encoded image of the currently drawn signature with the specified stroke color. /// - public Task GetImageStreamAsync (SignatureImageFormat imageFormat, ImageConstructionSettings settings) + public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, bool shouldCrop = true, bool keepAspectRatio = true) { - var args = new ImageStreamRequestedEventArgs (imageFormat, settings); - ImageStreamRequested?.Invoke (this, args); - return args.ImageStreamTask; + return SignaturePadCanvas.GetImageStreamAsync (format, strokeColor, shouldCrop, keepAspectRatio); } - public void Clear () + /// + /// Create an encoded image of the currently drawn signature at the specified size with the specified stroke color. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, Size size, bool shouldCrop = true, bool keepAspectRatio = true) { - ClearRequested?.Invoke (this, null); + return SignaturePadCanvas.GetImageStreamAsync (format, strokeColor, size, shouldCrop, keepAspectRatio); } - private IEnumerable GetSignaturePoints () + /// + /// Create an encoded image of the currently drawn signature at the specified scale with the specified stroke color. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, float scale, bool shouldCrop = true, bool keepAspectRatio = true) { - var args = new PointsEventArgs (); - PointsRequested?.Invoke (this, args); - return args.Points; + return SignaturePadCanvas.GetImageStreamAsync (format, strokeColor, scale, shouldCrop, keepAspectRatio); } - private void SetSignaturePoints (IEnumerable points) + /// + /// Create an encoded image of the currently drawn signature with the specified stroke and background colors. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, Color fillColor, bool shouldCrop = true, bool keepAspectRatio = true) { - PointsSpecified?.Invoke (this, new PointsEventArgs { Points = points }); + return SignaturePadCanvas.GetImageStreamAsync (format, strokeColor, fillColor, shouldCrop, keepAspectRatio); } - private bool RequestIsBlank () + /// + /// Create an encoded image of the currently drawn signature at the specified size with the specified stroke and background colors. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, Color fillColor, Size size, bool shouldCrop = true, bool keepAspectRatio = true) { - var args = new IsBlankRequestedEventArgs (); - IsBlankRequested?.Invoke (this, args); - return args.IsBlank; + return SignaturePadCanvas.GetImageStreamAsync (format, strokeColor, fillColor, size, shouldCrop, keepAspectRatio); } - internal event EventHandler ImageStreamRequested; - internal event EventHandler IsBlankRequested; - internal event EventHandler PointsRequested; - internal event EventHandler PointsSpecified; - internal event EventHandler ClearRequested; - - internal class ImageStreamRequestedEventArgs : EventArgs + /// + /// Create an encoded image of the currently drawn signature at the specified scale with the specified stroke and background colors. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, Color strokeColor, Color fillColor, float scale, bool shouldCrop = true, bool keepAspectRatio = true) { - public ImageStreamRequestedEventArgs (SignatureImageFormat imageFormat, ImageConstructionSettings settings) - { - ImageFormat = imageFormat; - Settings = settings; - } - - public SignatureImageFormat ImageFormat { get; private set; } - - public ImageConstructionSettings Settings { get; private set; } - - public Task ImageStreamTask { get; set; } = Task.FromResult (null); + return SignaturePadCanvas.GetImageStreamAsync (format, strokeColor, fillColor, scale, shouldCrop, keepAspectRatio); } - internal class IsBlankRequestedEventArgs : EventArgs + /// + /// Create an encoded image of the currently drawn signature using the specified settings. + /// + public Task GetImageStreamAsync (SignatureImageFormat format, ImageConstructionSettings settings) { - public bool IsBlank { get; set; } = true; + return SignaturePadCanvas.GetImageStreamAsync (format, settings); } - internal class PointsEventArgs : EventArgs + private void UpdateUi () { - public IEnumerable Points { get; set; } = new Point[0]; + ClearLabel.IsVisible = !IsBlank; } } } diff --git a/src/SignaturePad.Forms/SignaturePad.Forms.csproj b/src/SignaturePad.Forms/SignaturePad.Forms.csproj index 78e93cb..9f3ff3b 100644 --- a/src/SignaturePad.Forms/SignaturePad.Forms.csproj +++ b/src/SignaturePad.Forms/SignaturePad.Forms.csproj @@ -40,7 +40,7 @@ Properties\AssemblyInfo.Forms.cs - + diff --git a/src/SignaturePad.Forms/SignaturePadCanvasRenderer.cs b/src/SignaturePad.Forms/SignaturePadCanvasRenderer.cs new file mode 100644 index 0000000..d8bbd30 --- /dev/null +++ b/src/SignaturePad.Forms/SignaturePadCanvasRenderer.cs @@ -0,0 +1,6 @@ +namespace SignaturePad.Forms +{ + internal class SignaturePadCanvasRenderer + { + } +} diff --git a/src/SignaturePad.Forms/SignaturePadRenderer.cs b/src/SignaturePad.Forms/SignaturePadRenderer.cs deleted file mode 100644 index f7fa95a..0000000 --- a/src/SignaturePad.Forms/SignaturePadRenderer.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace SignaturePad.Forms -{ - internal class SignaturePadRenderer - { - } -}