feat: wip: implement year view notification.
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
x:Class="Ursa.Demo.Pages.DatePickerDemo">
|
x:Class="Ursa.Demo.Pages.DatePickerDemo">
|
||||||
<StackPanel Margin="20" HorizontalAlignment="Left">
|
<StackPanel Margin="20" HorizontalAlignment="Left">
|
||||||
<u:CalendarMonthView />
|
<u:CalendarMonthView />
|
||||||
|
<u:CalendarYearView />
|
||||||
<u:Calendar/>
|
<u:Calendar/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
xmlns:u="https://irihi.tech/ursa">
|
xmlns:u="https://irihi.tech/ursa">
|
||||||
<Design.PreviewWith>
|
<Design.PreviewWith>
|
||||||
<StackPanel Margin="20" Spacing="5">
|
<StackPanel Margin="20" Spacing="5">
|
||||||
<u:CalendarMonthView/>
|
<u:CalendarMonthView />
|
||||||
<u:Calendar />
|
<u:Calendar />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Design.PreviewWith>
|
</Design.PreviewWith>
|
||||||
@@ -121,6 +121,7 @@
|
|||||||
</ControlTheme>
|
</ControlTheme>
|
||||||
|
|
||||||
<ControlTheme x:Key="{x:Type u:Calendar}" TargetType="u:Calendar">
|
<ControlTheme x:Key="{x:Type u:Calendar}" TargetType="u:Calendar">
|
||||||
|
<Setter Property="MinHeight" Value="300"></Setter>
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<ControlTemplate TargetType="u:Calendar">
|
<ControlTemplate TargetType="u:Calendar">
|
||||||
<Panel>
|
<Panel>
|
||||||
@@ -152,13 +153,20 @@
|
|||||||
Foreground="{DynamicResource CalendarItemIconForeground}" />
|
Foreground="{DynamicResource CalendarItemIconForeground}" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Grid ColumnDefinitions="*, *" Grid.Column="2">
|
||||||
Name="PART_HeaderButton"
|
<Button Grid.Column="0"
|
||||||
Grid.Column="2"
|
Name="{x:Static u:Calendar.PART_YearButton}"
|
||||||
HorizontalContentAlignment="Center"
|
HorizontalContentAlignment="Center"
|
||||||
Content="Apr 2024"
|
Content="2024"
|
||||||
Foreground="{TemplateBinding Foreground}"
|
Foreground="{TemplateBinding Foreground}"
|
||||||
Theme="{DynamicResource BorderlessButton}" />
|
Theme="{DynamicResource BorderlessButton}" />
|
||||||
|
<Button Grid.Column="1"
|
||||||
|
Name="{x:Static u:Calendar.PART_MonthButton}"
|
||||||
|
HorizontalContentAlignment="Center"
|
||||||
|
Content="Apr"
|
||||||
|
Foreground="{TemplateBinding Foreground}"
|
||||||
|
Theme="{DynamicResource BorderlessButton}" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
Name="{x:Static u:Calendar.PART_NextButton}"
|
Name="{x:Static u:Calendar.PART_NextButton}"
|
||||||
@@ -185,7 +193,18 @@
|
|||||||
Foreground="{DynamicResource CalendarItemIconForeground}" />
|
Foreground="{DynamicResource CalendarItemIconForeground}" />
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
<u:CalendarMonthView Grid.Row="1" Name="{x:Static u:Calendar.PART_MonthView}"></u:CalendarMonthView>
|
<u:CalendarMonthView
|
||||||
|
Name="{x:Static u:Calendar.PART_MonthView}"
|
||||||
|
Grid.Row="1"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
IsVisible="{TemplateBinding IsMonthMode}" />
|
||||||
|
<u:CalendarYearView
|
||||||
|
Name="{x:Static u:Calendar.PART_YearView}"
|
||||||
|
Grid.Row="1"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
IsVisible="{TemplateBinding IsMonthMode,
|
||||||
|
Converter={x:Static BoolConverters.Not}}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</Panel>
|
</Panel>
|
||||||
@@ -193,20 +212,76 @@
|
|||||||
</Setter>
|
</Setter>
|
||||||
</ControlTheme>
|
</ControlTheme>
|
||||||
|
|
||||||
<ControlTheme TargetType="u:CalendarMonthView" x:Key="{x:Type u:CalendarMonthView}">
|
<ControlTheme x:Key="{x:Type u:CalendarMonthView}" TargetType="u:CalendarMonthView">
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Grid Name="{x:Static u:CalendarMonthView.PART_Grid}" ColumnDefinitions="*, *, *, *, *, *, *" RowDefinitions="*, Auto, *, *, *, *, *, *">
|
<Grid
|
||||||
|
Name="{x:Static u:CalendarMonthView.PART_Grid}"
|
||||||
|
ColumnDefinitions="*, *, *, *, *, *, *"
|
||||||
|
RowDefinitions="*, Auto, *, *, *, *, *, *">
|
||||||
<Rectangle
|
<Rectangle
|
||||||
Grid.Column="0"
|
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
Grid.ColumnSpan="7"
|
Grid.ColumnSpan="7"
|
||||||
Height="1"
|
Height="1"
|
||||||
Margin="8 8 8 0"
|
Margin="8,8,8,0"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
Fill="{DynamicResource SemiGrey2}" />
|
Fill="{DynamicResource SemiGrey2}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter>
|
</Setter>
|
||||||
</ControlTheme>
|
</ControlTheme>
|
||||||
|
|
||||||
|
<ControlTheme x:Key="{x:Type u:CalendarYearView}" TargetType="u:CalendarYearView">
|
||||||
|
<Setter Property="Template">
|
||||||
|
<ControlTemplate>
|
||||||
|
<Grid
|
||||||
|
Name="{x:Static u:CalendarYearView.PART_Grid}"
|
||||||
|
ColumnDefinitions="*, *, *"
|
||||||
|
RowDefinitions="*, *, *, *" />
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter>
|
||||||
|
</ControlTheme>
|
||||||
|
|
||||||
|
<ControlTheme x:Key="{x:Type u:CalendarYearButton}" TargetType="u:CalendarYearButton">
|
||||||
|
<Setter Property="MinWidth" Value="32" />
|
||||||
|
<Setter Property="MinHeight" Value="32" />
|
||||||
|
<Setter Property="Margin" Value="0 2" />
|
||||||
|
<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"
|
||||||
|
Content="{TemplateBinding Content}"
|
||||||
|
Foreground="{TemplateBinding Foreground}" />
|
||||||
|
</Border>
|
||||||
|
</Panel>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter>
|
||||||
|
<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>
|
||||||
|
</ControlTheme>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Controls.Metadata;
|
using Avalonia.Controls.Metadata;
|
||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
|
using Irihi.Avalonia.Shared.Helpers;
|
||||||
|
|
||||||
namespace Ursa.Controls;
|
namespace Ursa.Controls;
|
||||||
|
|
||||||
@@ -11,8 +12,9 @@ namespace Ursa.Controls;
|
|||||||
[TemplatePart(PART_PreviousYearButton, typeof(Button))]
|
[TemplatePart(PART_PreviousYearButton, typeof(Button))]
|
||||||
[TemplatePart(PART_NextButton, typeof(Button))]
|
[TemplatePart(PART_NextButton, typeof(Button))]
|
||||||
[TemplatePart(PART_PreviousButton, typeof(Button))]
|
[TemplatePart(PART_PreviousButton, typeof(Button))]
|
||||||
|
[TemplatePart(PART_YearButton, typeof(Button))]
|
||||||
|
[TemplatePart(PART_MonthButton, typeof(Button))]
|
||||||
[TemplatePart(PART_HeaderButton, typeof(Button))]
|
[TemplatePart(PART_HeaderButton, typeof(Button))]
|
||||||
[TemplatePart(PART_BackButton, typeof(Button))]
|
|
||||||
[TemplatePart(PART_MonthView, typeof(CalendarMonthView))]
|
[TemplatePart(PART_MonthView, typeof(CalendarMonthView))]
|
||||||
[TemplatePart(PART_YearView, typeof(CalendarYearView))]
|
[TemplatePart(PART_YearView, typeof(CalendarYearView))]
|
||||||
public class Calendar: TemplatedControl
|
public class Calendar: TemplatedControl
|
||||||
@@ -21,14 +23,18 @@ public class Calendar: TemplatedControl
|
|||||||
public const string PART_PreviousYearButton = "PART_PreviousYearButton";
|
public const string PART_PreviousYearButton = "PART_PreviousYearButton";
|
||||||
public const string PART_NextButton = "PART_NextButton";
|
public const string PART_NextButton = "PART_NextButton";
|
||||||
public const string PART_PreviousButton = "PART_PreviousButton";
|
public const string PART_PreviousButton = "PART_PreviousButton";
|
||||||
public const string PART_HeaderButton = "PART_HeaderButton";
|
public const string PART_YearButton = "PART_YearButton";
|
||||||
public const string PART_BackButton = "PART_BackButton";
|
public const string PART_MonthButton = "PART_MonthButton";
|
||||||
public const string PART_MonthView = "PART_MonthView";
|
public const string PART_MonthView = "PART_MonthView";
|
||||||
public const string PART_YearView = "PART_YearView";
|
public const string PART_YearView = "PART_YearView";
|
||||||
|
public const string PART_HeaderButton = "PART_HeaderButton";
|
||||||
|
|
||||||
private CalendarMonthView? _monthView;
|
private CalendarMonthView? _monthView;
|
||||||
private CalendarYearView? _yearView;
|
private CalendarYearView? _yearView;
|
||||||
private DatePickerState _state = DatePickerState.None;
|
private DatePickerState _state = DatePickerState.None;
|
||||||
|
private Button? _yearButton;
|
||||||
|
private Button? _monthButton;
|
||||||
|
private Button? _headerButton;
|
||||||
|
|
||||||
|
|
||||||
public static readonly StyledProperty<DateTime> SelectedDateProperty = AvaloniaProperty.Register<Calendar, DateTime>(nameof(SelectedDate), DateTime.Now);
|
public static readonly StyledProperty<DateTime> SelectedDateProperty = AvaloniaProperty.Register<Calendar, DateTime>(nameof(SelectedDate), DateTime.Now);
|
||||||
@@ -73,6 +79,17 @@ public class Calendar: TemplatedControl
|
|||||||
set => SetValue(BlackoutDateRuleProperty, value);
|
set => SetValue(BlackoutDateRuleProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _isMonthMode = true;
|
||||||
|
|
||||||
|
public static readonly DirectProperty<Calendar, bool> IsMonthModeProperty = AvaloniaProperty.RegisterDirect<Calendar, bool>(
|
||||||
|
nameof(IsMonthMode), o => o.IsMonthMode, (o, v) => o.IsMonthMode = v);
|
||||||
|
|
||||||
|
public bool IsMonthMode
|
||||||
|
{
|
||||||
|
get => _isMonthMode;
|
||||||
|
set => SetAndRaise(IsMonthModeProperty, ref _isMonthMode, value);
|
||||||
|
}
|
||||||
|
|
||||||
internal DateTime? StartDate;
|
internal DateTime? StartDate;
|
||||||
internal DateTime? EndDate;
|
internal DateTime? EndDate;
|
||||||
|
|
||||||
@@ -84,13 +101,50 @@ public class Calendar: TemplatedControl
|
|||||||
_monthView.OnDateSelected -= OnDateSelected;
|
_monthView.OnDateSelected -= OnDateSelected;
|
||||||
_monthView.OnDatePreviewed -= OnDatePreviewed;
|
_monthView.OnDatePreviewed -= OnDatePreviewed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_yearView is not null)
|
||||||
|
{
|
||||||
|
_yearView.OnMonthSelected -= OnMonthSelected;
|
||||||
|
}
|
||||||
|
Button.ClickEvent.RemoveHandler(OnYearButtonClick, _yearButton);
|
||||||
|
Button.ClickEvent.RemoveHandler(OnMonthButtonClick, _monthButton);
|
||||||
_monthView = e.NameScope.Find<CalendarMonthView>(PART_MonthView);
|
_monthView = e.NameScope.Find<CalendarMonthView>(PART_MonthView);
|
||||||
_yearView = e.NameScope.Find<CalendarYearView>(PART_YearView);
|
_yearView = e.NameScope.Find<CalendarYearView>(PART_YearView);
|
||||||
|
_yearButton = e.NameScope.Find<Button>(PART_YearButton);
|
||||||
|
_monthButton = e.NameScope.Find<Button>(PART_MonthButton);
|
||||||
|
|
||||||
if(_monthView is not null)
|
if(_monthView is not null)
|
||||||
{
|
{
|
||||||
_monthView.OnDateSelected += OnDateSelected;
|
_monthView.OnDateSelected += OnDateSelected;
|
||||||
_monthView.OnDatePreviewed += OnDatePreviewed;
|
_monthView.OnDatePreviewed += OnDatePreviewed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_yearView is not null)
|
||||||
|
{
|
||||||
|
_yearView.OnMonthSelected += OnMonthSelected;
|
||||||
|
}
|
||||||
|
Button.ClickEvent.AddHandler(OnYearButtonClick, _yearButton);
|
||||||
|
Button.ClickEvent.AddHandler(OnMonthButtonClick, _monthButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMonthSelected(object sender, CalendarYearButtonEventArgs e)
|
||||||
|
{
|
||||||
|
SetCurrentValue(IsMonthModeProperty, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMonthButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
SetCurrentValue(IsMonthModeProperty, false);
|
||||||
|
if (_yearView is null) return;
|
||||||
|
_yearView.Mode = CalendarYearViewMode.Month;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnYearButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (_yearView is null) return;
|
||||||
|
_yearView.Mode = CalendarYearViewMode.Year;
|
||||||
|
SetCurrentValue(IsMonthModeProperty, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDatePreviewed(object sender, CalendarDayButtonEventArgs e)
|
private void OnDatePreviewed(object sender, CalendarDayButtonEventArgs e)
|
||||||
|
|||||||
@@ -107,7 +107,10 @@ public class CalendarMonthView : TemplatedControl
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set day buttons according to context date.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="date"></param>
|
||||||
private void SetDayButtons(DateTime date)
|
private void SetDayButtons(DateTime date)
|
||||||
{
|
{
|
||||||
if (_grid is null) return;
|
if (_grid is null) return;
|
||||||
@@ -150,7 +153,6 @@ public class CalendarMonthView : TemplatedControl
|
|||||||
button.IsNotCurrentMonth = true;
|
button.IsNotCurrentMonth = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public event EventHandler<CalendarDayButtonEventArgs>? OnDateSelected;
|
public event EventHandler<CalendarDayButtonEventArgs>? OnDateSelected;
|
||||||
public event EventHandler<CalendarDayButtonEventArgs>? OnDatePreviewed;
|
public event EventHandler<CalendarDayButtonEventArgs>? OnDatePreviewed;
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
namespace Ursa.Controls;
|
|
||||||
|
|
||||||
public class CalendarStateMachine
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum CalendarState
|
|
||||||
{
|
|
||||||
PreviewingStartDate,
|
|
||||||
PreviewingEndDate,
|
|
||||||
SelectingStartDate,
|
|
||||||
SelectingEndDate,
|
|
||||||
}
|
|
||||||
@@ -1,17 +1,25 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Metadata;
|
||||||
using Avalonia.Controls.Mixins;
|
using Avalonia.Controls.Mixins;
|
||||||
|
using Avalonia.Input;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
|
using Irihi.Avalonia.Shared.Common;
|
||||||
|
|
||||||
namespace Ursa.Controls;
|
namespace Ursa.Controls;
|
||||||
|
|
||||||
internal enum CalendarYearViewMode
|
internal enum CalendarYearViewMode
|
||||||
{
|
{
|
||||||
Month,
|
Month,
|
||||||
Year,
|
Year,
|
||||||
// The button represents ten year, with one year before and one year after, 12 in total.
|
// The button represents 10 years.
|
||||||
YearRange,
|
YearRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[PseudoClasses(PC_Range, PseudoClassName.PC_Selected)]
|
||||||
public class CalendarYearButton: ContentControl
|
public class CalendarYearButton: ContentControl
|
||||||
{
|
{
|
||||||
|
public const string PC_Range = ":range";
|
||||||
static CalendarYearButton()
|
static CalendarYearButton()
|
||||||
{
|
{
|
||||||
PressedMixin.Attach<CalendarYearButton>();
|
PressedMixin.Attach<CalendarYearButton>();
|
||||||
@@ -27,6 +35,15 @@ public class CalendarYearButton: ContentControl
|
|||||||
|
|
||||||
internal CalendarYearViewMode Mode { get; private set; }
|
internal CalendarYearViewMode Mode { get; private set; }
|
||||||
|
|
||||||
|
public static readonly RoutedEvent<CalendarYearButtonEventArgs> ItemSelectedEvent = RoutedEvent.Register<CalendarYearButton, CalendarYearButtonEventArgs>(
|
||||||
|
nameof(ItemSelected), RoutingStrategies.Bubble);
|
||||||
|
|
||||||
|
public event EventHandler<CalendarDayButtonEventArgs> ItemSelected
|
||||||
|
{
|
||||||
|
add => AddHandler(ItemSelectedEvent, value);
|
||||||
|
remove => RemoveHandler(ItemSelectedEvent, value);
|
||||||
|
}
|
||||||
|
|
||||||
internal void SetValues(CalendarYearViewMode mode, DateTime contextDate, int? month = null, int? year = null, int? startYear = null, int? endYear = null)
|
internal void SetValues(CalendarYearViewMode mode, DateTime contextDate, int? month = null, int? year = null, int? startYear = null, int? endYear = null)
|
||||||
{
|
{
|
||||||
Debug.Assert(!(month is null && year is null && startYear is null && endYear is null));
|
Debug.Assert(!(month is null && year is null && startYear is null && endYear is null));
|
||||||
@@ -43,4 +60,12 @@ public class CalendarYearButton: ContentControl
|
|||||||
_ => Content
|
_ => Content
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnPointerPressed(PointerPressedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnPointerPressed(e);
|
||||||
|
RaiseEvent(new CalendarYearButtonEventArgs(Mode, Year, Month, StartYear, EndYear)
|
||||||
|
{ RoutedEvent = ItemSelectedEvent, Source = this });
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,5 +4,17 @@ namespace Ursa.Controls;
|
|||||||
|
|
||||||
public class CalendarYearButtonEventArgs: RoutedEventArgs
|
public class CalendarYearButtonEventArgs: RoutedEventArgs
|
||||||
{
|
{
|
||||||
|
internal int? Year { get; }
|
||||||
|
internal int? Month { get; }
|
||||||
|
internal int? StartYear { get; }
|
||||||
|
internal int? EndYear { get; }
|
||||||
|
internal CalendarYearViewMode Mode { get; }
|
||||||
|
internal CalendarYearButtonEventArgs( CalendarYearViewMode mode, int? year, int? month, int? startYear, int? endYear )
|
||||||
|
{
|
||||||
|
Year = year;
|
||||||
|
Month = month;
|
||||||
|
StartYear = startYear;
|
||||||
|
EndYear = endYear;
|
||||||
|
Mode = mode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Controls.Documents;
|
using Avalonia.Controls.Documents;
|
||||||
using Avalonia.Controls.Metadata;
|
using Avalonia.Controls.Metadata;
|
||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
|
using Irihi.Avalonia.Shared.Helpers;
|
||||||
|
|
||||||
namespace Ursa.Controls;
|
namespace Ursa.Controls;
|
||||||
|
|
||||||
@@ -15,36 +16,21 @@ namespace Ursa.Controls;
|
|||||||
public class CalendarYearView: TemplatedControl
|
public class CalendarYearView: TemplatedControl
|
||||||
{
|
{
|
||||||
public const string PART_Grid = "PART_Grid";
|
public const string PART_Grid = "PART_Grid";
|
||||||
|
private readonly CalendarYearButton[] _buttons = new CalendarYearButton[12];
|
||||||
|
|
||||||
private CalendarYearViewMode _mode = CalendarYearViewMode.Month;
|
public event EventHandler<CalendarYearButtonEventArgs>? OnMonthSelected;
|
||||||
|
|
||||||
internal CalendarYearViewMode Mode
|
internal CalendarYearViewMode Mode { get; set; } = CalendarYearViewMode.Month;
|
||||||
{
|
internal DateTime ContextDate { get; set; } = DateTime.Today;
|
||||||
get => _mode;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_mode = value;
|
|
||||||
RefreshButtons();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private DateTime _contextDate = DateTime.Today;
|
|
||||||
internal DateTime ContextDate
|
|
||||||
{
|
|
||||||
get => _contextDate;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_contextDate = value;
|
|
||||||
RefreshButtons();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Grid? _grid;
|
private Grid? _grid;
|
||||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||||
{
|
{
|
||||||
|
ContextDate = DateTime.Today;
|
||||||
base.OnApplyTemplate(e);
|
base.OnApplyTemplate(e);
|
||||||
_grid = e.NameScope.Find<Grid>(PART_Grid);
|
_grid = e.NameScope.Find<Grid>(PART_Grid);
|
||||||
GenerateGridElements();
|
GenerateGridElements();
|
||||||
|
RefreshButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GenerateGridElements()
|
public void GenerateGridElements()
|
||||||
@@ -59,7 +45,43 @@ public class CalendarYearView: TemplatedControl
|
|||||||
var button = new CalendarYearButton();
|
var button = new CalendarYearButton();
|
||||||
Grid.SetRow(button, i / 3);
|
Grid.SetRow(button, i / 3);
|
||||||
Grid.SetColumn(button, i % 3);
|
Grid.SetColumn(button, i % 3);
|
||||||
|
button.AddHandler(CalendarYearButton.ItemSelectedEvent, OnItemSelected);
|
||||||
_grid.Children.Add(button);
|
_grid.Children.Add(button);
|
||||||
|
_buttons[i] = button;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnItemSelected(object sender, CalendarYearButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (_grid is null) return;
|
||||||
|
var buttons = _grid.Children.OfType<CalendarYearButton>().ToList();
|
||||||
|
if (e.Mode == CalendarYearViewMode.Month)
|
||||||
|
{
|
||||||
|
if (e.Month is null) return;
|
||||||
|
var day = MathHelpers.SafeClamp(e.Month.Value, 0, DateTime.DaysInMonth(ContextDate.Year, e.Month.Value+1));
|
||||||
|
ContextDate = new DateTime(ContextDate.Year, e.Month.Value+1, day+1);
|
||||||
|
OnMonthSelected?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
else if (e.Mode == CalendarYearViewMode.Year)
|
||||||
|
{
|
||||||
|
// Set CalendarYearView to Month mode
|
||||||
|
for (var i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
buttons[i].SetValues(CalendarYearViewMode.Month, ContextDate, month: i);
|
||||||
|
}
|
||||||
|
ContextDate = new DateTime(e.Year!.Value, ContextDate.Month, 1);
|
||||||
|
Mode = CalendarYearViewMode.Month;
|
||||||
|
}
|
||||||
|
else if (e.Mode == CalendarYearViewMode.YearRange)
|
||||||
|
{
|
||||||
|
// Set CalendarYearView to Year mode
|
||||||
|
for (var i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
if (e.StartYear is null || e.EndYear is null) continue;
|
||||||
|
var year = e.StartYear.Value - 1 + i;
|
||||||
|
buttons[i].SetValues(CalendarYearViewMode.Year, ContextDate, year: year);
|
||||||
|
}
|
||||||
|
Mode = CalendarYearViewMode.Year;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,4 +111,11 @@ public class CalendarYearView: TemplatedControl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ShiftMode()
|
||||||
|
{
|
||||||
|
if (Mode == CalendarYearViewMode.Month)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Avalonia" Version="$(AvaloniaVersion)"/>
|
<PackageReference Include="Avalonia" Version="$(AvaloniaVersion)"/>
|
||||||
<PackageReference Include="Irihi.Avalonia.Shared" Version="0.1.7" />
|
<PackageReference Include="Irihi.Avalonia.Shared" Version="0.1.8" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user