feat: add date button theme.

This commit is contained in:
rabbitism
2024-05-08 22:41:43 +08:00
parent d8358a9215
commit 5dea738c79
10 changed files with 334 additions and 12 deletions

View File

@@ -0,0 +1,34 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:u="https://irihi.tech/ursa"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Ursa.Demo.Pages.DatePickerDemo">
<StackPanel Margin="20" Spacing="5">
<u:CalendarDayButton />
<u:CalendarDayButton IsSelected="True" />
<u:CalendarDayButton IsBlackout="True" />
<StackPanel Orientation="Horizontal">
<u:CalendarDayButton IsStartDate="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsEndDate="True" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<u:CalendarDayButton IsPreviewStartDate="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsPreviewEndDate="True" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsInRange="True" IsStartDate="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsEndDate="True" IsInRange="True" />
<u:CalendarDayButton IsInRange="True" />
</StackPanel>
</StackPanel>
</UserControl>

View File

@@ -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();
}
}

View File

@@ -0,0 +1,6 @@
namespace Ursa.Demo.ViewModels;
public class DatePickerDemoViewModel
{
}

View File

@@ -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(),

View File

@@ -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";

View File

@@ -0,0 +1,134 @@
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:u="https://irihi.tech/ursa">
<Design.PreviewWith>
<StackPanel Margin="20" Spacing="5">
<u:CalendarDayButton />
<u:CalendarDayButton IsSelected="True" />
<u:CalendarDayButton IsBlackout="True" />
<StackPanel Orientation="Horizontal">
<u:CalendarDayButton IsStartDate="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsEndDate="True" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<u:CalendarDayButton IsPreviewStartDate="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsPreviewEndDate="True" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsInRange="True" IsStartDate="True" />
<u:CalendarDayButton IsInRange="True" />
<u:CalendarDayButton IsEndDate="True" IsInRange="True" />
<u:CalendarDayButton IsInRange="True" />
</StackPanel>
</StackPanel>
</Design.PreviewWith>
<!-- Add Resources Here -->
<ControlTheme x:Key="{x:Type u:CalendarDayButton}" TargetType="u:CalendarDayButton">
<Setter Property="Width" Value="32" />
<Setter Property="Height" Value="32" />
<Setter Property="Margin" Value="0 2"></Setter>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CornerRadius" Value="3"/>
<Setter Property="Template">
<ControlTemplate TargetType="u:CalendarDayButton">
<Panel>
<Border
Name="PART_Background"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<ContentPresenter
Name="PART_ContentPresenter"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{TemplateBinding Foreground}"
Content="1" />
</Border>
</Panel>
</ControlTemplate>
</Setter>
<Style Selector="^:in-range">
<Setter Property="Background" Value="{DynamicResource SemiBlue1}" />
<Setter Property="CornerRadius" Value="0" />
<Setter Property="BorderThickness" Value="0" />
</Style>
<Style Selector="^:pointerover">
<Setter Property="Background" Value="{DynamicResource SemiGrey1}"/>
<Setter Property="Cursor" Value="Hand"/>
</Style>
<Style Selector="^:selected">
<Setter Property="Background" Value="{DynamicResource SemiBlue5}" />
<Setter Property="CornerRadius" Value="3" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Foreground" Value="White"/>
<Style Selector="^:pointerover">
<Setter Property="Background" Value="{DynamicResource SemiBlue6}"/>
</Style>
</Style>
<Style Selector="^:start-date">
<Setter Property="CornerRadius" Value="3 0 0 3" />
<Setter Property="Background" Value="{DynamicResource SemiBlue5}" />
<Setter Property="BorderBrush" Value="{DynamicResource SemiBlue5}" />
<Setter Property="Foreground" Value="White" />
<Style Selector="^:pointerover">
<Setter Property="Background" Value="{DynamicResource SemiBlue6}"/>
</Style>
</Style>
<Style Selector="^:start-date:in-range">
<Setter Property="CornerRadius" Value="3 0 0 3" />
<Setter Property="Background" Value="{DynamicResource SemiBlue5}" />
<Setter Property="BorderBrush" Value="{DynamicResource SemiGrey5}" />
<Setter Property="BorderThickness" Value="1" />
</Style>
<Style Selector="^:end-date">
<Setter Property="CornerRadius" Value="0 3 3 0" />
<Setter Property="Background" Value="{DynamicResource SemiBlue5}" />
<Setter Property="BorderBrush" Value="{DynamicResource SemiBlue5}" />
<Setter Property="Foreground" Value="White" />
<Style Selector="^:pointerover">
<Setter Property="Background" Value="{DynamicResource SemiBlue6}"/>
</Style>
</Style>
<Style Selector="^:end-date:in-range">
<Setter Property="CornerRadius" Value="0 3 3 0" />
<Setter Property="Background" Value="{DynamicResource SemiBlue5}" />
<Setter Property="BorderBrush" Value="{DynamicResource SemiGrey5}" />
<Setter Property="BorderThickness" Value="1" />
</Style>
<Style Selector="^:preview-start-date">
<Setter Property="CornerRadius" Value="3 0 0 3" />
<Setter Property="Background" Value="{DynamicResource SemiBlue2}" />
<Setter Property="BorderBrush" Value="{DynamicResource SemiBlue2}" />
</Style>
<Style Selector="^:preview-end-date">
<Setter Property="CornerRadius" Value="0 3 3 0" />
<Setter Property="Background" Value="{DynamicResource SemiBlue2}" />
<Setter Property="BorderBrush" Value="{DynamicResource SemiBlue2}" />
</Style>
<Style Selector="^:blackout">
<Setter Property="Foreground" Value="{DynamicResource SemiGrey3}"/>
<Setter Property="Cursor" Value="No"/>
</Style>
</ControlTheme>
</ResourceDictionary>

