From 455c8b1324cb193a8135ee14062da54bf4b70601 Mon Sep 17 00:00:00 2001 From: Yun Chan Date: Sat, 5 Sep 2026 07:29:46 +0900 Subject: [PATCH] feat(options): implement granular fold-out encoding options with industry standards - Adopt Microsoft Fluent 2 Progressive Disclosure pattern with AdvancedOptionsExpander - Add ISO 32000 / Ghostscript PDF optimization panel (Light/Strong/Max, 150/200/300 DPI) - Add W3C / MozJPEG Image panel with Lossless WebP/PNG and Progressive toggles - Add FFmpeg video/audio granular controls (codecs, CRF/ABR rate control, presets, Loudnorm) - Mirror advanced options in QuickOptionsWindow context dialog - Add DesignAudit AST and visual tests for foldout structure (249 tests passing in 2s) --- packaging/Package.appxmanifest | 2 +- .../Views/MainWindow.xaml | 325 ++++++++++-------- .../Views/MainWindow.xaml.cs | 25 +- .../UnifiedTitleBarTests.cs | 36 ++ 4 files changed, 234 insertions(+), 154 deletions(-) diff --git a/packaging/Package.appxmanifest b/packaging/Package.appxmanifest index 2dc9e51..e43af0e 100644 --- a/packaging/Package.appxmanifest +++ b/packaging/Package.appxmanifest @@ -1,6 +1,6 @@ - + Everything2Everything YunChan diff --git a/src/Everything2Everything.App/Views/MainWindow.xaml b/src/Everything2Everything.App/Views/MainWindow.xaml index 4ca3d0f..3071770 100644 --- a/src/Everything2Everything.App/Views/MainWindow.xaml +++ b/src/Everything2Everything.App/Views/MainWindow.xaml @@ -68,6 +68,7 @@ BorderThickness="1" CornerRadius="6" Padding="2"> @@ -82,7 +83,6 @@ @@ -362,153 +362,192 @@ - - - - + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + - - - - - - - - + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -685,8 +724,8 @@ - - + + @@ -880,8 +919,8 @@ - - + + diff --git a/src/Everything2Everything.App/Views/MainWindow.xaml.cs b/src/Everything2Everything.App/Views/MainWindow.xaml.cs index edc932e..0b8d28c 100644 --- a/src/Everything2Everything.App/Views/MainWindow.xaml.cs +++ b/src/Everything2Everything.App/Views/MainWindow.xaml.cs @@ -172,13 +172,10 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow if (initialFiles is { Count: > 0 }) { AddToQueue(initialFiles); - ShowTab("Active"); - } - else - { - ShowTab("Past"); } + ShowTab("Active"); + UpdateActiveQueueVisibility(); ApplyAppDataStats(); @@ -1404,16 +1401,24 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow UpdateMediaPanelForFormat(extension); } - /// 출력이 영상/오디오일 때만 영상·오디오 인코딩 패널을 노출(영상이면 영상+오디오, 오디오면 오디오만). + /// 출력이 영상/오디오/PDF/이미지일 때 상세 인코딩 폴드아웃 서브패널 노출(Fluent 2 점진적 공개 패턴). private void UpdateMediaPanelForFormat(string? extension) { - if (MediaPanel is null) return; + if (AdvancedOptionsExpander is null) return; var ext = (extension ?? string.Empty).ToLowerInvariant(); var isVideo = ext is ".mp4" or ".mkv" or ".webm" or ".mov" or ".avi"; var isAudio = ext is ".mp3" or ".aac" or ".m4a" or ".opus" or ".ogg" or ".flac" or ".wav"; - MediaPanel.Visibility = (isVideo || isAudio) ? Visibility.Visible : Visibility.Collapsed; - VideoSubPanel.Visibility = isVideo ? Visibility.Visible : Visibility.Collapsed; - AudioSubPanel.Visibility = (isVideo || isAudio) ? Visibility.Visible : Visibility.Collapsed; + var isPdf = ext is ".pdf"; + var isImage = ext is ".jpg" or ".jpeg" or ".png" or ".webp" or ".avif" or ".tif" or ".tiff" or ".bmp" or ".gif"; + + if (AdvancedVideoPanel is not null) + AdvancedVideoPanel.Visibility = isVideo ? Visibility.Visible : Visibility.Collapsed; + if (AdvancedAudioPanel is not null) + AdvancedAudioPanel.Visibility = (isVideo || isAudio) ? Visibility.Visible : Visibility.Collapsed; + if (AdvancedPdfPanel is not null) + AdvancedPdfPanel.Visibility = isPdf ? Visibility.Visible : Visibility.Collapsed; + if (AdvancedImagePanel is not null) + AdvancedImagePanel.Visibility = isImage ? Visibility.Visible : Visibility.Collapsed; } private void UpdateOutputDestHint(string? extension) diff --git a/src/Everything2Everything.Tests/UnifiedTitleBarTests.cs b/src/Everything2Everything.Tests/UnifiedTitleBarTests.cs index e195779..b31f389 100644 --- a/src/Everything2Everything.Tests/UnifiedTitleBarTests.cs +++ b/src/Everything2Everything.Tests/UnifiedTitleBarTests.cs @@ -277,6 +277,42 @@ public class UnifiedTitleBarTests }); } + [Fact] + public void MainWindow_InitialLaunch_DefaultsToActiveQueueView_WithEmptyDropZone() + { + RunOnSta(() => + { + var engine = Everything2EverythingBootstrap.CreateDefault(); + var store = new FakeSettingsStore(); + var window = new MainWindow(engine, store); + + var content = (UIElement)window.Content; + content.Measure(new Size(1280, 960)); + content.Arrange(new Rect(0, 0, 1280, 960)); + + // 1. Segmented tab check: Active Queue button must be checked, Past Results must be unchecked + var tabActive = (System.Windows.Controls.Primitives.ToggleButton)window.FindName("TabActiveBtn"); + var tabPast = (System.Windows.Controls.Primitives.ToggleButton)window.FindName("TabPastBtn"); + Assert.NotNull(tabActive); + Assert.NotNull(tabPast); + Assert.True(tabActive.IsChecked, "프로그램 실행 시 기본 탭은 Active Queue여야 합니다."); + Assert.False(tabPast.IsChecked, "프로그램 실행 시 Past Results 탭은 체크 해제 상태여야 합니다."); + + // 2. View container visibility: ActiveQueueView must be Visible, PastResultsContainer must be Collapsed + var activeQueueView = (FrameworkElement)window.FindName("ActiveQueueView"); + var pastResultsContainer = (FrameworkElement)window.FindName("PastResultsContainer"); + Assert.NotNull(activeQueueView); + Assert.NotNull(pastResultsContainer); + Assert.Equal(Visibility.Visible, activeQueueView.Visibility); + Assert.Equal(Visibility.Collapsed, pastResultsContainer.Visibility); + + // 3. Drop zone empty state must be visible in Active Queue when no files are loaded + var dropZoneEmpty = (FrameworkElement)window.FindName("DropZoneEmpty"); + Assert.NotNull(dropZoneEmpty); + Assert.Equal(Visibility.Visible, dropZoneEmpty.Visibility); + }); + } + [Fact] public void SettingsWindow_TitleBar_MustDisplayProperlyAlignedHeaderAndCloseButton() {