Added DatePicker and TimePicker initial implementation (work in progress)

This commit is contained in:
Javier Suárez Ruiz 2021-01-11 12:05:50 +01:00
Родитель 93a85abc75
Коммит 3a3cb6deef
9 изменённых файлов: 892 добавлений и 0 удалений

Просмотреть файл

@ -30,6 +30,8 @@
<graphics:CheckBox
VisualType="Cupertino"
Text="CheckBox"/>
<graphics:DatePicker
VisualType="Cupertino"/>
<graphics:Editor
VisualType="Cupertino"
Placeholder="Placeholder"/>
@ -53,6 +55,8 @@
Value="50"/>
<graphics:Switch
VisualType="Cupertino"/>
<graphics:TimePicker
VisualType="Cupertino"/>
<Label
Text="Fluent"
FontSize="Large"
@ -69,6 +73,8 @@
VisualType="Fluent"
IsChecked="True"
Text="CheckBox"/>
<graphics:DatePicker
VisualType="Fluent"/>
<graphics:Editor
VisualType="Fluent"
Placeholder="Placeholder"/>
@ -93,6 +99,8 @@
Value="50"/>
<graphics:Switch
VisualType="Fluent"/>
<graphics:TimePicker
VisualType="Fluent"/>
<Label
Text="Material"
FontSize="Large"
@ -107,6 +115,8 @@
Clicked="OnButtonClicked"/>
<graphics:CheckBox
VisualType="Material"/>
<graphics:DatePicker
VisualType="Material"/>
<graphics:Editor
VisualType="Material"
Placeholder="Placeholder"/>
@ -130,6 +140,8 @@
Value="50"/>
<graphics:Switch
VisualType="Material"/>
<graphics:TimePicker
VisualType="Material"/>
</StackLayout>
</ScrollView>
</ContentPage>

Просмотреть файл

@ -0,0 +1,65 @@
using System.Graphics;
using GraphicsControls.Extensions;
using GraphicsControls.Helpers;
namespace GraphicsControls
{
public partial class DatePicker
{
void DrawCupertinoDatePickerBackground(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
canvas.FillColor = BackgroundColor.ToGraphicsColor(Material.Color.White, Material.Color.Black);
var x = dirtyRect.X;
var y = dirtyRect.Y;
var width = dirtyRect.Width;
var height = dirtyRect.Height;
canvas.FillRoundedRectangle(x, y, width, height, 2);
canvas.RestoreState();
}
void DrawCupertinoDatePickerBorder(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
var strokeWidth = 1.0f;
canvas.StrokeColor = ColorHelper.GetGraphicsColor(Material.Color.Gray3, Material.Color.Gray6);
canvas.StrokeSize = strokeWidth;
var x = dirtyRect.X;
var y = dirtyRect.Y;
var width = dirtyRect.Width;
var height = dirtyRect.Height;
canvas.DrawRoundedRectangle(x + strokeWidth / 2, y + strokeWidth / 2, width - strokeWidth, height - strokeWidth, 8);
canvas.RestoreState();
}
void DrawCupertinoDatePickerDate(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
canvas.FontColor = ColorHelper.GetGraphicsColor(Material.Color.Black, Material.Color.White);
canvas.FontSize = 14f;
float margin = 8f;
var x = dirtyRect.X + margin;
var height = dirtyRect.Height;
var width = dirtyRect.Width;
canvas.DrawString(Date.ToShortDateString(), x, 0, width - margin, height, HorizontalAlignment.Left, VerticalAlignment.Center);
canvas.RestoreState();
}
}
}

Просмотреть файл

