diff --git a/demo/Ursa.Demo/Pages/DatePickerDemo.axaml b/demo/Ursa.Demo/Pages/DatePickerDemo.axaml new file mode 100644 index 0000000..4a29a6a --- /dev/null +++ b/demo/Ursa.Demo/Pages/DatePickerDemo.axaml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/DatePickerDemo.axaml.cs b/demo/Ursa.Demo/Pages/DatePickerDemo.axaml.cs new file mode 100644 index 0000000..fa6e70c --- /dev/null +++ b/demo/Ursa.Demo/Pages/DatePickerDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class DatePickerDemo : UserControl +{ + public DatePickerDemo() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/DatePickerDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/DatePickerDemoViewModel.cs new file mode 100644 index 0000000..f77041c --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/DatePickerDemoViewModel.cs @@ -0,0 +1,6 @@ +namespace Ursa.Demo.ViewModels; + +public class DatePickerDemoViewModel +{ + +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs index f981fa6..c3cc88c 100644 --- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs @@ -31,6 +31,7 @@ public class MainViewViewModel : ViewModelBase MenuKeys.MenuKeyBreadcrumb => new BreadcrumbDemoViewModel(), MenuKeys.MenuKeyClassInput => new ClassInputDemoViewModel(), MenuKeys.MenuKeyClock => new ClockDemoViewModel(), + MenuKeys.MenuKeyDatePicker => new DatePickerDemoViewModel(), MenuKeys.MenuKeyDialog => new DialogDemoViewModel(), MenuKeys.MenuKeyDivider => new DividerDemoViewModel(), MenuKeys.MenuKeyDisableContainer => new DisableContainerDemoViewModel(), diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs index ead5ab8..b466005 100644 --- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs @@ -18,6 +18,7 @@ public class MenuViewModel: ViewModelBase new() { MenuHeader = "Button Group", Key = MenuKeys.MenuKeyButtonGroup }, new() { MenuHeader = "Class Input", Key = MenuKeys.MenuKeyClassInput }, new() { MenuHeader = "Clock", Key = MenuKeys.MenuKeyClock, Status = "New" }, + new() { MenuHeader = "Date Picker", Key = MenuKeys.MenuKeyDatePicker }, new() { MenuHeader = "Dialog", Key = MenuKeys.MenuKeyDialog }, new() { MenuHeader = "Disable Container", Key = MenuKeys.MenuKeyDisableContainer }, new() { MenuHeader = "Divider", Key = MenuKeys.MenuKeyDivider }, @@ -63,6 +64,7 @@ public static class MenuKeys public const string MenuKeyBreadcrumb= "Breadcrumb"; public const string MenuKeyClassInput = "Class Input"; public const string MenuKeyClock = "Clock"; + public const string MenuKeyDatePicker = "DatePicker"; public const string MenuKeyDialog = "Dialog"; public const string MenuKeyDivider = "Divider"; public const string MenuKeyDisableContainer = "DisableContainer"; diff --git a/src/Ursa.Themes.Semi/Controls/Calendar.axaml b/src/Ursa.Themes.Semi/Controls/Calendar.axaml new file mode 100644 index 0000000..13830c1 --- /dev/null +++ b/src/Ursa.Themes.Semi/Controls/Calendar.axaml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ursa.Themes.Semi/Controls/_index.axaml b/src/Ursa.Themes.Semi/Controls/_index.axaml index bf6acad..24549cf 100644 --- a/src/Ursa.Themes.Semi/Controls/_index.axaml +++ b/src/Ursa.Themes.Semi/Controls/_index.axaml @@ -5,6 +5,7 @@ + diff --git a/src/Ursa/Controls/DateTimePicker/Calendar.cs b/src/Ursa/Controls/DateTimePicker/Calendar.cs index 9aabeb0..daceb40 100644 --- a/src/Ursa/Controls/DateTimePicker/Calendar.cs +++ b/src/Ursa/Controls/DateTimePicker/Calendar.cs @@ -30,22 +30,22 @@ public class Calendar: TemplatedControl set => SetValue(IsTodayHighlightedProperty, value); } - public static readonly StyledProperty?> DisabledDatesProperty = + public static readonly StyledProperty?> BlackoutDatesProperty = AvaloniaProperty.Register?>( - nameof(DisabledDates)); + nameof(BlackoutDates)); - public AvaloniaList? DisabledDates + public AvaloniaList? BlackoutDates { - get => GetValue(DisabledDatesProperty); - set => SetValue(DisabledDatesProperty, value); + get => GetValue(BlackoutDatesProperty); + set => SetValue(BlackoutDatesProperty, value); } - public static readonly StyledProperty DisabledDateRuleProperty = AvaloniaProperty.Register( - nameof(DisabledDateRule)); + public static readonly StyledProperty BlackoutDateRuleProperty = AvaloniaProperty.Register( + nameof(BlackoutDateRule)); - public IDateSelector? DisabledDateRule + public IDateSelector? BlackoutDateRule { - get => GetValue(DisabledDateRuleProperty); - set => SetValue(DisabledDateRuleProperty, value); + get => GetValue(BlackoutDateRuleProperty); + set => SetValue(BlackoutDateRuleProperty, value); } } \ No newline at end of file diff --git a/src/Ursa/Controls/DateTimePicker/CalendarDayButton.cs b/src/Ursa/Controls/DateTimePicker/CalendarDayButton.cs index 1a5d18e..06ab696 100644 --- a/src/Ursa/Controls/DateTimePicker/CalendarDayButton.cs +++ b/src/Ursa/Controls/DateTimePicker/CalendarDayButton.cs @@ -1,8 +1,130 @@ -using Avalonia.Controls; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Metadata; +using Avalonia.Controls.Mixins; +using Avalonia.Controls.Primitives; +using Avalonia.Input; +using Irihi.Avalonia.Shared.Common; +using Irihi.Avalonia.Shared.Helpers; namespace Ursa.Controls; -public class CalendarDayButton: Button +[PseudoClasses(PseudoClassName.PC_Pressed, PseudoClassName.PC_Selected, + PC_StartDate, PC_EndDate, PC_PreviewStartDate, PC_PreviewEndDate, PC_InRange, PC_Today, PC_Blackout)] +public class CalendarDayButton: ContentControl { + public const string PC_StartDate = ":start-date"; + public const string PC_EndDate = ":end-date"; + public const string PC_PreviewStartDate = ":preview-start-date"; + public const string PC_PreviewEndDate = ":preview-end-date"; + public const string PC_InRange = ":in-range"; + public const string PC_Today = ":today"; + public const string PC_Blackout = ":blackout"; + + private bool _isToday; + public bool IsToday + { + get => _isToday; + set + { + _isToday = value; + PseudoClasses.Set(PC_Today, value); + } + } + private bool _isStartDate; + public bool IsStartDate + { + get => _isStartDate; + set + { + _isStartDate = value; + PseudoClasses.Set(PC_StartDate, value); + } + } + + private bool _isEndDate; + public bool IsEndDate + { + get => _isEndDate; + set + { + _isEndDate = value; + PseudoClasses.Set(PC_EndDate, value); + } + } + + private bool _isPreviewStartDate; + public bool IsPreviewStartDate + { + get => _isPreviewStartDate; + set + { + _isPreviewStartDate = value; + PseudoClasses.Set(PC_PreviewStartDate, value); + } + } + + private bool _isPreviewEndDate; + public bool IsPreviewEndDate + { + get => _isPreviewEndDate; + set + { + _isPreviewEndDate = value; + PseudoClasses.Set(PC_PreviewEndDate, value); + } + } + + private bool _isInRange; + public bool IsInRange + { + get => _isInRange; + set + { + _isInRange = value; + PseudoClasses.Set(PC_InRange, value); + } + } + + private bool _isSelected; + public bool IsSelected + { + get => _isSelected; + set + { + _isSelected = value; + PseudoClasses.Set(PseudoClassName.PC_Selected, value); + } + } + + private bool _isBlackout; + public bool IsBlackout + { + get => _isBlackout; + set + { + _isBlackout = value; + PseudoClasses.Set(PC_Blackout, value); + } + } + + static CalendarDayButton() + { + PressedMixin.Attach(); + } + + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + base.OnApplyTemplate(e); + PseudoClasses.Set(PseudoClassName.PC_Disabled, IsEnabled); + PseudoClasses.Set(PC_Today, IsToday); + PseudoClasses.Set(PC_StartDate, IsStartDate); + PseudoClasses.Set(PC_EndDate, IsEndDate); + PseudoClasses.Set(PC_PreviewStartDate, IsPreviewStartDate); + PseudoClasses.Set(PC_PreviewEndDate, IsPreviewEndDate); + PseudoClasses.Set(PC_InRange, IsInRange); + PseudoClasses.Set(PseudoClassName.PC_Selected, IsSelected); + + } } \ No newline at end of file diff --git a/src/Ursa/Controls/DateTimePicker/DateRange.cs b/src/Ursa/Controls/DateTimePicker/DateRange.cs index 9bbb437..d0ec637 100644 --- a/src/Ursa/Controls/DateTimePicker/DateRange.cs +++ b/src/Ursa/Controls/DateTimePicker/DateRange.cs @@ -33,4 +33,13 @@ public sealed record DateRange if (date is null) return false; return date >= Start && date <= End; } +} + +internal static class DateRangeExtension +{ + public static bool Contains(this IEnumerable? ranges, DateTime? date) + { + if (date is null || ranges is null) return false; + return ranges.Any(range => range.Contains(date)); + } } \ No newline at end of file