diff --git a/StabilityMatrix.Avalonia/App.axaml b/StabilityMatrix.Avalonia/App.axaml index fa522b62..01828799 100644 --- a/StabilityMatrix.Avalonia/App.axaml +++ b/StabilityMatrix.Avalonia/App.axaml @@ -57,6 +57,7 @@ + + diff --git a/StabilityMatrix.Avalonia/Controls/Paginator.axaml.cs b/StabilityMatrix.Avalonia/Controls/Paginator.axaml.cs new file mode 100644 index 00000000..9342ec12 --- /dev/null +++ b/StabilityMatrix.Avalonia/Controls/Paginator.axaml.cs @@ -0,0 +1,166 @@ +using System.Diagnostics.CodeAnalysis; +using System.Windows.Input; +using Avalonia; +using Avalonia.Controls.Primitives; +using AvaloniaEdit.Utils; +using CommunityToolkit.Mvvm.Input; + +namespace StabilityMatrix.Avalonia.Controls; + +[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] +public class Paginator : TemplatedControl +{ + private bool isFirstTemplateApplied; + private ICommand? firstPageCommandBinding; + private ICommand? previousPageCommandBinding; + private ICommand? nextPageCommandBinding; + private ICommand? lastPageCommandBinding; + + public static readonly StyledProperty CurrentPageNumberProperty = + AvaloniaProperty.Register("CurrentPageNumber", 1); + + public int CurrentPageNumber + { + get => GetValue(CurrentPageNumberProperty); + set => SetValue(CurrentPageNumberProperty, value); + } + + public static readonly StyledProperty TotalPagesProperty = AvaloniaProperty.Register< + Paginator, + int + >("TotalPages", 1); + + public int TotalPages + { + get => GetValue(TotalPagesProperty); + set => SetValue(TotalPagesProperty, value); + } + + public static readonly StyledProperty FirstPageCommandProperty = + AvaloniaProperty.Register("FirstPageCommand"); + + public ICommand? FirstPageCommand + { + get => GetValue(FirstPageCommandProperty); + set => SetValue(FirstPageCommandProperty, value); + } + + public static readonly StyledProperty PreviousPageCommandProperty = + AvaloniaProperty.Register("PreviousPageCommand"); + + public ICommand? PreviousPageCommand + { + get => GetValue(PreviousPageCommandProperty); + set => SetValue(PreviousPageCommandProperty, value); + } + + public static readonly StyledProperty NextPageCommandProperty = + AvaloniaProperty.Register("NextPageCommand"); + + public ICommand? NextPageCommand + { + get => GetValue(NextPageCommandProperty); + set => SetValue(NextPageCommandProperty, value); + } + + public static readonly StyledProperty LastPageCommandProperty = + AvaloniaProperty.Register("LastPageCommand"); + + public ICommand? LastPageCommand + { + get => GetValue(LastPageCommandProperty); + set => SetValue(LastPageCommandProperty, value); + } + + public static readonly StyledProperty CanNavForwardProperty = AvaloniaProperty.Register< + Paginator, + bool + >("CanNavForward"); + + public bool CanNavForward + { + get => GetValue(CanNavForwardProperty); + set => SetValue(CanNavForwardProperty, value); + } + + public static readonly StyledProperty CanNavBackProperty = AvaloniaProperty.Register< + Paginator, + bool + >("CanNavBack"); + + public bool CanNavBack + { + get => GetValue(CanNavBackProperty); + set => SetValue(CanNavBackProperty, value); + } + + /// + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + base.OnApplyTemplate(e); + + if (!isFirstTemplateApplied) + { + firstPageCommandBinding = FirstPageCommand; + previousPageCommandBinding = PreviousPageCommand; + nextPageCommandBinding = NextPageCommand; + lastPageCommandBinding = LastPageCommand; + isFirstTemplateApplied = true; + } + + // Wrap the commands + FirstPageCommand = new RelayCommand(() => + { + if (CurrentPageNumber > 1) + { + CurrentPageNumber = 1; + } + firstPageCommandBinding?.Execute(null); + }); + + PreviousPageCommand = new RelayCommand(() => + { + if (CurrentPageNumber > 1) + { + CurrentPageNumber--; + } + previousPageCommandBinding?.Execute(null); + }); + + NextPageCommand = new RelayCommand(() => + { + if (CurrentPageNumber < TotalPages) + { + CurrentPageNumber++; + } + nextPageCommandBinding?.Execute(null); + }); + + LastPageCommand = new RelayCommand(() => + { + if (CurrentPageNumber < TotalPages) + { + CurrentPageNumber = TotalPages; + } + lastPageCommandBinding?.Execute(null); + }); + } + + /// + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + + // Update the CanNavForward and CanNavBack properties + if (change.Property == CurrentPageNumberProperty && change.NewValue is int) + { + CanNavForward = (int)change.NewValue < TotalPages; + CanNavBack = (int)change.NewValue > 1; + } + else if (change.Property == TotalPagesProperty && change.NewValue is int) + { + CanNavForward = CurrentPageNumber < (int)change.NewValue; + CanNavBack = CurrentPageNumber > 1; + } + } +} diff --git a/StabilityMatrix.Avalonia/Converters/StringFormatConverters.cs b/StabilityMatrix.Avalonia/Converters/StringFormatConverters.cs new file mode 100644 index 00000000..e4ed2455 --- /dev/null +++ b/StabilityMatrix.Avalonia/Converters/StringFormatConverters.cs @@ -0,0 +1,10 @@ +using Avalonia.Data.Converters; + +namespace StabilityMatrix.Avalonia.Converters; + +public static class StringFormatConverters +{ + private static StringFormatValueConverter? _decimalConverter; + public static StringFormatValueConverter Decimal => + _decimalConverter ??= new StringFormatValueConverter("{0:D}", null); +}