Files
AmiReel/MainWindow.xaml
T
klevze 3e881b79b8 Bring WinUI app to feature/visual parity with WPF, fix drag-and-drop and branding assets
- Restyle Fluent controls (buttons, fields, dialogs, ListView) to match the
  app's navy dark/light palette and consistent corner radii/sizing
- Fix ContentDialog (Settings, exit-confirm, error) styling by binding
  PrimaryButtonStyle/CloseButtonStyle explicitly via new DialogHelper,
  since ContentDialog ignores implicit Button styles and forces accent
  color onto whichever button is DefaultButton
- Remove MicaBackdrop and theme the title bar directly so it no longer
  shows a gray tint mismatched with the app's navy background
- Replace placeholder Assets/*.png (unused VS template art) with the real
  AmiReel logo at all required tile/splash/store sizes
- Set explicit default window size (1280x860, matching the old WPF app)
  with DPI-aware centering and a minimum size, instead of sizing to content
- Fix drag-and-drop silently failing: InputList_Drop needs a
  DragOperationDeferral before the first await or the DataView is torn
  down before GetStorageItemsAsync completes
- Add Preview player path setting (was present in WPF, missing in WinUI)
  and error handling for preview playback
- Accept all ffmpeg-readable video formats (mp4, mov, mkv, webm, ...) for
  file picker and drag-and-drop, not just .avi
- Add exit-confirmation dialog to WinUI, mirroring the WPF app

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 13:53:55 +02:00

280 lines
19 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<Window x:Class="AmigaDB.VideoRenderer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AmiReel" Height="860" Width="1280" MinHeight="780" MinWidth="1100"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
ResizeMode="CanResize"
Icon="assets/AmiReel.ico">
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="40"
ResizeBorderThickness="6"
GlassFrameThickness="0"
UseAeroCaptionButtons="False"/>
</WindowChrome.WindowChrome>
<Grid Background="{DynamicResource PageBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="{DynamicResource PanelBrush}" Height="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image Source="assets/AmiReel.ico" Width="18" Height="18" Margin="14,0,8,0" VerticalAlignment="Center"
WindowChrome.IsHitTestVisibleInChrome="False"/>
<TextBlock Grid.Column="1" Text="AmiReel" VerticalAlignment="Center" FontWeight="SemiBold"
Foreground="{DynamicResource TextBrush}" WindowChrome.IsHitTestVisibleInChrome="False"/>
<Button x:Name="MinimizeButton" Grid.Column="2" Content="&#xE921;" Style="{StaticResource TitleBarButton}"
Click="Minimize_Click" ToolTip="Minimize" WindowChrome.IsHitTestVisibleInChrome="True"/>
<Button x:Name="MaximizeButton" Grid.Column="3" Content="&#xE922;" Style="{StaticResource TitleBarButton}"
Click="MaximizeRestore_Click" ToolTip="Maximize" WindowChrome.IsHitTestVisibleInChrome="True"/>
<Button x:Name="CloseWindowButton" Grid.Column="4" Content="&#xE8BB;" Style="{StaticResource TitleBarCloseButton}"
Click="CloseWindowButton_Click" ToolTip="Close" WindowChrome.IsHitTestVisibleInChrome="True"/>
</Grid>
<Grid Grid.Row="1">
<Grid>
<Grid.Background>
<DrawingBrush Stretch="None" Viewport="0,0,36,36" ViewportUnits="Absolute" Opacity="0.08">
<DrawingBrush.Drawing>
<GeometryDrawing Brush="{DynamicResource PageOverlayBrush}">
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry Center="10,10" RadiusX="1.2" RadiusY="1.2"/>
<EllipseGeometry Center="28,18" RadiusX="1.2" RadiusY="1.2"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Grid.Background>
</Grid>
<Grid Margin="18">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="14"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<GroupBox Header="Source recordings">
<Grid>
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="98"/><RowDefinition Height="Auto"/></Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<Button Content="Add video files…" Click="AddInputs_Click" Margin="0,0,8,0"/>
<Button Content="Clear" Click="ClearInputs_Click"/>
</StackPanel>
<ListBox x:Name="InputList" Grid.Row="1" SelectionChanged="InputList_SelectionChanged"
AllowDrop="True" DragEnter="InputList_DragEnter" DragOver="InputList_DragEnter" Drop="InputList_Drop"
ToolTip="Drag and drop video files here to add them"/>
<Button x:Name="PreviewSourceButton" Grid.Row="2" Content="Preview selected" Click="PreviewSource_Click"
HorizontalAlignment="Left" Margin="0,10,0,0" IsEnabled="False"/>
</Grid>
</GroupBox>
<GroupBox Grid.Column="2" Header="End card and output">
<Grid>
<Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="Auto"/></Grid.ColumnDefinitions>
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="55"/><RowDefinition Height="55"/><RowDefinition Height="55"/></Grid.RowDefinitions>
<TextBlock Text="Leave blank to use a built-in black end card." Foreground="{DynamicResource MutedBrush}" Margin="0,0,0,6"/>
<TextBox x:Name="EndCardBox" Grid.Row="1" Margin="0,0,8,8" ToolTip="Optional end-card image"/>
<Button Grid.Row="1" Grid.Column="1" Content="Browse…" Click="BrowseEndCard_Click" Margin="0,0,0,8"/>
<TextBox x:Name="OutputFolderBox" Grid.Row="2" Margin="0,0,8,8" ToolTip="Output folder"/>
<Button Grid.Row="2" Grid.Column="1" Content="Browse…" Click="BrowseOutput_Click" Margin="0,0,0,8"/>
<TextBox x:Name="OutputNameBox" Grid.Row="3" Grid.ColumnSpan="2" Text="amigadb_intro" ToolTip="Output filename prefix"/>
</Grid>
</GroupBox>
</Grid>
<GroupBox Grid.Row="1" Header="Render progress" Margin="0,14,0,0">
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<TextBlock x:Name="StageText" Text="Ready" FontWeight="SemiBold"/>
<TextBlock x:Name="PercentText" Text="0%" Foreground="{DynamicResource AccentBrush}" Margin="6,0,0,0"/>
</StackPanel>
<ProgressBar x:Name="RenderProgress" Minimum="0" Maximum="100" Foreground="{DynamicResource AccentBrush}"/>
<TextBlock x:Name="StatusText" Text="Select the recordings and start the render. The end card is optional."
Foreground="{DynamicResource MutedBrush}" TextWrapping="Wrap" Margin="0,8,0,0"/>
</StackPanel>
</GroupBox>
<GroupBox Grid.Row="2" Header="FFmpeg log" Margin="0,14,0,0">
<TextBox x:Name="LogBox" IsReadOnly="True" AcceptsReturn="True"
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
FontFamily="Consolas" FontSize="11" TextWrapping="NoWrap"/>
</GroupBox>
<DockPanel Grid.Row="3" Margin="0,12,0,0" LastChildFill="False">
<StackPanel Orientation="Horizontal" DockPanel.Dock="Left">
<Button x:Name="OpenOutputButton" Content="Open output folder" Click="OpenOutput_Click" IsEnabled="False" Margin="0,0,10,0"/>
<Button x:Name="PreviewRenderedButton" Content="Preview render" Click="PreviewRendered_Click" IsEnabled="False"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" DockPanel.Dock="Right">
<Button x:Name="OpenSettingsButton" Content="⚙" Click="OpenSettings_Click" Style="{StaticResource IconButton}" Margin="0,0,10,0" ToolTip="Settings"/>
<Button x:Name="CancelButton" Content="Cancel" Click="Cancel_Click" IsEnabled="False" Margin="0,0,10,0"/>
<Button x:Name="RenderButton" Content="Start render" Style="{StaticResource PrimaryButton}" Click="Render_Click"/>
</StackPanel>
</DockPanel>
<Border x:Name="SettingsOverlay" Grid.RowSpan="4" Background="#88060B14" Visibility="Collapsed">
<Grid Margin="40">
<Border Width="760"
MaxHeight="720"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="{DynamicResource PanelBrush}"
BorderBrush="{DynamicResource HeroBorderBrush}"
BorderThickness="1.5"
CornerRadius="24"
Padding="20">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text="Settings" FontSize="24" FontWeight="SemiBold" Margin="0,0,0,14"/>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<StackPanel>
<GroupBox Header="Appearance">
<StackPanel>
<TextBlock Text="Theme" Foreground="{DynamicResource MutedBrush}" Margin="0,0,0,4"/>
<ComboBox x:Name="ThemeBox" SelectionChanged="ThemeBox_SelectionChanged">
<ComboBoxItem Content="Dark" Tag="Dark"/>
<ComboBoxItem Content="Light" Tag="Light"/>
</ComboBox>
</StackPanel>
</GroupBox>
<GroupBox Header="Timing and screenshots">
<Grid>
<Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions>
<Grid.RowDefinitions><RowDefinition/><RowDefinition/></Grid.RowDefinitions>
<StackPanel Margin="0,0,8,10">
<TextBlock Text="Trim start (seconds)" Foreground="{DynamicResource MutedBrush}"/>
<TextBox x:Name="TrimBox"/>
</StackPanel>
<StackPanel Grid.Column="1" Margin="8,0,0,10">
<TextBlock Text="Fade (seconds)" Foreground="{DynamicResource MutedBrush}"/>
<TextBox x:Name="FadeBox"/>
</StackPanel>
<StackPanel Grid.Row="1" Margin="0,0,8,0">
<TextBlock Text="End-card hold (seconds)" Foreground="{DynamicResource MutedBrush}"/>
<TextBox x:Name="HoldBox"/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" Margin="8,0,0,0">
<TextBlock Text="Thumbnail interval (seconds)" Foreground="{DynamicResource MutedBrush}"/>
<TextBox x:Name="IntervalBox"/>
</StackPanel>
</Grid>
</GroupBox>
<GroupBox Header="Source files">
<StackPanel>
<CheckBox x:Name="MoveSourcesBox"
Content="Move source videos to destination\originals"
IsChecked="True"
Margin="0,0,0,6"/>
<TextBlock Foreground="{DynamicResource MutedBrush}"
TextWrapping="Wrap"
Text="After a successful render, original recordings are moved into an originals subfolder of the output folder. Uncheck to leave them where they are."/>
</StackPanel>
</GroupBox>
<GroupBox Header="Video encoding">
<Grid>
<Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="*"/></Grid.ColumnDefinitions>
<Grid.RowDefinitions><RowDefinition/><RowDefinition/></Grid.RowDefinitions>
<StackPanel Margin="0,0,8,8">
<TextBlock Text="Encoder" Foreground="{DynamicResource MutedBrush}" Margin="0,0,0,4"/>
<ComboBox x:Name="EncoderBox" SelectedIndex="0">
<ComboBoxItem Content="Auto (NVENC → CPU fallback)" Tag="Auto"/>
<ComboBoxItem Content="NVIDIA NVENC" Tag="NvidiaNvenc"/>
<ComboBoxItem Content="CPU libx264" Tag="CpuX264"/>
</ComboBox>
</StackPanel>
<StackPanel Grid.Column="1" Margin="8,0,0,8">
<TextBlock Text="Output" Foreground="{DynamicResource MutedBrush}" Margin="0,0,0,4"/>
<TextBox Text="3840 × 2160 · 50 FPS" IsReadOnly="True"/>
</StackPanel>
<TextBlock Grid.Row="1" Grid.ColumnSpan="2" Foreground="{DynamicResource MutedBrush}"
Text="NVENC: preset P6 / CQ 16 · CPU: slow / CRF 13"/>
</Grid>
</GroupBox>
<GroupBox Header="FFmpeg tools">
<Grid>
<Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="Auto"/></Grid.ColumnDefinitions>
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition/><RowDefinition/><RowDefinition/></Grid.RowDefinitions>
<TextBlock Text="Optional override. Leave blank to auto-detect FFmpeg and FFprobe from PATH, then use the embedded fallback."
Foreground="{DynamicResource MutedBrush}" Margin="0,0,0,6"/>
<TextBox x:Name="FfmpegPathBox" Grid.Row="1" Margin="0,0,8,8" ToolTip="Path to ffmpeg.exe"/>
<Button Grid.Row="1" Grid.Column="1" Content="Browse…" Click="BrowseFfmpeg_Click" Margin="0,0,0,8"/>
<TextBox x:Name="FfprobePathBox" Grid.Row="2" Margin="0,0,8,8" ToolTip="Path to ffprobe.exe"/>
<Button Grid.Row="2" Grid.Column="1" Content="Browse…" Click="BrowseFfprobe_Click" Margin="0,0,0,8"/>
<TextBox x:Name="PreviewPlayerPathBox" Grid.Row="3" Margin="0,0,8,0" ToolTip="Optional path to mpv.exe or another video player"/>
<Button Grid.Row="3" Grid.Column="1" Content="Browse…" Click="BrowsePreviewPlayer_Click"/>
</Grid>
</GroupBox>
</StackPanel>
</ScrollViewer>
<Grid Grid.Row="2" Margin="0,14,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Advanced settings are saved automatically." Foreground="{DynamicResource MutedBrush}" VerticalAlignment="Center"/>
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="Close" Click="CloseSettings_Click" MinWidth="140" Margin="0,0,10,0"/>
<Button Content="Done" Style="{StaticResource PrimaryButton}" Click="CloseSettings_Click" MinWidth="140"/>
</StackPanel>
</Grid>
</Grid>
</Border>
</Grid>
</Border>
</Grid>
</Grid>
<Border x:Name="ExitConfirmOverlay" Grid.RowSpan="2" Background="#88060B14" Visibility="Collapsed">
<Border Width="420"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="{DynamicResource PanelBrush}"
BorderBrush="{DynamicResource HeroBorderBrush}"
BorderThickness="1.5"
CornerRadius="20"
Padding="24">
<StackPanel>
<TextBlock Text="Exit AmiReel?" FontSize="20" FontWeight="SemiBold" Margin="0,0,0,10"/>
<TextBlock Text="Are you sure you want to close the application?"
Foreground="{DynamicResource MutedBrush}" TextWrapping="Wrap" Margin="0,0,0,20"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="Cancel" Click="CancelExit_Click" MinWidth="110" Margin="0,0,10,0"/>
<Button Content="Exit" Style="{StaticResource PrimaryButton}" Click="ConfirmExit_Click" MinWidth="110"/>
</StackPanel>
</StackPanel>
</Border>
</Border>
</Grid>
</Window>