using Avalonia; using Avalonia.Controls; using Avalonia.Media; namespace GSS2.UI.Core; public enum SectionDirection { UpDown, DownUp, LeftRight, RightLeft } public class SectionPanel : Panel { public static readonly StyledProperty CurrentIndexProperty = AvaloniaProperty.Register(nameof(CurrentIndex), 0); public int CurrentIndex { get => GetValue(CurrentIndexProperty); set => SetValue(CurrentIndexProperty, value); } public static readonly StyledProperty AnimationSpeedProperty = AvaloniaProperty.Register(nameof(AnimationSpeed), 300); public double AnimationSpeed { get => GetValue(AnimationSpeedProperty); set => SetValue(AnimationSpeedProperty, value); } public static readonly StyledProperty DirectionProperty = AvaloniaProperty.Register(nameof(Direction), SectionDirection.UpDown); public SectionDirection Direction { get => GetValue(DirectionProperty); set => SetValue(DirectionProperty, value); } public SectionPanel() : base() { CurrentIndexProperty.Changed.AddClassHandler((panel, _) => panel.InvalidateArrange()); } protected override Size MeasureOverride(Size availableSize) { foreach (var child in Children) child.Measure(availableSize); Console.WriteLine(availableSize); return availableSize; } protected override Size ArrangeOverride(Size finalSize) { for (int i = 0; i < Children.Count; i++) { var child = Children[i]; var rect = Direction switch { SectionDirection.UpDown => new Rect(0, i * finalSize.Height, finalSize.Width, finalSize.Height), SectionDirection.DownUp => new Rect(0, -i * finalSize.Height, finalSize.Width, finalSize.Height), SectionDirection.LeftRight => new Rect(i * finalSize.Width, 0, finalSize.Width, finalSize.Height), SectionDirection.RightLeft => new Rect(-i * finalSize.Width, 0, finalSize.Width, finalSize.Height), _ => default }; child.Arrange(rect); } ApplyOffset(finalSize); return finalSize; } private void ApplyOffset(Size size) { double offset = Direction switch { SectionDirection.UpDown => -CurrentIndex * size.Height, SectionDirection.DownUp => CurrentIndex * size.Height, SectionDirection.LeftRight => -CurrentIndex * size.Width, SectionDirection.RightLeft => CurrentIndex * size.Width, _ => 0 }; var transform = RenderTransform as TranslateTransform; if (transform is null) { transform = new TranslateTransform(); RenderTransform = transform; } if (Direction is SectionDirection.LeftRight or SectionDirection.RightLeft) transform.X = offset; else transform.Y = offset; } }