View File

@@ -5,6 +5,7 @@
<ResourceInclude Source="Banner.axaml" />
<ResourceInclude Source="ButtonGroup.axaml" />
<ResourceInclude Source="Breadcrumb.axaml" />
<ResourceInclude Source="Calendar.axaml" />
<ResourceInclude Source="ControlClassesInput.axaml" />
<ResourceInclude Source="Clock.axaml" />
<ResourceInclude Source="Dialog.axaml" />

View File

@@ -30,22 +30,22 @@ public class Calendar: TemplatedControl
set => SetValue(IsTodayHighlightedProperty, value);
}
public static readonly StyledProperty<AvaloniaList<DateRange>?> DisabledDatesProperty =
public static readonly StyledProperty<AvaloniaList<DateRange>?> BlackoutDatesProperty =
AvaloniaProperty.Register<Calendar, AvaloniaList<DateRange>?>(
nameof(DisabledDates));
nameof(BlackoutDates));
public AvaloniaList<DateRange>? DisabledDates
public AvaloniaList<DateRange>? BlackoutDates
{
get => GetValue(DisabledDatesProperty);
set => SetValue(DisabledDatesProperty, value);
get => GetValue(BlackoutDatesProperty);
set => SetValue(BlackoutDatesProperty, value);
}
public static readonly StyledProperty<IDateSelector?> DisabledDateRuleProperty = AvaloniaProperty.Register<Calendar, IDateSelector?>(
nameof(DisabledDateRule));
public static readonly StyledProperty<IDateSelector?> BlackoutDateRuleProperty = AvaloniaProperty.Register<Calendar, IDateSelector?>(
nameof(BlackoutDateRule));
public IDateSelector? DisabledDateRule
public IDateSelector? BlackoutDateRule
{
get => GetValue(DisabledDateRuleProperty);
set => SetValue(DisabledDateRuleProperty, value);
get => GetValue(BlackoutDateRuleProperty);
set => SetValue(BlackoutDateRuleProperty, value);
}
}

View File

@@ -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<CalendarDayButton>();
}
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);
}
}

View File

@@ -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<DateRange>? ranges, DateTime? date)
{
if (date is null || ranges is null) return false;
return ranges.Any(range => range.Contains(date));
}
}