From deff41b53dc6c220a6e80c1024260c7c7da8d24a Mon Sep 17 00:00:00 2001 From: amwx Date: Tue, 23 Jun 2020 00:08:29 -0500 Subject: [PATCH] New TimePicker/TimePickerPresenter --- .../DateTimePickers/TimePicker.cs | 288 +++++++++++++++++- .../DateTimePickers/TimePickerPresenter.cs | 259 +++++++++++++++- 2 files changed, 528 insertions(+), 19 deletions(-) diff --git a/src/Avalonia.Controls/DateTimePickers/TimePicker.cs b/src/Avalonia.Controls/DateTimePickers/TimePicker.cs index 5fdc3e5eb0..8b80cd8414 100644 --- a/src/Avalonia.Controls/DateTimePickers/TimePicker.cs +++ b/src/Avalonia.Controls/DateTimePickers/TimePicker.cs @@ -1,6 +1,4 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Controls.Primitives; +using Avalonia.Controls.Primitives; using Avalonia.Controls.Shapes; using Avalonia.Controls.Templates; using System; @@ -8,16 +6,288 @@ using System.Globalization; namespace Avalonia.Controls { - //TODO: WinUI issue proposal for DurationPicker - //https://github.com/microsoft/microsoft-ui-xaml/issues/1807 - //Could just extend this and add other time units, but design idea for this - //is unknown - /// /// A control to allow the user to select a time /// public class TimePicker : TemplatedControl { - + /// + /// Defines the property + /// + public static readonly DirectProperty MinuteIncrementProperty = + AvaloniaProperty.RegisterDirect("MinuteIncrement", x => x.MinuteIncrement, + (x, v) => x.MinuteIncrement = v); + + /// + /// Defines the property + /// + public static readonly StyledProperty HeaderProperty = + AvaloniaProperty.Register("Header"); + + /// + /// Defines the property + /// + public static readonly StyledProperty HeaderTemplateProperty = + AvaloniaProperty.Register("HeaderTemplate"); + + /// + /// Defines the property + /// + public static readonly DirectProperty ClockIdentifierProperty = + AvaloniaProperty.RegisterDirect("ClockIdentifier", x => x.ClockIdentifier, + (x, v) => x.ClockIdentifier = v); + + /// + /// Defines the property + /// + public static readonly DirectProperty SelectedTimeProperty = + AvaloniaProperty.RegisterDirect("Time", x => x.SelectedTime, (x, v) => x.SelectedTime = v); + + //Template Items + private TimePickerPresenter _presenter; + private Button _flyoutButton; + private Border _firstPickerHost; + private Border _secondPickerHost; + private Border _thirdPickerHost; + private TextBlock _hourText; + private TextBlock _minuteText; + public TextBlock _periodText; + private Rectangle _firstSplitter; + private Rectangle _secondSplitter; + private Grid _contentGrid; + private Popup _popup; + + private TimeSpan? _selectedTime; + private int _minuteIncrement = 1; + private string _clockIdentifier = "12HourClock"; + + public TimePicker() + { + PseudoClasses.Set(":hasnotime", true); + + var timePattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern; + if (timePattern.IndexOf("H") != -1) + _clockIdentifier = "24HourClock"; + } + + /// + /// Gets or sets the minute increment in the picker + /// + public int MinuteIncrement + { + get => _minuteIncrement; + set + { + if (value < 1 || value > 59) + throw new ArgumentOutOfRangeException("1 >= MinuteIncrement <= 59"); + SetAndRaise(MinuteIncrementProperty, ref _minuteIncrement, value); + SetSelectedTimeText(); + } + } + + /// + /// Gets or sets the header + /// + public object Header + { + get => GetValue(HeaderProperty); + set => SetValue(HeaderProperty, value); + } + + /// + /// Gets or sets the header template + /// + public IDataTemplate HeaderTemplate + { + get => GetValue(HeaderTemplateProperty); + set => SetValue(HeaderTemplateProperty, value); + } + + /// + /// Gets or sets the clock identifier, either 12HourClock or 24HourClock + /// + public string ClockIdentifier + { + get => _clockIdentifier; + set + { + if (!(string.IsNullOrEmpty(value) || value == "" || value == "12HourClock" || value == "24HourClock")) + throw new ArgumentException("Invalid ClockIdentifier"); + SetAndRaise(ClockIdentifierProperty, ref _clockIdentifier, value); + SetGrid(); + SetSelectedTimeText(); + } + } + + /// + /// Gets or sets the selected time. Can be null. + /// + public TimeSpan? SelectedTime + { + get => _selectedTime; + set + { + var old = _selectedTime; + SetAndRaise(SelectedTimeProperty, ref _selectedTime, value); + OnSelectedTimeChanged(old, value); + SetSelectedTimeText(); + } + } + + /// + /// Raised when the property changes + /// + public event EventHandler SelectedTimeChanged; + + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + if (_flyoutButton != null) + _flyoutButton.Click -= OnFlyoutButtonClicked; + + if(_presenter != null) + { + _presenter.Confirmed -= OnConfirmed; + _presenter.Dismissed -= OnDismissPicker; + } + base.OnApplyTemplate(e); + + _flyoutButton = e.NameScope.Find