diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_TimePicker.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_TimePicker.cs index 68e3d12873bc..db3cc5ef1b31 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_TimePicker.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_TimePicker.cs @@ -12,6 +12,7 @@ using MUXControlsTestApp.Utilities; using Private.Infrastructure; using SamplesApp.UITests; +using Uno.UI.Extensions; using Uno.UI.RuntimeTests.Helpers; using Uno.UI.RuntimeTests.MUX.Helpers; @@ -288,10 +289,86 @@ private async Task When_Native_Flyout_Theme(UIKit.UIUserInterfaceStyle expectedS Assert.AreEqual(expectedStyle, nativeTimePicker.OverrideUserInterfaceStyle); } #endif - } +#if __IOS__ || __ANDROID__ + [TestMethod] + public async Task When_Time_Uninitialized_Should_Display_Current_Time() + { + var timePicker = new Microsoft.UI.Xaml.Controls.TimePicker(); + timePicker.Time = new TimeSpan(TimePicker.DEFAULT_TIME_TICKS); - class MyContext - { - public object StartTime => null; + var expectedCurrentTime = GetCurrentTime(); + + TestServices.WindowHelper.WindowContent = timePicker; + await TestServices.WindowHelper.WaitForLoaded(timePicker); + + await DateTimePickerHelper.OpenDateTimePicker(timePicker); + + var openFlyouts = FlyoutBase.OpenFlyouts; + var associatedFlyout = openFlyouts[0]; + Assert.IsInstanceOfType(associatedFlyout, typeof(NativeTimePickerFlyout)); + +#if __ANDROID__ + var nativeFlyout = (NativeTimePickerFlyout)associatedFlyout; + + var dialog = nativeFlyout.GetNativeDialog(); + + var decorView = dialog.Window?.DecorView; + var timePickerView = FindTimePicker(decorView); + + var displayedHour = timePickerView.GetHourCompat(); + var displayedMinute = timePickerView.GetMinuteCompat(); + + Assert.AreEqual(expectedCurrentTime.Hours, displayedHour, "Hours should match the current time."); + Assert.AreEqual(expectedCurrentTime.Minutes, displayedMinute, "Minutes should match the current time."); +#elif __IOS__ + var nativeFlyout = (NativeTimePickerFlyout)associatedFlyout; + + var timeSelector = nativeFlyout.GetTimeSelector(); + var displayedTime = timeSelector.Time; + + Assert.AreEqual(expectedCurrentTime.Hours, displayedTime.Hours, "Hours should match the current time."); + Assert.AreEqual(expectedCurrentTime.Minutes, displayedTime.Minutes, "Minutes should match the current time."); +#endif + } + + private TimeSpan GetCurrentTime() + { + var calendar = new global::Windows.Globalization.Calendar(); + calendar.SetToNow(); + var now = calendar.GetDateTime(); + return new TimeSpan(now.Hour, now.Minute, now.Second); + } +#if __ANDROID__ + private Android.Widget.TimePicker FindTimePicker(Android.Views.View root) + { + if (root is Android.Widget.TimePicker picker) + { + return picker; + } + + if (root is not Android.Views.ViewGroup viewGroup) + { + return null; + } + + for (var i = 0; i < viewGroup.ChildCount; i++) + { + var child = viewGroup.GetChildAt(i); + var result = FindTimePicker(child); + if (result != null) + { + return result; + } + } + + return null; + } +#endif +#endif + + class MyContext + { + public object StartTime => null; + } } } diff --git a/src/Uno.UI/UI/Xaml/Controls/TimePicker/NativeTimePickerFlyout.Android.cs b/src/Uno.UI/UI/Xaml/Controls/TimePicker/NativeTimePickerFlyout.Android.cs index ecd3d6b3cb31..6c9a58469114 100644 --- a/src/Uno.UI/UI/Xaml/Controls/TimePicker/NativeTimePickerFlyout.Android.cs +++ b/src/Uno.UI/UI/Xaml/Controls/TimePicker/NativeTimePickerFlyout.Android.cs @@ -16,9 +16,16 @@ partial class NativeTimePickerFlyout private TimeSpan _initialTime; internal bool IsNativeDialogOpen => _dialog?.IsShowing ?? false; + internal UnoTimePickerDialog GetNativeDialog() => _dialog; + internal protected override void Open() { + if (Time.Ticks == TimePicker.DEFAULT_TIME_TICKS) + { + Time = GetCurrentTime(); + } + SaveInitialTime(); ShowTimePicker(); @@ -28,6 +35,7 @@ internal protected override void Open() private void SaveInitialTime() => _initialTime = Time; + private void SaveTime(TimeSpan time) { if (Time != time) @@ -58,7 +66,7 @@ private void AdjustAndSaveTime(int hourOfDay, int minutes) private void ShowTimePicker() { - var time = Time.RoundToNextMinuteInterval(MinuteIncrement); + var time = _initialTime.RoundToNextMinuteInterval(MinuteIncrement); var listener = new OnSetTimeListener((view, hourOfDay, minute) => AdjustAndSaveTime(hourOfDay, minute)); var themeResourceId = CoreApplication.RequestedTheme == Uno.Helpers.Theming.SystemTheme.Light ? diff --git a/src/Uno.UI/UI/Xaml/Controls/TimePicker/NativeTimePickerFlyout.cs b/src/Uno.UI/UI/Xaml/Controls/TimePicker/NativeTimePickerFlyout.cs index 681a1d81d20b..3eccce617707 100644 --- a/src/Uno.UI/UI/Xaml/Controls/TimePicker/NativeTimePickerFlyout.cs +++ b/src/Uno.UI/UI/Xaml/Controls/TimePicker/NativeTimePickerFlyout.cs @@ -1,7 +1,16 @@ -using Microsoft.UI.Xaml.Controls.Primitives; +using System; +using Windows.Globalization; +using Microsoft.UI.Xaml.Controls.Primitives; namespace Microsoft.UI.Xaml.Controls; internal partial class NativeTimePickerFlyout : TimePickerFlyout { + protected TimeSpan GetCurrentTime() + { + var calendar = new Calendar(); + calendar.SetToNow(); + var currentDateTime = calendar.GetDateTime(); + return new TimeSpan(currentDateTime.Hour, currentDateTime.Minute, currentDateTime.Second); + } } diff --git a/src/Uno.UI/UI/Xaml/Controls/TimePicker/NativeTimePickerFlyout.iOS.cs b/src/Uno.UI/UI/Xaml/Controls/TimePicker/NativeTimePickerFlyout.iOS.cs index 0941779e571a..fb0a8ea6d400 100644 --- a/src/Uno.UI/UI/Xaml/Controls/TimePicker/NativeTimePickerFlyout.iOS.cs +++ b/src/Uno.UI/UI/Xaml/Controls/TimePicker/NativeTimePickerFlyout.iOS.cs @@ -21,6 +21,8 @@ partial class NativeTimePickerFlyout private FlyoutPresenter? _timePickerPresenter; private bool _isInitialized; + internal TimePickerSelector? GetTimeSelector() => _timeSelector; + protected override void InitializePopupPanel() { _popup.PopupPanel = new PickerFlyoutPopupPanel(this) @@ -144,6 +146,11 @@ void onUnload(object sender, RoutedEventArgs e) protected internal override void Open() { + if (Time.Ticks == TimePicker.DEFAULT_TIME_TICKS) + { + Time = GetCurrentTime(); + } + InitializeContent(); _timeSelector?.Initialize(); diff --git a/src/Uno.UI/UI/Xaml/Controls/TimePicker/TimePicker.native.cs b/src/Uno.UI/UI/Xaml/Controls/TimePicker/TimePicker.native.cs index 12c73362d389..918681f9c4c4 100644 --- a/src/Uno.UI/UI/Xaml/Controls/TimePicker/TimePicker.native.cs +++ b/src/Uno.UI/UI/Xaml/Controls/TimePicker/TimePicker.native.cs @@ -12,6 +12,7 @@ namespace Microsoft.UI.Xaml.Controls; partial class TimePicker { + internal const long DEFAULT_TIME_TICKS = -1; #region FlyoutPlacement DependencyProperty [UnoOnly]