Refactor PLib video library manager's UI to implement a side panel for settings, enhancing accessibility and layout. Update MainWindow and SettingsView to accommodate the new design, ensuring the settings panel integrates seamlessly without overlaying the main content. Revise styles for app bars and status bars for consistency across the application. Update README.md to reflect these UI changes.

This commit is contained in:
Leonid Pershin
2026-08-08 12:52:59 +03:00
parent 835937357e
commit 5920f7a940
5 changed files with 125 additions and 130 deletions
+40 -39
View File
@@ -104,56 +104,57 @@
<Setter Property="FontSize" Value="12.5" />
</Style>
<!-- ======================== Settings overlay ======================== -->
<!-- ========================= Window bars ========================= -->
<!--
The overlay stays in the tree and hides behind opacity rather than IsVisible: a collapsed
element has nothing to animate from, and the slide-in is the whole point. Nothing inside
is focusable while it is closed, because the panel's content is null until it opens.
The library and the settings panel sit side by side, so their top and bottom bars have to
line up: the separators read as one continuous line across the window. Fixing the heights
here, in one place, is what keeps them from drifting apart as either side gains controls.
-->
<Style Selector="Panel.settingsOverlay">
<Setter Property="Opacity" Value="0" />
<Setter Property="IsHitTestVisible" Value="False" />
<Setter Property="Transitions">
<Transitions>
<DoubleTransition Property="Opacity" Duration="0:0:0.16" Easing="CubicEaseOut" />
</Transitions>
</Setter>
</Style>
<Style Selector="Panel.settingsOverlay.open">
<Setter Property="Opacity" Value="1" />
<Setter Property="IsHitTestVisible" Value="True" />
</Style>
<!-- Click-anywhere-to-dismiss backdrop. A Button gets the click handling for free. -->
<Style Selector="Button.scrim">
<Setter Property="Background" Value="{DynamicResource OverlayBrush}" />
<Setter Property="Focusable" Value="False" />
<Setter Property="Cursor" Value="Arrow" />
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}" />
</ControlTemplate>
</Setter>
</Style>
<Style Selector="Border.drawer">
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Width" Value="470" />
<Setter Property="Background" Value="{DynamicResource PageBackgroundBrush}" />
<Style Selector="Border.appBar">
<Setter Property="Height" Value="62" />
<Setter Property="Padding" Value="20,0" />
<Setter Property="Background" Value="{DynamicResource SurfaceBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource SurfaceBorderBrush}" />
<Setter Property="BorderThickness" Value="0,0,0,1" />
</Style>
<Style Selector="Border.statusBar">
<Setter Property="Height" Value="50" />
<Setter Property="Padding" Value="20,0" />
<Setter Property="Background" Value="{DynamicResource SurfaceBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource SurfaceBorderBrush}" />
<Setter Property="BorderThickness" Value="0,1,0,0" />
</Style>
<!-- ======================== Settings panel ======================== -->
<!--
The panel is a column of the layout rather than an overlay, so opening it squeezes the
grid instead of covering it. Width is animated because Avalonia has no transition for
GridLength; the content inside keeps its full width and is simply clipped while the
column grows, which stops the whole panel reflowing on every animation frame.
-->
<Style Selector="Border.settingsPanel">
<Setter Property="Width" Value="0" />
<Setter Property="ClipToBounds" Value="True" />
<!--
Its own backdrop and a stronger divider than the usual surface border: once the bars on
both sides line up, a hairline in the ordinary border colour reads as one continuous
bar and the panel stops looking like a separate region.
-->
<Setter Property="Background" Value="{DynamicResource PanelBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource PanelDividerBrush}" />
<Setter Property="BorderThickness" Value="1,0,0,0" />
<Setter Property="RenderTransform" Value="translateX(30px)" />
<Setter Property="Transitions">
<Transitions>
<TransformOperationsTransition Property="RenderTransform" Duration="0:0:0.2" Easing="CubicEaseOut" />
<DoubleTransition Property="Width" Duration="0:0:0.22" Easing="CubicEaseOut" />
</Transitions>
</Setter>
</Style>
<Style Selector="Panel.settingsOverlay.open Border.drawer">
<Setter Property="RenderTransform" Value="none" />
<Style Selector="Border.settingsPanel.open">
<Setter Property="Width" Value="400" />
</Style>
<!-- ============================ Badge ============================ -->
+53 -49
View File
@@ -1,49 +1,53 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--
Semantic brushes owned by this application. Semi.Avalonia styles the controls; the
surfaces the library grid is built from are defined here so the card design does not
depend on the internal resource keys of a third-party theme.
-->
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="PageBackgroundBrush" Color="#0E1014" />
<SolidColorBrush x:Key="SurfaceBrush" Color="#14171D" />
<SolidColorBrush x:Key="SurfaceBorderBrush" Color="#20252E" />
<SolidColorBrush x:Key="CardBackgroundBrush" Color="#171B22" />
<SolidColorBrush x:Key="CardBorderBrush" Color="#242A34" />
<SolidColorBrush x:Key="CardHoverBorderBrush" Color="#3F4B5E" />
<SolidColorBrush x:Key="ThumbnailPlaceholderBrush" Color="#1C222B" />
<SolidColorBrush x:Key="TextPrimaryBrush" Color="#E8EDF4" />
<SolidColorBrush x:Key="TextSecondaryBrush" Color="#97A2B2" />
<SolidColorBrush x:Key="TextTertiaryBrush" Color="#69737F" />
<SolidColorBrush x:Key="AccentBrush" Color="#5B8CFF" />
<SolidColorBrush x:Key="AccentSoftBrush" Color="#1E2A44" />
<SolidColorBrush x:Key="BadgeBackgroundBrush" Color="#B3000000" />
<SolidColorBrush x:Key="BadgeForegroundBrush" Color="#F2F5FA" />
<SolidColorBrush x:Key="OverlayBrush" Color="#59000000" />
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="PageBackgroundBrush" Color="#F4F6F9" />
<SolidColorBrush x:Key="SurfaceBrush" Color="#FFFFFF" />
<SolidColorBrush x:Key="SurfaceBorderBrush" Color="#E6E9EF" />
<SolidColorBrush x:Key="CardBackgroundBrush" Color="#FFFFFF" />
<SolidColorBrush x:Key="CardBorderBrush" Color="#E4E7EC" />
<SolidColorBrush x:Key="CardHoverBorderBrush" Color="#B9C3D3" />
<SolidColorBrush x:Key="ThumbnailPlaceholderBrush" Color="#E9EDF2" />
<SolidColorBrush x:Key="TextPrimaryBrush" Color="#111621" />
<SolidColorBrush x:Key="TextSecondaryBrush" Color="#586274" />
<SolidColorBrush x:Key="TextTertiaryBrush" Color="#8A93A2" />
<SolidColorBrush x:Key="AccentBrush" Color="#2F6BFF" />
<SolidColorBrush x:Key="AccentSoftBrush" Color="#E5EDFF" />
<SolidColorBrush x:Key="BadgeBackgroundBrush" Color="#B3101418" />
<SolidColorBrush x:Key="BadgeForegroundBrush" Color="#FFFFFF" />
<SolidColorBrush x:Key="OverlayBrush" Color="#4D000000" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--
Semantic brushes owned by this application. Semi.Avalonia styles the controls; the
surfaces the library grid is built from are defined here so the card design does not
depend on the internal resource keys of a third-party theme.
-->
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="PageBackgroundBrush" Color="#0E1014" />
<SolidColorBrush x:Key="SurfaceBrush" Color="#14171D" />
<SolidColorBrush x:Key="SurfaceBorderBrush" Color="#20252E" />
<SolidColorBrush x:Key="CardBackgroundBrush" Color="#171B22" />
<SolidColorBrush x:Key="CardBorderBrush" Color="#242A34" />
<SolidColorBrush x:Key="CardHoverBorderBrush" Color="#3F4B5E" />
<SolidColorBrush x:Key="ThumbnailPlaceholderBrush" Color="#1C222B" />
<SolidColorBrush x:Key="PanelBackgroundBrush" Color="#111419" />
<SolidColorBrush x:Key="PanelDividerBrush" Color="#333C4A" />
<SolidColorBrush x:Key="TextPrimaryBrush" Color="#E8EDF4" />
<SolidColorBrush x:Key="TextSecondaryBrush" Color="#97A2B2" />
<SolidColorBrush x:Key="TextTertiaryBrush" Color="#69737F" />
<SolidColorBrush x:Key="AccentBrush" Color="#5B8CFF" />
<SolidColorBrush x:Key="AccentSoftBrush" Color="#1E2A44" />
<SolidColorBrush x:Key="BadgeBackgroundBrush" Color="#B3000000" />
<SolidColorBrush x:Key="BadgeForegroundBrush" Color="#F2F5FA" />
<SolidColorBrush x:Key="OverlayBrush" Color="#59000000" />
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="PageBackgroundBrush" Color="#F4F6F9" />
<SolidColorBrush x:Key="SurfaceBrush" Color="#FFFFFF" />
<SolidColorBrush x:Key="SurfaceBorderBrush" Color="#E6E9EF" />
<SolidColorBrush x:Key="CardBackgroundBrush" Color="#FFFFFF" />
<SolidColorBrush x:Key="CardBorderBrush" Color="#E4E7EC" />
<SolidColorBrush x:Key="CardHoverBorderBrush" Color="#B9C3D3" />
<SolidColorBrush x:Key="ThumbnailPlaceholderBrush" Color="#E9EDF2" />
<SolidColorBrush x:Key="PanelBackgroundBrush" Color="#FAFBFD" />
<SolidColorBrush x:Key="PanelDividerBrush" Color="#C6CFDC" />
<SolidColorBrush x:Key="TextPrimaryBrush" Color="#111621" />
<SolidColorBrush x:Key="TextSecondaryBrush" Color="#586274" />
<SolidColorBrush x:Key="TextTertiaryBrush" Color="#8A93A2" />
<SolidColorBrush x:Key="AccentBrush" Color="#2F6BFF" />
<SolidColorBrush x:Key="AccentSoftBrush" Color="#E5EDFF" />
<SolidColorBrush x:Key="BadgeBackgroundBrush" Color="#B3101418" />
<SolidColorBrush x:Key="BadgeForegroundBrush" Color="#FFFFFF" />
<SolidColorBrush x:Key="OverlayBrush" Color="#4D000000" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
+22 -27
View File
@@ -9,7 +9,7 @@
Title="PLib — видеотека"
Width="1180"
Height="760"
MinWidth="640"
MinWidth="1000"
MinHeight="420"
Background="{DynamicResource PageBackgroundBrush}"
WindowStartupLocation="CenterScreen">
@@ -95,24 +95,22 @@
</Window.Resources>
<Grid RowDefinitions="Auto,*,Auto">
<Grid ColumnDefinitions="*,Auto">
<Grid Grid.Column="0" RowDefinitions="Auto,*,Auto">
<!-- ======================= Header ======================= -->
<Border Grid.Row="0"
Background="{DynamicResource SurfaceBrush}"
BorderBrush="{DynamicResource SurfaceBorderBrush}"
BorderThickness="0,0,0,1"
Padding="20,14">
<Border Grid.Row="0" Classes="appBar">
<Grid ColumnDefinitions="Auto,*,Auto" ColumnSpacing="20">
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="10" VerticalAlignment="Center">
<Border Width="34"
Height="34"
<Border Width="32"
Height="32"
CornerRadius="9"
Background="{DynamicResource AccentSoftBrush}">
<icons:MaterialIcon Kind="VideoVintage"
Width="19"
Height="19"
Width="18"
Height="18"
Foreground="{DynamicResource AccentBrush}" />
</Border>
<StackPanel VerticalAlignment="Center">
@@ -122,6 +120,7 @@
</StackPanel>
<TextBox Grid.Column="1"
MinWidth="150"
MaxWidth="420"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
@@ -154,7 +153,10 @@
<icons:MaterialIcon Kind="CogOutline" Width="17" Height="17" />
</Button>
<Button Classes="Primary" Command="{Binding AddFolderCommand}">
<!-- 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="Добавить папку" />
@@ -209,11 +211,7 @@
</Panel>
<!-- ======================= Status bar ======================= -->
<Border Grid.Row="2"
Background="{DynamicResource SurfaceBrush}"
BorderBrush="{DynamicResource SurfaceBorderBrush}"
BorderThickness="0,1,0,0"
Padding="20,9">
<Border Grid.Row="2" Classes="statusBar">
<Grid ColumnDefinitions="Auto,*,Auto" ColumnSpacing="14">
<ProgressBar Grid.Column="0"
@@ -239,17 +237,14 @@
</Grid>
</Border>
</Grid>
<!-- ======================= Settings panel ======================= -->
<Panel Grid.Row="0"
Grid.RowSpan="3"
Classes="settingsOverlay"
Classes.open="{Binding IsSettingsOpen}">
<Button Classes="scrim" Command="{Binding CloseSettingsCommand}" />
<Border Classes="drawer">
<ContentControl Content="{Binding SettingsPanel}"
ContentTemplate="{StaticResource SettingsTemplate}" />
</Border>
</Panel>
<Border Grid.Column="1" Classes="settingsPanel" Classes.open="{Binding IsSettingsOpen}">
<ContentControl Width="400"
Content="{Binding SettingsPanel}"
ContentTemplate="{StaticResource SettingsTemplate}" />
</Border>
</Grid>
</Window>
+2 -10
View File
@@ -31,11 +31,7 @@
<Grid RowDefinitions="Auto,*,Auto">
<!-- ======================= Header ======================= -->
<Border Grid.Row="0"
Background="{DynamicResource SurfaceBrush}"
BorderBrush="{DynamicResource SurfaceBorderBrush}"
BorderThickness="0,0,0,1"
Padding="20,14">
<Border Grid.Row="0" Classes="appBar">
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0"
Width="32"
@@ -227,11 +223,7 @@
</ScrollViewer>
<!-- ======================= Footer ======================= -->
<Border Grid.Row="2"
Background="{DynamicResource SurfaceBrush}"
BorderBrush="{DynamicResource SurfaceBorderBrush}"
BorderThickness="0,1,0,0"
Padding="20,12">
<Border Grid.Row="2" Classes="statusBar">
<Grid ColumnDefinitions="*,Auto" ColumnSpacing="14">
<TextBlock Grid.Column="0"
Classes="hint"