@ -0,0 +1,103 @@
using System.Graphics;
using GraphicsControls.Extensions;
using GraphicsControls.Helpers;
using GColor = System.Graphics.Color;
namespace GraphicsControls
{
public partial class DatePicker
{
const float FluentDatePickerHeight = 32.0f;
void DrawFluentDatePickerBackground(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
if (IsEnabled)
canvas.FillColor = BackgroundColor.ToGraphicsColor(Fluent.Color.Foreground.White, Fluent.Color.Foreground.NeutralPrimaryAlt);
else
canvas.FillColor = ColorHelper.GetGraphicsColor(Fluent.Color.Background.NeutralLighter, Fluent.Color.Background.NeutralDark);
var x = dirtyRect.X;
var y = dirtyRect.Y;
var width = dirtyRect.Width;
var height = dirtyRect.Height;
canvas.FillRoundedRectangle(x, y, width, height, 2);
canvas.RestoreState();
}
void DrawFluentDatePickerBorder(ICanvas canvas, RectangleF dirtyRect)
{
if (IsEnabled)
{
canvas.SaveState();
var strokeWidth = 1.0f;
canvas.StrokeColor = ColorHelper.GetGraphicsColor(Fluent.Color.Foreground.NeutralSecondary, Fluent.Color.Foreground.White);
canvas.StrokeSize = strokeWidth;
if (IsFocused)
{
strokeWidth = 2.0f;
canvas.StrokeColor = new GColor(Fluent.Color.Primary.ThemePrimary);
canvas.StrokeSize = strokeWidth;
}
var x = dirtyRect.X;
var y = dirtyRect.Y;
var width = dirtyRect.Width;
var height = dirtyRect.Height;
canvas.DrawRoundedRectangle(x + strokeWidth / 2, y + strokeWidth / 2, width - strokeWidth, height - strokeWidth, 2);
canvas.RestoreState();
}
}
void DrawFluentDatePickerIcon(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
var margin = 10;
canvas.Translate(dirtyRect.Width - (2 * margin), margin);
var vBuilder = new PathBuilder();
var path =
vBuilder.BuildPath(
"M4.5 4.5H5.25V5.25H4.5V4.5ZM6.75 9H7.5V9.75H6.75V9ZM9 4.5H9.75V5.25H9V4.5ZM6.75 4.5H7.5V5.25H6.75V4.5ZM4.5 6H5.25V6.75H4.5V6ZM2.25 6H3V6.75H2.25V6ZM9 6H9.75V6.75H9V6ZM6.75 6H7.5V6.75H6.75V6ZM4.5 7.5H5.25V8.25H4.5V7.5ZM2.25 7.5H3V8.25H2.25V7.5ZM9 7.5H9.75V8.25H9V7.5ZM6.75 7.5H7.5V8.25H6.75V7.5ZM4.5 9H5.25V9.75H4.5V9ZM2.25 9H3V9.75H2.25V9ZM12 0.75V11.25H0V0.75H2.25V0H3V0.75H9V0H9.75V0.75H12ZM0.75 1.5V3H11.25V1.5H9.75V2.25H9V1.5H3V2.25H2.25V1.5H0.75ZM11.25 10.5V3.75H0.75V10.5H11.25Z");
canvas.FillColor = ColorHelper.GetGraphicsColor(Fluent.Color.Foreground.NeutralSecondary, Fluent.Color.Foreground.White);
canvas.FillPath(path);
canvas.RestoreState();
}
void DrawFluentDatePickerDate(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
if (IsEnabled)
canvas.FontColor = ColorHelper.GetGraphicsColor(Fluent.Color.Foreground.Black, Fluent.Color.Foreground.White);
else
canvas.FontColor = ColorHelper.GetGraphicsColor(Fluent.Color.Foreground.NeutralTertiary, Fluent.Color.Foreground.White);
canvas.FontSize = 14f;
float margin = 8f;
var x = dirtyRect.X + margin;
var height = FluentDatePickerHeight;
var width = dirtyRect.Width;
canvas.DrawString(Date.ToShortDateString(), x, 0, width - margin, height, HorizontalAlignment.Left, VerticalAlignment.Center);
canvas.RestoreState();
}
}
}

Просмотреть файл

