From 41b530b7bf3f9228bd44b65e3c9415539f4a94a9 Mon Sep 17 00:00:00 2001 From: rabbitism Date: Fri, 26 Apr 2024 17:57:53 +0800 Subject: [PATCH] feat: work around .net standard 2.0 formatting to H --- .../Controls/TimePicker.axaml | 47 +++-- .../DateTimePicker/TimePickerPresenter.cs | 165 +++++++++++++++--- 2 files changed, 172 insertions(+), 40 deletions(-) diff --git a/src/Ursa.Themes.Semi/Controls/TimePicker.axaml b/src/Ursa.Themes.Semi/Controls/TimePicker.axaml index 38dbfe2..b6dd161 100644 --- a/src/Ursa.Themes.Semi/Controls/TimePicker.axaml +++ b/src/Ursa.Themes.Semi/Controls/TimePicker.axaml @@ -4,7 +4,7 @@ xmlns:u="https://irihi.tech/ursa"> - + @@ -12,32 +12,39 @@ - + - - + + + NeedsConfirmationProperty = AvaloniaProperty.Register( nameof(NeedsConfirmation)); @@ -51,17 +77,8 @@ public class TimePickerPresenter: TemplatedControl set => SetValue(TimeProperty, value); } - public static readonly StyledProperty Use12HoursProperty = AvaloniaProperty.Register( - nameof(Use12Hours)); - - public bool Use12Hours - { - get => GetValue(Use12HoursProperty); - set => SetValue(Use12HoursProperty, value); - } - public static readonly StyledProperty PanelFormatProperty = AvaloniaProperty.Register( - nameof(PanelFormat)); + nameof(PanelFormat), defaultValue: "hh mm ss t"); public string PanelFormat { @@ -69,6 +86,72 @@ public class TimePickerPresenter: TemplatedControl set => SetValue(PanelFormatProperty, value); } + static TimePickerPresenter() + { + PanelFormatProperty.Changed.AddClassHandler((presenter, args) => presenter.OnPanelFormatChanged(args)); + } + + private void OnPanelFormatChanged(AvaloniaPropertyChangedEventArgs args) + { + var format = args.NewValue.Value; + + UpdatePanelLayout(format); + } + + private void UpdatePanelLayout(string panelFormat) + { + var parts = panelFormat.Split(' ', '-', ':'); + var panels = new List(); + foreach (var part in parts) + { + if (part.Length < 1) continue; + if ((part.Contains('h') || part.Contains('H')) && !panels.Contains(_hourScrollPanel)) + { + panels.Add(_hourScrollPanel); + _use12Clock = part.Contains('h'); + _hourSelector?.SetValue(DateTimePickerPanel.ItemFormatProperty, part.ToLower()); + if (_hourSelector is not null) + { + _hourSelector.MaximumValue = _use12Clock ? 12 : 23; + _hourSelector.MinimumValue = _use12Clock ? 1 : 0; + } + } + else if (part[0] == 'm' && !panels.Contains(_minuteSelector)) + { + panels.Add(_minuteScrollPanel); + _minuteSelector?.SetValue(DateTimePickerPanel.ItemFormatProperty, part); + } + else if (part[0] == 's' && !panels.Contains(_secondScrollPanel)) + { + panels.Add(_secondScrollPanel); + _secondSelector?.SetValue(DateTimePickerPanel.ItemFormatProperty, part.Replace('s', 'm')); + } + else if (part[0] == 't' && !panels.Contains(_ampmScrollPanel)) + { + panels.Add(_ampmScrollPanel); + _ampmSelector?.SetValue(DateTimePickerPanel.ItemFormatProperty, part); + } + } + if (panels.Count < 1) return; + IsVisibleProperty.SetValue(false, _hourScrollPanel, _minuteScrollPanel, _secondScrollPanel, _ampmScrollPanel, + _firstSeparator, _secondSeparator, _thirdSeparator); + for(var i = 0; i< panels.Count; i++) + { + var panel = panels[i]; + if (panel is null) continue; + panel.IsVisible = true; + Grid.SetColumn(panel, 2 * i); + var separator = i switch + { + 0 => _firstSeparator, + 1 => _secondSeparator, + 2 => _thirdSeparator, + _ => null, + }; + IsVisibleProperty.SetValue(true, separator); + } + } + public TimePickerPresenter() { SetCurrentValue(TimeProperty, DateTime.Now.TimeOfDay); @@ -82,48 +165,74 @@ public class TimePickerPresenter: TemplatedControl _secondSelector = e.NameScope.Find(PART_SecondSelector); _ampmSelector = e.NameScope.Find(PART_AmPmSelector); _pickerContainer = e.NameScope.Find(PART_PickerContainer); + _hourScrollPanel = e.NameScope.Find(PART_HourScrollPanel); + _minuteScrollPanel = e.NameScope.Find(PART_MinuteScrollPanel); + _secondScrollPanel = e.NameScope.Find(PART_SecondScrollPanel); + _ampmScrollPanel = e.NameScope.Find(PART_AmPmScrollPanel); + _firstSeparator = e.NameScope.Find(PART_FirstSeparator); + _secondSeparator = e.NameScope.Find(PART_SecondSeparator); + _thirdSeparator = e.NameScope.Find(PART_ThirdSeparator); Initialize(); + UpdatePanelLayout(PanelFormat); + UpdatePanelsFromSelectedTime(); + } + + private void UpdatePanelsFromSelectedTime() + { + if (Time is null) return; + var time = Time ?? DateTime.Now.TimeOfDay; + if (_hourSelector is not null) + { + _hourSelector.SelectedValue = _use12Clock ? time.Hours % 12 : time.Hours; + } + if (_minuteSelector is not null) + { + _minuteSelector.SelectedValue = time.Minutes; + } + if (_secondSelector is not null) + { + _secondSelector.SelectedValue = time.Seconds; + } + if (_ampmSelector is not null) + { + _ampmSelector.SelectedValue = time.Hours switch + { + >= 12 => 1, + _ => 0 + }; + } } private void Initialize() { if (_pickerContainer is null) return; - var use12Clock = Use12Hours; if (_hourSelector is not null) { - _hourSelector.MaximumValue = use12Clock ? 12 : 23; - _hourSelector.MinimumValue = use12Clock ? 1 : 0; _hourSelector.ItemFormat = "%h"; - var hour = Time?.Hours; - _hourSelector.SelectedValue = hour ?? 0; + _hourSelector.MaximumValue = _use12Clock ? 12 : 23; + _hourSelector.MinimumValue = _use12Clock ? 1 : 0; + } if(_minuteSelector is not null) { + _minuteSelector.ItemFormat = "mm"; _minuteSelector.MaximumValue = 59; _minuteSelector.MinimumValue = 0; - _minuteSelector.ItemFormat = "mm"; - var minute = Time?.Minutes; - _minuteSelector.SelectedValue = minute ?? 0; + } if(_secondSelector is not null) { + _secondSelector.ItemFormat = "mm"; _secondSelector.MaximumValue = 59; _secondSelector.MinimumValue = 0; - _secondSelector.ItemFormat = "mm"; - var second = Time?.Seconds; - _secondSelector.SelectedValue = second ?? 0; + } if(_ampmSelector is not null) { + _ampmSelector.ItemFormat = "t"; _ampmSelector.MaximumValue = 1; _ampmSelector.MinimumValue = 0; - _ampmSelector.ItemFormat = "%t"; - var ampm = Time?.Hours switch - { - >= 12 => 1, - _ => 0 - }; - _ampmSelector.SelectedValue = ampm; + } } } \ No newline at end of file