diff --git a/demo/Ursa.Demo/Pages/DatePickerDemo.axaml b/demo/Ursa.Demo/Pages/DatePickerDemo.axaml index a01c673..e1e8e8f 100644 --- a/demo/Ursa.Demo/Pages/DatePickerDemo.axaml +++ b/demo/Ursa.Demo/Pages/DatePickerDemo.axaml @@ -6,8 +6,6 @@ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Ursa.Demo.Pages.DatePickerDemo"> - - diff --git a/src/Ursa.Themes.Semi/Controls/Calendar.axaml b/src/Ursa.Themes.Semi/Controls/Calendar.axaml index a1cfb19..411ad1b 100644 --- a/src/Ursa.Themes.Semi/Controls/Calendar.axaml +++ b/src/Ursa.Themes.Semi/Controls/Calendar.axaml @@ -4,7 +4,6 @@ xmlns:u="https://irihi.tech/ursa"> - @@ -119,144 +118,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -298,4 +159,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ursa/Controls/DateTimePicker/CalendarMonthView.cs b/src/Ursa/Controls/DateTimePicker/CalendarMonthView.cs index 29c010e..b8b1235 100644 --- a/src/Ursa/Controls/DateTimePicker/CalendarMonthView.cs +++ b/src/Ursa/Controls/DateTimePicker/CalendarMonthView.cs @@ -8,6 +8,7 @@ using Avalonia.Layout; namespace Ursa.Controls; +/* /// /// Show days in a month. CalendarMonthView itself doesn't handle any date range selection logic. /// it provides a method to mark preview range and selection range. The range limit may out of current displayed month. @@ -226,4 +227,6 @@ public class CalendarMonthView : TemplatedControl button.IsInRange = false; } } -} \ No newline at end of file +} + +*/ \ No newline at end of file diff --git a/src/Ursa/Controls/DateTimePicker/CalendarView.cs b/src/Ursa/Controls/DateTimePicker/CalendarView.cs index 9b9a921..bd3ddeb 100644 --- a/src/Ursa/Controls/DateTimePicker/CalendarView.cs +++ b/src/Ursa/Controls/DateTimePicker/CalendarView.cs @@ -1,14 +1,13 @@ -using System.Globalization; -using System.Reflection; +using System.Diagnostics; +using System.Globalization; using Avalonia; -using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Controls.Metadata; using Avalonia.Controls.Primitives; using Avalonia.Interactivity; using Avalonia.Layout; -using Avalonia.Media.TextFormatting; using Irihi.Avalonia.Shared.Helpers; +using Calendar = System.Globalization.Calendar; namespace Ursa.Controls; @@ -19,11 +18,10 @@ namespace Ursa.Controls; [TemplatePart(PART_YearButton, typeof(Button))] [TemplatePart(PART_MonthButton, typeof(Button))] [TemplatePart(PART_HeaderButton, typeof(Button))] -[TemplatePart(PART_MonthView, typeof(CalendarMonthView))] -[TemplatePart(PART_YearView, typeof(CalendarYearView))] [TemplatePart(PART_MonthGrid, typeof(Grid))] [TemplatePart(PART_YearGrid, typeof(Grid))] -public class CalendarView: TemplatedControl +[PseudoClasses(PC_Month)] +public class CalendarView : TemplatedControl { public const string PART_NextYearButton = "PART_NextYearButton"; public const string PART_PreviousYearButton = "PART_PreviousYearButton"; @@ -31,51 +29,79 @@ public class CalendarView: TemplatedControl public const string PART_PreviousButton = "PART_PreviousButton"; public const string PART_YearButton = "PART_YearButton"; public const string PART_MonthButton = "PART_MonthButton"; - public const string PART_MonthView = "PART_MonthView"; - public const string PART_YearView = "PART_YearView"; public const string PART_HeaderButton = "PART_HeaderButton"; public const string PART_MonthGrid = "PART_MonthGrid"; - public const string PART_YearGrid = "PART_YearGried"; - + public const string PART_YearGrid = "PART_YearGrid"; + public const string PC_Month = ":month"; + private const string ShortestDayName = "ShortestDayName"; - - private readonly System.Globalization.Calendar _calendar = new GregorianCalendar(); - internal CalendarViewMode Mode; - - //private CalendarMonthView? _monthView; - //private CalendarYearView? _yearView; - private Grid? _monthGrid; - private Grid? _yearGrid; - // Year button only shows the year in month mode. - private Button? _yearButton; - // Month button only shows the month in month mode. - private Button? _monthButton; - // Header button shows year in year mode, and year range in higher mode. - private Button? _headerButton; - - public DateContext ContextDate { get; set; } = new DateContext(); - - public event EventHandler? OnDateSelected; - public event EventHandler? OnDatePreviewed; + internal static readonly DirectProperty ModeProperty = + AvaloniaProperty.RegisterDirect( + nameof(Mode), o => o.Mode, (o, v) => o.Mode = v, unsetValue: CalendarViewMode.Month); public static readonly StyledProperty IsTodayHighlightedProperty = DatePickerBase.IsTodayHighlightedProperty.AddOwner(); + + public static readonly StyledProperty FirstDayOfWeekProperty = + DatePickerBase.FirstDayOfWeekProperty.AddOwner(); + + private readonly Calendar _calendar = new GregorianCalendar(); + + // Header button shows year in year mode, and year range in higher mode. + private Button? _headerButton; + + private CalendarViewMode _mode; + + // Month button only shows the month in month mode. + private Button? _monthButton; + + private Grid? _monthGrid; + + // Year button only shows the year in month mode. + private Button? _yearButton; + private Grid? _yearGrid; + + static CalendarView() + { + FirstDayOfWeekProperty.Changed.AddClassHandler((view, args) => + view.OnFirstDayOfWeekChanged(args)); + ModeProperty.Changed.AddClassHandler((view, args) => + { + view.PseudoClasses.Set(PC_Month, args.NewValue.Value == CalendarViewMode.Month); + Debug.WriteLine(args.NewValue.Value); + }); + } + + internal CalendarViewMode Mode + { + get => _mode; + set => SetAndRaise(ModeProperty, ref _mode, value); + } + + public DateContext ContextDate { get; set; } = new(); + public bool IsTodayHighlighted { get => GetValue(IsTodayHighlightedProperty); set => SetValue(IsTodayHighlightedProperty, value); } - public static readonly StyledProperty FirstDayOfWeekProperty = - DatePickerBase.FirstDayOfWeekProperty.AddOwner(); - public DayOfWeek FirstDayOfWeek { get => GetValue(FirstDayOfWeekProperty); set => SetValue(FirstDayOfWeekProperty, value); } - + + public event EventHandler? OnDateSelected; + public event EventHandler? OnDatePreviewed; + + private void OnFirstDayOfWeekChanged(AvaloniaPropertyChangedEventArgs args) + { + UpdateMonthViewHeader(args.NewValue.Value); + RefreshDayButtons(); + } + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); @@ -83,7 +109,7 @@ public class CalendarView: TemplatedControl Button.ClickEvent.RemoveHandler(OnHeaderYearButtonClick, _yearButton); Button.ClickEvent.RemoveHandler(OnHeaderMonthButtonClick, _monthButton); Button.ClickEvent.RemoveHandler(OnHeaderButtonClick, _headerButton); - + _monthGrid = e.NameScope.Find(PART_MonthGrid); _yearGrid = e.NameScope.Find(PART_YearGrid); _yearButton = e.NameScope.Find