@ -0,0 +1,107 @@
using System.Graphics;
using GraphicsControls.Extensions;
using GraphicsControls.Helpers;
using Xamarin.Forms;
using GColor = System.Graphics.Color;
namespace GraphicsControls
{
public partial class DatePicker
{
void DrawMaterialDatePickerBackground(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
canvas.FillColor = BackgroundColor.ToGraphicsColor(Material.Color.Gray5, Material.Color.Dark);
var width = dirtyRect.Width;
var vBuilder = new PathBuilder();
var path =
vBuilder.BuildPath(
$"M0 4C0 1.79086 1.79086 0 4 0H{width - 4}C{width - 2}.209 0 {width} 1.79086 {width} 4V56H0V4Z");
canvas.FillPath(path);
canvas.RestoreState();
}
void DrawMaterialDatePickerBorder(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
var strokeWidth = 1.0f;
canvas.FillColor = ColorHelper.GetGraphicsColor(Material.Color.Black, Material.Color.White);
if (IsFocused)
{
strokeWidth = 2.0f;
canvas.FillColor = new GColor(Material.Color.Blue);
}
var x = dirtyRect.X;
var y = 53.91f;
var width = dirtyRect.Width;
var height = strokeWidth;
canvas.FillRectangle(x, y, width, height);
canvas.RestoreState();
}
void DrawMaterialDatePickerPlaceholder(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
canvas.FontColor = ColorHelper.GetGraphicsColor(Material.Color.Gray1, Material.Color.Gray6);
canvas.FontSize = 12f;
float margin = 12f;
var horizontalAlignment = HorizontalAlignment.Left;
var x = dirtyRect.X + margin;
if (FlowDirection == FlowDirection.RightToLeft)
{
x = dirtyRect.X;
horizontalAlignment = HorizontalAlignment.Right;
}
var height = dirtyRect.Height;
var width = dirtyRect.Width;
canvas.DrawString("Date", x, 6f, width - margin, height, horizontalAlignment, VerticalAlignment.Top);
canvas.RestoreState();
}
void DrawMaterialDatePickerDate(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
canvas.FontColor = ColorHelper.GetGraphicsColor(Material.Color.Dark, Material.Color.Light);
canvas.FontSize = 16f;
float margin = 12f;
var horizontalAlignment = HorizontalAlignment.Left;
var x = dirtyRect.X + margin;
if (FlowDirection == FlowDirection.RightToLeft)
{
x = dirtyRect.X;
horizontalAlignment = HorizontalAlignment.Right;
}
var height = dirtyRect.Height;
var width = dirtyRect.Width;
canvas.DrawString(Date.ToShortDateString(), x, 22f, width - margin, height, horizontalAlignment, VerticalAlignment.Top);
canvas.RestoreState();
}
}
}

Просмотреть файл

