diff --git a/Content.Client/UserInterface/Controls/DatePicker.xaml b/Content.Client/UserInterface/Controls/DatePicker.xaml new file mode 100644 index 0000000000..e1dd4e1cd7 --- /dev/null +++ b/Content.Client/UserInterface/Controls/DatePicker.xaml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Content.Client/UserInterface/Controls/DatePicker.xaml.cs b/Content.Client/UserInterface/Controls/DatePicker.xaml.cs new file mode 100644 index 0000000000..189182df19 --- /dev/null +++ b/Content.Client/UserInterface/Controls/DatePicker.xaml.cs @@ -0,0 +1,84 @@ +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.XAML; + +namespace Content.Client.UserInterface.Controls; + +/// +/// An input control for dates. +/// +[GenerateTypedNameReferences] +public sealed partial class DatePicker : Control +{ + /// + /// Raised when is changed. + /// + public event Action? OnChanged; + + /// + /// The date currently selected by the input, or null if it's not a valid date. + /// + public DateOnly? SelectedDate; + + /// + /// The oldest possible date that the user can select. + /// + public DateOnly MinDate = DateOnly.MinValue; + + /// + /// The most recent date that the user can select. + /// + public DateOnly MaxDate = DateOnly.MaxValue; + + /// + /// True if a valid date is selected. + /// + public bool IsValid => SelectedDate is not null; + + public DatePicker() + { + RobustXamlLoader.Load(this); + + MonthOptionButton.AddItem(Loc.GetString("datepicker-month"), 0); + for (var i = 1; i <= 12; i++) + { + MonthOptionButton.AddItem(Loc.GetString($"month-{i}"), i); + } + + DayLineEdit.OnTextChanged += _ => Update(); + YearLineEdit.OnTextChanged += _ => Update(); + MonthOptionButton.OnItemSelected += args => { + if (args.Id != 0) + { + MonthOptionButton.SelectId(args.Id); + } + Update(); + }; + } + + private void Update() + { + var monthNum = MonthOptionButton.SelectedId; + + DateOnly? newDate = null; + + if (int.TryParse(YearLineEdit.Text, out var year) + && int.TryParse(DayLineEdit.Text, out var day) + && monthNum != 0 + ) + { + newDate = new DateOnly(year, monthNum, day); + } + + if (newDate < MinDate || newDate > MaxDate) + { + newDate = null; + } + + if (SelectedDate != newDate) + { + SelectedDate = newDate; + OnChanged?.Invoke(); + } + } +} diff --git a/Resources/Locale/en-US/date.ftl b/Resources/Locale/en-US/date.ftl new file mode 100644 index 0000000000..c3525d7899 --- /dev/null +++ b/Resources/Locale/en-US/date.ftl @@ -0,0 +1,18 @@ +## Used for date picker + +month-1 = January +month-2 = February +month-3 = Mars +month-4 = April +month-5 = May +month-6 = June +month-7 = July +month-8 = August +month-9 = September +month-10 = October +month-11 = November +month-12 = December + +datepicker-month = Month +datepicker-day = Day +datepicker-year = Year