Files
PLib/src/PLib.Desktop/Views/MainWindow.axaml
T

251 lines
10 KiB
XML

<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:PLib.Desktop.Controls"
xmlns:icons="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:views="clr-namespace:PLib.Desktop.Views"
xmlns:vm="clr-namespace:PLib.Desktop.ViewModels"
x:Class="PLib.Desktop.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Title="PLib — видеотека"
Width="1180"
Height="760"
MinWidth="1000"
MinHeight="420"
Background="{DynamicResource PageBackgroundBrush}"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<DataTemplate x:Key="SettingsTemplate" DataType="vm:SettingsViewModel">
<views:SettingsView />
</DataTemplate>
<!-- ======================= Video card ======================= -->
<DataTemplate x:Key="VideoCardTemplate" DataType="vm:VideoCardViewModel">
<Button Classes="card" Command="{Binding PlayCommand}" ToolTip.Tip="{Binding FullPath}">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Воспроизвести" Command="{Binding PlayCommand}" />
<MenuItem Header="Показать в папке" Command="{Binding RevealCommand}" />
</ContextMenu>
</Button.ContextMenu>
<Grid RowDefinitions="*,Auto">
<!-- Poster frame -->
<Border Grid.Row="0"
CornerRadius="9"
ClipToBounds="True"
Background="{DynamicResource ThumbnailPlaceholderBrush}">
<Panel>
<controls:AsyncImage Source="{Binding ThumbnailPath}"
DecodeWidth="480"
PlaceholderBrush="{DynamicResource ThumbnailPlaceholderBrush}" />
<!-- Shown until ffmpeg has produced a frame for this file. -->
<icons:MaterialIcon Kind="FilmstripBoxMultiple"
Width="30"
Height="30"
Opacity="0.35"
Foreground="{DynamicResource TextTertiaryBrush}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsVisible="{Binding IsPending}" />
<Border Classes="badge"
Margin="8"
HorizontalAlignment="Left"
VerticalAlignment="Top"
IsVisible="{Binding QualityText, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="{Binding QualityText}" />
</Border>
<Border Classes="badge"
Margin="8"
HorizontalAlignment="Right"
VerticalAlignment="Bottom">
<TextBlock Text="{Binding DurationText}" />
</Border>
<Border Classes="playOverlay" Background="{DynamicResource OverlayBrush}">
<Border Width="46"
Height="46"
CornerRadius="23"
Background="{DynamicResource AccentBrush}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<icons:MaterialIcon Kind="Play" Width="24" Height="24" Foreground="White" />
</Border>
</Border>
</Panel>
</Border>
<!-- Caption -->
<StackPanel Grid.Row="1" Margin="4,10,4,2" Spacing="3">
<TextBlock Classes="cardTitle" Text="{Binding Title}" />
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBlock Classes="cardMeta" Text="{Binding SizeText}" />
</StackPanel>
</StackPanel>
</Grid>
</Button>
</DataTemplate>
</Window.Resources>
<Grid ColumnDefinitions="*,Auto">
<Grid Grid.Column="0" RowDefinitions="Auto,*,Auto">
<!-- ======================= Header ======================= -->
<Border Grid.Row="0" Classes="appBar">
<Grid ColumnDefinitions="Auto,*,Auto" ColumnSpacing="20">
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="10" VerticalAlignment="Center">
<Border Width="32"
Height="32"
CornerRadius="9"
Background="{DynamicResource AccentSoftBrush}">
<icons:MaterialIcon Kind="VideoVintage"
Width="18"
Height="18"
Foreground="{DynamicResource AccentBrush}" />
</Border>
<StackPanel VerticalAlignment="Center">
<TextBlock Classes="sectionTitle" Text="Видеотека" />
<TextBlock Classes="cardMeta" Text="{Binding Videos.Count, StringFormat='{}{0} видео'}" />
</StackPanel>
</StackPanel>
<TextBox Grid.Column="1"
MinWidth="150"
MaxWidth="420"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
PlaceholderText="Поиск по названию…"
Text="{Binding SearchText}" />
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="8" VerticalAlignment="Center">
<ComboBox MinWidth="180"
ItemsSource="{Binding SortOptions}"
SelectedItem="{Binding SelectedSort}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="vm:SortOption">
<TextBlock Text="{Binding Label}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Button Command="{Binding ScanCommand}"
IsEnabled="{Binding !IsScanning}"
ToolTip.Tip="Пересканировать библиотеку">
<icons:MaterialIcon Kind="Refresh" Width="17" Height="17" />
</Button>
<Button Command="{Binding ToggleThemeCommand}" ToolTip.Tip="Сменить тему">
<icons:MaterialIcon Kind="ThemeLightDark" Width="17" Height="17" />
</Button>
<Button Command="{Binding OpenSettingsCommand}" ToolTip.Tip="Настройки">
<icons:MaterialIcon Kind="CogOutline" Width="17" Height="17" />
</Button>
<!-- Redundant while the panel is open, and the header needs the room there. -->
<Button Classes="Primary"
Command="{Binding AddFolderCommand}"
IsVisible="{Binding !IsSettingsOpen}">
<StackPanel Orientation="Horizontal" Spacing="7">
<icons:MaterialIcon Kind="FolderPlusOutline" Width="17" Height="17" />
<TextBlock Text="Добавить папку" />
</StackPanel>
</Button>
</StackPanel>
</Grid>
</Border>
<!-- ======================= Grid ======================= -->
<Panel Grid.Row="1">
<ScrollViewer Padding="20,18" HorizontalScrollBarVisibility="Disabled">
<ItemsRepeater ItemsSource="{Binding Videos}" ItemTemplate="{StaticResource VideoCardTemplate}">
<ItemsRepeater.Layout>
<UniformGridLayout ItemsStretch="Fill"
MinItemWidth="230"
MinItemHeight="212"
MinColumnSpacing="16"
MinRowSpacing="16" />
</ItemsRepeater.Layout>
</ItemsRepeater>
</ScrollViewer>
<!-- Empty state -->
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="14"
MaxWidth="420"
IsVisible="{Binding IsEmpty}">
<icons:MaterialIcon Kind="VideoBoxOff"
Width="52"
Height="52"
Opacity="0.35"
Foreground="{DynamicResource TextTertiaryBrush}"
HorizontalAlignment="Center" />
<TextBlock Classes="sectionTitle"
HorizontalAlignment="Center"
Text="Здесь пока пусто" />
<TextBlock Classes="subtle"
HorizontalAlignment="Center"
TextAlignment="Center"
TextWrapping="Wrap"
Text="Укажите папку с видеофайлами — PLib пройдётся по ней, соберёт превью и покажет всё карточками." />
<Button Classes="Primary"
HorizontalAlignment="Center"
Command="{Binding AddFolderCommand}"
Content="Выбрать папку" />
</StackPanel>
</Panel>
<!-- ======================= Status bar ======================= -->
<Border Grid.Row="2" Classes="statusBar">
<Grid ColumnDefinitions="Auto,*,Auto" ColumnSpacing="14">
<ProgressBar Grid.Column="0"
Width="160"
VerticalAlignment="Center"
Minimum="0"
Maximum="100"
Value="{Binding ScanProgress}"
IsIndeterminate="{Binding IsProgressIndeterminate}"
IsVisible="{Binding IsScanning}" />
<TextBlock Grid.Column="1"
Classes="subtle"
VerticalAlignment="Center"
TextTrimming="CharacterEllipsis"
Text="{Binding StatusText}" />
<Button Grid.Column="2"
Content="Отмена"
Command="{Binding CancelScanCommand}"
IsVisible="{Binding IsScanning}" />
</Grid>
</Border>
</Grid>
<!-- ======================= Settings panel ======================= -->
<Border Grid.Column="1" Classes="settingsPanel" Classes.open="{Binding IsSettingsOpen}">
<ContentControl Width="400"
Content="{Binding SettingsPanel}"
ContentTemplate="{StaticResource SettingsTemplate}" />
</Border>
</Grid>
</Window>