@ -0,0 +1,194 @@
using System;
using System.Graphics;
using Xamarin.Forms;
namespace GraphicsControls
{
public partial class DatePicker : GraphicsVisualView
{
public static readonly BindableProperty DateProperty =
BindableProperty.Create(nameof(Date), typeof(DateTime), typeof(DatePicker), default(DateTime), BindingMode.TwoWay,
coerceValue: CoerceDate,
propertyChanged: DatePropertyChanged,
defaultValueCreator: (bindable) => DateTime.Today);
public static readonly BindableProperty MinimumDateProperty =
BindableProperty.Create(nameof(MinimumDate), typeof(DateTime), typeof(DatePicker), new DateTime(1900, 1, 1),
validateValue: ValidateMinimumDate, coerceValue: CoerceMinimumDate);
public static readonly BindableProperty MaximumDateProperty =
BindableProperty.Create(nameof(MaximumDate), typeof(DateTime), typeof(DatePicker), new DateTime(2100, 12, 31),
validateValue: ValidateMaximumDate, coerceValue: CoerceMaximumDate);
static object CoerceDate(BindableObject bindable, object value)
{
var picker = (DatePicker)bindable;
DateTime dateValue = ((DateTime)value).Date;
if (dateValue > picker.MaximumDate)
dateValue = picker.MaximumDate;
if (dateValue < picker.MinimumDate)
dateValue = picker.MinimumDate;
return dateValue;
}
static void DatePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var datePicker = (DatePicker)bindable;
datePicker.DateSelected?.Invoke(datePicker, new DateChangedEventArgs((DateTime)oldValue, (DateTime)newValue));
}
static bool ValidateMinimumDate(BindableObject bindable, object value)
{
return ((DateTime)value).Date <= ((DatePicker)bindable).MaximumDate.Date;
}
static object CoerceMinimumDate(BindableObject bindable, object value)
{
DateTime dateValue = ((DateTime)value).Date;
var picker = (DatePicker)bindable;
if (picker.Date < dateValue)
picker.Date = dateValue;
return dateValue;
}
static bool ValidateMaximumDate(BindableObject bindable, object value)
{
return ((DateTime)value).Date >= ((DatePicker)bindable).MinimumDate.Date;
}
static object CoerceMaximumDate(BindableObject bindable, object value)
{
DateTime dateValue = ((DateTime)value).Date;
var picker = (DatePicker)bindable;
if (picker.Date > dateValue)
picker.Date = dateValue;
return dateValue;
}
public DateTime Date
{
get { return (DateTime)GetValue(DateProperty); }
set { SetValue(DateProperty, value); }
}
public DateTime MaximumDate
{
get { return (DateTime)GetValue(MaximumDateProperty); }
set { SetValue(MaximumDateProperty, value); }
}
public DateTime MinimumDate
{
get { return (DateTime)GetValue(MinimumDateProperty); }
set { SetValue(MinimumDateProperty, value); }
}
public event EventHandler<DateChangedEventArgs> DateSelected;
public override void Load()
{
base.Load();
switch (VisualType)
{
case VisualType.Material:
default:
HeightRequest = 56;
break;
case VisualType.Cupertino:
HeightRequest = 36;
break;
case VisualType.Fluent:
HeightRequest = 32;
break;
}
}
public override void Draw(ICanvas canvas, RectangleF dirtyRect)
{
base.Draw(canvas, dirtyRect);
DrawDatePickerBackground(canvas, dirtyRect);
DrawDatePickerBorder(canvas, dirtyRect);
DrawDatePickerIcon(canvas, dirtyRect);
DrawDatePickerPlaceholder(canvas, dirtyRect);
DrawDatePickerDate(canvas, dirtyRect);
}
protected virtual void DrawDatePickerBackground(ICanvas canvas, RectangleF dirtyRect)
{
switch (VisualType)
{
case VisualType.Material:
default:
DrawMaterialDatePickerBackground(canvas, dirtyRect);
break;
case VisualType.Cupertino:
DrawCupertinoDatePickerBackground(canvas, dirtyRect);
break;
case VisualType.Fluent:
DrawFluentDatePickerBackground(canvas, dirtyRect);
break;
}
}
protected virtual void DrawDatePickerBorder(ICanvas canvas, RectangleF dirtyRect)
{
switch (VisualType)
{
case VisualType.Material:
default:
DrawMaterialDatePickerBorder(canvas, dirtyRect);
break;
case VisualType.Cupertino:
DrawCupertinoDatePickerBorder(canvas, dirtyRect);
break;
case VisualType.Fluent:
DrawFluentDatePickerBorder(canvas, dirtyRect);
break;
}
}
protected virtual void DrawDatePickerIcon(ICanvas canvas, RectangleF dirtyRect)
{
switch (VisualType)
{
case VisualType.Fluent:
DrawFluentDatePickerIcon(canvas, dirtyRect);
break;
}
}
protected virtual void DrawDatePickerPlaceholder(ICanvas canvas, RectangleF dirtyRect)
{
switch (VisualType)
{
case VisualType.Material:
DrawMaterialDatePickerPlaceholder(canvas, dirtyRect);
break;
}
}
protected virtual void DrawDatePickerDate(ICanvas canvas, RectangleF dirtyRect)
{
switch (VisualType)
{
case VisualType.Material:
default:
DrawMaterialDatePickerDate(canvas, dirtyRect);
break;
case VisualType.Cupertino:
DrawCupertinoDatePickerDate(canvas, dirtyRect);
break;
case VisualType.Fluent:
DrawFluentDatePickerDate(canvas, dirtyRect);
break;
}
}
}
}

