TimeSelectorButton.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using Avalonia;
  2. using Avalonia.Controls;
  3. using Avalonia.Controls.Primitives;
  4. using Avalonia.Data.Converters;
  5. using CommunityToolkit.Mvvm.Input;
  6. using ExCSS;
  7. using InABox.Avalonia.Components.TimeSelector;
  8. using InABox.Avalonia.Converters;
  9. using InABox.Core;
  10. using System.Globalization;
  11. using System.Windows.Input;
  12. namespace InABox.Avalonia.Components;
  13. public class TimeSelectorTimeChangedEventArgs(TimeSpan? oldTime, TimeSpan? newTime)
  14. {
  15. public TimeSpan? OldTime { get; set; } = oldTime;
  16. public TimeSpan? NewTime { get; set; } = newTime;
  17. }
  18. public partial class TimeSelectorButton : TemplatedControl
  19. {
  20. public static readonly StyledProperty<string> PromptProperty =
  21. AvaloniaProperty.Register<TimeSelectorButton, string>(nameof(Prompt));
  22. public static readonly StyledProperty<string> PrefixProperty =
  23. AvaloniaProperty.Register<TimeSelectorButton, string>(nameof(Prefix));
  24. public static readonly StyledProperty<string> FormatProperty =
  25. AvaloniaProperty.Register<TimeSelectorButton, string>(nameof(Format));
  26. public static readonly StyledProperty<TimeSpan?> TimeProperty =
  27. AvaloniaProperty.Register<TimeSelectorButton, TimeSpan?>(nameof(Time));
  28. public string Prompt
  29. {
  30. get => GetValue(PromptProperty);
  31. set => SetValue(PromptProperty, value);
  32. }
  33. public string Prefix
  34. {
  35. get => GetValue(PrefixProperty);
  36. set => SetValue(PrefixProperty, value);
  37. }
  38. public string Format
  39. {
  40. get => GetValue(FormatProperty);
  41. set => SetValue(FormatProperty, value);
  42. }
  43. public TimeSpan? Time
  44. {
  45. get => GetValue(TimeProperty);
  46. set => SetValue(TimeProperty, value);
  47. }
  48. public event EventHandler<TimeSelectorTimeChangedEventArgs>? TimeChanged;
  49. static TimeSelectorButton()
  50. {
  51. TimeProperty.Changed.AddClassHandler<TimeSelectorButton>(TimeProperty_Changed);
  52. }
  53. private static void TimeProperty_Changed(TimeSelectorButton button, AvaloniaPropertyChangedEventArgs args)
  54. {
  55. button.TimeChanged?.Invoke(button, new(
  56. args.OldValue is TimeSpan oldTime ? oldTime : null,
  57. args.NewValue is TimeSpan newTime ? newTime : null));
  58. }
  59. [RelayCommand]
  60. private async Task Click()
  61. {
  62. var time = await Navigation.Popup<TimeSelectorViewModel, TimeSpan?>(x =>
  63. {
  64. x.Time = Time;
  65. });
  66. if (time.HasValue)
  67. {
  68. Time = time.Value == TimeSpan.MinValue ? null : time.Value;
  69. }
  70. }
  71. }
  72. public class TimeSelectorTimeSpanFormatter : IMultiValueConverter
  73. {
  74. public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
  75. {
  76. var time = values[0] as TimeSpan?;
  77. if (values[1] is not TimeSelectorButton btn) return null;
  78. if (time.HasValue && time.Value != TimeSpan.MinValue)
  79. {
  80. var sFormat = btn.Format.NotWhiteSpaceOr("hh\\:mm tt");
  81. var fmt = "{0} {1:" + sFormat + "}";
  82. return string.Format(fmt, btn.Prefix, DateTime.Today.Add(time.Value)).Trim();
  83. }
  84. return btn.Prompt.NotWhiteSpaceOr("Select Time");
  85. }
  86. }