]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add date picker (#40660)
author0x6273 <0x40@keemail.me>
Tue, 14 Oct 2025 17:26:07 +0000 (19:26 +0200)
committerGitHub <noreply@github.com>
Tue, 14 Oct 2025 17:26:07 +0000 (17:26 +0000)
* Add DatePicker

* DatePicker fixes

- Now uses `DateOnly` (currently fails sandbox, but PJB has promised to add
it in engine)
- Add MinDate and MaxDate fields
- Use constructor instead of parsing date string

Content.Client/UserInterface/Controls/DatePicker.xaml [new file with mode: 0644]
Content.Client/UserInterface/Controls/DatePicker.xaml.cs [new file with mode: 0644]
Resources/Locale/en-US/date.ftl [new file with mode: 0644]

diff --git a/Content.Client/UserInterface/Controls/DatePicker.xaml b/Content.Client/UserInterface/Controls/DatePicker.xaml
new file mode 100644 (file)
index 0000000..e1dd4e1
--- /dev/null
@@ -0,0 +1,7 @@
+<Control xmlns="https://spacestation14.io">
+    <BoxContainer Orientation="Horizontal" >
+        <LineEdit Name="DayLineEdit" PlaceHolder="{Loc 'datepicker-day'}" Margin="4 4" MinWidth="38" />
+        <OptionButton Name="MonthOptionButton" Margin="4 4" MinWidth="120" />
+        <LineEdit Name="YearLineEdit" PlaceHolder="{Loc 'datepicker-year'}" Margin="4 4" MinWidth="55" />
+    </BoxContainer>
+</Control>
diff --git a/Content.Client/UserInterface/Controls/DatePicker.xaml.cs b/Content.Client/UserInterface/Controls/DatePicker.xaml.cs
new file mode 100644 (file)
index 0000000..189182d
--- /dev/null
@@ -0,0 +1,84 @@
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client.UserInterface.Controls;
+
+/// <summary>
+/// An input control for dates.
+/// </summary>
+[GenerateTypedNameReferences]
+public sealed partial class DatePicker : Control
+{
+    /// <summary>
+    /// Raised when <see cref="SelectedDate"> is changed.
+    /// </summary>
+    public event Action? OnChanged;
+
+    /// <summary>
+    /// The date currently selected by the input, or null if it's not a valid date.
+    /// </summary>
+    public DateOnly? SelectedDate;
+
+    /// <summary>
+    /// The oldest possible date that the user can select.
+    /// </summary>
+    public DateOnly MinDate = DateOnly.MinValue;
+
+    /// <summary>
+    /// The most recent date that the user can select.
+    /// </summary>
+    public DateOnly MaxDate = DateOnly.MaxValue;
+
+    /// <summary>
+    /// True if a valid date is selected.
+    /// </summary>
+    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 (file)
index 0000000..c3525d7
--- /dev/null
@@ -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