Просмотреть файл

@ -0,0 +1,67 @@
using System;
using System.Graphics;
using GraphicsControls.Extensions;
using GraphicsControls.Helpers;
namespace GraphicsControls
{
public partial class TimePicker
{
void DrawCupertinoTimePickerBackground(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
canvas.FillColor = BackgroundColor.ToGraphicsColor(Material.Color.White, Material.Color.Black);
var x = dirtyRect.X;
var y = dirtyRect.Y;
var width = dirtyRect.Width;
var height = dirtyRect.Height;
canvas.FillRoundedRectangle(x, y, width, height, 2);
canvas.RestoreState();
}
void DrawCupertinoTimePickerBorder(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
var strokeWidth = 1.0f;
canvas.StrokeColor = ColorHelper.GetGraphicsColor(Material.Color.Gray3, Material.Color.Gray6);
canvas.StrokeSize = strokeWidth;
var x = dirtyRect.X;
var y = dirtyRect.Y;
var width = dirtyRect.Width;
var height = dirtyRect.Height;
canvas.DrawRoundedRectangle(x + strokeWidth / 2, y + strokeWidth / 2, width - strokeWidth, height - strokeWidth, 8);
canvas.RestoreState();
}
void DrawCupertinoTimePickerDate(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
canvas.FontColor = ColorHelper.GetGraphicsColor(Material.Color.Black, Material.Color.White);
canvas.FontSize = 14f;
float margin = 8f;
var x = dirtyRect.X + margin;
var height = dirtyRect.Height;
var width = dirtyRect.Width;
var date = new DateTime(Time.Ticks);
canvas.DrawString(date.ToString("HH:mm tt"), x, 0, width - margin, height, HorizontalAlignment.Left, VerticalAlignment.Center);
canvas.RestoreState();
}
}
}

Просмотреть файл

