using System.Globalization; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Metadata; using Avalonia.Controls.Primitives; using Avalonia.Data; using Avalonia.Input; using Avalonia.Interactivity; using Irihi.Avalonia.Shared.Common; using Irihi.Avalonia.Shared.Contracts; using Irihi.Avalonia.Shared.Helpers; namespace Ursa.Controls; [TemplatePart(PART_TextBox, typeof(TextBox))] [TemplatePart(PartNames.PART_Popup, typeof(Popup))] [TemplatePart(PART_Presenter, typeof(TimePickerPresenter))] [TemplatePart(PART_Button, typeof(Button))] public class TimePicker : TimePickerBase, IClearControl { public const string PART_TextBox = "PART_TextBox"; public const string PART_Presenter = "PART_Presenter"; public const string PART_Button = "PART_Button"; public static readonly StyledProperty SelectedTimeProperty = AvaloniaProperty.Register( nameof(SelectedTime), defaultBindingMode: BindingMode.TwoWay); public static readonly StyledProperty WatermarkProperty = AvaloniaProperty.Register( nameof(Watermark)); private Button? _button; private bool _isFocused; private Popup? _popup; private TimePickerPresenter? _presenter; private bool _suppressTextPresenterEvent; private TextBox? _textBox; static TimePicker() { FocusableProperty.OverrideDefaultValue(true); SelectedTimeProperty.Changed.AddClassHandler((picker, args) => picker.OnSelectionChanged(args)); DisplayFormatProperty.Changed.AddClassHandler((picker, args) => picker.OnDisplayFormatChanged(args)); } public string? Watermark { get => GetValue(WatermarkProperty); set => SetValue(WatermarkProperty, value); } public TimeSpan? SelectedTime { get => GetValue(SelectedTimeProperty); set => SetValue(SelectedTimeProperty, value); } public void Clear() { SetCurrentValue(SelectedTimeProperty, null); Focus(NavigationMethod.Pointer); } private void OnDisplayFormatChanged(AvaloniaPropertyChangedEventArgs _) { if (_textBox is null) return; SyncTimeToText(SelectedTime); } /// protected override void OnPointerPressed(PointerPressedEventArgs e) { base.OnPointerPressed(e); if (!e.Handled && e.Source is Visual source) if (_popup?.IsInsidePopup(source) == true) e.Handled = true; } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); GotFocusEvent.RemoveHandler(OnTextBoxGetFocus, _textBox); TextBox.TextChangedEvent.RemoveHandler(OnTextChanged, _textBox); Button.ClickEvent.RemoveHandler(OnButtonClick, _button); TimePickerPresenter.SelectedTimeChangedEvent.RemoveHandler(OnPresenterTimeChanged, _presenter); _textBox = e.NameScope.Find(PART_TextBox); _popup = e.NameScope.Find(PartNames.PART_Popup); _presenter = e.NameScope.Find(PART_Presenter); _button = e.NameScope.Find