using Avalonia;
using Avalonia.Animation;
using Avalonia.Animation.Easings;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Media;
using Avalonia.Media.Transformation;
using Avalonia.Threading;
using Avalonia.VisualTree;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Windows.Input;
namespace LANCommander.Launcher.Controls;
///
/// Implemented by carousel item content (e.g. inline video players) that should
/// only run while on-screen. The carousel toggles activity as items scroll in
/// and out of view to avoid wasting CPU on off-screen playback.
///
public interface ICarouselPlaybackItem
{
void SetCarouselActive(bool active);
}
public class CarouselControl : TemplatedControl
{
public static readonly StyledProperty ItemsSourceProperty =
AvaloniaProperty.Register(nameof(ItemsSource));
public static readonly StyledProperty ItemWidthProperty =
AvaloniaProperty.Register(nameof(ItemWidth), 200);
public static readonly StyledProperty GapProperty =
AvaloniaProperty.Register(nameof(Gap), 10);
public static readonly StyledProperty VisibleItemsProperty =
AvaloniaProperty.Register(nameof(VisibleItems), 3);
public static readonly StyledProperty SelectedIndexProperty =
AvaloniaProperty.Register(nameof(SelectedIndex), 0);
public static readonly StyledProperty TitleProperty =
AvaloniaProperty.Register(nameof(Title));
public static readonly StyledProperty ItemTemplateProperty =
AvaloniaProperty.Register(nameof(ItemTemplate));
public static readonly StyledProperty SeeAllCommandProperty =
AvaloniaProperty.Register(nameof(SeeAllCommand));
public static readonly StyledProperty IsInfiniteProperty =
AvaloniaProperty.Register(nameof(IsInfinite), false);
public static readonly StyledProperty WrapItemsProperty =
AvaloniaProperty.Register(nameof(WrapItems), false);
public static readonly StyledProperty ItemOverflowProperty =
AvaloniaProperty.Register(nameof(ItemOverflow), 0);
public IEnumerable? ItemsSource
{
get => GetValue(ItemsSourceProperty);
set => SetValue(ItemsSourceProperty, value);
}
public double ItemWidth
{
get => GetValue(ItemWidthProperty);
set => SetValue(ItemWidthProperty, value);
}
public double Gap
{
get => GetValue(GapProperty);
set => SetValue(GapProperty, value);
}
public int VisibleItems
{
get => GetValue(VisibleItemsProperty);
set => SetValue(VisibleItemsProperty, value);
}
public int SelectedIndex
{
get => GetValue(SelectedIndexProperty);
set => SetValue(SelectedIndexProperty, value);
}
public string? Title
{
get => GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
public IDataTemplate? ItemTemplate
{
get => GetValue(ItemTemplateProperty);
set => SetValue(ItemTemplateProperty, value);
}
public ICommand? SeeAllCommand
{
get => GetValue(SeeAllCommandProperty);
set => SetValue(SeeAllCommandProperty, value);
}
public bool IsInfinite
{
get => GetValue(IsInfiniteProperty);
set => SetValue(IsInfiniteProperty, value);
}
public bool WrapItems
{
get => GetValue(WrapItemsProperty);
set => SetValue(WrapItemsProperty, value);
}
public double ItemOverflow
{
get => GetValue(ItemOverflowProperty);
set => SetValue(ItemOverflowProperty, value);
}
private Control? _itemsContainer;
private Control? _clipPanel;
private ItemsControl? _itemsControl;
private Button? _leftButton;
private Button? _rightButton;
private Transitions? _transitions;
private RectangleGeometry? _clipGeometry;
private int _virtualIndex = 0;
private double _currentOffsetX = 0;
private WindowBase? _hostWindow;
private bool _windowActive = true;
static CarouselControl()
{
ItemsSourceProperty.Changed.AddClassHandler((c, _) => c.RebuildInternalSource());
WrapItemsProperty.Changed.AddClassHandler((c, _) => { c.RebuildInternalSource(); c.UpdateClipGeometry(); });
ItemOverflowProperty.Changed.AddClassHandler((c, _) => c.ApplyItemOverflow());
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
_itemsContainer = e.NameScope.Find("PART_ItemsContainer");
_clipPanel = e.NameScope.Find("PART_ClipPanel");
_itemsControl = e.NameScope.Find("PART_ItemsControl");
_leftButton = e.NameScope.Find