@ -0,0 +1,123 @@
using System;
using System.Graphics;
using GraphicsControls.Extensions;
using GraphicsControls.Helpers;
namespace GraphicsControls
{
public partial class TimePicker
{
const float FluentTimePickerHeight = 32.0f;
const float FluentDatePickerWidth = 250.0f;
void DrawFluentTimePickerBackground(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
if (IsEnabled)
canvas.FillColor = BackgroundColor.ToGraphicsColor(Fluent.Color.Foreground.White, Fluent.Color.Foreground.NeutralPrimaryAlt);
else
canvas.FillColor = ColorHelper.GetGraphicsColor(Fluent.Color.Background.NeutralLighter, Fluent.Color.Background.NeutralDark);
var x = dirtyRect.X;
var y = dirtyRect.Y;
var width = FluentDatePickerWidth;
var height = dirtyRect.Height;
canvas.FillRoundedRectangle(x, y, width, height, 2);
canvas.RestoreState();
}
void DrawFluentTimePickerBorder(ICanvas canvas, RectangleF dirtyRect)
{
if (IsEnabled)
{
canvas.SaveState();
var strokeWidth = 1.0f;
canvas.StrokeColor = ColorHelper.GetGraphicsColor(Fluent.Color.Foreground.NeutralSecondary, Fluent.Color.Foreground.White);
canvas.StrokeSize = strokeWidth;
var x = dirtyRect.X;
var y = dirtyRect.Y;
var width = FluentDatePickerWidth;
var height = dirtyRect.Height;
canvas.DrawRoundedRectangle(x + strokeWidth / 2, y + strokeWidth / 2, width - strokeWidth, height - strokeWidth, 2);
canvas.RestoreState();
var divided = FluentDatePickerWidth / 3;
canvas.SaveState();
canvas.StrokeColor = ColorHelper.GetGraphicsColor(Fluent.Color.Foreground.NeutralSecondary, Fluent.Color.Foreground.White);
canvas.StrokeSize = strokeWidth;
canvas.Alpha = 0.5f;
canvas.DrawLine(new PointF(divided, 0), new PointF(divided, dirtyRect.Height));
canvas.RestoreState();
canvas.SaveState();
canvas.StrokeColor = ColorHelper.GetGraphicsColor(Fluent.Color.Foreground.NeutralSecondary, Fluent.Color.Foreground.White);
canvas.StrokeSize = strokeWidth;
canvas.Alpha = 0.5f;
canvas.DrawLine(new PointF(divided * 2, 0), new PointF(divided * 2, dirtyRect.Height));
canvas.RestoreState();
}
}
void DrawFluentTimePickerDate(ICanvas canvas, RectangleF dirtyRect)
{
var height = FluentTimePickerHeight;
var divided = FluentDatePickerWidth / 3;
var date = new DateTime(Time.Ticks);
Color textColor;
if (IsEnabled)
textColor = ColorHelper.GetGraphicsColor(Fluent.Color.Foreground.Black, Fluent.Color.Foreground.White);
else
textColor = ColorHelper.GetGraphicsColor(Fluent.Color.Foreground.NeutralTertiary, Fluent.Color.Foreground.White);
float fontSize = 14f;
canvas.SaveState();
canvas.FontColor = textColor;
canvas.FontSize = fontSize;
canvas.DrawString(date.ToString("HH"), 0, 0, divided, height, HorizontalAlignment.Center, VerticalAlignment.Center);
canvas.RestoreState();
canvas.SaveState();
canvas.FontColor = textColor;
canvas.FontSize = fontSize;
canvas.DrawString(date.ToString("mm"), divided, 0, divided, height, HorizontalAlignment.Center, VerticalAlignment.Center);
canvas.RestoreState();
canvas.SaveState();
canvas.FontColor = textColor;
canvas.FontSize = fontSize;
canvas.DrawString(date.ToString("tt"), divided * 2, 0, divided, height, HorizontalAlignment.Center, VerticalAlignment.Center);
canvas.RestoreState();
}
}
}

Просмотреть файл

@ -0,0 +1,109 @@
using System;
using System.Graphics;
using GraphicsControls.Extensions;
using GraphicsControls.Helpers;
using Xamarin.Forms;
using GColor = System.Graphics.Color;
namespace GraphicsControls
{
public partial class TimePicker
{
void DrawMaterialTimePickerBackground(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
canvas.FillColor = BackgroundColor.ToGraphicsColor(Material.Color.Gray5, Material.Color.Dark);
var width = dirtyRect.Width;
var vBuilder = new PathBuilder();
var path =
vBuilder.BuildPath(
$"M0 4C0 1.79086 1.79086 0 4 0H{width - 4}C{width - 2}.209 0 {width} 1.79086 {width} 4V56H0V4Z");
canvas.FillPath(path);
canvas.RestoreState();
}
void DrawMaterialTimePickerBorder(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
var strokeWidth = 1.0f;
canvas.FillColor = ColorHelper.GetGraphicsColor(Material.Color.Black, Material.Color.White);
if (IsFocused)
{
strokeWidth = 2.0f;
canvas.FillColor = new GColor(Material.Color.Blue);
}
var x = dirtyRect.X;
var y = 53.91f;
var width = dirtyRect.Width;
var height = strokeWidth;
canvas.FillRectangle(x, y, width, height);
canvas.RestoreState();
}
void DrawMaterialTimePickerPlaceholder(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
canvas.FontColor = ColorHelper.GetGraphicsColor(Material.Color.Gray1, Material.Color.Gray6);
canvas.FontSize = 12f;
float margin = 12f;
var horizontalAlignment = HorizontalAlignment.Left;
var x = dirtyRect.X + margin;
if (FlowDirection == FlowDirection.RightToLeft)
{
x = dirtyRect.X;
horizontalAlignment = HorizontalAlignment.Right;
}
var height = dirtyRect.Height;
var width = dirtyRect.Width;
canvas.DrawString("Time", x, 6f, width - margin, height, horizontalAlignment, VerticalAlignment.Top);
canvas.RestoreState();
}
void DrawMaterialTimePickerDate(ICanvas canvas, RectangleF dirtyRect)
{
canvas.SaveState();
canvas.FontColor = ColorHelper.GetGraphicsColor(Material.Color.Dark, Material.Color.Light);
canvas.FontSize = 16f;
float margin = 12f;
var horizontalAlignment = HorizontalAlignment.Left;
var x = dirtyRect.X + margin;
if (FlowDirection == FlowDirection.RightToLeft)
{
x = dirtyRect.X;
horizontalAlignment = HorizontalAlignment.Right;
}
var height = dirtyRect.Height;
var width = dirtyRect.Width;
var date = new DateTime(Time.Ticks);
canvas.DrawString(date.ToString("HH:mm tt"), x, 22f, width - margin, height, horizontalAlignment, VerticalAlignment.Top);
canvas.RestoreState();
}
}
}

