Skip to content

Commit

Permalink
Set TimePicker.Time seconds to zero when UseSeconds is False (#17251)
Browse files Browse the repository at this point in the history
* Set TimePickerPresenter.Time seconds component to zero when UseSeconds is false

* Remove unneeded PART_FirstSpace annotation from TimePickerPresenter

---------

Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
  • Loading branch information
2 people authored and maxkatz6 committed Oct 27, 2024
1 parent f965634 commit 7da26e2
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 6 deletions.
9 changes: 5 additions & 4 deletions src/Avalonia.Controls/DateTimePickers/TimePickerPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ namespace Avalonia.Controls
[TemplatePart("PART_PeriodSelector", typeof(DateTimePickerPanel), IsRequired = true)]
[TemplatePart("PART_PeriodUpButton", typeof(RepeatButton))]
[TemplatePart("PART_PickerContainer", typeof(Grid), IsRequired = true)]
[TemplatePart("PART_ThirdSpacer", typeof(Rectangle), IsRequired = true)]
[TemplatePart("PART_SecondSpacer", typeof(Rectangle), IsRequired = true)]
[TemplatePart("PART_ThirdSpacer", typeof(Rectangle), IsRequired = true)]
public class TimePickerPresenter : PickerPresenterBase
{
/// <summary>
Expand Down Expand Up @@ -241,7 +242,7 @@ protected override void OnConfirmed()
hr = per == 1 ? (hr == 12) ? 12 : hr + 12 : per == 0 && hr == 12 ? 0 : hr;
}

SetCurrentValue(TimeProperty, new TimeSpan(hr, min, sec));
SetCurrentValue(TimeProperty, new TimeSpan(hr, min, UseSeconds ? sec : 0));

base.OnConfirmed();
}
Expand All @@ -262,14 +263,14 @@ private void InitPicker()
_minuteSelector!.MaximumValue = 59;
_minuteSelector.MinimumValue = 0;
_minuteSelector.Increment = MinuteIncrement;
_minuteSelector.SelectedValue = Time.Minutes;
_minuteSelector.ItemFormat = "mm";
_minuteSelector.SelectedValue = Time.Minutes;

_secondSelector!.MaximumValue = 59;
_secondSelector.MinimumValue = 0;
_secondSelector.Increment = SecondIncrement;
_secondSelector.SelectedValue = Time.Seconds;
_secondSelector.ItemFormat = "ss";
_secondSelector.SelectedValue = Time.Seconds;

_periodSelector!.MaximumValue = 1;
_periodSelector.MinimumValue = 0;
Expand Down
151 changes: 149 additions & 2 deletions tests/Avalonia.Controls.UnitTests/TimePickerTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Reactive.Subjects;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Shapes;
using Avalonia.Controls.Templates;
using Avalonia.Data;
Expand Down Expand Up @@ -94,6 +95,67 @@ public void UseSeconds_Equals_False_Should_Hide_Seconds()
}
}

[Fact]
public void UseSeconds_Equals_False_Should_Have_Zero_Seconds()
{
using (UnitTestApplication.Start(Services))
{
TimePicker timePicker = new TimePicker()
{
UseSeconds = false,
Template = CreateTemplate(includePopup: true)
};
timePicker.ApplyTemplate();

var desc = timePicker.GetVisualDescendants();
Assert.True(desc.Count() > 2);

// find button
Assert.True(desc.ElementAt(1) is Button);
var btn = (Button)desc.ElementAt(1);

Assert.True(desc.ElementAt(2) is Popup);
var popup = (Popup)desc.ElementAt(2);

Assert.True(popup.Child is TimePickerPresenter);
var timePickerPresenter = (TimePickerPresenter)popup.Child;

var panel = (Panel)timePickerPresenter.VisualChildren[0];
var acceptBtn = (Button)panel.VisualChildren[0];

Assert.False(popup.IsOpen);
btn.PerformClick();
Assert.True(popup.IsOpen);
Assert.False(timePickerPresenter.UseSeconds);

acceptBtn.PerformClick();

Assert.Equal(0, timePickerPresenter.Time.Seconds);
Assert.Equal(0, timePicker.SelectedTime?.Seconds);
}
}

