diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CalendarShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/CalendarShowCase.axaml new file mode 100644 index 000000000..eb7e1a6de --- /dev/null +++ b/samples/AtomUI.Demo.Desktop/ShowCase/CalendarShowCase.axaml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CalendarShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/CalendarShowCase.axaml.cs new file mode 100644 index 000000000..1e4e2f34c --- /dev/null +++ b/samples/AtomUI.Demo.Desktop/ShowCase/CalendarShowCase.axaml.cs @@ -0,0 +1,11 @@ +using Avalonia.Controls; + +namespace AtomUI.Demo.Desktop.ShowCase; + +public partial class CalendarShowCase : UserControl +{ + public CalendarShowCase() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls/Calendar/Calendar.cs b/src/AtomUI.Controls/Calendar/Calendar.cs index 0f6154e4d..a36f1fa3e 100644 --- a/src/AtomUI.Controls/Calendar/Calendar.cs +++ b/src/AtomUI.Controls/Calendar/Calendar.cs @@ -3,9 +3,11 @@ // Please see https://go.microsoft.com/fwlink/?LinkID=131993 for details. // All other rights reserved. -using System; using System.Collections.ObjectModel; using System.Diagnostics; +using AtomUI.Theme.Data; +using AtomUI.Theme.Styling; +using AtomUI.Utils; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Metadata; @@ -13,6 +15,7 @@ using Avalonia.Controls.Primitives; using Avalonia.Data; using Avalonia.Input; using Avalonia.Interactivity; +using Avalonia.Layout; using Avalonia.Media; namespace AtomUI.Controls; @@ -225,8 +228,8 @@ public class CalendarModeChangedEventArgs : RoutedEventArgs /// element in XAML. /// /// -[TemplatePart(PART_ElementMonth, typeof(CalendarItem))] -[TemplatePart(PART_ElementRoot, typeof(Panel))] +[TemplatePart(CalendarTheme.CalendarItemPart, typeof(CalendarItem))] +[TemplatePart(CalendarTheme.RootPart, typeof(Panel))] public class Calendar : TemplatedControl { internal const int RowsPerMonth = 7; @@ -1189,7 +1192,6 @@ public class Calendar : TemplatedControl if (!LastSelectedDate.HasValue || DateTimeHelper.CompareYearMonth(LastSelectedDate.Value, d.Value) != 0) { LastSelectedDate = d.Value; } - SetCurrentValue(DisplayDateProperty, d.Value); } } else { @@ -1934,11 +1936,10 @@ public class Calendar : TemplatedControl BlackoutDates = new CalendarBlackoutDatesCollection(this); SelectedDates = new SelectedDatesCollection(this); RemovedItems = new Collection(); + HorizontalAlignmentProperty.OverrideDefaultValue(HorizontalAlignment.Left); + VerticalAlignmentProperty.OverrideDefaultValue(VerticalAlignment.Top); } - private const string PART_ElementRoot = "PART_Root"; - private const string PART_ElementMonth = "PART_CalendarItem"; - /// /// Builds the visual tree for the /// when a new @@ -1946,17 +1947,25 @@ public class Calendar : TemplatedControl /// protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { - Root = e.NameScope.Find(PART_ElementRoot); + Root = e.NameScope.Find(CalendarTheme.RootPart); SelectedMonth = DisplayDate; SelectedYear = DisplayDate; if (Root != null) { - CalendarItem? month = e.NameScope.Find(PART_ElementMonth); + CalendarItem? month = e.NameScope.Find(CalendarTheme.CalendarItemPart); if (month != null) { month.Owner = this; } } } + + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + TokenResourceBinder.CreateGlobalTokenBinding(this, BorderThicknessProperty, GlobalTokenResourceKey.BorderThickness, + BindingPriority.Template, + new RenderScaleAwareThicknessConfigure(this)); + } } \ No newline at end of file diff --git a/src/AtomUI.Controls/Calendar/CalendarBlackoutDatesCollection.cs b/src/AtomUI.Controls/Calendar/CalendarBlackoutDatesCollection.cs index eb2db3cb4..344b9f8b6 100644 --- a/src/AtomUI.Controls/Calendar/CalendarBlackoutDatesCollection.cs +++ b/src/AtomUI.Controls/Calendar/CalendarBlackoutDatesCollection.cs @@ -1,5 +1,4 @@ using System.Collections.ObjectModel; -using Avalonia.Controls; using Avalonia.Threading; namespace AtomUI.Controls; diff --git a/src/AtomUI.Controls/Calendar/CalendarButton.cs b/src/AtomUI.Controls/Calendar/CalendarButton.cs index ab856933f..57cf27513 100644 --- a/src/AtomUI.Controls/Calendar/CalendarButton.cs +++ b/src/AtomUI.Controls/Calendar/CalendarButton.cs @@ -2,6 +2,7 @@ using Avalonia.Controls.Metadata; using Avalonia.Controls.Primitives; using Avalonia.Input; +using AvaloniaButton = Avalonia.Controls.Button; namespace AtomUI.Controls; @@ -10,7 +11,7 @@ namespace AtomUI.Controls; /// . /// [PseudoClasses(":selected", ":inactive", ":btnfocused")] -public sealed class CalendarButton : Button +internal sealed class CalendarButton : AvaloniaButton { /// /// A value indicating whether the button is focused. diff --git a/src/AtomUI.Controls/Calendar/CalendarDayButton.cs b/src/AtomUI.Controls/Calendar/CalendarDayButton.cs index 6966ecfd4..5d5caf288 100644 --- a/src/AtomUI.Controls/Calendar/CalendarDayButton.cs +++ b/src/AtomUI.Controls/Calendar/CalendarDayButton.cs @@ -3,12 +3,18 @@ using Avalonia.Controls; using Avalonia.Controls.Metadata; using Avalonia.Controls.Primitives; using Avalonia.Input; +using AvaloniaButton = Avalonia.Controls.Button; namespace AtomUI.Controls; -[PseudoClasses(":pressed", ":disabled", ":selected", ":inactive", ":today", ":blackout", ":dayfocused")] -public sealed class CalendarDayButton : Button +[PseudoClasses(StdPseudoClass.Pressed, StdPseudoClass.Disabled, StdPseudoClass.Selected, InactivePC, TodayPC, BlackoutPC, DayfocusedPC)] +internal sealed class CalendarDayButton : AvaloniaButton { + private const string InactivePC = ":inactive"; + private const string TodayPC = ":today"; + private const string BlackoutPC = ":blackout"; + private const string DayfocusedPC = ":dayfocused"; + /// /// Default content for the CalendarDayButton. /// @@ -27,7 +33,6 @@ public sealed class CalendarDayButton : Button /// class. /// public CalendarDayButton() - : base() { //Focusable = false; SetCurrentValue(ContentProperty, DefaultContent.ToString(CultureInfo.CurrentCulture)); @@ -152,15 +157,15 @@ public sealed class CalendarDayButton : Button private void SetPseudoClasses() { if (_ignoringMouseOverState) { - PseudoClasses.Set(":pressed", IsPressed); - PseudoClasses.Set(":disabled", !IsEnabled); + PseudoClasses.Set(StdPseudoClass.Pressed, IsPressed); + PseudoClasses.Set(StdPseudoClass.Disabled, !IsEnabled); } - PseudoClasses.Set(":selected", IsSelected); - PseudoClasses.Set(":inactive", IsInactive); - PseudoClasses.Set(":today", IsToday); - PseudoClasses.Set(":blackout", IsBlackout); - PseudoClasses.Set(":dayfocused", IsCurrent && IsEnabled); + PseudoClasses.Set(StdPseudoClass.Selected, IsSelected); + PseudoClasses.Set(InactivePC, IsInactive); + PseudoClasses.Set(TodayPC, IsToday); + PseudoClasses.Set(BlackoutPC, IsBlackout); + PseudoClasses.Set(DayfocusedPC, IsCurrent && IsEnabled); } /// diff --git a/src/AtomUI.Controls/Calendar/CalendarItem.cs b/src/AtomUI.Controls/Calendar/CalendarItem.cs index c085953f0..ad5f45477 100644 --- a/src/AtomUI.Controls/Calendar/CalendarItem.cs +++ b/src/AtomUI.Controls/Calendar/CalendarItem.cs @@ -9,6 +9,7 @@ using Avalonia.Data; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Media; +using AvaloniaButton = Avalonia.Controls.Button; namespace AtomUI.Controls; @@ -16,28 +17,23 @@ namespace AtomUI.Controls; /// Represents the currently displayed month or year on a /// . /// -[TemplatePart(PART_ElementHeaderButton, typeof(Button))] -[TemplatePart(PART_ElementMonthView, typeof(Grid))] -[TemplatePart(PART_ElementNextButton, typeof(Button))] -[TemplatePart(PART_ElementPreviousButton, typeof(Button))] -[TemplatePart(PART_ElementYearView, typeof(Grid))] -[PseudoClasses(":calendardisabled")] -public sealed class CalendarItem : TemplatedControl +[TemplatePart(CalendarItemTheme.HeaderButtonPart, typeof(AvaloniaButton))] +[TemplatePart(CalendarItemTheme.MonthViewPart, typeof(Grid))] +[TemplatePart(CalendarItemTheme.NextButtonPart, typeof(AvaloniaButton))] +[TemplatePart(CalendarItemTheme.PreviousButtonPart, typeof(AvaloniaButton))] +[TemplatePart(CalendarItemTheme.YearViewPart, typeof(Grid))] +[PseudoClasses(CalendarDisabledPC)] +internal sealed class CalendarItem : TemplatedControl { + private const string CalendarDisabledPC = ":calendardisabled"; /// /// The number of days per week. /// private const int NumberOfDaysPerWeek = 7; - private const string PART_ElementHeaderButton = "PART_HeaderButton"; - private const string PART_ElementPreviousButton = "PART_PreviousButton"; - private const string PART_ElementNextButton = "PART_NextButton"; - private const string PART_ElementMonthView = "PART_MonthView"; - private const string PART_ElementYearView = "PART_YearView"; - - private Button? _headerButton; - private Button? _nextButton; - private Button? _previousButton; + private AvaloniaButton? _headerButton; + private AvaloniaButton? _nextButton; + private AvaloniaButton? _previousButton; private DateTime _currentMonth; private bool _isMouseLeftButtonDown; @@ -73,7 +69,7 @@ public sealed class CalendarItem : TemplatedControl /// Gets the button that allows switching between month mode, year mode, /// and decade mode. /// - internal Button? HeaderButton + internal AvaloniaButton? HeaderButton { get => _headerButton; private set @@ -93,7 +89,7 @@ public sealed class CalendarItem : TemplatedControl /// Gets the button that displays the next page of the calendar when it /// is clicked. /// - internal Button? NextButton + internal AvaloniaButton? NextButton { get => _nextButton; private set @@ -122,7 +118,7 @@ public sealed class CalendarItem : TemplatedControl /// Gets the button that displays the previous page of the calendar when /// it is clicked. /// - internal Button? PreviousButton + internal AvaloniaButton? PreviousButton { get => _previousButton; private set @@ -234,11 +230,11 @@ public sealed class CalendarItem : TemplatedControl /// protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { - HeaderButton = e.NameScope.Find