Просмотреть файл

@ -0,0 +1,112 @@
using System;
using System.Graphics;
using Xamarin.Forms;
namespace GraphicsControls
{
public partial class TimePicker : GraphicsVisualView
{
public static readonly BindableProperty TimeProperty =
BindableProperty.Create(nameof(Time), typeof(TimeSpan), typeof(TimePicker), new TimeSpan(0), BindingMode.TwoWay, (bindable, value) =>
{
var time = (TimeSpan)value;
return time.TotalHours < 24 && time.TotalMilliseconds >= 0;
});
public TimeSpan Time
{
get { return (TimeSpan)GetValue(TimeProperty); }
set { SetValue(TimeProperty, value); }
}
public override void Load()
{
base.Load();
switch (VisualType)
{
case VisualType.Material:
default:
HeightRequest = 56;
break;
case VisualType.Cupertino:
HeightRequest = 36;
break;
case VisualType.Fluent:
HeightRequest = 32;
break;
}
}
public override void Draw(ICanvas canvas, RectangleF dirtyRect)
{
base.Draw(canvas, dirtyRect);
DrawTimePickerBackground(canvas, dirtyRect);
DrawTimePickerBorder(canvas, dirtyRect);
DrawTimePickerPlaceholder(canvas, dirtyRect);
DrawTimePickerDate(canvas, dirtyRect);
}
protected virtual void DrawTimePickerBackground(ICanvas canvas, RectangleF dirtyRect)
{
switch (VisualType)
{
case VisualType.Material:
default:
DrawMaterialTimePickerBackground(canvas, dirtyRect);
break;
case VisualType.Cupertino:
DrawCupertinoTimePickerBackground(canvas, dirtyRect);
break;
case VisualType.Fluent:
DrawFluentTimePickerBackground(canvas, dirtyRect);
break;
}
}
protected virtual void DrawTimePickerBorder(ICanvas canvas, RectangleF dirtyRect)
{
switch (VisualType)
{
case VisualType.Material:
default:
DrawMaterialTimePickerBorder(canvas, dirtyRect);
break;
case VisualType.Cupertino:
DrawCupertinoTimePickerBorder(canvas, dirtyRect);
break;
case VisualType.Fluent:
DrawFluentTimePickerBorder(canvas, dirtyRect);
break;
}
}
protected virtual void DrawTimePickerPlaceholder(ICanvas canvas, RectangleF dirtyRect)
{
switch (VisualType)
{
case VisualType.Material:
DrawMaterialTimePickerPlaceholder(canvas, dirtyRect);
break;
}
}
protected virtual void DrawTimePickerDate(ICanvas canvas, RectangleF dirtyRect)
{
switch (VisualType)
{
case VisualType.Material:
default:
DrawMaterialTimePickerDate(canvas, dirtyRect);
break;
case VisualType.Cupertino:
DrawCupertinoTimePickerDate(canvas, dirtyRect);
break;
case VisualType.Fluent:
DrawFluentTimePickerDate(canvas, dirtyRect);
break;
}
}
}
}