[Fact]
public void TimePickerPresenter_UseSeconds_Equals_False_Should_Have_Zero_Seconds()
{
using (UnitTestApplication.Start(Services))
{
TimePickerPresenter timePickerPresenter = new TimePickerPresenter()
{
UseSeconds = false,
Template = CreatePickerTemplate(),
};
timePickerPresenter.ApplyTemplate();

var panel = (Panel)timePickerPresenter.VisualChildren[0];
var acceptBtn = (Button)panel.VisualChildren[0];

acceptBtn.PerformClick();

Assert.Equal(0, timePickerPresenter.Time.Seconds);
}
}

[Fact]
public void SelectedTime_null_Should_Use_Placeholders()
{
Expand Down Expand Up @@ -219,14 +281,15 @@ public void SelectedTime_EnableDataValidation()
textShaperImpl: new HeadlessTextShaperStub(),
renderInterface: new HeadlessPlatformRenderInterface());

private static IControlTemplate CreateTemplate()
private static IControlTemplate CreateTemplate(bool includePopup = false)
{
return new FuncControlTemplate((control, scope) =>
{
var layoutRoot = new Grid
{
Name = "LayoutRoot"
}.RegisterInNameScope(scope);

//Skip contentpresenter
var flyoutButton = new Button
{
Expand Down Expand Up @@ -288,7 +351,7 @@ private static IControlTemplate CreateTemplate()
Name = "PART_SecondColumnDivider"
}.RegisterInNameScope(scope);
Grid.SetColumn(secondSpacer, 3);

var thirdSpacer = new Rectangle
{
Name = "PART_ThirdColumnDivider"
Expand All @@ -298,8 +361,92 @@ private static IControlTemplate CreateTemplate()
contentGrid.Children.AddRange(new Control[] { firstPickerHost, firstSpacer, secondPickerHost, secondSpacer, thirdPickerHost, thirdSpacer, fourthPickerHost });
flyoutButton.Content = contentGrid;
layoutRoot.Children.Add(flyoutButton);

if (includePopup)
{
var popup = new Popup
{
Name = "PART_Popup"
}.RegisterInNameScope(scope);

var pickerPresenter = new TimePickerPresenter
{
Name = "PART_PickerPresenter",
Template = CreatePickerTemplate()
}.RegisterInNameScope(scope);
pickerPresenter.ApplyTemplate();

popup.Child = pickerPresenter;

layoutRoot.Children.Add(popup);
}

return layoutRoot;
});
}

private static IControlTemplate CreatePickerTemplate()
{
return new FuncControlTemplate((control, scope) =>
{
var acceptButton = new Button
{
Name = "PART_AcceptButton"
}.RegisterInNameScope(scope);

var hourSelector = new DateTimePickerPanel
{
Name = "PART_HourSelector",
PanelType = DateTimePickerPanelType.Hour,
}.RegisterInNameScope(scope);

var minuteSelector = new DateTimePickerPanel
{
Name = "PART_MinuteSelector",
PanelType = DateTimePickerPanelType.Minute,
}.RegisterInNameScope(scope);

var secondHost = new Panel
{
Name = "PART_SecondHost"
}.RegisterInNameScope(scope);

var secondSelector = new DateTimePickerPanel
{
Name = "PART_SecondSelector",
PanelType = DateTimePickerPanelType.Second,
}.RegisterInNameScope(scope);

var periodHost = new Panel
{
Name = "PART_PeriodHost"
}.RegisterInNameScope(scope);

var periodSelector = new DateTimePickerPanel
{
Name = "PART_PeriodSelector",
PanelType = DateTimePickerPanelType.TimePeriod,
}.RegisterInNameScope(scope);

var pickerContainer = new Grid
{
Name = "PART_PickerContainer"
}.RegisterInNameScope(scope);

var secondSpacer = new Rectangle
{
Name = "PART_SecondSpacer"
}.RegisterInNameScope(scope);

var thirdSpacer = new Rectangle
{
Name = "PART_ThirdSpacer"
}.RegisterInNameScope(scope);

var contentPanel = new StackPanel();
contentPanel.Children.AddRange(new Control[] { acceptButton, hourSelector, minuteSelector, secondHost, secondSelector, periodHost, periodSelector, pickerContainer, secondSpacer, thirdSpacer });
return contentPanel;
});
}
}
}

0 comments on commit 7da26e2

Please sign in to comment.