Files
GSS2Rework/GSS2.UI.Core/SectionPanel.cs
T
2026-02-09 15:23:43 +03:00

96 lines
3.1 KiB
C#

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<int> CurrentIndexProperty = AvaloniaProperty.Register<SectionPanel, int>(nameof(CurrentIndex), 0);
public int CurrentIndex
{
get => GetValue(CurrentIndexProperty);
set => SetValue(CurrentIndexProperty, value);
}
public static readonly StyledProperty<double> AnimationSpeedProperty = AvaloniaProperty.Register<SectionPanel, double>(nameof(AnimationSpeed), 300);
public double AnimationSpeed
{
get => GetValue(AnimationSpeedProperty);
set => SetValue(AnimationSpeedProperty, value);
}
public static readonly StyledProperty<SectionDirection> DirectionProperty = AvaloniaProperty.Register<SectionPanel, SectionDirection>(nameof(Direction), SectionDirection.UpDown);
public SectionDirection Direction
{
get => GetValue(DirectionProperty);
set => SetValue(DirectionProperty, value);
}
public SectionPanel()
: base()
{
CurrentIndexProperty.Changed.AddClassHandler<SectionPanel>((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;
}
}