重构 RangeCalendar 到 DatePicker

This commit is contained in:
polarboy
2024-09-10 17:50:37 +08:00
parent 0aedeeb6e3
commit d371663124
14 changed files with 186 additions and 20 deletions
@@ -5,7 +5,12 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:desktop="clr-namespace:AtomUI.Demo.Desktop"
xmlns:atom="https://atomui.net"
mc:Ignorable="d">
<desktop:ShowCasePanel />
<desktop:ShowCasePanel>
<desktop:ShowCaseItem
Title="Basic"
Description="Click TimePicker, and then we could select or input a time in panel.">
</desktop:ShowCaseItem>
</desktop:ShowCasePanel>
</UserControl>
@@ -1,5 +1,128 @@
namespace AtomUI.Controls;
using AtomUI.Media;
using AtomUI.Theme.TokenSystem;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
public class DatePickerToken
namespace AtomUI.Controls;
[ControlDesignToken]
internal class DatePickerToken : AbstractControlDesignToken
{
public const string ID = "DatePicker";
public DatePickerToken()
: base(ID)
{
}
/// <summary>
/// 单元格悬浮态背景色
/// </summary>
public Color CellHoverBg { get; set; }
/// <summary>
/// 选取范围内的单元格背景色
/// </summary>
public Color CellActiveWithRangeBg { get; set; }
/// <summary>
/// 选取范围内的单元格悬浮态背景色
/// </summary>
public Color CellHoverWithRangeBg { get; set; }
/// <summary>
/// 单元格禁用态背景色
/// </summary>
public Color CellBgDisabled { get; set; }
/// <summary>
/// 选取范围时单元格边框色
/// </summary>
public Color CellRangeBorderColor { get; set; }
/// <summary>
/// 单元格高度
/// </summary>
public double CellHeight { get; set; }
/// <summary>
/// 单元格宽度
/// </summary>
public double CellWidth { get; set; }
/// <summary>
/// 单元格行高
/// </summary>
public double CellLineHeight { get; set; }
/// <summary>
/// 单元格外边距
/// </summary>
public Thickness CellMargin { get; set; }
/// <summary>
/// 日历项最小宽度
/// </summary>
public double ItemPanelMinWidth { get; set; }
/// <summary>
/// 日历项最小高度
/// </summary>
public double ItemPanelMinHeight { get; set; }
/// <summary>
/// 单元格文本高度
/// </summary>
public double TextHeight { get; set; }
/// <summary>
/// 面板内容内边距
/// </summary>
public Thickness PanelContentPadding { get; set; }
/// <summary>
/// 十年/年/季/月/周单元格高度
/// </summary>
public double WithoutTimeCellHeight { get; set; }
/// <summary>
/// 星期的高度
/// </summary>
public GridLength DayTitleHeight { get; set; }
/// <summary>
/// Header 头外边距
/// </summary>
public Thickness HeaderMargin { get; set; }
/// <summary>
/// 范围日历间距
/// </summary>
public double RangeCalendarSpacing { get; set; }
internal override void CalculateFromAlias()
{
base.CalculateFromAlias();
var colorPrimary = _globalToken.ColorToken.ColorPrimaryToken.ColorPrimary;
CellHoverBg = _globalToken.ControlItemBgHover;
CellActiveWithRangeBg = _globalToken.ControlItemBgActive;
CellHoverWithRangeBg = colorPrimary.Lighten(35);
CellRangeBorderColor = colorPrimary.Lighten(20);
CellBgDisabled = _globalToken.ColorBgContainerDisabled;
CellWidth = _globalToken.HeightToken.ControlHeightSM;
CellHeight = _globalToken.HeightToken.ControlHeightSM;
TextHeight = _globalToken.HeightToken.ControlHeightLG;
WithoutTimeCellHeight = _globalToken.HeightToken.ControlHeightLG * 1.65;
CellMargin = new Thickness(_globalToken.MarginXXS);
PanelContentPadding = new Thickness(_globalToken.PaddingSM);
ItemPanelMinWidth = 260;
ItemPanelMinHeight = 290;
DayTitleHeight = new GridLength(40, GridUnitType.Pixel);
HeaderMargin = new Thickness(0, 0, 0, _globalToken.MarginXS);
CellLineHeight = CellHeight - 2; // 不知道为啥设置成一样,或者不设置文字有些靠下
RangeCalendarSpacing = 20;
}
}
@@ -24,6 +24,15 @@ public class RangeDateSelectedEventArgs : RoutedEventArgs
}
}
public class HoverDateSelectedEventArgs : RoutedEventArgs
{
public DateTime? HoverDate { get; }
public HoverDateSelectedEventArgs(DateTime? date)
{
HoverDate = date;
}
}
[TemplatePart(RangeCalendarTheme.CalendarItemPart, typeof(RangeCalendarItem))]
[TemplatePart(RangeCalendarTheme.RootPart, typeof(Panel))]
public class RangeCalendar : TemplatedControl
@@ -308,9 +317,6 @@ public class RangeCalendar : TemplatedControl
#endregion
private bool _displayDateIsChanging;
private bool _isShiftPressed;
private DateTime _selectedMonth;
private DateTime _selectedYear;
@@ -498,6 +504,11 @@ public class RangeCalendar : TemplatedControl
}
}
internal void NotifyHoverDateChanged(DateTime? hoverDate)
{
HoverDateChanged?.Invoke(this, new HoverDateSelectedEventArgs(hoverDate));
}
/// <summary>
/// Inherited code: Requires comment.
/// </summary>
@@ -1192,6 +1203,11 @@ public class RangeCalendar : TemplatedControl
/// 当范围选择完成的时候派发这个事件
/// </summary>
public event EventHandler<RangeDateSelectedEventArgs>? RangeDateSelected;
/// <summary>
/// 当前 Pointer 选中的日期事件
/// </summary>
public event EventHandler<HoverDateSelectedEventArgs>? HoverDateChanged;
protected override void OnPointerReleased(PointerReleasedEventArgs e)
{
@@ -1193,6 +1193,7 @@ internal class RangeCalendarItem : TemplatedControl
Owner.HoverDateTime = selectedDate;
// Update the States of the buttons
Owner.UpdateHighlightDays();
Owner.NotifyHoverDateChanged(selectedDate);
}
}
}
@@ -154,7 +154,7 @@ internal class RangeCalendarItemTheme : BaseControlTheme
CreateTemplateParentBinding(headerLayout, Visual.IsVisibleProperty, RangeCalendarItem.IsMonthViewModeProperty);
TokenResourceBinder.CreateTokenBinding(headerLayout, Layoutable.MarginProperty,
CalendarTokenResourceKey.RangeCalendarSpacing, BindingPriority.Template,
DatePickerTokenResourceKey.RangeCalendarSpacing, BindingPriority.Template,
v =>
{
if (v is double dval)
@@ -322,7 +322,7 @@ internal class RangeCalendarItemTheme : BaseControlTheme
monthView.Children.Add(secondaryMonthView);
TokenResourceBinder.CreateTokenBinding(secondaryMonthView, Layoutable.MarginProperty,
CalendarTokenResourceKey.RangeCalendarSpacing, BindingPriority.Template,
DatePickerTokenResourceKey.RangeCalendarSpacing, BindingPriority.Template,
v =>
{
if (v is double dval)
@@ -365,7 +365,7 @@ internal class RangeCalendarItemTheme : BaseControlTheme
{
var dayTitleRowDef = new RowDefinition();
TokenResourceBinder.CreateTokenBinding(dayTitleRowDef, RowDefinition.HeightProperty,
CalendarTokenResourceKey.DayTitleHeight);
DatePickerTokenResourceKey.DayTitleHeight);
var monthView = new Grid
{
Name = name,
@@ -400,7 +400,7 @@ internal class RangeCalendarItemTheme : BaseControlTheme
var commonStyle = new Style(selector => selector.Nesting());
var headerLayoutStyle = new Style(selector => selector.Nesting().Template().Name(HeaderLayoutPart));
headerLayoutStyle.Add(Layoutable.MarginProperty, CalendarTokenResourceKey.HeaderMargin);
headerLayoutStyle.Add(Layoutable.MarginProperty, DatePickerTokenResourceKey.HeaderMargin);
commonStyle.Add(headerLayoutStyle);
@@ -15,7 +15,6 @@ public class RangeCalendarTheme : BaseControlTheme
{
public const string RootPart = "PART_Root";
public const string CalendarItemPart = "PART_CalendarItem";
public const string SecondaryCalendarItemPart = "PART_SecondaryCalendarItem";
public const string FramePart = "PART_Frame";
public RangeCalendarTheme()
@@ -45,7 +44,7 @@ public class RangeCalendarTheme : BaseControlTheme
ClipToBounds = true
};
TokenResourceBinder.CreateTokenBinding(rootLayout, StackPanel.SpacingProperty,
CalendarTokenResourceKey.RangeCalendarSpacing);
DatePickerTokenResourceKey.RangeCalendarSpacing);
rootLayout.RegisterInNameScope(scope);
var calendarItem = new RangeCalendarItem
@@ -69,9 +68,9 @@ public class RangeCalendarTheme : BaseControlTheme
commonStyle.Add(TemplatedControl.BorderBrushProperty, GlobalTokenResourceKey.ColorBorder);
commonStyle.Add(TemplatedControl.CornerRadiusProperty, GlobalTokenResourceKey.BorderRadius);
commonStyle.Add(TemplatedControl.BackgroundProperty, GlobalTokenResourceKey.ColorBgContainer);
commonStyle.Add(TemplatedControl.PaddingProperty, CalendarTokenResourceKey.PanelContentPadding);
commonStyle.Add(Layoutable.MinWidthProperty, CalendarTokenResourceKey.ItemPanelMinWidth);
commonStyle.Add(Layoutable.MinHeightProperty, CalendarTokenResourceKey.ItemPanelMinHeight);
commonStyle.Add(TemplatedControl.PaddingProperty, DatePickerTokenResourceKey.PanelContentPadding);
commonStyle.Add(Layoutable.MinWidthProperty, DatePickerTokenResourceKey.ItemPanelMinWidth);
commonStyle.Add(Layoutable.MinHeightProperty, DatePickerTokenResourceKey.ItemPanelMinHeight);
Add(commonStyle);
}
}
@@ -23,14 +23,14 @@
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.CalendarItemTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.CalendarTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.HeadTextButtonTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.RangeCalendarItemTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.RangeCalendarTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.CheckBoxTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.CollapseItemTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.CollapseTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.ComboBoxItemTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.ComboBoxSpinnerInnerBoxTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.ComboBoxTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.RangeCalendarItemTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.RangeCalendarTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.EmptyIndicatorTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.ExpanderTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.MenuFlyoutPresenterTheme());
@@ -14,6 +14,7 @@
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.CheckBoxToken));
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.CollapseToken));
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.ComboBoxToken));
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.DatePickerToken));
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.EmptyIndicatorToken));
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.ExpanderToken));
ThemeManager.Current.RegisterControlTokenType(typeof(AtomUI.Controls.FlyoutPresenterToken));
@@ -188,6 +188,27 @@ namespace AtomUI.Theme.Styling
public static readonly TokenResourceKey PopupMarginToAnchor = new TokenResourceKey("ComboBox.PopupMarginToAnchor", "AtomUI.Token");
}
public static class DatePickerTokenResourceKey
{
public static readonly TokenResourceKey CellHoverBg = new TokenResourceKey("DatePicker.CellHoverBg", "AtomUI.Token");
public static readonly TokenResourceKey CellActiveWithRangeBg = new TokenResourceKey("DatePicker.CellActiveWithRangeBg", "AtomUI.Token");
public static readonly TokenResourceKey CellHoverWithRangeBg = new TokenResourceKey("DatePicker.CellHoverWithRangeBg", "AtomUI.Token");
public static readonly TokenResourceKey CellBgDisabled = new TokenResourceKey("DatePicker.CellBgDisabled", "AtomUI.Token");
public static readonly TokenResourceKey CellRangeBorderColor = new TokenResourceKey("DatePicker.CellRangeBorderColor", "AtomUI.Token");
public static readonly TokenResourceKey CellHeight = new TokenResourceKey("DatePicker.CellHeight", "AtomUI.Token");
public static readonly TokenResourceKey CellWidth = new TokenResourceKey("DatePicker.CellWidth", "AtomUI.Token");
public static readonly TokenResourceKey CellLineHeight = new TokenResourceKey("DatePicker.CellLineHeight", "AtomUI.Token");
public static readonly TokenResourceKey CellMargin = new TokenResourceKey("DatePicker.CellMargin", "AtomUI.Token");
public static readonly TokenResourceKey ItemPanelMinWidth = new TokenResourceKey("DatePicker.ItemPanelMinWidth", "AtomUI.Token");
public static readonly TokenResourceKey ItemPanelMinHeight = new TokenResourceKey("DatePicker.ItemPanelMinHeight", "AtomUI.Token");
public static readonly TokenResourceKey TextHeight = new TokenResourceKey("DatePicker.TextHeight", "AtomUI.Token");
public static readonly TokenResourceKey PanelContentPadding = new TokenResourceKey("DatePicker.PanelContentPadding", "AtomUI.Token");
public static readonly TokenResourceKey WithoutTimeCellHeight = new TokenResourceKey("DatePicker.WithoutTimeCellHeight", "AtomUI.Token");
public static readonly TokenResourceKey DayTitleHeight = new TokenResourceKey("DatePicker.DayTitleHeight", "AtomUI.Token");
public static readonly TokenResourceKey HeaderMargin = new TokenResourceKey("DatePicker.HeaderMargin", "AtomUI.Token");
public static readonly TokenResourceKey RangeCalendarSpacing = new TokenResourceKey("DatePicker.RangeCalendarSpacing", "AtomUI.Token");
}
public static class EmptyIndicatorTokenResourceKey
{
public static readonly TokenResourceKey EmptyImgHeight = new TokenResourceKey("EmptyIndicator.EmptyImgHeight", "AtomUI.Token");
@@ -29,7 +29,7 @@ public enum DateTimePickerPanelType
TimePeriod //AM or PM
}
public class DateTimePickerPanel : Panel, ILogicalScrollable
internal class DateTimePickerPanel : Panel, ILogicalScrollable
{
/// <summary>
/// Defines the <see cref="ItemHeight" /> property
@@ -23,7 +23,7 @@ namespace AtomUI.Controls;
[TemplatePart(TimePickerPresenterTheme.PeriodSelectorPart, typeof(DateTimePickerPanel), IsRequired = true)]
[TemplatePart(TimePickerPresenterTheme.PickerContainerPart, typeof(Grid), IsRequired = true)]
[TemplatePart(TimePickerPresenterTheme.SecondSpacerPart, typeof(Rectangle), IsRequired = true)]
public class TimePickerPresenter : PickerPresenterBase
internal class TimePickerPresenter : PickerPresenterBase
{
#region 公共属性定义