finish DualMonthRangeDatePicker Control

finish DualMonthRangeDatePicker Control
This commit is contained in:
polarboy 2024-09-18 18:51:20 +08:00
parent 6ba7b30f7f
commit d7b107b2c4
13 changed files with 66 additions and 32 deletions

View File

@ -9,18 +9,18 @@
xmlns:calendarView="clr-namespace:AtomUI.Controls.CalendarView;assembly=AtomUI.Controls"
mc:Ignorable="d">
<desktop:ShowCasePanel>
<desktop:ShowCaseItem
Title="Basic"
Description="Click DatePicker, and then we could select or input a date in panel.">
<atom:DatePicker Watermark="Select date"/>
</desktop:ShowCaseItem>
<desktop:ShowCaseItem
Title="With Time Picker"
Description="Date selection panel with time selection.">
<atom:DatePicker Watermark="Select date" IsShowTime="True" IsNeedConfirm="True" ClockIdentifier="HourClock12"/>
</desktop:ShowCaseItem>
<!-- <desktop:ShowCaseItem -->
<!-- Title="Basic" -->
<!-- Description="Click DatePicker, and then we could select or input a date in panel."> -->
<!-- <atom:DatePicker Watermark="Select date"/> -->
<!-- </desktop:ShowCaseItem> -->
<!-- -->
<!-- <desktop:ShowCaseItem -->
<!-- Title="With Time Picker" -->
<!-- Description="Date selection panel with time selection."> -->
<!-- <atom:DatePicker Watermark="Select date" IsShowTime="True" IsNeedConfirm="True" ClockIdentifier="HourClock12"/> -->
<!-- </desktop:ShowCaseItem> -->
<!-- -->
<!-- <desktop:ShowCaseItem -->
<!-- Title="With Time Picker" -->
<!-- Description="Date selection panel with time selection."> -->
@ -30,7 +30,7 @@
<!-- <desktop:ShowCaseItem -->
<!-- Title="With Time Picker" -->
<!-- Description="Date selection panel with time selection."> -->
<!-- <calendarView:RangeCalendar IsSelectRangeStart="True" SecondarySelectedDate="2024-10-1"/> -->
<!-- <calendarView:DualMonthRangeCalendar IsSelectRangeStart="True" SecondarySelectedDate="2024-10-1"/> -->
<!-- </desktop:ShowCaseItem> -->
<desktop:ShowCaseItem
@ -38,6 +38,12 @@
Description="Date selection panel with time selection.">
<atom:RangeDatePicker IsShowTime="true" Watermark="Select date"/>
</desktop:ShowCaseItem>
<desktop:ShowCaseItem
Title="With Time Picker"
Description="Date selection panel with time selection.">
<atom:RangeDatePicker IsShowTime="False" Watermark="Select date" IsNeedConfirm="True"/>
</desktop:ShowCaseItem>
<!-- -->
<!-- <desktop:ShowCaseItem -->
<!-- Title="Need Confirm" -->

View File

@ -21,7 +21,7 @@ public class DateSelectedEventArgs : EventArgs
}
[TemplatePart(CalendarTheme.CalendarItemPart, typeof(CalendarItem))]
public class Calendar : TemplatedControl
internal class Calendar : TemplatedControl
{
internal const int RowsPerMonth = 7;
internal const int ColumnsPerMonth = 7;

View File

@ -3,7 +3,7 @@ using Avalonia.Threading;
namespace AtomUI.Controls.CalendarView;
public sealed class CalendarBlackoutDatesCollection : ObservableCollection<CalendarDateRange>
internal sealed class CalendarBlackoutDatesCollection : ObservableCollection<CalendarDateRange>
{
/// <summary>
/// The Calendar whose dates this object represents.

View File

@ -2,7 +2,7 @@
namespace AtomUI.Controls.CalendarView;
public class DualMonthRangeCalendar : RangeCalendar
internal class DualMonthRangeCalendar : RangeCalendar
{
protected override Type StyleKeyOverride => typeof(DualMonthRangeCalendar);

View File

@ -18,7 +18,7 @@ public class RangeDateSelectedEventArgs : EventArgs
}
}
public class RangeCalendar : Calendar
internal class RangeCalendar : Calendar
{
protected override Type StyleKeyOverride => typeof(RangeCalendar);

View File

@ -180,7 +180,7 @@ internal class DatePickerPresenter : PickerPresenterBase
_todayButton = e.NameScope.Get<Button>(DatePickerPresenterTheme.TodayButtonPart);
_confirmButton = e.NameScope.Get<Button>(DatePickerPresenterTheme.ConfirmButtonPart);
_calendarView = e.NameScope.Get<PickerCalendar>(DatePickerPresenterTheme.CalendarViewPart);
_timeView = e.NameScope.Get<TimeView>(DatePickerPresenterTheme.TimeViewPart);
_timeView = e.NameScope.Find<TimeView>(DatePickerPresenterTheme.TimeViewPart);
SetupButtonStatus();
if (_calendarView is not null)
{

View File

@ -150,8 +150,8 @@ internal class DatePickerToken : AbstractControlDesignToken
HeaderPadding = new Thickness(0, 0, 0, _globalToken.PaddingSM);
CellLineHeight = CellHeight - 2; // 不知道为啥设置成一样,或者不设置文字有些靠下
RangeCalendarSpacing = 20;
PickerInputMinWidth = 150;
PickerInputWithTimeMinWidth = 200;
PickerInputMinWidth = 100;
PickerInputWithTimeMinWidth = 160;
ButtonsPanelMargin = new Thickness(0, _globalToken.MarginXS, 0, 0);
}
}

View File

@ -1,4 +1,7 @@
using AtomUI.Theme.Styling;
using AtomUI.Controls.CalendarView;
using AtomUI.Theme.Styling;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
namespace AtomUI.Controls;
@ -12,4 +15,16 @@ internal class DualMonthRangeDatePickerPresenterTheme : DatePickerPresenterTheme
public DualMonthRangeDatePickerPresenterTheme(Type targetType) : base(targetType)
{
}
protected override Control BuildCalendarView(DatePickerPresenter presenter, INameScope scope)
{
var calendarView = new DualMonthRangeCalendar()
{
Name = CalendarViewPart,
};
CreateTemplateParentBinding(calendarView, DualMonthRangeCalendar.SelectedDateProperty, DualMonthRangeDatePickerPresenter.SelectedDateTimeProperty);
CreateTemplateParentBinding(calendarView, DualMonthRangeCalendar.SecondarySelectedDateProperty, DualMonthRangeDatePickerPresenter.SecondarySelectedDateTimeProperty);
calendarView.RegisterInNameScope(scope);
return calendarView;
}
}

