Added DatePicker and TimePicker initial implementation (work in progress)
This commit is contained in:
Родитель
93a85abc75
Коммит
3a3cb6deef
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче