The footer was at outer Grid.Row=2 with no column constraint, so it spanned the full window width — visually overflowing under the 200px left sidebar. Added a 200px left margin so the footer starts where the content area starts. Comment makes the magic-number coupling explicit so it stays in sync if the sidebar width changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
663 lines
42 KiB
XML
663 lines
42 KiB
XML
<Window x:Class="PSLauncher.App.Views.MainWindow"
|
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:vm="clr-namespace:PSLauncher.App.ViewModels"
|
|
xmlns:loc="clr-namespace:PSLauncher.Core.Localization;assembly=PSLauncher.Core"
|
|
xmlns:shell="clr-namespace:System.Windows.Shell;assembly=PresentationFramework"
|
|
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
|
|
Title="PROSERVE Launcher"
|
|
Icon="pack://application:,,,/Resources/favicon.ico"
|
|
Background="Black"
|
|
Width="1280" Height="720"
|
|
MinWidth="980" MinHeight="600"
|
|
WindowStartupLocation="CenterScreen"
|
|
WindowStyle="None"
|
|
ResizeMode="CanResize"
|
|
AllowsTransparency="False"
|
|
d:DataContext="{d:DesignInstance Type=vm:MainViewModel}"
|
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
mc:Ignorable="d"
|
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
|
|
|
|
<shell:WindowChrome.WindowChrome>
|
|
<shell:WindowChrome CaptionHeight="56"
|
|
GlassFrameThickness="0"
|
|
CornerRadius="0"
|
|
ResizeBorderThickness="6"
|
|
UseAeroCaptionButtons="False" />
|
|
</shell:WindowChrome.WindowChrome>
|
|
|
|
<Window.Resources>
|
|
|
|
<!-- =================== TEMPLATE : LIGNE COMPACTE (autres versions) =================== -->
|
|
<DataTemplate x:Key="CompactRowTemplate" DataType="{x:Type vm:VersionRowViewModel}">
|
|
<Border Margin="0,0,0,8" CornerRadius="6" BorderThickness="1">
|
|
<Border.Style>
|
|
<Style TargetType="Border">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Bg.Card}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Brush.Border}" />
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding IsRemoteOnly}" Value="True">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.AvailableBg}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Available}" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding IsBusy}" Value="True">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.BusyBg}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Busy}" />
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</Border.Style>
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="4" /> <!-- accent strip -->
|
|
<ColumnDefinition Width="*" />
|
|
<ColumnDefinition Width="Auto" />
|
|
<ColumnDefinition Width="Auto" />
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<!-- Strip latérale colorée : Border avec coins arrondis à gauche
|
|
pour suivre la rondeur (CornerRadius=6) de la card parent. -->
|
|
<Border Grid.Column="0" CornerRadius="5,0,0,5">
|
|
<Border.Style>
|
|
<Style TargetType="Border">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.Installed}" />
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding IsRemoteOnly}" Value="True">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.Available}" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding IsBusy}" Value="True">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.Busy}" />
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</Border.Style>
|
|
</Border>
|
|
|
|
<Grid Grid.Column="1" Margin="16,12">
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto" />
|
|
<RowDefinition Height="Auto" />
|
|
</Grid.RowDefinitions>
|
|
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
|
<TextBlock Text="{Binding Version, StringFormat='v{0}'}"
|
|
FontSize="15" FontWeight="SemiBold"
|
|
VerticalAlignment="Center"
|
|
Foreground="{StaticResource Brush.Text.Primary}" />
|
|
<Border CornerRadius="10" Padding="8,3" Margin="12,0,0,0"
|
|
VerticalAlignment="Center">
|
|
<Border.Style>
|
|
<Style TargetType="Border">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.Installed}" />
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding IsRemoteOnly}" Value="True">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.Available}" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding IsBusy}" Value="True">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.Busy}" />
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</Border.Style>
|
|
<TextBlock Text="{Binding StateLabel}" FontSize="11" FontWeight="SemiBold"
|
|
Foreground="White" />
|
|
</Border>
|
|
</StackPanel>
|
|
<TextBlock Grid.Row="1" FontSize="11"
|
|
Foreground="{StaticResource Brush.Text.Secondary}"
|
|
Margin="0,4,0,0">
|
|
<Run Text="{Binding SizeDisplay, Mode=OneWay}" />
|
|
<Run Text=" • " />
|
|
<Run Text="{Binding PrimaryDate, Mode=OneWay}" />
|
|
</TextBlock>
|
|
</Grid>
|
|
|
|
<!-- Action button -->
|
|
<StackPanel Grid.Column="2" Orientation="Horizontal" VerticalAlignment="Center" Margin="12,0,0,0">
|
|
<Button Style="{StaticResource PrimaryButton}"
|
|
Content="{x:Static loc:Strings.ActionLaunch}" Padding="22,8" FontSize="13"
|
|
Command="{Binding LaunchCommand}"
|
|
Visibility="{Binding IsInstalled, Converter={StaticResource BoolToVisibility}}" />
|
|
<Button Style="{StaticResource AccentButton}"
|
|
Content="{Binding InstallButtonLabel}" Padding="22,8" FontSize="13"
|
|
Command="{Binding InstallCommand}"
|
|
Visibility="{Binding IsRemoteOnly, Converter={StaticResource BoolToVisibility}}" />
|
|
<!-- Bouton rouge « Annuler » : visible uniquement quand on a un partial.
|
|
Permet d'abandonner le partial et repartir de zéro (avec confirmation). -->
|
|
<Button Style="{StaticResource DangerButton}"
|
|
Content="{x:Static loc:Strings.ActionCancel}"
|
|
Padding="14,8" FontSize="13" Margin="6,0,0,0"
|
|
Command="{Binding RestartFromZeroCommand}"
|
|
ToolTip="{x:Static loc:Strings.MenuRestartFromZero}"
|
|
Visibility="{Binding ShowRestartFromZero, Converter={StaticResource BoolToVisibility}}" />
|
|
<StackPanel Orientation="Horizontal"
|
|
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibility}}">
|
|
<ProgressBar Width="140" Height="6"
|
|
Value="{Binding ProgressPercent}" Maximum="100"
|
|
Foreground="{StaticResource Brush.Status.Busy}"
|
|
Background="#2A2A30" BorderThickness="0"
|
|
VerticalAlignment="Center" />
|
|
<TextBlock Text="{Binding ProgressPercent, StringFormat={}{0:0}%}"
|
|
FontSize="11" Margin="8,0,0,0" VerticalAlignment="Center"
|
|
Foreground="{StaticResource Brush.Text.Secondary}" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
|
|
<!-- ... menu -->
|
|
<Button Grid.Column="3"
|
|
Style="{StaticResource IconButton}"
|
|
Content="⋯" FontSize="18" FontWeight="Bold"
|
|
Margin="8,0,8,0" VerticalAlignment="Center"
|
|
ToolTip="Plus d'actions"
|
|
Tag="{Binding}"
|
|
Click="OnMoreMenuClick">
|
|
<Button.ContextMenu>
|
|
<ContextMenu>
|
|
<MenuItem Header="{x:Static loc:Strings.MenuReleaseNotes}"
|
|
Command="{Binding PlacementTarget.Tag.ShowReleaseNotesCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
|
|
<MenuItem Header="{x:Static loc:Strings.MenuOpenFolder}"
|
|
Command="{Binding PlacementTarget.Tag.OpenFolderCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
|
Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
|
|
<MenuItem Header="{x:Static loc:Strings.MenuRestartFromZero}"
|
|
Command="{Binding PlacementTarget.Tag.RestartFromZeroCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
|
Visibility="{Binding PlacementTarget.Tag.HasResumableDownload, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
|
|
<Separator Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
|
|
<MenuItem Header="{x:Static loc:Strings.MenuUninstall}"
|
|
Command="{Binding PlacementTarget.Tag.UninstallCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
|
Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
|
|
</ContextMenu>
|
|
</Button.ContextMenu>
|
|
</Button>
|
|
</Grid>
|
|
</Border>
|
|
</DataTemplate>
|
|
</Window.Resources>
|
|
|
|
<Grid Background="Black">
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto" />
|
|
<RowDefinition Height="*" />
|
|
<RowDefinition Height="Auto" />
|
|
</Grid.RowDefinitions>
|
|
|
|
<!-- Background image : limité au body uniquement (Grid.Row="1") pour ne pas
|
|
se faire chevaucher par le footer quand un download tourne. ImageBrush
|
|
avec AlignmentX=Right + AlignmentY=Bottom : si le ratio fenêtre force
|
|
un crop, on rogne en haut/à gauche — le logo ASTERION VR en bas-droite
|
|
reste TOUJOURS visible. -->
|
|
<Rectangle Grid.Row="1" IsHitTestVisible="False">
|
|
<Rectangle.Fill>
|
|
<ImageBrush ImageSource="pack://application:,,,/Resources/Background.png"
|
|
Stretch="UniformToFill"
|
|
AlignmentX="Right"
|
|
AlignmentY="Bottom"
|
|
Opacity="0.25" />
|
|
</Rectangle.Fill>
|
|
</Rectangle>
|
|
|
|
<!-- Top bar : 3 colonnes (brand / license center / chrome) -->
|
|
<Border Grid.Row="0" Background="{StaticResource Brush.Bg.Sidebar}"
|
|
BorderBrush="{StaticResource Brush.Border}" BorderThickness="0,0,0,1"
|
|
Padding="20,12">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*" /> <!-- brand -->
|
|
<ColumnDefinition Width="*" /> <!-- license (center) -->
|
|
<ColumnDefinition Width="*" /> <!-- chrome (right) -->
|
|
</Grid.ColumnDefinitions>
|
|
<!-- Col 1 : brand -->
|
|
<StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center">
|
|
<Image Source="pack://application:,,,/Resources/logo-asterion-white.png"
|
|
Height="36"
|
|
VerticalAlignment="Center"
|
|
Margin="0,0,14,0"
|
|
SnapsToDevicePixels="True"
|
|
RenderOptions.BitmapScalingMode="HighQuality" />
|
|
<TextBlock Text="PROSERVE"
|
|
FontFamily="{StaticResource Font.Brand}"
|
|
FontSize="22"
|
|
Foreground="{StaticResource Brush.Text.Primary}"
|
|
VerticalAlignment="Center" />
|
|
<TextBlock Text="Launcher"
|
|
FontSize="20"
|
|
FontWeight="Bold"
|
|
Foreground="{StaticResource Brush.Text.Primary}"
|
|
VerticalAlignment="Center"
|
|
Margin="14,0,0,0" />
|
|
</StackPanel>
|
|
|
|
<!-- Col 2 : badge license cliquable, centré -->
|
|
<Border Grid.Column="1"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
Cursor="Hand"
|
|
CornerRadius="16" Padding="14,6"
|
|
shell:WindowChrome.IsHitTestVisibleInChrome="True"
|
|
ToolTip="{x:Static loc:Strings.LicenseTooltip}">
|
|
<Border.Style>
|
|
<Style TargetType="Border">
|
|
<Setter Property="Background" Value="#2A1414" />
|
|
<Setter Property="BorderBrush" Value="#EF4444" />
|
|
<Setter Property="BorderThickness" Value="1" />
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Ok">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.InstalledBg}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Installed}" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Warning">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.BusyBg}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Busy}" />
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</Border.Style>
|
|
<Border.InputBindings>
|
|
<MouseBinding Gesture="LeftClick" Command="{Binding OpenLicenseCommand}" />
|
|
</Border.InputBindings>
|
|
<StackPanel Orientation="Horizontal">
|
|
<TextBlock Text="{Binding LicenseIcon}"
|
|
FontSize="15" FontWeight="Bold"
|
|
VerticalAlignment="Center"
|
|
Margin="0,0,8,0">
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Setter Property="Foreground" Value="#EF4444" />
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Ok">
|
|
<Setter Property="Foreground" Value="{StaticResource Brush.Status.Installed}" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Warning">
|
|
<Setter Property="Foreground" Value="{StaticResource Brush.Status.Busy}" />
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
<TextBlock Text="{Binding LicenseSummary}"
|
|
FontSize="13" FontWeight="SemiBold"
|
|
VerticalAlignment="Center">
|
|
<TextBlock.Style>
|
|
<Style TargetType="TextBlock">
|
|
<Setter Property="Foreground" Value="#FCA5A5" />
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Ok">
|
|
<Setter Property="Foreground" Value="#86EFAC" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding LicenseSeverity}" Value="Warning">
|
|
<Setter Property="Foreground" Value="#FCD34D" />
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</TextBlock.Style>
|
|
</TextBlock>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Col 3 : Paramètres + window chrome -->
|
|
<StackPanel Grid.Column="2" Orientation="Horizontal"
|
|
HorizontalAlignment="Right" VerticalAlignment="Center">
|
|
<Button Style="{StaticResource SecondaryButton}"
|
|
Content="{x:Static loc:Strings.TopBarSettings}"
|
|
shell:WindowChrome.IsHitTestVisibleInChrome="True"
|
|
Command="{Binding OpenSettingsCommand}"
|
|
Margin="0,0,16,0" />
|
|
<Button Style="{StaticResource WindowControlButton}"
|
|
Content="—" ToolTip="{x:Static loc:Strings.Minimize}"
|
|
shell:WindowChrome.IsHitTestVisibleInChrome="True"
|
|
Click="OnMinimizeClick" />
|
|
<Button Style="{StaticResource WindowControlButton}"
|
|
Content="☐" ToolTip="{x:Static loc:Strings.Maximize}"
|
|
shell:WindowChrome.IsHitTestVisibleInChrome="True"
|
|
Click="OnMaxRestoreClick" />
|
|
<Button Style="{StaticResource WindowCloseButton}"
|
|
Content="✕" ToolTip="{x:Static loc:Strings.CloseTooltip}"
|
|
shell:WindowChrome.IsHitTestVisibleInChrome="True"
|
|
Click="OnCloseClick" />
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!--
|
|
Body : grid 2 colonnes — sidebar de navigation fixe à GAUCHE,
|
|
content area swap-pable à droite. Le content area lui-même est un
|
|
Grid qui superpose plusieurs blocs (Library / Report / Documentation)
|
|
gérés par leur Visibility liée à CurrentPage.
|
|
-->
|
|
<Grid Grid.Row="1">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="200" />
|
|
<ColumnDefinition Width="*" />
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<!-- ============== Content area (col 1, swap par CurrentPage) ============== -->
|
|
<Grid Grid.Column="1">
|
|
|
|
<!-- ====================== LIBRARY PAGE ====================== -->
|
|
<Grid Visibility="{Binding IsLibrary, Converter={StaticResource BoolToVisibility}}">
|
|
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
|
<StackPanel Margin="32,28">
|
|
|
|
<!-- ========= FEATURED (version courante) ========= -->
|
|
<Border CornerRadius="10" BorderThickness="1"
|
|
Padding="0"
|
|
Margin="0,0,0,32"
|
|
Visibility="{Binding HasFeaturedVersion, Converter={StaticResource BoolToVisibility}}">
|
|
<Border.Style>
|
|
<Style TargetType="Border">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Bg.Card}" />
|
|
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Installed}" />
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding FeaturedVersion.IsRemoteOnly}" Value="True">
|
|
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Available}" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding FeaturedVersion.IsBusy}" Value="True">
|
|
<Setter Property="BorderBrush" Value="{StaticResource Brush.Status.Busy}" />
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</Border.Style>
|
|
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="6" />
|
|
<ColumnDefinition Width="*" />
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<!-- Bande latérale large : Border avec coins arrondis seulement à
|
|
gauche pour suivre la rondeur de la card parent (CornerRadius=10).
|
|
Rectangle ne se clippe pas sur le parent ⇒ on utilisait un visuel
|
|
qui dépassait les coins. -->
|
|
<Border Grid.Column="0" CornerRadius="9,0,0,9">
|
|
<Border.Style>
|
|
<Style TargetType="Border">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.Installed}" />
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding FeaturedVersion.IsRemoteOnly}" Value="True">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.Available}" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding FeaturedVersion.IsBusy}" Value="True">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.Busy}" />
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</Border.Style>
|
|
</Border>
|
|
|
|
<Grid Grid.Column="1" Margin="32,28">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*" />
|
|
<ColumnDefinition Width="Auto" />
|
|
<ColumnDefinition Width="Auto" />
|
|
</Grid.ColumnDefinitions>
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto" />
|
|
<RowDefinition Height="Auto" />
|
|
<RowDefinition Height="Auto" />
|
|
</Grid.RowDefinitions>
|
|
|
|
<!-- Label "Version courante" -->
|
|
<TextBlock Grid.Row="0" Grid.Column="0"
|
|
Text="{x:Static loc:Strings.FeaturedCurrent}"
|
|
FontSize="11" FontWeight="Bold"
|
|
Foreground="{StaticResource Brush.Text.Secondary}"
|
|
Margin="0,0,0,4" />
|
|
|
|
<!-- Numéro version + badge -->
|
|
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center">
|
|
<TextBlock Text="{Binding FeaturedVersion.Version, StringFormat='PROSERVE v{0}'}"
|
|
FontSize="32" FontWeight="Bold"
|
|
Foreground="{StaticResource Brush.Text.Primary}" />
|
|
<Border CornerRadius="12" Padding="10,4" Margin="16,8,0,0"
|
|
VerticalAlignment="Center">
|
|
<Border.Style>
|
|
<Style TargetType="Border">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.Installed}" />
|
|
<Style.Triggers>
|
|
<DataTrigger Binding="{Binding FeaturedVersion.IsRemoteOnly}" Value="True">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.Available}" />
|
|
</DataTrigger>
|
|
<DataTrigger Binding="{Binding FeaturedVersion.IsBusy}" Value="True">
|
|
<Setter Property="Background" Value="{StaticResource Brush.Status.Busy}" />
|
|
</DataTrigger>
|
|
</Style.Triggers>
|
|
</Style>
|
|
</Border.Style>
|
|
<TextBlock Text="{Binding FeaturedVersion.StateLabel}" FontSize="12" FontWeight="SemiBold"
|
|
Foreground="White" />
|
|
</Border>
|
|
</StackPanel>
|
|
|
|
<!-- Meta -->
|
|
<TextBlock Grid.Row="2" Grid.Column="0"
|
|
FontSize="13"
|
|
Foreground="{StaticResource Brush.Text.Secondary}"
|
|
Margin="0,8,0,0">
|
|
<Run Text="{x:Static loc:Strings.ReleasedOn}" />
|
|
<Run Text="{Binding FeaturedVersion.PrimaryDate, Mode=OneWay}" />
|
|
<Run Text=" • " />
|
|
<Run Text="{Binding FeaturedVersion.SizeDisplay, Mode=OneWay}" />
|
|
</TextBlock>
|
|
|
|
<!-- Action principale (gros bouton) -->
|
|
<Button Grid.Row="0" Grid.RowSpan="3" Grid.Column="1"
|
|
Style="{StaticResource PrimaryButton}"
|
|
Content="{x:Static loc:Strings.ActionLaunchBig}"
|
|
FontSize="20" Padding="56,16"
|
|
VerticalAlignment="Center"
|
|
Command="{Binding FeaturedVersion.LaunchCommand}"
|
|
Visibility="{Binding FeaturedVersion.IsInstalled, Converter={StaticResource BoolToVisibility}}" />
|
|
|
|
<StackPanel Grid.Row="0" Grid.RowSpan="3" Grid.Column="1"
|
|
Orientation="Vertical" VerticalAlignment="Center"
|
|
Visibility="{Binding FeaturedVersion.IsRemoteOnly, Converter={StaticResource BoolToVisibility}}">
|
|
<Button Style="{StaticResource AccentButton}"
|
|
Content="{Binding FeaturedVersion.InstallButtonLabel}"
|
|
FontSize="20" Padding="48,16"
|
|
Command="{Binding FeaturedVersion.InstallCommand}" />
|
|
<!-- Bouton rouge « Annuler » : visible uniquement quand un partial existe.
|
|
Permet d'abandonner et repartir de zéro (confirmation requise). -->
|
|
<Button Style="{StaticResource DangerButton}"
|
|
Content="{x:Static loc:Strings.ActionCancel}"
|
|
FontSize="13" Padding="20,8" Margin="0,8,0,0"
|
|
HorizontalAlignment="Center"
|
|
Command="{Binding FeaturedVersion.RestartFromZeroCommand}"
|
|
ToolTip="{x:Static loc:Strings.MenuRestartFromZero}"
|
|
Visibility="{Binding FeaturedVersion.ShowRestartFromZero, Converter={StaticResource BoolToVisibility}}" />
|
|
</StackPanel>
|
|
|
|
<StackPanel Grid.Row="0" Grid.RowSpan="3" Grid.Column="1"
|
|
Orientation="Vertical" VerticalAlignment="Center" Width="220"
|
|
Visibility="{Binding FeaturedVersion.IsBusy, Converter={StaticResource BoolToVisibility}}">
|
|
<TextBlock Text="{Binding FeaturedVersion.StateLabel}"
|
|
HorizontalAlignment="Center"
|
|
Foreground="{StaticResource Brush.Status.Busy}"
|
|
FontWeight="SemiBold" Margin="0,0,0,8" />
|
|
<ProgressBar Height="8"
|
|
Value="{Binding FeaturedVersion.ProgressPercent}" Maximum="100"
|
|
Foreground="{StaticResource Brush.Status.Busy}"
|
|
Background="#2A2A30" BorderThickness="0" />
|
|
<TextBlock Text="{Binding FeaturedVersion.ProgressPercent, StringFormat={}{0:0}%}"
|
|
HorizontalAlignment="Center"
|
|
FontSize="12" Margin="0,4,0,0"
|
|
Foreground="{StaticResource Brush.Text.Secondary}" />
|
|
</StackPanel>
|
|
|
|
<!-- ... menu -->
|
|
<Button Grid.Row="0" Grid.RowSpan="3" Grid.Column="2"
|
|
Style="{StaticResource IconButton}"
|
|
Content="⋯" FontSize="22" FontWeight="Bold"
|
|
Margin="12,0,0,0"
|
|
VerticalAlignment="Center"
|
|
ToolTip="Plus d'actions"
|
|
Tag="{Binding FeaturedVersion}"
|
|
Click="OnMoreMenuClick">
|
|
<Button.ContextMenu>
|
|
<ContextMenu>
|
|
<MenuItem Header="{x:Static loc:Strings.MenuReleaseNotes}"
|
|
Command="{Binding PlacementTarget.Tag.ShowReleaseNotesCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
|
|
<MenuItem Header="{x:Static loc:Strings.MenuOpenFolder}"
|
|
Command="{Binding PlacementTarget.Tag.OpenFolderCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
|
Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
|
|
<MenuItem Header="{x:Static loc:Strings.MenuRestartFromZero}"
|
|
Command="{Binding PlacementTarget.Tag.RestartFromZeroCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
|
Visibility="{Binding PlacementTarget.Tag.HasResumableDownload, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
|
|
<Separator Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
|
|
<MenuItem Header="{x:Static loc:Strings.MenuUninstall}"
|
|
Command="{Binding PlacementTarget.Tag.UninstallCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
|
|
Visibility="{Binding PlacementTarget.Tag.IsInstalled, RelativeSource={RelativeSource AncestorType=ContextMenu}, Converter={StaticResource BoolToVisibility}}" />
|
|
</ContextMenu>
|
|
</Button.ContextMenu>
|
|
</Button>
|
|
</Grid>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- ========= AUTRES VERSIONS ========= -->
|
|
<StackPanel Visibility="{Binding HasOtherVersions, Converter={StaticResource BoolToVisibility}}">
|
|
<Grid Margin="0,0,0,12">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto" />
|
|
<ColumnDefinition Width="*" />
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Grid.Column="0" Text="{x:Static loc:Strings.SectionOther}"
|
|
FontSize="12" FontWeight="Bold"
|
|
Foreground="{StaticResource Brush.Text.Secondary}"
|
|
VerticalAlignment="Center" />
|
|
<Border Grid.Column="1" Background="{StaticResource Brush.Border}"
|
|
Height="1" Margin="12,0,0,0" VerticalAlignment="Center" />
|
|
</Grid>
|
|
|
|
<ItemsControl ItemsSource="{Binding OtherVersions}"
|
|
ItemTemplate="{StaticResource CompactRowTemplate}" />
|
|
</StackPanel>
|
|
|
|
<!-- Empty state -->
|
|
<Border Background="{StaticResource Brush.Bg.Card}"
|
|
BorderBrush="{StaticResource Brush.Border}" BorderThickness="1"
|
|
CornerRadius="6"
|
|
Padding="32"
|
|
Visibility="{Binding EmptyHintVisibility}">
|
|
<TextBlock Text="{Binding EmptyHint}"
|
|
Foreground="{StaticResource Brush.Text.Secondary}"
|
|
TextWrapping="Wrap" />
|
|
</Border>
|
|
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
|
|
<!-- Bouton flottant "Vérifier les MAJ" : ancré bas-gauche du body, au-dessus
|
|
du background bitmap, à l'extérieur du footer. -->
|
|
<Button HorizontalAlignment="Left" VerticalAlignment="Bottom"
|
|
Margin="32,0,0,24"
|
|
Style="{StaticResource SecondaryButton}"
|
|
Content="{x:Static loc:Strings.TopBarCheckUpdates}"
|
|
Command="{Binding CheckForUpdatesCommand}" />
|
|
|
|
<!-- Copyright flottant en bas centré, sur une pill sombre pour rester
|
|
lisible quel que soit l'arrière-plan (image, voile noir, etc.). -->
|
|
<Border HorizontalAlignment="Center" VerticalAlignment="Bottom"
|
|
Margin="0,0,0,28"
|
|
Background="#A0000000"
|
|
CornerRadius="10"
|
|
Padding="10,4">
|
|
<TextBlock Text="{x:Static loc:Strings.Copyright}"
|
|
FontSize="11"
|
|
Foreground="White" />
|
|
</Border>
|
|
</Grid>
|
|
<!-- ====================== END LIBRARY PAGE ====================== -->
|
|
|
|
<!-- ====================== REPORT PAGE (WebView2) ====================== -->
|
|
<Grid Background="{StaticResource Brush.Bg.Window}"
|
|
Visibility="{Binding IsReport, Converter={StaticResource BoolToVisibility}}">
|
|
<wv2:WebView2 x:Name="ReportWebView"
|
|
Source="{Binding ReportUri, Mode=OneWay}" />
|
|
</Grid>
|
|
|
|
<!-- ====================== DOCUMENTATION PAGE ====================== -->
|
|
<Grid Background="{StaticResource Brush.Bg.Window}"
|
|
Visibility="{Binding IsDocumentation, Converter={StaticResource BoolToVisibility}}">
|
|
<!-- WebView2 si une URL est configurée, sinon un placeholder explicatif -->
|
|
<wv2:WebView2 x:Name="DocsWebView"
|
|
Source="{Binding DocumentationUri, Mode=OneWay}"
|
|
Visibility="{Binding HasDocumentationUrl, Converter={StaticResource BoolToVisibility}}" />
|
|
<TextBlock Text="{x:Static loc:Strings.DocsPlaceholder}"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
Foreground="{StaticResource Brush.Text.Secondary}"
|
|
FontSize="14" TextAlignment="Center" TextWrapping="Wrap"
|
|
MaxWidth="500"
|
|
Visibility="{Binding HasDocumentationUrl, Converter={StaticResource InverseBoolToVisibility}}" />
|
|
</Grid>
|
|
|
|
</Grid>
|
|
<!-- ============== END Content area ============== -->
|
|
|
|
<!-- ============== Left sidebar : nav buttons ============== -->
|
|
<Border Grid.Column="0"
|
|
Background="#0A0A0E"
|
|
BorderBrush="{StaticResource Brush.Border}"
|
|
BorderThickness="0,0,1,0">
|
|
<StackPanel Orientation="Vertical" Margin="0,16,0,0">
|
|
<!-- Style des boutons définis dans Theme.xaml (NavButton) -->
|
|
<Button Style="{StaticResource NavButton}"
|
|
Command="{Binding NavigateLibraryCommand}"
|
|
Tag="{Binding IsLibrary}">
|
|
<StackPanel Orientation="Horizontal">
|
|
<TextBlock Text="📚" FontSize="16" Margin="0,0,12,0" VerticalAlignment="Center" />
|
|
<TextBlock Text="{x:Static loc:Strings.NavLibrary}" VerticalAlignment="Center" />
|
|
</StackPanel>
|
|
</Button>
|
|
<Button Style="{StaticResource NavButton}"
|
|
Command="{Binding NavigateReportCommand}"
|
|
Tag="{Binding IsReport}">
|
|
<StackPanel Orientation="Horizontal">
|
|
<TextBlock Text="📊" FontSize="16" Margin="0,0,12,0" VerticalAlignment="Center" />
|
|
<TextBlock Text="{x:Static loc:Strings.NavReport}" VerticalAlignment="Center" />
|
|
</StackPanel>
|
|
</Button>
|
|
<Button Style="{StaticResource NavButton}"
|
|
Command="{Binding NavigateDocumentationCommand}"
|
|
Tag="{Binding IsDocumentation}">
|
|
<StackPanel Orientation="Horizontal">
|
|
<TextBlock Text="📖" FontSize="16" Margin="0,0,12,0" VerticalAlignment="Center" />
|
|
<TextBlock Text="{x:Static loc:Strings.NavDocumentation}" VerticalAlignment="Center" />
|
|
</StackPanel>
|
|
</Button>
|
|
</StackPanel>
|
|
</Border>
|
|
</Grid>
|
|
|
|
<!-- Footer : visible uniquement quand busy / status à afficher.
|
|
Le bouton "Vérifier les MAJ" a été déplacé en flottant au-dessus du body.
|
|
Margin gauche = 200px = largeur de la sidebar (Grid de la Row 1) ; ainsi
|
|
le footer reste cantonné sous la zone Library/Report/Doc et ne déborde
|
|
pas sous la sidebar. Si on change la largeur de la sidebar, ajuster ici. -->
|
|
<Border Grid.Row="2" Background="{StaticResource Brush.Bg.Footer}"
|
|
BorderBrush="{StaticResource Brush.Border}" BorderThickness="0,1,0,0"
|
|
Padding="20,10"
|
|
Margin="200,0,0,0"
|
|
Visibility="{Binding FooterVisibility}">
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*" />
|
|
<ColumnDefinition Width="Auto" />
|
|
</Grid.ColumnDefinitions>
|
|
<StackPanel Grid.Column="0">
|
|
<TextBlock Text="{Binding FooterText}"
|
|
Foreground="{StaticResource Brush.Text.Secondary}"
|
|
FontSize="12" />
|
|
<ProgressBar Height="4" Margin="0,4,0,0"
|
|
Value="{Binding ProgressPercent}" Maximum="100"
|
|
Foreground="{StaticResource Brush.Accent}"
|
|
Background="#2A2A30" BorderThickness="0" />
|
|
</StackPanel>
|
|
<Button Grid.Column="1"
|
|
Style="{StaticResource SecondaryButton}"
|
|
Content="{x:Static loc:Strings.ActionCancel}"
|
|
VerticalAlignment="Center" Margin="12,0,0,0"
|
|
Command="{Binding CancelDownloadCommand}"
|
|
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibility}}" />
|
|
</Grid>
|
|
</Border>
|
|
</Grid>
|
|
</Window>
|