From ccba168f9a543d839fd41b79626256802d2df8a2 Mon Sep 17 00:00:00 2001 From: Yun Chan Date: Tue, 2 Jun 2026 10:12:26 +0900 Subject: [PATCH] =?UTF-8?q?refactor(P5b-6):=20=EC=98=B5=EC=85=98/=ED=83=AD?= =?UTF-8?q?/=EC=B6=A9=EB=8F=8C/=EA=B2=B0=ED=95=A9=20=ED=95=B8=EB=93=A4?= =?UTF-8?q?=EB=9F=AC=205=EA=B0=9C=20=E2=86=92=20=EC=84=A0=EC=96=B8?= =?UTF-8?q?=EC=A0=81=20=EB=B0=94=EC=9D=B8=EB=94=A9=C2=B7=EC=BB=A4=EB=A7=A8?= =?UTF-8?q?=EB=93=9C=20(=EC=9D=98=EC=A1=B4=EC=84=B1=200)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 새 패키지 없이 회귀 없는 핸들러 제거/전환: - OnQualityChanged 제거 → QualityValueText.Text를 Options.Quality에 StringFormat 바인딩. - OnAiTaskChanged 제거 → AiTargetLangPanel.Visibility를 AiTaskCombo.SelectedIndex DataTrigger로. - OnTabClick 제거 → TabCommand(ToggleButton.Command + CommandParameter "Active"/"Past"). - OnConflictSegmentClick → SetConflictRule + ConflictRuleCommand(CommandParameter "Skip/Rename/Replace"). - OnCombineToggleChanged 제거 → CombineToggleCommand(CheckBox.Command, 토글 시 발화). - 검증: 빌드 0/0, 83 테스트 그린, publish 후 메인 창 크래시 없이 로드(언핸들드 로그 없음). - 잔여: 동적 포맷 콤보 SelectionChanged, 드래그앤드롭, 행 미리보기 클릭(IsInsideButton 가드), 복합 ProcessQueue 버튼. --- .../Views/MainWindow.xaml | 43 +++++++++++------- .../Views/MainWindow.xaml.cs | 45 +++++-------------- 2 files changed, 38 insertions(+), 50 deletions(-) diff --git a/src/Everything2Everything.App/Views/MainWindow.xaml b/src/Everything2Everything.App/Views/MainWindow.xaml index 3ff0122..ac6d56a 100644 --- a/src/Everything2Everything.App/Views/MainWindow.xaml +++ b/src/Everything2Everything.App/Views/MainWindow.xaml @@ -107,8 +107,7 @@ Margin="0,12,0,0" Content="단일 파일로 결합 (큐 전체 → 한 파일)" IsEnabled="False" - Checked="OnCombineToggleChanged" - Unchecked="OnCombineToggleChanged"/> + Command="{Binding CombineToggleCommand, RelativeSource={RelativeSource AncestorType=Window}}"/> @@ -129,14 +128,13 @@ + Text="{Binding Options.Quality, RelativeSource={RelativeSource AncestorType=Window}, StringFormat={}{0}%}"/> + Value="{Binding Options.Quality, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}"/> @@ -178,17 +176,17 @@ + Command="{Binding ConflictRuleCommand, RelativeSource={RelativeSource AncestorType=Window}}" + CommandParameter="Skip"/> + Command="{Binding ConflictRuleCommand, RelativeSource={RelativeSource AncestorType=Window}}" + CommandParameter="Rename"/> + Command="{Binding ConflictRuleCommand, RelativeSource={RelativeSource AncestorType=Window}}" + CommandParameter="Replace"/> @@ -202,8 +200,7 @@ + SelectedIndex="0"> @@ -211,8 +208,18 @@ - + + + + + Command="{Binding TabCommand, RelativeSource={RelativeSource AncestorType=Window}}" + CommandParameter="Active"> @@ -351,7 +359,8 @@ + Command="{Binding TabCommand, RelativeSource={RelativeSource AncestorType=Window}}" + CommandParameter="Past"> diff --git a/src/Everything2Everything.App/Views/MainWindow.xaml.cs b/src/Everything2Everything.App/Views/MainWindow.xaml.cs index ded3f96..2296a29 100644 --- a/src/Everything2Everything.App/Views/MainWindow.xaml.cs +++ b/src/Everything2Everything.App/Views/MainWindow.xaml.cs @@ -50,6 +50,9 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow public ICommand PreviewOpenFolderCommand { get; } public ICommand RemoveQueueItemCommand { get; } public ICommand OpenFolderCommand { get; } + public ICommand TabCommand { get; } + public ICommand ConflictRuleCommand { get; } + public ICommand CombineToggleCommand { get; } public MainWindow(ConversionEngine engine, ISettingsStore settings, IReadOnlyList? initialFiles = null) { @@ -72,6 +75,9 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow PreviewOpenFolderCommand = new RelayCommand(_ => OnPreviewOpenFolder(this, new RoutedEventArgs())); RemoveQueueItemCommand = new RelayCommand(p => RemoveQueueItem(p as QueueItem)); OpenFolderCommand = new RelayCommand(p => OpenFolderForPath(p as string)); + TabCommand = new RelayCommand(p => ShowTab(p as string ?? "Past")); + ConflictRuleCommand = new RelayCommand(p => SetConflictRule(p as string)); + CombineToggleCommand = new RelayCommand(_ => UpdateCombineState(SelectedOutputExtension)); InitializeComponent(); @@ -147,14 +153,6 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow // ============== Tabs ============== - private void OnTabClick(object sender, RoutedEventArgs e) - { - if (sender is ToggleButton tb && tb.Tag is string tag) - { - ShowTab(tag); - } - } - private void ShowTab(string tag) { TabActiveBtn.IsChecked = tag == "Active"; @@ -270,32 +268,18 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow // ============== Sidebar inputs ============== - private void OnQualityChanged(object sender, RoutedPropertyChangedEventArgs e) + private void SetConflictRule(string? tag) { - if (QualityValueText is null) return; - QualityValueText.Text = $"{(int)e.NewValue}%"; - } - - private void OnConflictSegmentClick(object sender, RoutedEventArgs e) - { - if (sender is not ToggleButton clicked) return; - ConflictSkipBtn.IsChecked = clicked == ConflictSkipBtn; - ConflictRenameBtn.IsChecked = clicked == ConflictRenameBtn; - ConflictReplaceBtn.IsChecked = clicked == ConflictReplaceBtn; - _conflictRule = (clicked.Tag as string) switch + _conflictRule = tag switch { "Skip" => NameCollision.Skip, "Replace" => NameCollision.Overwrite, _ => NameCollision.AppendNumber, }; - } - - private void OnAiTaskChanged(object sender, SelectionChangedEventArgs e) - { - // 번역(인덱스 1)일 때만 대상 언어 입력을 표시 - if (AiTargetLangPanel is null) return; - AiTargetLangPanel.Visibility = - (AiTaskCombo?.SelectedIndex == 1) ? Visibility.Visible : Visibility.Collapsed; + // 세그먼트 토글 그룹의 상호배제(하나만 체크). + ConflictSkipBtn.IsChecked = tag == "Skip"; + ConflictRenameBtn.IsChecked = tag == "Rename"; + ConflictReplaceBtn.IsChecked = tag == "Replace"; } private void OnPickOutputFolderClick(object sender, RoutedEventArgs e) @@ -1052,11 +1036,6 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow }; } - private void OnCombineToggleChanged(object sender, RoutedEventArgs e) - { - UpdateCombineState(SelectedOutputExtension); - } - private void OnOutputFormatChanged(object sender, SelectionChangedEventArgs e) { if (_suppressFormatChanged) return;