mirror of
https://gitee.com/chinware/atomui.git
synced 2024-11-29 18:38:16 +08:00
完成基本的 TimePicker
This commit is contained in:
parent
14005e1d35
commit
bb585e3dc1
@ -62,6 +62,7 @@ internal class FlyoutStateHelper : AvaloniaObject
|
||||
public event EventHandler<EventArgs>? FlyoutAboutToShow;
|
||||
|
||||
public Func<Point, bool>? OpenFlyoutPredicate;
|
||||
public Func<IPopupHostProvider, RawPointerEventArgs, bool>? ClickHideFlyoutPredicate;
|
||||
|
||||
private DispatcherTimer? _mouseEnterDelayTimer;
|
||||
private DispatcherTimer? _mouseLeaveDelayTimer;
|
||||
@ -258,9 +259,16 @@ internal class FlyoutStateHelper : AvaloniaObject
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if (Flyout is IPopupHostProvider popupHostProvider) {
|
||||
if (popupHostProvider.PopupHost != pointerEventArgs.Root) {
|
||||
HideFlyout();
|
||||
if (ClickHideFlyoutPredicate is not null) {
|
||||
if (ClickHideFlyoutPredicate(popupHostProvider, pointerEventArgs)) {
|
||||
HideFlyout();
|
||||
}
|
||||
} else {
|
||||
if (popupHostProvider.PopupHost != pointerEventArgs.Root) {
|
||||
HideFlyout();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
@ -15,4 +16,18 @@ internal class PickerIndicator : TemplatedControl
|
||||
get => GetValue(IsInClearModeProperty);
|
||||
set => SetValue(IsInClearModeProperty, value);
|
||||
}
|
||||
|
||||
private IconButton? _clearButton;
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
_clearButton = e.NameScope.Get<IconButton>(PickerIndicatorTheme.ClearButtonPart);
|
||||
if (_clearButton is not null) {
|
||||
_clearButton.Click += (sender, args) =>
|
||||
{
|
||||
ClearRequest?.Invoke(this, EventArgs.Empty);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
using AtomUI.Data;
|
||||
using AtomUI.Controls.Utils;
|
||||
using AtomUI.Data;
|
||||
using AtomUI.Theme.Styling;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Diagnostics;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Input;
|
||||
@ -162,9 +164,15 @@ public class TimePicker : LineEdit
|
||||
_flyoutStateHelper.FlyoutAboutToShow += HandleFlyoutAboutToShow;
|
||||
_flyoutStateHelper.FlyoutAboutToClose += HandleFlyoutAboutToClose;
|
||||
_flyoutStateHelper.OpenFlyoutPredicate = FlyoutOpenPredicate;
|
||||
_flyoutStateHelper.ClickHideFlyoutPredicate = ClickHideFlyoutPredicate;
|
||||
}
|
||||
|
||||
private bool FlyoutOpenPredicate(Point position)
|
||||
{
|
||||
return PositionInEditKernel(position);
|
||||
}
|
||||
|
||||
private bool PositionInEditKernel(Point position)
|
||||
{
|
||||
if (_textBoxInnerBox is not null) {
|
||||
var pos = _textBoxInnerBox.TranslatePoint(new Point(0, 0), TopLevel.GetTopLevel(this)!);
|
||||
@ -200,6 +208,17 @@ public class TimePicker : LineEdit
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ClickHideFlyoutPredicate(IPopupHostProvider hostProvider, RawPointerEventArgs args)
|
||||
{
|
||||
if (hostProvider.PopupHost != args.Root) {
|
||||
if (!PositionInEditKernel(args.Position)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void HandleFlyoutAboutToShow(object? sender, EventArgs args)
|
||||
{
|
||||
_currentValidSelected = false;
|
||||
@ -208,7 +227,11 @@ public class TimePicker : LineEdit
|
||||
private void HandleFlyoutAboutToClose(object? sender, EventArgs args)
|
||||
{
|
||||
if (!_currentValidSelected) {
|
||||
Text = SelectedTime.ToString();
|
||||
if (SelectedTime.HasValue) {
|
||||
Text = DateTimeUtils.FormatTimeSpan(SelectedTime.Value, ClockIdentifier == "12HourClock");
|
||||
} else {
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,6 +245,11 @@ public class TimePicker : LineEdit
|
||||
base.OnApplyTemplate(e);
|
||||
if (InnerRightContent is null) {
|
||||
_pickerIndicator = new PickerIndicator();
|
||||
_pickerIndicator.ClearRequest += (sender, args) =>
|
||||
{
|
||||
Clear();
|
||||
SelectedTime = null;
|
||||
};
|
||||
InnerRightContent = _pickerIndicator;
|
||||
}
|
||||
if (_pickerFlyout is null) {
|
||||
@ -260,7 +288,21 @@ public class TimePicker : LineEdit
|
||||
_indicatorDetectDisposable = inputManager.Process.Subscribe(DetectIndicatorState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
if (VisualRoot is not null) {
|
||||
if (change.Property == SelectedTimeProperty) {
|
||||
if (SelectedTime.HasValue) {
|
||||
Text = DateTimeUtils.FormatTimeSpan(SelectedTime.Value, ClockIdentifier == "12HourClock");
|
||||
} else {
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DetectIndicatorState(RawInputEventArgs args)
|
||||
{
|
||||
if (args is RawPointerEventArgs pointerEventArgs) {
|
||||
@ -318,7 +360,7 @@ public class TimePicker : LineEdit
|
||||
|
||||
internal void NotifyTemporaryTimeSelected(TimeSpan selected)
|
||||
{
|
||||
Text = selected.ToString();
|
||||
Text = DateTimeUtils.FormatTimeSpan(selected, ClockIdentifier == "12HourClock");
|
||||
}
|
||||
|
||||
internal void NotifyConfirmed(TimeSpan value)
|
||||
|
@ -15,7 +15,8 @@ public class TimePickerFlyoutPresenter : FlyoutPresenter
|
||||
private TimePickerPresenter? _timePickerPresenter;
|
||||
private IDisposable? _disposable;
|
||||
private Button? _confirmButton;
|
||||
|
||||
private Button? _nowButton;
|
||||
|
||||
public TimePickerFlyoutPresenter(TimePicker timePicker)
|
||||
{
|
||||
TimePickerRef = timePicker;
|
||||
@ -27,6 +28,7 @@ public class TimePickerFlyoutPresenter : FlyoutPresenter
|
||||
base.OnApplyTemplate(e);
|
||||
_timePickerPresenter = e.NameScope.Get<TimePickerPresenter>(TimePickerFlyoutPresenterTheme.ContentPresenterPart);
|
||||
_confirmButton = e.NameScope.Get<Button>(TimePickerFlyoutPresenterTheme.ConfirmButtonPart);
|
||||
_nowButton = e.NameScope.Get<Button>(TimePickerFlyoutPresenterTheme.NowButtonPart);
|
||||
if (_timePickerPresenter is not null) {
|
||||
_timePickerPresenter.Confirmed += (sender, args) =>
|
||||
{
|
||||
@ -37,6 +39,16 @@ public class TimePickerFlyoutPresenter : FlyoutPresenter
|
||||
if (_confirmButton is not null) {
|
||||
_confirmButton.Click += HandleConfirmButtonClicked;
|
||||
}
|
||||
|
||||
if (_nowButton is not null) {
|
||||
_nowButton.Click += HandleNowButtonClicked;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleNowButtonClicked(object? sender, RoutedEventArgs args)
|
||||
{
|
||||
_timePickerPresenter?.NowConfirm();
|
||||
TimePickerRef.ClosePickerFlyout();
|
||||
}
|
||||
|
||||
private void HandleConfirmButtonClicked(object? sender, RoutedEventArgs args)
|
||||
|
@ -188,18 +188,8 @@ public class TimePickerPresenter : PickerPresenterBase
|
||||
var selectedValue = CollectValue();
|
||||
TemporaryTime = selectedValue;
|
||||
if (IsShowHeader) {
|
||||
var dateTime = DateTime.Today.Add(selectedValue);
|
||||
if (ClockIdentifier == "12HourClock") {
|
||||
var formatInfo = new DateTimeFormatInfo();
|
||||
formatInfo.AMDesignator = LanguageResourceBinder.GetLangResource(TimePickerLangResourceKey.AMText)!;
|
||||
formatInfo.PMDesignator = LanguageResourceBinder.GetLangResource(TimePickerLangResourceKey.PMText)!;
|
||||
if (_headerText is not null) {
|
||||
_headerText.Text = dateTime.ToString(@"hh:mm:ss tt", formatInfo);
|
||||
}
|
||||
} else {
|
||||
if (_headerText is not null) {
|
||||
_headerText.Text = dateTime.ToString(@"HH:mm:ss");
|
||||
}
|
||||
if (_headerText is not null) {
|
||||
_headerText.Text = DateTimeUtils.FormatTimeSpan(selectedValue, ClockIdentifier == "12HourClock");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -260,6 +250,12 @@ public class TimePickerPresenter : PickerPresenterBase
|
||||
SetCurrentValue(TimeProperty, value);
|
||||
base.OnConfirmed();
|
||||
}
|
||||
|
||||
internal void NowConfirm()
|
||||
{
|
||||
SetCurrentValue(TimeProperty, DateTime.Now.TimeOfDay);
|
||||
base.OnConfirmed();
|
||||
}
|
||||
|
||||
internal void Confirm()
|
||||
{
|
||||
|
21
src/AtomUI.Controls/Utils/DateTimeUtils.cs
Normal file
21
src/AtomUI.Controls/Utils/DateTimeUtils.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System.Globalization;
|
||||
using AtomUI.Controls.TimePickerLang;
|
||||
using AtomUI.Data;
|
||||
|
||||
namespace AtomUI.Controls.Utils;
|
||||
|
||||
internal static class DateTimeUtils
|
||||
{
|
||||
public static string FormatTimeSpan(TimeSpan value, bool is12HourClock = false)
|
||||
{
|
||||
var dateTime = DateTime.Today.Add(value);
|
||||
if (is12HourClock) {
|
||||
var formatInfo = new DateTimeFormatInfo();
|
||||
formatInfo.AMDesignator = LanguageResourceBinder.GetLangResource(TimePickerLangResourceKey.AMText)!;
|
||||
formatInfo.PMDesignator = LanguageResourceBinder.GetLangResource(TimePickerLangResourceKey.PMText)!;
|
||||
return dateTime.ToString(@"hh:mm:ss tt", formatInfo);
|
||||
}
|
||||
|
||||
return dateTime.ToString(@"HH:mm:ss");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user