Refine UI layout in PLib video library manager by adjusting MainWindow and SettingsView for a more cohesive design. Implement dedicated styles for panel headers and footers, ensuring consistent visual hierarchy. Update README.md to document these layout enhancements and style changes.

This commit is contained in:
Leonid Pershin
2026-08-08 13:48:41 +03:00
parent 5920f7a940
commit bf2c825244
4 changed files with 69 additions and 51 deletions
+3 -2
View File
@@ -67,8 +67,9 @@ dotnet test
сдвигает сетку, и та переливается в меньшее число столбцов, оставаясь целиком доступной.
В alt-tab ничего не добавляется, и приложение остаётся переносимым на
`ISingleViewApplicationLifetime`, где `ShowDialog` попросту не существует.
Верхняя и нижняя полосы обеих половин заданы одной парой стилей, поэтому разделители
читаются как сплошные линии через всё окно.
Панель занимает только строку контента: шапка и статус-бар остаются цельными на всю
ширину окна. Собственные заголовок и строка действий у панели заведомо легче оконных —
равные по весу читались как два приложения, сшитых по шву.
- **Настройки — рабочая копия.** Панель правит снимок `AppSettings` и записывает его целиком
только по «Сохранить», так что отмена не оставляет следов. Пересканирование запускается
только если изменилось то, что влияет на состав библиотеки, — смена темы или ширины кадра
+38 -7
View File
@@ -127,6 +127,30 @@
<Setter Property="BorderThickness" Value="0,1,0,0" />
</Style>
<!--
The panel's own header and action row. Deliberately lighter than the window bars above:
they belong to a region inside the content, and giving them the same weight made the two
halves read as two applications stitched together.
-->
<Style Selector="Border.panelHeader">
<Setter Property="Padding" Value="16,13" />
<Setter Property="BorderBrush" Value="{DynamicResource SurfaceBorderBrush}" />
<Setter Property="BorderThickness" Value="0,0,0,1" />
</Style>
<Style Selector="Border.panelFooter">
<Setter Property="Padding" Value="16,12" />
<Setter Property="BorderBrush" Value="{DynamicResource SurfaceBorderBrush}" />
<Setter Property="BorderThickness" Value="0,1,0,0" />
</Style>
<Style Selector="TextBlock.panelTitle">
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}" />
<Setter Property="FontSize" Value="14" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<!-- ======================== Settings panel ======================== -->
<!--
@@ -138,14 +162,11 @@
<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.
-->
<!-- Its own backdrop, so the panel reads as a separate region even where the bars on
both sides share a colour. The divider itself is a sibling element, not this
border: a border belongs to the panel and is only as visible as the panel's own
background, whereas the separation has to hold across the bars too. -->
<Setter Property="Background" Value="{DynamicResource PanelBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource PanelDividerBrush}" />
<Setter Property="BorderThickness" Value="1,0,0,0" />
<Setter Property="Transitions">
<Transitions>
<DoubleTransition Property="Width" Duration="0:0:0.22" Easing="CubicEaseOut" />
@@ -157,6 +178,16 @@
<Setter Property="Width" Value="400" />
</Style>
<!--
Drawn after the panel and over both bars, so nothing can paint across it. This is the
one line that tells the eye where the library ends and the settings begin.
-->
<Style Selector="Rectangle.panelDivider">
<Setter Property="Width" Value="1" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Fill" Value="{DynamicResource PanelDividerBrush}" />
</Style>
<!-- ============================ Badge ============================ -->
<Style Selector="Border.badge">
+20 -20
View File
@@ -9,7 +9,7 @@
Title="PLib — видеотека"
Width="1180"
Height="760"
MinWidth="1000"
MinWidth="900"
MinHeight="420"
Background="{DynamicResource PageBackgroundBrush}"
WindowStartupLocation="CenterScreen">
@@ -95,9 +95,7 @@
</Window.Resources>
<Grid ColumnDefinitions="*,Auto">
<Grid Grid.Column="0" RowDefinitions="Auto,*,Auto">
<Grid RowDefinitions="Auto,*,Auto">
<!-- ======================= Header ======================= -->
<Border Grid.Row="0" Classes="appBar">
@@ -153,10 +151,7 @@
<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}">
<Button Classes="Primary" Command="{Binding AddFolderCommand}">
<StackPanel Orientation="Horizontal" Spacing="7">
<icons:MaterialIcon Kind="FolderPlusOutline" Width="17" Height="17" />
<TextBlock Text="Добавить папку" />
@@ -167,8 +162,10 @@
</Grid>
</Border>
<!-- ======================= Grid ======================= -->
<Panel Grid.Row="1">
<!-- =================== Library and settings =================== -->
<Grid Grid.Row="1" ColumnDefinitions="*,Auto">
<Panel Grid.Column="0">
<ScrollViewer Padding="20,18" HorizontalScrollBarVisibility="Disabled">
<ItemsRepeater ItemsSource="{Binding Videos}" ItemTemplate="{StaticResource VideoCardTemplate}">
@@ -208,7 +205,19 @@
Content="Выбрать папку" />
</StackPanel>
</Panel>
</Panel>
<!-- The panel is a column of the content row, so the bars above and below it stay
whole: one header and one status bar belonging to the window, not two of each. -->
<Border Grid.Column="1" Classes="settingsPanel" Classes.open="{Binding IsSettingsOpen}">
<ContentControl Width="400"
Content="{Binding SettingsPanel}"
ContentTemplate="{StaticResource SettingsTemplate}" />
</Border>
<Rectangle Grid.Column="1" Classes="panelDivider" IsVisible="{Binding IsSettingsOpen}" />
</Grid>
<!-- ======================= Status bar ======================= -->
<Border Grid.Row="2" Classes="statusBar">
@@ -237,14 +246,5 @@
</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>
+8 -22
View File
@@ -31,34 +31,20 @@
<Grid RowDefinitions="Auto,*,Auto">
<!-- ======================= Header ======================= -->
<Border Grid.Row="0" Classes="appBar">
<Grid ColumnDefinitions="Auto,*,Auto">
<Border Grid.Column="0"
Width="32"
Height="32"
CornerRadius="9"
Background="{DynamicResource AccentSoftBrush}">
<icons:MaterialIcon Kind="CogOutline"
Width="18"
Height="18"
Foreground="{DynamicResource AccentBrush}" />
</Border>
<TextBlock Grid.Column="1"
Classes="sectionTitle"
Margin="10,0,0,0"
Text="Настройки"
VerticalAlignment="Center" />
<Button Grid.Column="2"
<Border Grid.Row="0" Classes="panelHeader">
<Grid ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Classes="panelTitle" Text="Настройки" />
<Button Grid.Column="1"
Command="{Binding CancelCommand}"
Padding="7"
Padding="6"
ToolTip.Tip="Закрыть без сохранения">
<icons:MaterialIcon Kind="Close" Width="15" Height="15" />
<icons:MaterialIcon Kind="Close" Width="14" Height="14" />
</Button>
</Grid>
</Border>
<!-- ======================= Body ======================= -->
<ScrollViewer Grid.Row="1" Padding="20,18">
<ScrollViewer Grid.Row="1" Padding="16,14">
<StackPanel Spacing="14">
<!-- Folders -->
@@ -223,7 +209,7 @@
</ScrollViewer>
<!-- ======================= Footer ======================= -->
<Border Grid.Row="2" Classes="statusBar">
<Border Grid.Row="2" Classes="panelFooter">
<Grid ColumnDefinitions="*,Auto" ColumnSpacing="14">
<TextBlock Grid.Column="0"
Classes="hint"