LANCommander/LANCommander.Launcher/Views/GamesGroupedView.axaml
Pat Hartl b183e4b18c Remove old launcher, rename Avalonia launcher
Also adds ARM builds for Linux + Windows launcher
2026-06-06 05:49:24 -05:00

171 lines
11 KiB
XML

<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:LANCommander.Launcher.ViewModels"
xmlns:vmComponents="using:LANCommander.Launcher.ViewModels.Components"
xmlns:components="using:LANCommander.Launcher.Views.Components"
xmlns:controls="using:LANCommander.Launcher.Controls"
x:Class="LANCommander.Launcher.Views.GamesGroupedView"
x:DataType="vm:GamesCollectionViewModel">
<Grid ColumnDefinitions="*,Auto">
<!-- Main grouped scroll — outer ItemsControl is non-virtualizing (≤26 groups),
so all group headers are always realized and A-Z index scrolling works.
Inner per-group repeaters remain virtualizing for cover/list items. -->
<ScrollViewer x:Name="GroupedScrollViewer"
Classes="TitlebarOffset"
Grid.Column="0"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto"
controls:ScrollPersistence.ViewModel="{Binding}">
<ItemsControl x:Name="GroupedItemsControl"
ItemsSource="{Binding GroupedGames}"
Margin="16,56,16,8">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" Spacing="0" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="vm:GameGroupViewModel">
<StackPanel Margin="0,0,0,24">
<!-- Group header -->
<Border Padding="4,8,4,6">
<DockPanel>
<Border DockPanel.Dock="Right"
Width="1" Background="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
VerticalAlignment="Center" Height="1"
HorizontalAlignment="Stretch" Margin="8,0,0,0" />
<TextBlock Text="{Binding Name}"
FontSize="13" FontWeight="SemiBold"
Opacity="0.7" LetterSpacing="1" />
</DockPanel>
</Border>
<!-- Grid layout inside group -->
<ItemsRepeater ItemsSource="{Binding Items}"
IsVisible="{Binding $parent[ItemsControl].((vm:GamesCollectionViewModel)DataContext).IsGridView}"
ClipToBounds="False"
controls:DirectionalNavigation.IsEnabled="True">
<ItemsRepeater.Layout>
<UniformGridLayout MinItemWidth="148" MinItemHeight="218"
MinColumnSpacing="12" MinRowSpacing="12"
ItemsStretch="Fill"
ItemsJustification="Start" />
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate DataType="vmComponents:GameItemViewModel">
<components:CoverButton
Width="140" Height="210"
Margin="4"
Command="{Binding $parent[ItemsControl].((vm:GamesCollectionViewModel)DataContext).ViewGameDetailsCommand}"
CommandParameter="{Binding}" />
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
<!-- List layout inside group -->
<ItemsRepeater ItemsSource="{Binding Items}"
IsVisible="{Binding $parent[ItemsControl].((vm:GamesCollectionViewModel)DataContext).IsListView}"
controls:DirectionalNavigation.IsEnabled="True">
<ItemsRepeater.Layout>
<StackLayout Orientation="Vertical" Spacing="2" />
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate DataType="vmComponents:GameItemViewModel">
<Button Command="{Binding $parent[ItemsControl].((vm:GamesCollectionViewModel)DataContext).ViewGameDetailsCommand}"
CommandParameter="{Binding}"
Background="Transparent"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Padding="4,2" Cursor="Hand">
<Border Padding="8,6" CornerRadius="0"
Background="{DynamicResource SystemControlBackgroundChromeMediumLowBrush}">
<DockPanel>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal"
Spacing="8" VerticalAlignment="Center">
<Border Background="#CC000000" CornerRadius="0" Padding="4,2"
IsVisible="{Binding ShowInLibraryBadge}">
<Icon Type="Regular" Value="Check" Width="10" Height="10" Color="White" />
</Border>
<TextBlock Text="{Binding ReleasedOn, StringFormat='{}{0:yyyy}'}"
FontSize="12" Opacity="0.55" VerticalAlignment="Center" />
</StackPanel>
<components:Cover Source="{Binding CoverPath}"
MimeType="{Binding CoverMimeType}"
Title="{Binding Title}"
Width="40" Height="55"
Margin="0,0,12,0" />
<StackPanel VerticalAlignment="Center" Spacing="2">
<TextBlock Text="{Binding Title}"
FontSize="14" FontWeight="SemiBold"
TextTrimming="CharacterEllipsis" />
<TextBlock Text="{Binding Genres}" FontSize="12" Opacity="0.6"
TextTrimming="CharacterEllipsis"
IsVisible="{Binding Genres, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
</StackPanel>
</DockPanel>
</Border>
</Button>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
<!-- Horizontal shelf layout inside group -->
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Disabled"
IsVisible="{Binding $parent[ItemsControl].((vm:GamesCollectionViewModel)DataContext).IsHorizontalView}">
<ItemsRepeater ItemsSource="{Binding Items}" Margin="0,10,0,16" ClipToBounds="False"
controls:DirectionalNavigation.IsEnabled="True">
<ItemsRepeater.Layout>
<StackLayout Orientation="Horizontal" Spacing="8" />
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate DataType="vmComponents:GameItemViewModel">
<components:CoverButton
Width="120" Height="180"
Command="{Binding $parent[ItemsControl].((vm:GamesCollectionViewModel)DataContext).ViewGameDetailsCommand}"
CommandParameter="{Binding}" />
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</ScrollViewer>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<!-- A-Z index — only shown when grouping by first letter -->
<ScrollViewer Grid.Column="1"
IsVisible="{Binding IsGroupByFirstLetter}"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
Padding="0,52,4,4">
<ItemsControl ItemsSource="{Binding GroupedGames}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" Spacing="2" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="vm:GameGroupViewModel">
<Button Content="{Binding Name}"
Click="IndexLetter_Click"
Background="Transparent"
BorderThickness="0"
Padding="6,3"
FontSize="11"
HorizontalContentAlignment="Center"
Width="28" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</UserControl>