View File

@ -94,9 +94,13 @@ internal class RangeDatePickerPresenter : DatePickerPresenter
}
else
{
SecondarySelectedDateTime = CollectDateTime(rangeCalendar.SecondarySelectedDate, TempSelectedTime ?? _timeView?.SelectedTime);
}
if (!IsNeedConfirm)
{
OnConfirmed();
}
}
}

View File

@ -38,11 +38,11 @@ internal class RangeDatePickerTheme : RangeInfoPickerInputTheme
withTimeStyle.Add(DatePicker.MinWidthProperty, DatePickerTokenResourceKey.PickerInputWithTimeMinWidth);
{
var infoInputBoxStyle = new Style(selector => selector.Nesting().Template().Name(InfoInputBoxPart));
infoInputBoxStyle.Add(TextBox.MinWidthProperty, DatePickerTokenResourceKey.PickerInputMinWidth);
infoInputBoxStyle.Add(TextBox.MinWidthProperty, DatePickerTokenResourceKey.PickerInputWithTimeMinWidth);
withTimeStyle.Add(infoInputBoxStyle);
var secondaryInfoInputBoxStyle = new Style(selector => selector.Nesting().Template().Name(SecondaryInfoInputBoxPart));
secondaryInfoInputBoxStyle.Add(TextBox.MinWidthProperty, DatePickerTokenResourceKey.PickerInputMinWidth);
secondaryInfoInputBoxStyle.Add(TextBox.MinWidthProperty, DatePickerTokenResourceKey.PickerInputWithTimeMinWidth);
withTimeStyle.Add(secondaryInfoInputBoxStyle);
}
Add(withTimeStyle);

View File

@ -37,8 +37,8 @@ internal class TimedRangeDatePickerPresenterTheme : DatePickerPresenterTheme
Name = TimeViewPart,
VerticalAlignment = VerticalAlignment.Top,
};
CreateTemplateParentBinding(timeView, TimeView.ClockIdentifierProperty, DatePickerPresenter.ClockIdentifierProperty);
CreateTemplateParentBinding(timeView, TimeView.IsVisibleProperty, DatePickerPresenter.IsShowTimeProperty);
CreateTemplateParentBinding(timeView, TimeView.ClockIdentifierProperty, TimedRangeDatePickerPresenter.ClockIdentifierProperty);
CreateTemplateParentBinding(timeView, TimeView.IsVisibleProperty, TimedRangeDatePickerPresenter.IsShowTimeProperty);
timeView.RegisterInNameScope(scope);
calendarLayout.Children.Add(timeView);

View File

@ -257,11 +257,11 @@ internal class FlyoutStateHelper : AvaloniaObject
{
return;
}
_flyoutCloseDetectDisposable?.Dispose();
_flyoutCloseDetectDisposable = null;
StopMouseEnterTimer();
if (immediately || MouseLeaveDelay == 0)
{
FlyoutAboutToClose?.Invoke(this, EventArgs.Empty);

View File

@ -35,13 +35,11 @@ internal class PopupShadowLayer : LiteWindow, IShadowDecorator
private ShadowRenderer? _shadowRenderer;
private CompositeDisposable? _compositeDisposable;
private readonly IManagedPopupPositionerPopup? _managedPopupPositionerPopup;
private TopLevel? _topLevel;
private bool _isOpened;
public PopupShadowLayer(TopLevel topLevel)
: base(topLevel, topLevel.PlatformImpl?.CreatePopup()!)
{
_topLevel = topLevel;
Background = new SolidColorBrush(Colors.Transparent);
if (this is WindowBase window)
{
@ -190,8 +188,12 @@ internal class PopupShadowLayer : LiteWindow, IShadowDecorator
{
if (_target is not null)
{
_target.Opened -= HandleTargetOpened;
_target.Closed -= HandleTargetClosed;
_target.Opened -= HandleTargetOpened;
_target.Closed -= HandleTargetClosed;
if (_target.Child is not null)
{
_target.Child.SizeChanged -= HandleChildSizeChange;
}
}
_compositeDisposable?.Dispose();
@ -204,6 +206,7 @@ internal class PopupShadowLayer : LiteWindow, IShadowDecorator
{
if (_target?.Child is not null && _shadowRenderer is not null)
{
_target.Child.SizeChanged += HandleChildSizeChange;
// 理论上现在已经有大小了
var content = _target?.Child!;
var detectPopupWinSize = DetectShadowWindowSize(_target!);
@ -243,6 +246,12 @@ internal class PopupShadowLayer : LiteWindow, IShadowDecorator
}
}
private void HandleChildSizeChange(object? sender, SizeChangedEventArgs args)
{
SetupShadowRenderer();
InvalidateMeasure();
}
private Size CalculateShadowRendererSize(Size content)
{
var shadowThickness = MaskShadows.Thickness();